Address some issues in PListViewer detected by Codacy/IDE

This commit is contained in:
Richard Cordovano 2018-02-23 08:54:49 -05:00
parent 6ef7317c8a
commit 88edf39ca5

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.sleuthkit.autopsy.contentviewers; package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component; import java.awt.Component;
@ -56,66 +55,65 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
/** /**
* PListViewer - a file viewer for binary plist files. * PListViewer - a file viewer for binary plist files.
* *
*/ */
public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, ExplorerManager.Provider { public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, ExplorerManager.Provider {
private static final long serialVersionUID = 1L;
private static final String[] MIMETYPES = new String[]{"application/x-bplist"}; private static final String[] MIMETYPES = new String[]{"application/x-bplist"};
private static final Logger LOGGER = Logger.getLogger(PListViewer.class.getName()); private static final Logger LOGGER = Logger.getLogger(PListViewer.class.getName());
private final org.openide.explorer.view.OutlineView outlineView; private final org.openide.explorer.view.OutlineView outlineView;
private final Outline outline; private final Outline outline;
private ExplorerManager explorerManager; private ExplorerManager explorerManager;
private NSDictionary rootDict; private NSDictionary rootDict;
/** /**
* Creates new form PListViewer * Creates new form PListViewer
*/ */
public PListViewer() { public PListViewer() {
// Create an Outlineview and add to the panel // Create an Outlineview and add to the panel
outlineView = new org.openide.explorer.view.OutlineView(); outlineView = new org.openide.explorer.view.OutlineView();
initComponents(); initComponents();
outline = outlineView.getOutline(); outline = outlineView.getOutline();
((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel("Key"); ((DefaultOutlineModel) outline.getOutlineModel()).setNodesColumnLabel("Key");
outlineView.setPropertyColumns( outlineView.setPropertyColumns(
"Type", Bundle.PListNode_TypeCol(), "Type", Bundle.PListNode_TypeCol(),
"Value", Bundle.PListNode_ValueCol()); "Value", Bundle.PListNode_ValueCol());
customize(); customize();
} }
@NbBundle.Messages({"PListNode.KeyCol=Key", @NbBundle.Messages({"PListNode.KeyCol=Key",
"PListNode.TypeCol=Type", "PListNode.TypeCol=Type",
"PListNode.ValueCol=Value" }) "PListNode.ValueCol=Value"})
private void customize() { private void customize() {
outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); outline.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
outline.setRootVisible(false); outline.setRootVisible(false);
if (null == explorerManager) { if (null == explorerManager) {
explorerManager = new ExplorerManager(); explorerManager = new ExplorerManager();
} }
//outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); //outline.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
plistTableScrollPane.setViewportView(outlineView); plistTableScrollPane.setViewportView(outlineView);
outline.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN); outline.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
this.setVisible(true); this.setVisible(true);
outline.setRowSelectionAllowed(false); outline.setRowSelectionAllowed(false);
} }
/** /**
* This method is called from within the constructor to initialize the form. * This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always * WARNING: Do NOT modify this code. The content of this method is always
@ -180,14 +178,13 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@NbBundle.Messages({"PListViewer.ExportSuccess.message=Plist file exported successfully", @NbBundle.Messages({"PListViewer.ExportSuccess.message=Plist file exported successfully",
"PListViewer.ExportFailed.message=Plist file export failed.", "PListViewer.ExportFailed.message=Plist file export failed.",})
})
/** /**
* Handles the Export button pressed action * Handles the Export button pressed action
*/ */
private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
final JFileChooser fileChooser = new JFileChooser(); final JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory())); fileChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
fileChooser.setFileFilter(new FileNameExtensionFilter("XML file", "xml")); fileChooser.setFileFilter(new FileNameExtensionFilter("XML file", "xml"));
@ -204,33 +201,33 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
//Save the propery list as XML //Save the propery list as XML
PropertyListParser.saveAsXML(this.rootDict, selectedFile); PropertyListParser.saveAsXML(this.rootDict, selectedFile);
JOptionPane.showMessageDialog(this, JOptionPane.showMessageDialog(this,
String.format("Plist file exported successfully to %s ", selectedFile.getName() ), String.format("Plist file exported successfully to %s ", selectedFile.getName()),
Bundle.PListViewer_ExportSuccess_message(), Bundle.PListViewer_ExportSuccess_message(),
JOptionPane.INFORMATION_MESSAGE); JOptionPane.INFORMATION_MESSAGE);
} catch (IOException ex) { } catch (IOException ex) {
JOptionPane.showMessageDialog(this, JOptionPane.showMessageDialog(this,
String.format("Failed to export plist file to %s ", selectedFile.getName() ), String.format("Failed to export plist file to %s ", selectedFile.getName()),
Bundle.PListViewer_ExportFailed_message(), Bundle.PListViewer_ExportFailed_message(),
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
LOGGER.log(Level.SEVERE, "Error exporting plist to XML file " + selectedFile.getName(), ex); LOGGER.log(Level.SEVERE, "Error exporting plist to XML file " + selectedFile.getName(), ex);
} }
} }
}//GEN-LAST:event_exportButtonActionPerformed }//GEN-LAST:event_exportButtonActionPerformed
/** /**
* Returns mime types supported by this viewer * Returns mime types supported by this viewer
* *
* @return list of supported mime types * @return list of supported mime types
*/ */
@Override @Override
public List<String> getSupportedMIMETypes() { public List<String> getSupportedMIMETypes() {
return Arrays.asList(MIMETYPES); return Arrays.asList(MIMETYPES);
} }
/** /**
* Sets the file to be displayed in the viewer * Sets the file to be displayed in the viewer
* *
* @param file file to display * @param file file to display
*/ */
@Override @Override
@ -239,25 +236,24 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
} }
/** /**
* Returns the viewer component * Returns the viewer component
* *
* @return the viewer component * @return the viewer component
*/ */
@Override @Override
public Component getComponent() { public Component getComponent() {
return this; return this;
} }
/** /**
* Resets the viewer component * Resets the viewer component
* *
*/ */
@Override @Override
public void resetComponent() { public void resetComponent() {
rootDict = null; rootDict = null;
} }
/** /**
* Process the given Plist file * Process the given Plist file
* *
@ -266,7 +262,7 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
* @return none * @return none
*/ */
private void processPlist(final AbstractFile plistFile) { private void processPlist(final AbstractFile plistFile) {
final byte[] plistFileBuf = new byte[(int) plistFile.getSize()]; final byte[] plistFileBuf = new byte[(int) plistFile.getSize()];
try { try {
plistFile.read(plistFileBuf, 0, plistFile.getSize()); plistFile.read(plistFileBuf, 0, plistFile.getSize());
@ -274,25 +270,28 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
LOGGER.log(Level.SEVERE, "Error reading bytes of plist file.", ex); LOGGER.log(Level.SEVERE, "Error reading bytes of plist file.", ex);
} }
final List<PropKeyValue> plist = parsePList(plistFileBuf); final List<PropKeyValue> plist;
try {
new SwingWorker<Void, Void>() { plist = parsePList(plistFileBuf);
@Override new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception { @Override
setupTable(plist); protected Void doInBackground() {
return null; setupTable(plist);
} return null;
}
@Override @Override
protected void done() { protected void done() {
super.done(); super.done();
setColumnWidths(); setColumnWidths();
} }
}.execute(); }.execute();
} catch (IOException | PropertyListFormatException | ParseException | ParserConfigurationException | SAXException ex) {
LOGGER.log(Level.SEVERE, String.format("Error parsing plist for file (obj_id = %d)", plistFile.getId()), ex);
}
} }
/** /**
* Sets up the columns in the display table * Sets up the columns in the display table
* *
@ -301,7 +300,7 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
private void setupTable(final List<PropKeyValue> tableRows) { private void setupTable(final List<PropKeyValue> tableRows) {
explorerManager.setRootContext(new AbstractNode(Children.create(new PListRowFactory(tableRows), true))); explorerManager.setRootContext(new AbstractNode(Children.create(new PListRowFactory(tableRows), true)));
} }
/** /**
* Sets up the column widths * Sets up the column widths
* *
@ -310,7 +309,7 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
final int margin = 4; final int margin = 4;
final int padding = 8; final int padding = 8;
// find the maximum width needed to fit the values for the first N rows, at most // find the maximum width needed to fit the values for the first N rows, at most
final int rows = Math.min(20, outline.getRowCount()); final int rows = Math.min(20, outline.getRowCount());
for (int col = 0; col < outline.getColumnCount(); col++) { for (int col = 0; col < outline.getColumnCount(); col++) {
final int columnWidthLimit = 2000; final int columnWidthLimit = 2000;
@ -319,7 +318,7 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
for (int row = 0; row < rows; row++) { for (int row = 0; row < rows; row++) {
final TableCellRenderer renderer = outline.getCellRenderer(row, col); final TableCellRenderer renderer = outline.getCellRenderer(row, col);
final Component comp = outline.prepareRenderer(renderer, row, col); final Component comp = outline.prepareRenderer(renderer, row, col);
columnWidth = Math.max(comp.getPreferredSize().width, columnWidth); columnWidth = Math.max(comp.getPreferredSize().width, columnWidth);
} }
@ -328,8 +327,7 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
outline.getColumnModel().getColumn(col).setPreferredWidth(columnWidth); outline.getColumnModel().getColumn(col).setPreferredWidth(columnWidth);
} }
} }
/** /**
* Parses the given plist key/value * Parses the given plist key/value
*/ */
@ -342,71 +340,65 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
} else if (value instanceof NSNumber) { } else if (value instanceof NSNumber) {
final NSNumber number = (NSNumber) value; final NSNumber number = (NSNumber) value;
if (number.isInteger()) { if (number.isInteger()) {
return new PropKeyValue(key, PropertyType.NUMBER, Long.valueOf(number.longValue()) ); return new PropKeyValue(key, PropertyType.NUMBER, number.longValue());
} else if (number.isBoolean()) { } else if (number.isBoolean()) {
return new PropKeyValue(key, PropertyType.BOOLEAN, Boolean.valueOf(number.boolValue()) ); return new PropKeyValue(key, PropertyType.BOOLEAN, number.boolValue());
} else { } else {
return new PropKeyValue(key, PropertyType.NUMBER, Float.valueOf(number.floatValue())) ; return new PropKeyValue(key, PropertyType.NUMBER, number.floatValue());
} }
} else if (value instanceof NSDate) { } else if (value instanceof NSDate) {
final NSDate date = (NSDate) value; final NSDate date = (NSDate) value;
return new PropKeyValue(key, PropertyType.DATE, date.toString()); return new PropKeyValue(key, PropertyType.DATE, date.toString());
} } else if (value instanceof NSData) {
else if (value instanceof NSData ) {
return new PropKeyValue(key, PropertyType.DATA, Bundle.PListViewer_DataType_message()); return new PropKeyValue(key, PropertyType.DATA, Bundle.PListViewer_DataType_message());
} else if (value instanceof NSArray) { } else if (value instanceof NSArray) {
final List<PropKeyValue> children = new ArrayList<>(); final List<PropKeyValue> children = new ArrayList<>();
final NSArray array = (NSArray) value; final NSArray array = (NSArray) value;
final PropKeyValue pkv = new PropKeyValue(key, PropertyType.ARRAY, array); final PropKeyValue pkv = new PropKeyValue(key, PropertyType.ARRAY, array);
for (int i = 0; i < array.count(); i++) { for (int i = 0; i < array.count(); i++) {
children.add(parseProperty("", array.objectAtIndex(i))); children.add(parseProperty("", array.objectAtIndex(i)));
} }
pkv.setChildren(children.toArray(new PropKeyValue[children.size()] )); pkv.setChildren(children.toArray(new PropKeyValue[children.size()]));
return pkv; return pkv;
} else if (value instanceof NSDictionary) { } else if (value instanceof NSDictionary) {
final List<PropKeyValue> children = new ArrayList<>(); final List<PropKeyValue> children = new ArrayList<>();
final NSDictionary dict = (NSDictionary) value; final NSDictionary dict = (NSDictionary) value;
final PropKeyValue pkv = new PropKeyValue(key, PropertyType.DICTIONARY, dict); final PropKeyValue pkv = new PropKeyValue(key, PropertyType.DICTIONARY, dict);
for (final String key2 : ((NSDictionary) value).allKeys()) { for (final String key2 : ((NSDictionary) value).allKeys()) {
final NSObject obj = ((NSDictionary) value).objectForKey(key2); final NSObject obj = ((NSDictionary) value).objectForKey(key2);
children.add(parseProperty(key2, obj)); children.add(parseProperty(key2, obj));
} }
pkv.setChildren(children.toArray(new PropKeyValue[children.size()] )); pkv.setChildren(children.toArray(new PropKeyValue[children.size()]));
return pkv; return pkv;
} else { } else {
LOGGER.severe("Can't parse Plist for key = " + key + " value of type " + value.getClass()); LOGGER.log(Level.SEVERE, "Can''t parse Plist for key = {0} value of type {1}", new Object[]{key, value.getClass()});
} }
return null; return null;
} }
/** /**
* Parses given binary stream and extracts Plist key/value * Parses given binary stream and extracts Plist key/value
* *
* @param plistbytes * @param plistbytes
* *
* @return list of PropKeyValue * @return list of PropKeyValue
*/ */
private List<PropKeyValue> parsePList(final byte[] plistbytes) { private List<PropKeyValue> parsePList(final byte[] plistbytes) throws IOException, PropertyListFormatException, ParseException, ParserConfigurationException, SAXException {
final List<PropKeyValue> plist = new ArrayList<>(); final List<PropKeyValue> plist = new ArrayList<>();
try { rootDict = (NSDictionary) PropertyListParser.parse(plistbytes);
rootDict = (NSDictionary) PropertyListParser.parse(plistbytes);
final String[] keys = rootDict.allKeys(); final String[] keys = rootDict.allKeys();
for (final String key : keys) { for (final String key : keys) {
final PropKeyValue pkv = parseProperty(key, rootDict.objectForKey(key)); final PropKeyValue pkv = parseProperty(key, rootDict.objectForKey(key));
if (null != pkv) { if (null != pkv) {
plist.add(pkv); plist.add(pkv);
}
} }
} catch (PropertyListFormatException | IOException | ParseException | ParserConfigurationException | SAXException ex) {
LOGGER.log(Level.SEVERE, "Failed to parse PList.", ex);
return null;
} }
return plist; return plist;
@ -416,84 +408,85 @@ public class PListViewer extends javax.swing.JPanel implements FileTypeViewer, E
public ExplorerManager getExplorerManager() { public ExplorerManager getExplorerManager() {
return explorerManager; return explorerManager;
} }
/** /**
* Plist property type * Plist property type
*/ */
enum PropertyType { enum PropertyType {
STRING, STRING,
NUMBER, NUMBER,
BOOLEAN, BOOLEAN,
DATE, DATE,
DATA, DATA,
ARRAY, ARRAY,
DICTIONARY DICTIONARY
}; };
/** /**
* Encapsulates a Plist property * Encapsulates a Plist property
* *
*/ */
class PropKeyValue { final static class PropKeyValue {
private final String key; private final String key;
private final PropertyType type; private final PropertyType type;
private final Object value; private final Object value;
private PropKeyValue[] children; private PropKeyValue[] children;
PropKeyValue(String key, PropertyType type, Object value) { PropKeyValue(String key, PropertyType type, Object value) {
this.key = key; this.key = key;
this.type = type; this.type = type;
this.value = value; this.value = value;
this.children = null; this.children = null;
} }
/** /**
* Copy constructor * Copy constructor
*/ */
PropKeyValue(PropKeyValue other) { PropKeyValue(PropKeyValue other) {
this.key = other.key; this.key = other.getKey();
this.type = other.type; this.type = other.getType();
this.value = other.value; this.value = other.getValue();
this.setChildren(other.getChildren()); this.setChildren(other.getChildren());
} }
String getKey() { String getKey() {
return this.key; return this.key;
} }
PropertyType getType() { PropertyType getType() {
return this.type; return this.type;
} }
Object getValue() { Object getValue() {
return this.value; return this.value;
} }
/** /**
* Returns an array of children, if any. * Returns an array of children, if any.
* @return *
* @return
*/ */
PropKeyValue[] getChildren() { PropKeyValue[] getChildren() {
if (children == null) { if (children == null) {
return null; return null;
} }
// return a copy // return a copy
return Arrays.stream(children) return Arrays.stream(children)
.map(child -> new PropKeyValue(child) ) .map(child -> new PropKeyValue(child))
.toArray(PropKeyValue[]::new); .toArray(PropKeyValue[]::new);
} }
void setChildren(final PropKeyValue...children) { void setChildren(final PropKeyValue... children) {
this.children = children; this.children = Arrays.stream(children)
.map(child -> new PropKeyValue(child))
.toArray(PropKeyValue[]::new);
} }
} }
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables