/* * Autopsy Forensic Browser * * Copyright 2011-2014 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.datamodel; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.FileSystem; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.VolumeSystem; /** * Makes the children nodes / keys for a given content object. Has knowledge * about the structure of the directory tree and what levels should be ignored. * TODO consider a ContentChildren child factory */ class ContentChildren extends AbstractContentChildren<Content> { private static final Logger logger = Logger.getLogger(ContentChildren.class.getName()); //private static final int MAX_CHILD_COUNT = 1000000; private final Content parent; ContentChildren(Content parent) { super(); //initialize lazy behavior this.parent = parent; } /** * Get the children of the Content object based on what we want to display. * As an example, we don't display the direct children of VolumeSystems or * FileSystems. We hide some of the levels in the tree. This method takes * care of that and returns the children we want to display * * @param parent * * @return */ private static List<Content> getDisplayChildren(Content parent) { // what does the content think its children are? List<Content> tmpChildren; try { tmpChildren = parent.getChildren(); } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error getting Content children.", ex); //NON-NLS tmpChildren = Collections.emptyList(); } // Cycle through the list and make a new one based // on what we actually want to display. List<Content> children = new ArrayList<>(); for (Content c : tmpChildren) { if (c instanceof VolumeSystem) { children.addAll(getDisplayChildren(c)); } else if (c instanceof FileSystem) { children.addAll(getDisplayChildren(c)); } else if (c instanceof Directory) { Directory dir = (Directory) c; /* * For root directories, we want to return their contents. * Special case though for '.' and '..' entries, because they * should not have children (and in fact don't in the DB). Other * drs get treated as files and added as is. */ if ((dir.isRoot()) && (dir.getName().equals(".") == false) && (dir.getName().equals("..") == false)) { children.addAll(getDisplayChildren(dir)); } else { children.add(c); } } else { children.add(c); } } return children; } @Override protected void addNotify() { super.addNotify(); //TODO check global settings //if above limit, query and return subrange //StopWatch s2 = new StopWatch(); //s2.start(); //logger.log(Level.INFO, "GETTING CHILDREN CONTENT for parent: " + parent.getName()); List<Content> children = getDisplayChildren(parent); //s2.stop(); //logger.log(Level.INFO, "GOT CHILDREN CONTENTS:" + children.size() + ", took: " + s2.getElapsedTime()); //limit number children //setKeys(children.subList(0, Math.min(children.size(), MAX_CHILD_COUNT))); setKeys(children); } @Override protected void removeNotify() { super.removeNotify(); setKeys(new ArrayList<>()); } /** * Refresh the list of children due to a change in one (or more) of our * children (e.g. archive files can change as new content is extracted from * them). */ void refreshChildren() { List<Content> children = getDisplayChildren(parent); setKeys(children); } }