1
0
mirror of https://github.com/elisspace/autopsy.git synced 2026-09-04 06:50:00 +00:00

Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 2594-GoToSourceArtifactAction

This commit is contained in:
William Schaefer
2017-05-24 15:14:35 -04:00
18 changed files with 174 additions and 239 deletions

View File

@@ -2,7 +2,7 @@ Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.core/10
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
OpenIDE-Module-Implementation-Version: 18
OpenIDE-Module-Implementation-Version: 19
OpenIDE-Module-Requires: org.openide.windows.WindowManager
AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true

View File

@@ -140,11 +140,28 @@ public class Case {
private volatile ExecutorService caseLockingExecutor;
private CoordinationService.Lock caseDirLock;
private SleuthkitCase caseDb;
private SleuthkitErrorReporter sleuthkitErrorReporter;
private CollaborationMonitor collaborationMonitor;
private Services caseServices;
private boolean hasDataSources;
/*
* Get a reference to the main window of the desktop application to use to
* parent pop up dialogs and initialize the application name for use in
* changing the main window title.
*
* TODO (JIRA-2231): Make the application name a RuntimeProperties item set
* by Installers.
*/
static {
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
public void run() {
mainFrame = WindowManager.getDefault().getMainWindow();
appName = mainFrame.getTitle();
}
});
}
/**
* An enumeration of case types.
*/
@@ -474,8 +491,8 @@ public class Case {
throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(), ex);
}
if (CaseType.MULTI_USER_CASE == metadata.getCaseType() && !UserPreferences.getIsMultiUserModeEnabled()) {
throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
}
throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
}
openAsCurrentCase(new Case(metadata), false);
}
@@ -634,28 +651,6 @@ public class Case {
"Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window"
})
private static void openAsCurrentCase(Case newCurrentCase, boolean isNewCase) throws CaseActionException, CaseActionCancelledException {
if (RuntimeProperties.runningWithGUI() && null == mainFrame) {
/*
* Get a reference to the main window of the desktop application to
* use to parent pop up dialogs and initialize the application name
* for use in changing the main window title. This is tricky and
* fragile. The application name aspect can be resolved thus:
*
* TODO (JIRA-2231): Make the application name a RuntimeProperties
* item set by Installers.
*
* And the getting of the main frame should be resolved when the
* code is refactored to separate the presentation layer fomr the
* business layer.
*
* TODO (JIRA-multiple): Make it possible to run "headless."
*/
assert (!SwingUtilities.isEventDispatchThread());
SwingUtilities.invokeLater(() -> {
mainFrame = WindowManager.getDefault().getMainWindow();
appName = mainFrame.getTitle();
});
}
synchronized (caseActionSerializationLock) {
if (null != currentCase) {
try {
@@ -1815,7 +1810,6 @@ public class Case {
*/
@Messages({
"Case.progressMessage.switchingLogDirectory=Switching log directory...",
"Case.progressMessage.settingUpTskErrorReporting=Setting up SleuthKit error reporting...",
"Case.progressMessage.clearingTempDirectory=Clearing case temp directory...",
"Case.progressMessage.openingCaseLevelServices=Opening case-level services...",
"Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
@@ -1831,18 +1825,6 @@ public class Case {
throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelledByUser());
}
/*
* Hook up a SleuthKit layer error reporter.
*/
progressIndicator.progress(Bundle.Case_progressMessage_settingUpTskErrorReporting());
sleuthkitErrorReporter
= new SleuthkitErrorReporter(MIN_SECS_BETWEEN_TSK_ERROR_REPORTS, NbBundle.getMessage(Case.class,
"IntervalErrorReport.ErrorText"));
caseDb.addErrorObserver(this.sleuthkitErrorReporter);
if (Thread.currentThread().isInterrupted()) {
throw new CaseActionCancelledException(Bundle.Case_exceptionMessage_cancelledByUser());
}
/*
* Clear the temp subdirectory of the case directory.
*/
@@ -2077,8 +2059,8 @@ public class Case {
"Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
"Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
"Case.progressMessage.closingCaseLevelServices=Closing case-level services...",
"Case.progressMessage.closingCaseDatabase=Closing case database...",
"Case.progressMessage.shuttingDownTskErrorReporting=Shutting down SleuthKit error reporting..."})
"Case.progressMessage.closingCaseDatabase=Closing case database..."
})
private void close(ProgressIndicator progressIndicator) {
IngestManager.getInstance().cancelAllIngestJobs(IngestJob.CancellationReason.CASE_CLOSED);
@@ -2119,10 +2101,6 @@ public class Case {
if (null != caseDb) {
progressIndicator.progress(Bundle.Case_progressMessage_closingCaseDatabase());
caseDb.close();
if (null != sleuthkitErrorReporter) {
progressIndicator.progress(Bundle.Case_progressMessage_shuttingDownTskErrorReporting());
caseDb.removeErrorObserver(sleuthkitErrorReporter);
}
}
/*
@@ -2391,6 +2369,17 @@ public class Case {
}
/**
* Gets the application name.
*
* @return The application name.
* @deprecated
*/
@Deprecated
public static String getAppName() {
return appName;
}
/**
* Creates a new, single-user Autopsy case.
*
@@ -2632,16 +2621,4 @@ public class Case {
deleteReports(reports);
}
/**
* Sets the name of the keyword search index for the case.
*
* @param textIndexName The text index name.
*
* @throws CaseMetadataException
* @deprecated Do not use.
*/
@Deprecated
public void setTextIndexName(String textIndexName) throws CaseMetadataException {
}
}

View File

@@ -1,85 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 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.casemodule;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* Acts as a bridge between the Sleuthkit Java bindings classes and Autopsy by
* implementing the SleuthkitCase$ErrorObserver interface. All errors are
* written to the Autopsy logs. If a GUI is running, errors are also batched up
* and reported periodically to the user via the notification area in the lower
* right hand corner of the main application window.
*/
class SleuthkitErrorReporter implements SleuthkitCase.ErrorObserver {
private static final Logger LOGGER = Logger.getLogger(SleuthkitErrorReporter.class.getName());
private final int milliSecondsBetweenReports;
private final String message;
private long newProblems;
private long totalProblems;
private long lastReportedDate;
/**
* Create a new IntervalErrorReprotData instance and subscribe for TSK error
* notifications for the current case.
*
* @param secondsBetweenReports Minimum number of seconds between reports.
* It will not warn more frequently than this.
* @param message The message that will be shown when warning
* the user.
*/
SleuthkitErrorReporter(int secondsBetweenReports, String message) {
this.newProblems = 0;
this.totalProblems = 0;
this.lastReportedDate = 0; // arm the first warning by choosing zero
this.milliSecondsBetweenReports = secondsBetweenReports * 1000; // convert to milliseconds
this.message = message;
}
/**
* Call this to add problems to the class. When the time threshold is met
* (or if this is the first problem encountered), a warning will be shown to
* the user.
*
* @param context The context in which the error occurred.
* @param errorMessage A description of the error that occurred.
*/
@Override
public void receiveError(String context, String errorMessage) {
LOGGER.log(Level.SEVERE, String.format("%s error in the SleuthKit layer: %s", context, errorMessage));
this.newProblems += 1;
this.totalProblems += newProblems;
long currentTimeStamp = System.currentTimeMillis();
if ((currentTimeStamp - lastReportedDate) > milliSecondsBetweenReports) {
this.lastReportedDate = currentTimeStamp;
MessageNotifyUtil.Notify.error(message, context + ", " + errorMessage + " "
+ this.newProblems + " "
+ NbBundle.getMessage(SleuthkitErrorReporter.class, "IntervalErrorReport.NewIssues")
+ " " + this.totalProblems + " "
+ NbBundle.getMessage(SleuthkitErrorReporter.class, "IntervalErrorReport.TotalIssues")
+ ".");
this.newProblems = 0;
}
}
}

View File

@@ -64,7 +64,6 @@ public final class UserPreferences {
private static final String MESSAGE_SERVICE_PORT = "MessageServicePort"; //NON-NLS
public static final String PROCESS_TIME_OUT_ENABLED = "ProcessTimeOutEnabled"; //NON-NLS
public static final String PROCESS_TIME_OUT_HOURS = "ProcessTimeOutHours"; //NON-NLS
public static final String AGENCY_LOGO_IMAGE_PATH = "AgencyLogoImagePath"; //NON-NLS
private static final int DEFAULT_PROCESS_TIMEOUT_HR = 60;
private static final String DEFAULT_PORT_STRING = "61616";
private static final int DEFAULT_PORT_INT = 61616;

View File

@@ -33,7 +33,7 @@ import org.openide.util.NbBundle;
*/
@ActionID(id = "org.sleuthkit.autopsy.corecomponents.AboutWindowAction", category = "Help")
@ActionRegistration(displayName = "#CTL_CustomAboutAction", iconInMenu = true, lazy = false)
@ActionReference(path = "Menu/Help", name = "org-sleuthkit-autopsy-corecomponents-CustomAboutAction", position = 3000)
@ActionReference(path = "Menu/Help", position = 3000)
public class AboutWindowAction extends AboutAction {
@Override

View File

@@ -27,7 +27,7 @@ Format_OperatingSystem_Value={0} version {1} running on {2}
LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; ">Autopsy&trade; is a digital forensics platform based on The Sleuth Kit&trade; and other tools. <br><ul><li>General Information: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>.</li><li>Training: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/autopsy-training">http://www.basistech.com/autopsy-training</a></li><li>Commercial Support: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/digital-forensics/autopsy/support/">http://www.basistech.com/digital-forensics/autopsy/support/</a></li></ul>Copyright &copy; 2003-2017. </div>
URL_ON_IMG=http://www.sleuthkit.org/
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.3/
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.4/
FILE_FOR_LOCAL_HELP=file:///
INDEX_FOR_LOCAL_HELP=/docs/index.html

View File

@@ -138,7 +138,7 @@ public class ImageUtils {
SUPPORTED_IMAGE_EXTENSIONS.addAll(Arrays.asList(ImageIO.getReaderFileSuffixes()));
SUPPORTED_IMAGE_EXTENSIONS.add("tec"); // Add JFIF .tec files
SUPPORTED_IMAGE_EXTENSIONS.removeIf("db"::equals); // remove db files
SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
/*
* special cases and variants that we support, but don't get registered
@@ -213,7 +213,7 @@ public class ImageUtils {
* @param file the AbstractFile to test
*
* @return true if the file is an image we can read and generate thumbnail
* for.
* for.
*/
public static boolean isImageThumbnailSupported(AbstractFile file) {
return isMediaThumbnailSupported(file, "image/", SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS) || hasImageFileHeader(file);//NON-NLS
@@ -239,17 +239,16 @@ public class ImageUtils {
* VideoUtils both implement/extend some base interface/abstract class. That
* would be the natural place to put this.
*
* @param file the AbstractFile to test
* @param mimeTypePrefix a MIME 'top-level type name' such as "image/",
* including the "/". In addition to the list of
* supported MIME types, any type that starts with
* this prefix will be regarded as supported
* @param file the AbstractFile to test
* @param mimeTypePrefix a MIME 'top-level type name' such as "image/",
* including the "/". In addition to the list of supported MIME types, any
* type that starts with this prefix will be regarded as supported
* @param supportedMimeTypes a collection of mimetypes that are supported
* @param supportedExtension a collection of extensions that are supported
*
* @return true if a thumbnail can be generated for the given file based on
* the given MIME type prefix and lists of supported MIME types and
* extensions
* the given MIME type prefix and lists of supported MIME types and
* extensions
*/
static boolean isMediaThumbnailSupported(AbstractFile file, String mimeTypePrefix, final Collection<String> supportedMimeTypes, final List<String> supportedExtension) {
if (false == file.isFile() || file.getSize() <= 0) {
@@ -283,7 +282,7 @@ public class ImageUtils {
* @return a FileTypeDetector
*
* @throws FileTypeDetectorInitException if initializing the
* FileTypeDetector failed.
* FileTypeDetector failed.
*/
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
if (fileTypeDetector == null) {
@@ -296,11 +295,11 @@ public class ImageUtils {
* Get a thumbnail of a specified size for the given image. Generates the
* thumbnail if it is not already cached.
*
* @param content the content to generate a thumbnail for
* @param content the content to generate a thumbnail for
* @param iconSize the size (one side of a square) in pixels to generate
*
* @return A thumbnail for the given image or a default one if there was a
* problem making a thumbnail.
* problem making a thumbnail.
*/
public static BufferedImage getThumbnail(Content content, int iconSize) {
if (content instanceof AbstractFile) {
@@ -339,7 +338,7 @@ public class ImageUtils {
* @param file The AbstractFile to get a stream for.
*
* @return A BufferedInputStream wrapped around a ReadContentStream for the
* given AbstractFile
* given AbstractFile
*/
private static BufferedInputStream getBufferedReadContentStream(AbstractFile file) {
return new BufferedInputStream(new ReadContentInputStream(file));
@@ -349,11 +348,11 @@ public class ImageUtils {
* Get a thumbnail of a specified size for the given image. Generates the
* thumbnail if it is not already cached.
*
* @param content the content to generate a thumbnail for
* @param content the content to generate a thumbnail for
* @param iconSize the size (one side of a square) in pixels to generate
*
* @return File object for cached image. Is guaranteed to exist, as long as
* there was not an error generating or saving the thumbnail.
* there was not an error generating or saving the thumbnail.
*/
@Nullable
public static File getCachedThumbnailFile(Content content, int iconSize) {
@@ -368,8 +367,8 @@ public class ImageUtils {
* @param fileID the fileID to get the cached thumbnail location for
*
* @return A File object representing the location of the cached thumbnail.
* This file may not actually exist(yet). Returns null if there was
* any problem getting the file, such as no case was open.
* This file may not actually exist(yet). Returns null if there was any
* problem getting the file, such as no case was open.
*/
private static File getCachedThumbnailLocation(long fileID) {
return cacheFileMap.computeIfAbsent(fileID, id -> {
@@ -427,7 +426,7 @@ public class ImageUtils {
* @param file the AbstractFile to parse
*
* @return Offset of first Start Of Image marker, or 0 if none found. This
* will let ImageIO try to open it from offset 0.
* will let ImageIO try to open it from offset 0.
*/
private static long getJfifStartOfImageOffset(AbstractFile file) {
byte[] fileHeaderBuffer;
@@ -507,7 +506,7 @@ public class ImageUtils {
* @return the width in pixels
*
* @throws IOException If the file is not a supported image or the width
* could not be determined.
* could not be determined.
*/
static public int getImageWidth(AbstractFile file) throws IOException {
return getImageProperty(file,
@@ -524,7 +523,7 @@ public class ImageUtils {
* @return the height in pixels
*
* @throws IOException If the file is not a supported image or the height
* could not be determined.
* could not be determined.
*/
static public int getImageHeight(AbstractFile file) throws IOException {
return getImageProperty(file,
@@ -537,8 +536,8 @@ public class ImageUtils {
/**
* Functional interface for methods that extract a property out of an
* ImageReader. Initially created to abstract over
* {@link #getImageHeight(org.sleuthkit.datamodel.AbstractFile)} and
* {@link #getImageWidth(org.sleuthkit.datamodel.AbstractFile)}
* getImageHeight(org.sleuthkit.datamodel.AbstractFile) and
* getImageWidth(org.sleuthkit.datamodel.AbstractFile)
*
* @param <T> The type of the property.
*/
@@ -553,18 +552,17 @@ public class ImageUtils {
* public methods that pull particular (usually meta-)data out of a image
* file.
*
* @param file the file to extract the data from
* @param errorTemplate a message template used to log errors. Should
* take one parameter: the file's unique path or
* name.
* @param file the file to extract the data from
* @param errorTemplate a message template used to log errors. Should take
* one parameter: the file's unique path or name.
* @param propertyExtractor an implementation of {@link PropertyExtractor}
* used to retrieve the specific property.
* used to retrieve the specific property.
*
* @return the the value of the property extracted by the given
* propertyExtractor
* propertyExtractor
*
* @throws IOException if there was a problem reading the property from the
* file.
* file.
*
* @see PropertyExtractor
* @see #getImageHeight(org.sleuthkit.datamodel.AbstractFile)
@@ -608,8 +606,8 @@ public class ImageUtils {
* but is not started automatically. Clients are responsible for running the
* task, monitoring its progress, and using its result.
*
* @param file The file to create a thumbnail for.
* @param iconSize The size of the thumbnail.
* @param file The file to create a thumbnail for.
* @param iconSize The size of the thumbnail.
* @param defaultOnFailure Whether or not to default on failure.
*
* @return a new Task that returns a thumbnail as its result.
@@ -978,10 +976,10 @@ public class ImageUtils {
* @param iconSize
*
* @return a thumbnail for the given image or a default one if there was a
* problem making a thumbnail.
* problem making a thumbnail.
*
* @deprecated use {@link #getThumbnail(org.sleuthkit.datamodel.Content, int)
* } instead.
* @deprecated use getThumbnail(org.sleuthkit.datamodel.Content, int)
* instead.
*/
@Nonnull
@Deprecated
@@ -997,10 +995,10 @@ public class ImageUtils {
* @param iconSize
*
* @return File object for cached image. Is guaranteed to exist, as long as
* there was not an error generating or saving the thumbnail.
* there was not an error generating or saving the thumbnail.
*
* @deprecated use {@link #getCachedThumbnailFile(org.sleuthkit.datamodel.Content, int)
* } instead.
* @deprecated use getCachedThumbnailFile(org.sleuthkit.datamodel.Content,
* int) instead.
*
*/
@Nullable

View File

@@ -1,15 +1,15 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 - 2015 Basis Technology Corp.
*
* Copyright 2011-2017 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.
@@ -27,57 +27,92 @@ import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
/**
* A DisplayableItem is any node in the Autopsy directory tree. All of the nodes
* in the tree will eventually extend this. This includes the data source,
* views, extracted results, etc. areas.
* An abstract base class for nodes that are eligible for display in the tree
* view or results view. Capabilitites of a DisplayableItemNode include
* accepting a DisplayableItemNodeVisitor, indicating whether or not the node is
* a leaf node, providing an item type string suitable for use as a key, and
* storing information about a child node that is to be selected if the node is
* selected in the tree view.
*/
public abstract class DisplayableItemNode extends AbstractNode {
/*
* An item type shared by DisplayableItemNodes that can be the parents of
* file nodes.
*/
final static String FILE_PARENT_NODE_KEY = "orgsleuthkitautopsydatamodel" + "FileTypeParentNode";
public DisplayableItemNode(Children children) {
super(children);
}
public DisplayableItemNode(Children children, Lookup lookup) {
super(children, lookup);
}
public abstract boolean isLeafTypeNode();
public abstract <T> T accept(DisplayableItemNodeVisitor<T> v);
/**
* Returns type of DisplayableItemNode to allow TableFilterNode to pass
* the information to DataResultViewerTable to allow custom settings for
* column orderings.
*
* @return A String representing the type of node, based on its name and
* whether or not it wraps any special items (filters, artifact
* types).
*/
public abstract String getItemType();
/**
* this code started as a cut and past of
* DataResultFilterNode.GetPopupActionsDisplayableItemNodeVisitor.findLinked(BlackboardArtifactNode
* ba)
* Gets the file, if any, linked to an artifact via a TSK_PATH_ID attribute
*
* @param artifact
* @param artifact The artifact.
*
* @return
* @return An AbstractFile or null.
*
* @throws TskCoreException
*/
static AbstractFile findLinked(BlackboardArtifact artifact) throws TskCoreException {
BlackboardAttribute pathIDAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
if (pathIDAttribute != null) {
long contentID = pathIDAttribute.getValueLong();
if (contentID != -1) {
return artifact.getSleuthkitCase().getAbstractFileById(contentID);
}
}
return null;
}
/**
* Constructs a node that is eligible for display in the tree view or
* results view. Capabilitites include accepting a
* DisplayableItemNodeVisitor, indicating whether or not the node is a leaf
* node, providing an item type string suitable for use as a key, and
* storing information about a child node that is to be selected if the node
* is selected in the tree view.
*
* @param children The Children object for the node.
*/
public DisplayableItemNode(Children children) {
super(children);
}
/**
* Constructs a node that is eligible for display in the tree view or
* results view. Capabilitites include accepting a
* DisplayableItemNodeVisitor, indicating whether or not the node is a leaf
* node, providing an item type string suitable for use as a key, and
* storing information about a child node that is to be selected if the node
* is selected in the tree view.
*
* @param children The Children object for the node.
* @param lookup The Lookup object for the node.
*/
public DisplayableItemNode(Children children, Lookup lookup) {
super(children, lookup);
}
/**
* Accepts a DisplayableItemNodeVisitor.
*
* @param <T> The type parameter of the visitor.
* @param visitor The visitor.
*
* @return
*/
public abstract <T> T accept(DisplayableItemNodeVisitor<T> visitor);
/**
* Indicates whether or not the node is a leaf node.
*
* @return True or false.
*/
public abstract boolean isLeafTypeNode();
/**
* Gets the item type string of the node, suitable for use as a key.
*
* @return A String representing the item type of node.
*/
public abstract String getItemType();
}