Autopsy  4.12.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CaseUcoFormatExporter.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2018-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.report.caseuco;
20 
21 import com.fasterxml.jackson.core.JsonEncoding;
22 import com.fasterxml.jackson.core.JsonFactory;
23 import com.fasterxml.jackson.core.JsonGenerator;
24 import com.fasterxml.jackson.core.util.DefaultIndenter;
25 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
26 import com.google.common.collect.Lists;
27 import java.io.File;
28 import java.io.IOException;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.sql.ResultSet;
33 import java.sql.SQLException;
34 import java.util.List;
35 import java.util.SimpleTimeZone;
36 import java.util.TimeZone;
37 import java.util.logging.Level;
38 import org.apache.commons.io.FileUtils;
39 import org.openide.util.NbBundle;
48 import org.sleuthkit.datamodel.AbstractFile;
49 import org.sleuthkit.datamodel.BlackboardArtifact;
50 import org.sleuthkit.datamodel.BlackboardArtifactTag;
51 import org.sleuthkit.datamodel.BlackboardAttribute;
52 import org.sleuthkit.datamodel.Content;
53 import org.sleuthkit.datamodel.ContentTag;
54 import org.sleuthkit.datamodel.DataSource;
55 import org.sleuthkit.datamodel.SleuthkitCase;
56 import org.sleuthkit.datamodel.TskCoreException;
57 import org.sleuthkit.datamodel.TskData;
58 import org.sleuthkit.datamodel.TagName;
59 
63 public final class CaseUcoFormatExporter {
64 
65  private static final Logger logger = Logger.getLogger(CaseUcoFormatExporter.class.getName());
66 
67  private static final BlackboardAttribute.Type SET_NAME = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME);
68  private static final BlackboardArtifact.ARTIFACT_TYPE INTERESTING_FILE_HIT = BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
69  private static final BlackboardArtifact.ARTIFACT_TYPE INTERESTING_ARTIFACT_HIT = BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
70  private static final String TEMP_DIR_NAME = "case_uco_tmp";
71 
73  }
74 
83  @NbBundle.Messages({
84  "ReportCaseUco.noCaseOpen=Unable to open currect case",
85  "ReportCaseUco.unableToCreateDirectories=Unable to create directory for CASE-UCO report",
86  "ReportCaseUco.initializing=Creating directories...",
87  "ReportCaseUco.querying=Querying files...",
88  "ReportCaseUco.ingestWarning=Warning, this report will be created before ingest services completed",
89  "ReportCaseUco.processing=Saving files in CASE-UCO format...",
90  "ReportCaseUco.srcModuleName.text=CASE-UCO Report"
91  })
92  @SuppressWarnings("deprecation")
93  public static void generateReport(Long selectedDataSourceId, String reportOutputPath, ReportProgressPanel progressPanel) {
94 
95  // Start the progress bar and setup the report
96  progressPanel.setIndeterminate(false);
97  progressPanel.start();
98  progressPanel.updateStatusLabel(Bundle.ReportCaseUco_initializing());
99 
100  // Create the JSON generator
101  JsonFactory jsonGeneratorFactory = new JsonFactory();
102  java.io.File reportFile = Paths.get(reportOutputPath).toFile();
103  try {
104  Files.createDirectories(Paths.get(reportFile.getParent()));
105  } catch (IOException ex) {
106  logger.log(Level.SEVERE, "Unable to create directory for CASE-UCO report", ex); //NON-NLS
107  MessageNotifyUtil.Message.error(Bundle.ReportCaseUco_unableToCreateDirectories());
109  return;
110  }
111 
112  // Check if ingest has finished
114  MessageNotifyUtil.Message.warn(Bundle.ReportCaseUco_ingestWarning());
115  }
116 
117  JsonGenerator jsonGenerator = null;
118  SimpleTimeZone timeZone = new SimpleTimeZone(0, "GMT");
119  try {
120  jsonGenerator = jsonGeneratorFactory.createGenerator(reportFile, JsonEncoding.UTF8);
121  // instert \n after each field for more readable formatting
122  jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter().withObjectIndenter(new DefaultIndenter(" ", "\n")));
123 
124  SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
125 
126  progressPanel.updateStatusLabel(Bundle.ReportCaseUco_querying());
127 
128  // create the required CASE-UCO entries at the beginning of the output file
129  initializeJsonOutputFile(jsonGenerator);
130 
131  // create CASE-UCO entry for the Autopsy case
132  String caseTraceId = saveCaseInfo(skCase, jsonGenerator);
133 
134  // create CASE-UCO data source entry
135  String dataSourceTraceId = saveDataSourceInfo(selectedDataSourceId, caseTraceId, skCase, jsonGenerator);
136 
137  // Run getAllFilesQuery to get all files, exclude directories
138  final String getAllFilesQuery = "select obj_id, name, size, crtime, atime, mtime, md5, parent_path, mime_type, extension from tsk_files where "
139  + "data_source_obj_id = " + Long.toString(selectedDataSourceId)
140  + " AND ((meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_UNDEF.getValue()
141  + ") OR (meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue()
142  + ") OR (meta_type = " + TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT.getValue() + "))"; //NON-NLS
143 
144  try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getAllFilesQuery)) {
145  ResultSet resultSet = queryResult.getResultSet();
146 
147  progressPanel.updateStatusLabel(Bundle.ReportCaseUco_processing());
148 
149  // Loop files and write info to CASE-UCO report
150  while (resultSet.next()) {
151 
152  if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
153  break;
154  }
155 
156  Long objectId = resultSet.getLong(1);
157  String fileName = resultSet.getString(2);
158  long size = resultSet.getLong("size");
159  String crtime = ContentUtils.getStringTimeISO8601(resultSet.getLong("crtime"), timeZone);
160  String atime = ContentUtils.getStringTimeISO8601(resultSet.getLong("atime"), timeZone);
161  String mtime = ContentUtils.getStringTimeISO8601(resultSet.getLong("mtime"), timeZone);
162  String md5Hash = resultSet.getString("md5");
163  String parent_path = resultSet.getString("parent_path");
164  String mime_type = resultSet.getString("mime_type");
165  String extension = resultSet.getString("extension");
166 
167  saveFileInCaseUcoFormat(objectId, fileName, parent_path, md5Hash, mime_type, size, crtime, atime, mtime, extension, jsonGenerator, dataSourceTraceId);
168  }
169  }
170 
171  // create the required CASE-UCO entries at the end of the output file
172  finilizeJsonOutputFile(jsonGenerator);
173 
174  Case.getCurrentCaseThrows().addReport(reportOutputPath, Bundle.ReportCaseUco_srcModuleName_text(), "");
175 
177  } catch (TskCoreException ex) {
178  logger.log(Level.SEVERE, "Failed to get list of files from case database", ex); //NON-NLS
180  } catch (IOException ex) {
181  logger.log(Level.SEVERE, "Failed to create JSON output for the CASE-UCO report", ex); //NON-NLS
183  } catch (SQLException ex) {
184  logger.log(Level.WARNING, "Unable to read result set", ex); //NON-NLS
186  } catch (NoCurrentCaseException ex) {
187  logger.log(Level.SEVERE, "No current case open", ex); //NON-NLS
189  } finally {
190  if (jsonGenerator != null) {
191  try {
192  jsonGenerator.close();
193  } catch (IOException ex) {
194  logger.log(Level.WARNING, "Failed to close JSON output file", ex); //NON-NLS
195  }
196  }
197  }
198  }
199 
214  @NbBundle.Messages({
215  "CaseUcoFormatExporter.startMsg=Generating CASE-UCO Report",
216  "CaseUcoFormatExporter.datasourceMsg=Generating CASE-UCO Report for %s",
217  "CaseUcoFormatExporter.finishMsg=Finished generating CASE-UCO Report"
218  })
219  public static void export(List<TagName> tagTypes, List<String> interestingItemSets,
220  File caseReportFolder, ReportProgressPanel progressPanel) throws IOException, SQLException,
221  NoCurrentCaseException, TskCoreException {
222 
223  progressPanel.updateStatusLabel(Bundle.CaseUcoFormatExporter_startMsg());
224  //Acquire references for file discovery
225  Case currentCase = Case.getCurrentCaseThrows();
226  String caseTempDirectory = currentCase.getTempDirectory();
227  SleuthkitCase skCase = currentCase.getSleuthkitCase();
228  TagsManager tagsManager = currentCase.getServices().getTagsManager();
229 
230  //Create temp directory to filter out duplicate files.
231  Path tmpDir = Paths.get(caseTempDirectory, TEMP_DIR_NAME);
232  FileUtils.deleteDirectory(tmpDir.toFile());
233  Files.createDirectory(tmpDir);
234 
235  //Create our report file
236  Path reportFile = Paths.get(caseReportFolder.toString(),
238 
239  //Timezone for formatting file creation, modification, and accessed times
240  SimpleTimeZone timeZone = new SimpleTimeZone(0, "GMT");
241 
242  try (JsonGenerator jsonGenerator = createJsonGenerator(reportFile.toFile())) {
243  initializeJsonOutputFile(jsonGenerator);
244  //Make the case the first entity in the report file.
245  String caseTraceId = saveCaseInfo(skCase, jsonGenerator);
246 
247  for (DataSource ds : skCase.getDataSources()) {
248  progressPanel.updateStatusLabel(String.format(
249  Bundle.CaseUcoFormatExporter_datasourceMsg(), ds.getName()));
250  String dataSourceTraceId = saveDataSourceInfo(ds.getId(),
251  caseTraceId, skCase, jsonGenerator);
252  for (TagName tn : tagTypes) {
253  for (ContentTag ct : tagsManager.getContentTagsByTagName(tn, ds.getId())) {
254  saveUniqueFilesToCaseUcoFormat(ct.getContent(), tmpDir,
255  jsonGenerator, timeZone, dataSourceTraceId);
256  }
257  for (BlackboardArtifactTag bat : tagsManager.getBlackboardArtifactTagsByTagName(tn, ds.getId())) {
258  saveUniqueFilesToCaseUcoFormat(bat.getContent(), tmpDir,
259  jsonGenerator, timeZone, dataSourceTraceId);
260  }
261  }
262  if(!interestingItemSets.isEmpty()) {
263  List<BlackboardArtifact.ARTIFACT_TYPE> typesToQuery = Lists.newArrayList(
265  for(BlackboardArtifact.ARTIFACT_TYPE artType : typesToQuery) {
266  for(BlackboardArtifact bArt : skCase.getBlackboardArtifacts(artType)) {
267  if(bArt.getDataSource().getId() != ds.getId()) {
268  continue;
269  }
270  BlackboardAttribute setAttr = bArt.getAttribute(SET_NAME);
271  if (interestingItemSets.contains(setAttr.getValueString())) {
272  Content content = skCase.getContentById(bArt.getObjectID());
273  saveUniqueFilesToCaseUcoFormat(content, tmpDir,
274  jsonGenerator, timeZone, dataSourceTraceId);
275  }
276  }
277  }
278  }
279  }
280  finilizeJsonOutputFile(jsonGenerator);
281  progressPanel.updateStatusLabel(Bundle.CaseUcoFormatExporter_finishMsg());
282  }
283  }
284 
297  private static void saveUniqueFilesToCaseUcoFormat(Content content, Path tmpDir, JsonGenerator jsonGenerator,
298  TimeZone timeZone, String dataSourceTraceId) throws IOException {
299  if (content instanceof AbstractFile && !(content instanceof DataSource)) {
300  AbstractFile absFile = (AbstractFile) content;
301  Path filePath = tmpDir.resolve(Long.toString(absFile.getId()));
302  if (!Files.exists(filePath) && !absFile.isDir()) {
304  absFile.getId(),
305  absFile.getName(),
306  absFile.getParentPath(),
307  absFile.getMd5Hash(),
308  absFile.getMIMEType(),
309  absFile.getSize(),
310  ContentUtils.getStringTimeISO8601(absFile.getCtime(), timeZone),
311  ContentUtils.getStringTimeISO8601(absFile.getAtime(), timeZone),
312  ContentUtils.getStringTimeISO8601(absFile.getMtime(), timeZone),
313  absFile.getNameExtension(),
314  jsonGenerator,
315  dataSourceTraceId
316  );
317  filePath.toFile().createNewFile();
318  }
319  }
320  }
321 
322  private static JsonGenerator createJsonGenerator(File reportFile) throws IOException {
323  JsonFactory jsonGeneratorFactory = new JsonFactory();
324  JsonGenerator jsonGenerator = jsonGeneratorFactory.createGenerator(reportFile, JsonEncoding.UTF8);
325  // instert \n after each field for more readable formatting
326  jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter().withObjectIndenter(new DefaultIndenter(" ", "\n")));
327  return jsonGenerator;
328  }
329 
330  private static void initializeJsonOutputFile(JsonGenerator catalog) throws IOException {
331  catalog.writeStartObject();
332  catalog.writeFieldName("@graph");
333  catalog.writeStartArray();
334  }
335 
336  private static void finilizeJsonOutputFile(JsonGenerator catalog) throws IOException {
337  catalog.writeEndArray();
338  catalog.writeEndObject();
339  }
340 
352  private static String saveCaseInfo(SleuthkitCase skCase, JsonGenerator catalog) throws TskCoreException, SQLException, IOException, NoCurrentCaseException {
353 
354  // create a "trace" entry for the Autopsy case iteself
355  String uniqueCaseName;
356  String dbFileName;
357  TskData.DbType dbType = skCase.getDatabaseType();
358  if (dbType == TskData.DbType.SQLITE) {
359  uniqueCaseName = Case.getCurrentCaseThrows().getName();
360  dbFileName = skCase.getDatabaseName();
361  } else {
362  uniqueCaseName = skCase.getDatabaseName();
363  dbFileName = "";
364  }
365 
366  String caseDirPath = skCase.getDbDirPath();
367  String caseTraceId = "case-" + uniqueCaseName;
368  catalog.writeStartObject();
369  catalog.writeStringField("@id", caseTraceId);
370  catalog.writeStringField("@type", "Trace");
371 
372  catalog.writeFieldName("propertyBundle");
373  catalog.writeStartArray();
374  catalog.writeStartObject();
375 
376  // replace double slashes with single ones
377  caseDirPath = caseDirPath.replaceAll("\\\\", "/");
378 
379  catalog.writeStringField("@type", "File");
380  if (dbType == TskData.DbType.SQLITE) {
381  catalog.writeStringField("filePath", caseDirPath + "/" + dbFileName);
382  catalog.writeBooleanField("isDirectory", false);
383  } else {
384  catalog.writeStringField("filePath", caseDirPath);
385  catalog.writeBooleanField("isDirectory", true);
386  }
387  catalog.writeEndObject();
388 
389  catalog.writeEndArray();
390  catalog.writeEndObject();
391 
392  return caseTraceId;
393  }
394 
407  private static String saveDataSourceInfo(Long selectedDataSourceId, String caseTraceId, SleuthkitCase skCase, JsonGenerator jsonGenerator) throws TskCoreException, SQLException, IOException {
408 
409  Long imageSize = (long) 0;
410  String imageName = "";
411  boolean isImageDataSource = false;
412  String getImageDataSourceQuery = "select size from tsk_image_info where obj_id = " + selectedDataSourceId;
413  try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getImageDataSourceQuery)) {
414  ResultSet resultSet = queryResult.getResultSet();
415  // check if we got a result
416  while (resultSet.next()) {
417  // we got a result so the data source was an image data source
418  imageSize = resultSet.getLong(1);
419  isImageDataSource = true;
420  break;
421  }
422  }
423 
424  if (isImageDataSource) {
425  // get caseDirPath to image file
426  String getPathToDataSourceQuery = "select name from tsk_image_names where obj_id = " + selectedDataSourceId;
427  try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getPathToDataSourceQuery)) {
428  ResultSet resultSet = queryResult.getResultSet();
429  while (resultSet.next()) {
430  imageName = resultSet.getString(1);
431  break;
432  }
433  }
434  } else {
435  // logical file data source
436  String getLogicalDataSourceQuery = "select name from tsk_files where obj_id = " + selectedDataSourceId;
437  try (SleuthkitCase.CaseDbQuery queryResult = skCase.executeQuery(getLogicalDataSourceQuery)) {
438  ResultSet resultSet = queryResult.getResultSet();
439  while (resultSet.next()) {
440  imageName = resultSet.getString(1);
441  break;
442  }
443  }
444  }
445 
446  return saveDataSourceInCaseUcoFormat(jsonGenerator, imageName, imageSize, selectedDataSourceId, caseTraceId);
447  }
448 
449  private static String saveDataSourceInCaseUcoFormat(JsonGenerator catalog, String imageName, Long imageSize, Long selectedDataSourceId, String caseTraceId) throws IOException {
450 
451  // create a "trace" entry for the data source
452  String dataSourceTraceId = "data-source-" + selectedDataSourceId;
453  catalog.writeStartObject();
454  catalog.writeStringField("@id", dataSourceTraceId);
455  catalog.writeStringField("@type", "Trace");
456 
457  catalog.writeFieldName("propertyBundle");
458  catalog.writeStartArray();
459 
460  catalog.writeStartObject();
461  catalog.writeStringField("@type", "File");
462 
463  // replace double back slashes with single ones
464  imageName = imageName.replaceAll("\\\\", "/");
465 
466  catalog.writeStringField("filePath", imageName);
467  catalog.writeEndObject();
468 
469  if (imageSize > 0) {
470  catalog.writeStartObject();
471  catalog.writeStringField("@type", "ContentData");
472  catalog.writeStringField("sizeInBytes", Long.toString(imageSize));
473  catalog.writeEndObject();
474  }
475 
476  catalog.writeEndArray();
477  catalog.writeEndObject();
478 
479  // create a "relationship" entry between the case and the data source
480  catalog.writeStartObject();
481  catalog.writeStringField("@id", "relationship-" + caseTraceId);
482  catalog.writeStringField("@type", "Relationship");
483  catalog.writeStringField("source", dataSourceTraceId);
484  catalog.writeStringField("target", caseTraceId);
485  catalog.writeStringField("kindOfRelationship", "contained-within");
486  catalog.writeBooleanField("isDirectional", true);
487 
488  catalog.writeFieldName("propertyBundle");
489  catalog.writeStartArray();
490  catalog.writeStartObject();
491  catalog.writeStringField("@type", "PathRelation");
492  catalog.writeStringField("path", imageName);
493  catalog.writeEndObject();
494  catalog.writeEndArray();
495 
496  catalog.writeEndObject();
497 
498  return dataSourceTraceId;
499  }
500 
501  private static void saveFileInCaseUcoFormat(Long objectId, String fileName, String parent_path, String md5Hash, String mime_type, long size, String ctime,
502  String atime, String mtime, String extension, JsonGenerator catalog, String dataSourceTraceId) throws IOException {
503 
504  String fileTraceId = "file-" + objectId;
505 
506  // create a "trace" entry for the file
507  catalog.writeStartObject();
508  catalog.writeStringField("@id", fileTraceId);
509  catalog.writeStringField("@type", "Trace");
510 
511  catalog.writeFieldName("propertyBundle");
512  catalog.writeStartArray();
513 
514  catalog.writeStartObject();
515  catalog.writeStringField("@type", "File");
516  catalog.writeStringField("createdTime", ctime);
517  catalog.writeStringField("accessedTime", atime);
518  catalog.writeStringField("modifiedTime", mtime);
519  if (extension != null) {
520  catalog.writeStringField("extension", extension);
521  }
522  catalog.writeStringField("fileName", fileName);
523  if (parent_path != null) {
524  catalog.writeStringField("filePath", parent_path + fileName);
525  }
526  catalog.writeBooleanField("isDirectory", false);
527  catalog.writeStringField("sizeInBytes", Long.toString(size));
528  catalog.writeEndObject();
529 
530  catalog.writeStartObject();
531  catalog.writeStringField("@type", "ContentData");
532  if (mime_type != null) {
533  catalog.writeStringField("mimeType", mime_type);
534  }
535  if (md5Hash != null) {
536  catalog.writeFieldName("hash");
537  catalog.writeStartArray();
538  catalog.writeStartObject();
539  catalog.writeStringField("@type", "Hash");
540  catalog.writeStringField("hashMethod", "MD5");
541  catalog.writeStringField("hashValue", md5Hash);
542  catalog.writeEndObject();
543  catalog.writeEndArray();
544  }
545  catalog.writeStringField("sizeInBytes", Long.toString(size));
546 
547  catalog.writeEndObject();
548 
549  catalog.writeEndArray();
550  catalog.writeEndObject();
551 
552  // create a "relationship" entry between the file and the data source
553  catalog.writeStartObject();
554  catalog.writeStringField("@id", "relationship-" + objectId);
555  catalog.writeStringField("@type", "Relationship");
556  catalog.writeStringField("source", fileTraceId);
557  catalog.writeStringField("target", dataSourceTraceId);
558  catalog.writeStringField("kindOfRelationship", "contained-within");
559  catalog.writeBooleanField("isDirectional", true);
560 
561  catalog.writeFieldName("propertyBundle");
562  catalog.writeStartArray();
563  catalog.writeStartObject();
564  catalog.writeStringField("@type", "PathRelation");
565  if (parent_path != null) {
566  catalog.writeStringField("path", parent_path + fileName);
567  } else {
568  catalog.writeStringField("path", fileName);
569  }
570  catalog.writeEndObject();
571  catalog.writeEndArray();
572 
573  catalog.writeEndObject();
574  }
575 }
static synchronized IngestManager getInstance()
static void generateReport(Long selectedDataSourceId, String reportOutputPath, ReportProgressPanel progressPanel)
static void export(List< TagName > tagTypes, List< String > interestingItemSets, File caseReportFolder, ReportProgressPanel progressPanel)
void addReport(String localPath, String srcModuleName, String reportName)
Definition: Case.java:1570
static String saveDataSourceInfo(Long selectedDataSourceId, String caseTraceId, SleuthkitCase skCase, JsonGenerator jsonGenerator)
static final BlackboardArtifact.ARTIFACT_TYPE INTERESTING_ARTIFACT_HIT
static String getStringTimeISO8601(long epochSeconds, TimeZone tzone)
List< BlackboardArtifactTag > getBlackboardArtifactTagsByTagName(TagName tagName)
static final BlackboardArtifact.ARTIFACT_TYPE INTERESTING_FILE_HIT
static String saveCaseInfo(SleuthkitCase skCase, JsonGenerator catalog)
static void saveUniqueFilesToCaseUcoFormat(Content content, Path tmpDir, JsonGenerator jsonGenerator, TimeZone timeZone, String dataSourceTraceId)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void saveFileInCaseUcoFormat(Long objectId, String fileName, String parent_path, String md5Hash, String mime_type, long size, String ctime, String atime, String mtime, String extension, JsonGenerator catalog, String dataSourceTraceId)
List< ContentTag > getContentTagsByTagName(TagName tagName)
static String saveDataSourceInCaseUcoFormat(JsonGenerator catalog, String imageName, Long imageSize, Long selectedDataSourceId, String caseTraceId)

Copyright © 2012-2018 Basis Technology. Generated on: Wed Sep 18 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.