Java tutorial
/******************************************************************************* * Copyright (c) 2016 KDM Analytics, Inc. All rights reserved. This program and * the accompanying materials are made available under the terms of the Open * Source Initiative OSI - Open Software License v3.0 which accompanies this * distribution, and is available at * http://www.opensource.org/licenses/osl-3.0.php/ ******************************************************************************/ package com.kdmanalytics.toif.report.internal.importWizard; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.preference.FileFieldEditor; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.part.DrillDownComposite; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.kdmanalytics.toif.report.internal.items.FileGroup; import com.kdmanalytics.toif.report.internal.providers.TOIFImportTreeContentProvider; import com.kdmanalytics.toif.report.items.IFileGroup; import com.kdmanalytics.toif.ui.common.FindingData; import com.kdmanalytics.toif.ui.views.FindingView; import com.kdmanalytics.toif.util.MemberUtil; /** * Import *.tsv Citing file and apply the data to the existing defect database * * @author Ken Duck * */ public class TsvImportWizardPage extends WizardPage implements Listener, ISelectionChangedListener, ModifyListener { private static final Logger LOG = LoggerFactory.getLogger(TsvImportWizardPage.class); private static final int SIZING_CONTAINER_GROUP_HEIGHT = 250; private static final int SIZING_SELECTION_PANE_WIDTH = 320; protected FileFieldEditor editor; boolean complete = false; private IProject project; private TOIFImportTreeContentProvider contentprovider; /** * The digest allows us to generate simple and short unique IDs for each finding. */ private static MessageDigest digest; static { try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } /** * * @param pageName * @param selection */ public TsvImportWizardPage(String pageName, IStructuredSelection selection) { super(pageName); setPageComplete(false); } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets .Composite) */ @Override public void createControl(Composite parent) { LOG.debug("Creating import page"); // The main page Composite page = new Composite(parent, SWT.None); GridLayout gl = new GridLayout(); gl.numColumns = 1; page.setLayout(gl); createFileSelectionArea(page); createProjectTree(page); // Set the page's control setControl(page); } /** * create the project tree * * @param page */ private void createProjectTree(Composite page) { Label label = new Label(page, SWT.NONE); label.setText("Select target project:"); DrillDownComposite drillDown = new DrillDownComposite(page, SWT.BORDER); GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true); spec.widthHint = SIZING_SELECTION_PANE_WIDTH; spec.heightHint = SIZING_CONTAINER_GROUP_HEIGHT; drillDown.setLayoutData(spec); TreeViewer tree = new TreeViewer(drillDown, SWT.NONE); drillDown.setChildTree(tree); contentprovider = new TOIFImportTreeContentProvider(); tree.setContentProvider(contentprovider); tree.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider()); tree.setComparator(new ViewerComparator()); tree.setUseHashlookup(true); tree.setInput(ResourcesPlugin.getWorkspace()); tree.addSelectionChangedListener(this); } /** * create the file selection area * * @param page */ private void createFileSelectionArea(Composite page) { Composite fileSelectionArea = new Composite(page, SWT.NONE); GridData fileSelectionData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL); fileSelectionArea.setLayoutData(fileSelectionData); GridLayout fileSelectionLayout = new GridLayout(); fileSelectionLayout.numColumns = 3; fileSelectionLayout.makeColumnsEqualWidth = false; fileSelectionLayout.marginWidth = 0; fileSelectionLayout.marginHeight = 0; fileSelectionArea.setLayout(fileSelectionLayout); editor = new FileFieldEditor("fileSelect", "Select TOIF Data: ", fileSelectionArea); editor.setStringValue(""); editor.getTextControl(fileSelectionArea).addModifyListener(this); String[] extensions = new String[] { "*.tsv", "." }; editor.setFileExtensions(extensions); // fileSelectionArea.moveAbove(null); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets. Event) */ @Override public void handleEvent(Event event) { setPageComplete(); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged( * org.eclipse.jface.viewers.SelectionChangedEvent) */ @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); // Unset target folder project = null; if (selection.isEmpty()) { setErrorMessage("A target project must be selected"); return; } Object first = selection.getFirstElement(); if (first instanceof IProject) { project = (IProject) first; setPageComplete(); return; } } /* * (non-Javadoc) * * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events .ModifyEvent) */ @Override public void modifyText(ModifyEvent e) { setPageComplete(); } /** * Called to determine if the data is consistent, and if it is then set the page complete boolean. * */ private void setPageComplete() { // Default is page is not complete setPageComplete(false); setMessage(null); setErrorMessage(null); // Check input file String name = editor.getStringValue(); if (name == null) { setErrorMessage("No input file specified"); return; } if (name.isEmpty()) { setErrorMessage("No input file specified"); return; } if (project == null) { setErrorMessage("Select a target project"); return; } // Check for file existence IPath location = new Path(name); IFileStore srcStore = EFS.getLocalFileSystem().getStore(location); if (!srcStore.fetchInfo().exists()) { setErrorMessage("Source file " + srcStore + " does not exist"); return; } // Check target folder else this.setMessage("Click finish to import into existing repository"); // If we get here the results are good. setPageComplete(true); } /** * Perform the actual load. * * @return */ public boolean finish() { // Check source file final String name = editor.getStringValue(); setErrorMessage("Importing " + name + " into " + project + "..."); IPath location = new Path(name); File file = location.toFile(); Reader in = null; CSVParser parser = null; try { in = new FileReader(file); CSVFormat format = CSVFormat.EXCEL.withDelimiter('\t').withIgnoreEmptyLines(); parser = new CSVParser(in, format); System.err.println("FILE: " + name); Map<Integer, String> lookup = new HashMap<Integer, String>(); boolean header = true; for (CSVRecord record : parser) { int size = record.size(); IFile ifile = null; String tool = null; String description = null; int line = 0; int offset = 0; int trust = 0; Boolean status = null; int kdmLine = 0; String cwe = null; String sfp = null; // Read the header first if (header) { System.err.print(" "); for (int i = 0; i < size; i++) { if (i > 0) System.err.print(","); String cell = record.get(i); lookup.put(i, cell); System.err.print(cell); } header = false; System.err.println(); System.err.println(" ------------------------------------------"); } // Otherwise this is a data row else { for (int i = 0; i < size; i++) { String cell = record.get(i); String colName = lookup.get(i); if ("Resource".equals(colName)) { IFileGroup group = new FileGroup(cell); try { IResource resource = MemberUtil.findMembers(project, group); if (resource != null) { ifile = (IFile) resource; } } catch (CoreException e) { e.printStackTrace(); } } else if ("SFP".equals(colName)) { sfp = cell; } else if ("CWE".equals(colName)) { cwe = cell; } // Valid is *old* name for "Citing Status" else if ("Valid".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { status = Boolean.parseBoolean(cell); } } else if ("Citing Status".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { status = Boolean.parseBoolean(cell); } } else if ("Trust".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { try { trust = Integer.parseInt(cell); } catch (NumberFormatException e) { } } } else if ("Confidence".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { try { trust = Integer.parseInt(cell); } catch (NumberFormatException e) { } } } else if ("Line Number".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { try { line = Integer.parseInt(cell); } catch (NumberFormatException e) { } } } else if ("KDM Line Number".equals(colName)) { if (cell != null && !cell.trim().isEmpty()) { try { kdmLine = Integer.parseInt(cell); } catch (NumberFormatException e) { } } } // "Generator Tool" is *old* name for "SCA Tool" else if ("Generator Tool".equals(colName)) { tool = cell; } else if ("SCA tool".equalsIgnoreCase(colName)) { tool = cell; } else if ("Weakness Description".equals(colName)) { description = cell; } else { System.err.println("WARNING: Unknown column name '" + colName + "'"); } } System.err.print(" "); System.err.print(sfp); System.err.print(","); System.err.print(cwe); System.err.print(","); System.err.print(status); System.err.print(","); System.err.print(trust); System.err.print(","); System.err.print(ifile); System.err.print(","); System.err.print(line); System.err.print(","); System.err.print(kdmLine); System.err.print(","); System.err.print(tool); System.err.print(","); System.err.print(description); System.err.println(); if (ifile != null) { // Create an associated finding. This will allow us to // set the citing status for the finding. If the // finding does not actually exist in the database this information // is still stored in case the finding exists in the future. FindingData finding = new FindingData(ifile, tool, description, line, offset, cwe, sfp); if (status != null) { finding.cite(status); } } } } try { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { FindingView view = (FindingView) page.showView("com.kdmanalytics.toif.views.FindingView"); view.refresh(); } } } catch (PartInitException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } finally { if (parser != null) { try { parser.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } // PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() // { // public void run() // { // final ToifReportImportJob job = new ToifReportImportJob("Import SFP/CWE Data", project, // name); // job.setUser(true); // job.setPriority(Job.BUILD); // job.setRule(project); // job.schedule(); // } // }); return true; } /** * Returns a unique ID for the finding. Uses an MD5 checksum for uniqueness while keeping the * value reasonably short. * * @return */ public String getUniqueId(String tool, int line, int offset, String cwe, String description) { if (digest != null) { String id = tool + ":" + line + ":" + offset + ":" + cwe + ":" + description; return getHex(digest.digest(id.getBytes())); } else { // Fall back that should never ever be required. Not necessarily unique. String id = tool + ":" + line + ":" + offset + ":" + cwe; return id; } } /** * * @param hash * @return */ private String getHex(byte[] hash) { StringBuffer hexString = new StringBuffer(); for (int i = 0; i < hash.length; i++) { if ((0xff & hash[i]) < 0x10) { hexString.append("0" + Integer.toHexString((0xFF & hash[i]))); } else { hexString.append(Integer.toHexString(0xFF & hash[i])); } } return hexString.toString(); } }