Package

Source Code of FeatureLine

import java.util.Vector;
import java.io.File;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;

//import java.awt.font.TextAttribute;
//import javax.swing.SwingUtilities;

/**
* The <code>FeatureLine</code> class encapsulates the attributes of a feature line.
*/
public class FeatureLine {
  // input fields
  public final File reportImageFile;
  public final File featuresFile;
  public final long startByte;
  public final int numBytes;

  // extracted fields
  public final String firstField;
  public final byte[] featureField;
  public final byte[] contextField;

  // derived fields
  /**
   * The actual image file used if the report image file is a directory
   * and the actual image is in the first field.
   */
  public final File actualImageFile;
  /**
   * firstField, without filename, if present.
   */
  public final String forensicPath;
  /**
   * firstField without filename, if present
   */
  public final String formattedFeature; // format is based on feature file type

  // note if initialization failed
  private boolean isFailedInitialization;

  /**
   * Constructs a blank FeatureLine because FeatureListCellRenderer requires
   * a prototype display value in order to get the height right.
   */
  public FeatureLine() {
    reportImageFile = null;
    featuresFile = null;
    startByte = 0;
    numBytes = 0;

    firstField = "";
    featureField = new byte[0];
    contextField = new byte[0];

    actualImageFile = null;
    forensicPath = "";
    formattedFeature = "";

    isFailedInitialization = true;
  }

  /**
   * Constructs a FeatureLine object for containing attributes realting to a feature line
   * @param reportImageFile the image file associated with the report for the feature line
   * @param featuresFile the features file file associated with the feature line
   * @param startByte the start byte in the features file where the feature line text resides
   * @param numBytes the length of text in the features file defining this feature line
   * @param isUseHexPath whether to format the printable forensic path in hex
   */
  public FeatureLine(File reportImageFile, File featuresFile, long startByte, int numBytes) {

    // record input parameters
    this.reportImageFile = reportImageFile;
    this.featuresFile = featuresFile;
    this.startByte = startByte;
    this.numBytes = numBytes;

    // read the feature line bytes
    long size = 0;
    byte[] lineBytes = new byte[numBytes];
    try {
      // establish the file channel and file size for the feature file
      FileInputStream fileInputStream = new FileInputStream(featuresFile);
      FileChannel fileChannel = fileInputStream.getChannel();
      size = fileChannel.size();

      // get byte[] lineBytes from features file
      MappedByteBuffer mappedByteBuffer;
      mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, startByte, numBytes);
      mappedByteBuffer.load();
      mappedByteBuffer.get(lineBytes, 0, numBytes);
      fileChannel.close()// JVM garbage collector does not close these, so force closure
      fileInputStream.close()// JVM garbage collector does not close these, so force closure

      isFailedInitialization = false;
    } catch (Exception e) {

      // indicate error
      if (!featuresFile.exists()) {
        // the file doesn't exist
        WError.showErrorLater( "Features file " + featuresFile + " does not exist.", "BEViewer file error", null);
      } else {
        // something more went wrong so show the exception
        WError.showErrorLater( "Unable to open features file " + featuresFile + ".", "BEViewer file error", e);
      }

      // set remaining values for failed read
      firstField = "";
      featureField = new byte[0];
      contextField = new byte[0];
      actualImageFile = null;
      forensicPath = "";
      formattedFeature = "";
      isFailedInitialization = true;
      return;
    }

    // make sure the line bytes are in range of the feature file
    if (startByte + numBytes >= size) {
      throw new RuntimeException("Invalid line request");
    }

    // the line should end in \n and never in \r\n, but check for and strip out \r anyway.
    // It is possible for transport tools such as zip to turn \n into \r\n.
    // If deemed unnecessary, this check may be removed.
    // The \n is stripped out already.  Strip out the \r now if it is there.
    if (numBytes > 0 && lineBytes[numBytes - 1] == 0x0d) {
      numBytes--;
    }

    int i;
    int j;
    // define firstField as text before first tab else all text
    for (i=0; i < numBytes; i++) {
      if (lineBytes[i] == '\t') {
        // at first tab
        break;
      }
    }

    // firstField is text before first tab
    firstField = new String(lineBytes, 0, i);

    // featureField is text after first tab and before second tab
    // else remaining text
    // Do not remove any escape codes.
    ByteArrayOutputStream featureStream = new ByteArrayOutputStream();
    if (i < numBytes - 1) {
      // there was a first tab
      for (j=i+1; j < numBytes; j++) {
        if (lineBytes[j] == '\t') {
          // at second tab
          break;
        }
      }
      featureStream.write(lineBytes, i + 1, j - (i + 1));

    } else {
      // there was no first tab, so set feature field as whole line
      j = numBytes - 1;
      WLog.log("Malformed line: " + new String(lineBytes));
      featureStream.write(lineBytes, 0, lineBytes.length);
    }
    featureField = featureStream.toByteArray();

    // define contextField as text after second tab, leaving in any escape codes
    ByteArrayOutputStream contextStream = new ByteArrayOutputStream();
    if (j < numBytes - 1) {
      // there was a second tab
      contextStream.write(lineBytes, j + 1, numBytes - (j + 1));
    } else {
      // there was no second tab so there is no text to add to the context field
    }
    contextField = contextStream.toByteArray();

    // define the image file that is actually associated with this forensic path
    if (ForensicPath.hasFilename(firstField)) {
      // NOTE: currently, the user cannot move the directory of image files.
      // This can be fixed by recomposing the path based on the path to the
      // Report's image, but still, it is not compatible between Win and Linux
      // because the filename embedded in the path is sysem-specific.
      // Generic slash management should fix that, but not now.
      actualImageFile = new File(ForensicPath.getFilename(firstField));
    } else {
      actualImageFile = reportImageFile;
    }

    // set derived fields
    forensicPath = ForensicPath.getPathWithoutFilename(firstField);
    formattedFeature = FeatureFieldFormatter.getFormattedFeatureText(featuresFile, featureField, contextField);
  }

  /**
   * Returns a printable summary string of this feature line.
   */
  public String getSummaryString() {
    // compose a printable summary that fits on one line
    String summary;
    if (actualImageFile == null) {
      if (featuresFile == null) {
        // this string is returned by the FeatureListCellRenderer as the prototype display value
        return "no image file and no features file";
      } else {
        // indicate what is available
        summary = "No image file selected, " + firstField + ", " + formattedFeature;
      }
    } else {
      summary = ForensicPath.getPrintablePath(forensicPath, BEViewer.imageView.getUseHexPath())
               + ", " + featuresFile.getName()
               + ", " + actualImageFile.getName()
               + ", " + formattedFeature;
    }

    // truncate the sumamry
    final int MAX_LENGTH = 200;
    if (summary.length() > MAX_LENGTH) {
      summary = summary.substring(0, MAX_LENGTH) + "\u2026";
    }

    return summary;
  }

  /**
   * Identifies whether this is really a blank feature line.
   */
  public boolean isBlank() {
    return (reportImageFile == null && featuresFile == null);
  }

  /**
   * Identifies if this FeatureLine was unable to initialize.
   */
  public boolean isBad() {
    return isFailedInitialization;
  }

  /**
   * Returns a printable summary string of the given feature line.
   */
  public static String getSummaryString(FeatureLine featureLine) {
    return featureLine.getSummaryString();
  }

  /**
   * Returns a string detailing the state of the feature line.
   */
  public String toString() {
    StringBuffer stringBuffer = new StringBuffer();

    // input fields
    stringBuffer.append("reportImageFile: " + reportImageFile);
    stringBuffer.append(", actualImageFile: " + actualImageFile);
    stringBuffer.append(", featuresFile: " + featuresFile);
    stringBuffer.append(", startByte: " + startByte);
    stringBuffer.append(", numBytes: " + numBytes);

    // derived fields
    stringBuffer.append(", firstField: " + firstField);
    stringBuffer.append(", forensicPath: " + forensicPath);
    stringBuffer.append(", featureField: " + featureField);
    stringBuffer.append(", contextField: " + contextField);
    return stringBuffer.toString();
  }

  /**
   * Identifies whether the feature line is from the given report
   */
  public boolean isFromReport(ReportsModel.ReportTreeNode reportTreeNode) {
    // image file and features directory must be equivalent
    File reportImageFile = reportTreeNode.reportImageFile;
    File reportFeaturesDirectory = reportTreeNode.featuresDirectory;
    File featuresDirectory = (featuresFile == null) ? null : featuresFile.getParentFile();
    return (FileTools.filesAreEqual(reportImageFile, reportImageFile)
     && FileTools.filesAreEqual(reportFeaturesDirectory, featuresDirectory));
  }

  /**
   * Identifies when two FeatureLine objects are equivalent
   * @return true when equivalent
   */
  public boolean equals(FeatureLine featureLine) {
    return (FileTools.filesAreEqual(reportImageFile, featureLine.reportImageFile)
            && FileTools.filesAreEqual(featuresFile, featureLine.featuresFile)
            && startByte == featureLine.startByte
            && numBytes == featureLine.numBytes);
  }

  public int hashCode() {
    // sufficient effort to avoid collision
    return (int)startByte;
  }
}
TOP

Related Classes of FeatureLine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.