Java tutorial
/* * Autopsy Forensic Browser * * Copyright 2013 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sleuthkit.autopsy.imageanalyzer.datamodel; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.image.Image; import javafx.util.Pair; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.imageanalyzer.ImageAnalyzerModule; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG; import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.ContentTag; import org.sleuthkit.datamodel.ContentVisitor; import org.sleuthkit.datamodel.SleuthkitItemVisitor; import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TagName; import org.sleuthkit.datamodel.TskCoreException; /** * @TODO: There is something I don't understand or have done wrong about * implementing this class,as it is unreadable by * {@link ReadContentInputStream}. As a work around we keep a reference to the * original {@link AbstractFile} to use when reading the image. -jm */ public abstract class DrawableFile<T extends AbstractFile> extends AbstractFile { public static DrawableFile<?> create(AbstractFile abstractFileById, boolean analyzed) { if (ImageAnalyzerModule.isVideoFile(abstractFileById)) { return new VideoFile<>(abstractFileById, analyzed); } else { return new ImageFile<>(abstractFileById, analyzed); } } public static DrawableFile<?> create(Long id, boolean analyzed) throws TskCoreException, IllegalStateException { AbstractFile abstractFileById = Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(id); if (ImageAnalyzerModule.isVideoFile(abstractFileById)) { return new VideoFile<>(abstractFileById, analyzed); } else { return new ImageFile<>(abstractFileById, analyzed); } } private String drawablePath; protected T file; private final SimpleBooleanProperty analyzed; private final SimpleObjectProperty<Category> category = new SimpleObjectProperty<>(null); private Collection<String> hashHitSetNames; private String make; private String model; protected DrawableFile(T file, Boolean analyzed) { /* @TODO: the two 'new Integer(0).shortValue()' values and null are * placeholders because the super constructor expects values i can't get * easily at the moment. I assume this is related to why ReadContentInputStream can't read from DrawableFiles.*/ super(file.getSleuthkitCase(), file.getId(), file.getAttrType(), file.getAttrId(), file.getName(), file.getType(), file.getMetaAddr(), (int) file.getMetaSeq(), file.getDirType(), file.getMetaType(), null, new Integer(0).shortValue(), file.getSize(), file.getCtime(), file.getCrtime(), file.getAtime(), file.getMtime(), new Integer(0).shortValue(), file.getUid(), file.getGid(), file.getMd5Hash(), file.getKnown(), file.getParentPath()); this.analyzed = new SimpleBooleanProperty(analyzed); this.file = file; } public abstract boolean isVideo(); public Collection<String> getHashHitSetNames() { updateHashSets(); return hashHitSetNames; } @SuppressWarnings("unchecked") private void updateHashSets() { hashHitSetNames = (Collection<String>) getValuesOfBBAttribute( BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME); } @Override public boolean isRoot() { return false; } @Override public <T> T accept(SleuthkitItemVisitor<T> v) { return file.accept(v); } @Override public <T> T accept(ContentVisitor<T> v) { return file.accept(v); } @Override public List<Content> getChildren() throws TskCoreException { return new ArrayList<>(); } @Override public List<Long> getChildrenIds() throws TskCoreException { return new ArrayList<>(); } public ObservableList<Pair<DrawableAttribute<?>, ? extends Object>> getAttributesList() { final ObservableList<Pair<DrawableAttribute<?>, ? extends Object>> attributeList = FXCollections .observableArrayList(); for (DrawableAttribute<?> attr : DrawableAttribute.getValues()) { attributeList.add(new Pair<>(attr, attr.getValue(this))); } return attributeList; } public String getModel() { if (model == null) { model = WordUtils.capitalizeFully( (String) getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL)); } return model; } public String getMake() { if (make == null) { make = WordUtils.capitalizeFully( (String) getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE)); } return make; } public Set<TagName> getTagNames() { try { List<ContentTag> contentTagsByContent = Case.getCurrentCase().getServices().getTagsManager() .getContentTagsByContent(this); return contentTagsByContent.stream().map(Tag::getName).collect(Collectors.toSet()); } catch (TskCoreException ex) { Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up " + DrawableAttribute.TAGS.getDisplayName() + " for " + file.getName(), ex); return Collections.emptySet(); } } @Deprecated protected final List<? extends Object> getValuesOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE artType, BlackboardAttribute.ATTRIBUTE_TYPE attrType) { ArrayList<Object> vals = new ArrayList<>(); try { //why doesn't file.getArtifacts() work? //TODO: this seams like overkill, use a more targeted query ArrayList<BlackboardArtifact> artifacts = getAllArtifacts(); for (BlackboardArtifact artf : artifacts) { if (artf.getArtifactTypeID() == artType.getTypeID()) { for (BlackboardAttribute attr : artf.getAttributes()) { if (attr.getAttributeTypeID() == attrType.getTypeID()) { switch (attr.getValueType()) { case BYTE: vals.add(attr.getValueBytes()); break; case DOUBLE: vals.add(attr.getValueDouble()); break; case INTEGER: vals.add(attr.getValueInt()); break; case LONG: vals.add(attr.getValueLong()); break; case STRING: vals.add(attr.getValueString()); break; } } } } } } catch (TskCoreException ex) { Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up {0}/{1}" + " " + " for {2}", new Object[] { artType.getDisplayName(), attrType.getDisplayName(), getName() }); } return vals; } protected Object getValueOfBBAttribute(BlackboardArtifact.ARTIFACT_TYPE artType, BlackboardAttribute.ATTRIBUTE_TYPE attrType) { try { //why doesn't file.getArtifacts() work? //TODO: this seams like overkill, use a more targeted query ArrayList<BlackboardArtifact> artifacts = file.getArtifacts(artType);// getAllArtifacts(); for (BlackboardArtifact artf : artifacts) { if (artf.getArtifactTypeID() == artType.getTypeID()) { for (BlackboardAttribute attr : artf.getAttributes()) { if (attr.getAttributeTypeID() == attrType.getTypeID()) { switch (attr.getValueType()) { case BYTE: return attr.getValueBytes(); case DOUBLE: return attr.getValueDouble(); case INTEGER: return attr.getValueInt(); case LONG: return attr.getValueLong(); case STRING: return attr.getValueString(); } } } } } } catch (TskCoreException ex) { Logger.getAnonymousLogger().log(Level.WARNING, "problem looking up {0}/{1}" + " " + " for {2}", new Object[] { artType.getDisplayName(), attrType.getDisplayName(), getName() }); } return ""; } public void setCategory(Category category) { categoryProperty().set(category); } public Category getCategory() { updateCategory(); return category.get(); } public SimpleObjectProperty<Category> categoryProperty() { return category; } public void updateCategory() { try { List<ContentTag> contentTagsByContent = Case.getCurrentCase().getServices().getTagsManager() .getContentTagsByContent(this); Category cat = null; for (ContentTag ct : contentTagsByContent) { if (ct.getName().getDisplayName().startsWith(Category.CATEGORY_PREFIX)) { cat = Category.fromDisplayName(ct.getName().getDisplayName()); break; } } if (cat == null) { category.set(Category.ZERO); } else { category.set(cat); } } catch (TskCoreException ex) { Logger.getLogger(DrawableFile.class.getName()).log(Level.WARNING, "problem looking up category for file " + this.getName(), ex); } } public abstract Image getThumbnail(); public void setAnalyzed(Boolean analyzed) { this.analyzed.set(analyzed); } public boolean isAnalyzed() { return analyzed.get(); } public T getAbstractFile() { return this.file; } abstract Double getWidth(); abstract Double getHeight(); public String getDrawablePath() { if (drawablePath != null) { return drawablePath; } else { try { drawablePath = StringUtils.removeEnd(getUniquePath(), getName()); return drawablePath; } catch (TskCoreException ex) { Logger.getLogger(DrawableFile.class.getName()).log(Level.WARNING, "failed to get drawablePath from {0}", getName()); return ""; } } } }