diff --git a/pom.xml b/pom.xml
index 0a628aa..c645906 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
com.github.AppSecDev
asoc-core
- 1.0.2
+ scan_manager-SNAPSHOT
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties b/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties
index fc31099..c83490c 100644
--- a/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/messages.properties
@@ -23,4 +23,5 @@ error.running.scan=An error occurred running the scan. {0}
error.scan.failed=The security analysis process failed. {0}
error.target.invalid=The scan target {0} is invalid.
error.creating.scan=An error occurred initiating the scan.
-
+error.delete=Failed to delete {0}.
+error.dom.state=Bad DOM state.
\ No newline at end of file
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java
index bf80e6e..adfdca7 100644
--- a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScan.java
@@ -17,6 +17,9 @@
import com.ibm.appscan.plugin.core.scanners.ASoCScan;
import com.ibm.appscan.plugin.core.scanners.Messages;
+/**
+ * A class for running static scans. For greater control over what gets scanned a {@link SASTScanManager} should be used.
+ */
public class SASTScan extends ASoCScan implements SASTConstants {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java
new file mode 100644
index 0000000..40b77ef
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/SASTScanManager.java
@@ -0,0 +1,87 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.transform.TransformerException;
+
+import com.ibm.appscan.plugin.core.CoreConstants;
+import com.ibm.appscan.plugin.core.error.AppScanException;
+import com.ibm.appscan.plugin.core.error.InvalidTargetException;
+import com.ibm.appscan.plugin.core.error.ScannerException;
+import com.ibm.appscan.plugin.core.logging.IProgress;
+import com.ibm.appscan.plugin.core.scan.IScanManager;
+import com.ibm.appscan.plugin.core.scan.IScanServiceProvider;
+import com.ibm.appscan.plugin.core.scan.ITarget;
+import com.ibm.appscan.plugin.core.scanners.sast.SASTConstants;
+import com.ibm.appscan.plugin.core.scanners.sast.SASTScan;
+import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget;
+import com.ibm.appscan.plugin.core.scanners.sast.xml.ModelWriter;
+import com.ibm.appscan.plugin.core.scanners.sast.xml.XmlWriter;
+
+public class SASTScanManager implements IScanManager{
+
+ private List m_targets;
+ private SASTScan m_scan;
+ private String m_workingDirectory;
+
+ public SASTScanManager(String workingDir) {
+ m_workingDirectory = workingDir;
+ m_targets = new ArrayList();
+ }
+
+ @Override
+ public void prepare(IProgress progress, Map properties) throws AppScanException {
+ createConfig();
+ properties.put(CoreConstants.TARGET, m_workingDirectory);
+ properties.put(SASTConstants.PREPARE_ONLY, Boolean.toString(true));
+ run(progress, properties, null);
+ }
+
+ @Override
+ public void analyze(IProgress progress, Map properties, IScanServiceProvider provider) throws AppScanException {
+ if(m_scan == null || m_scan.getIrx() == null) {
+ createConfig();
+ properties.put(CoreConstants.TARGET, m_workingDirectory);
+ }
+ else
+ properties.put(CoreConstants.TARGET, m_scan.getIrx().getAbsolutePath());
+
+ run(progress, properties, provider);
+ }
+
+ @Override
+ public void addScanTarget(ITarget target) {
+ if(target instanceof ISASTTarget)
+ m_targets.add((ISASTTarget)target);
+ }
+
+ private void run(IProgress progress,Map properties, IScanServiceProvider provider) throws AppScanException {
+ try {
+ m_scan = new SASTScan(properties, progress, provider);
+ m_scan.run();
+ } catch (InvalidTargetException | ScannerException e) {
+ throw new AppScanException(e.getLocalizedMessage());
+ }
+ }
+
+ private String createConfig() throws AppScanException {
+ try {
+ ModelWriter writer = new XmlWriter();
+ writer.initWriters(new File(m_workingDirectory));
+ writer.visit(m_targets);
+ writer.write();
+ return writer.getOutputLocation();
+ } catch (IOException | TransformerException e) {
+ throw new AppScanException(e.getLocalizedMessage(), e);
+ }
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java
new file mode 100644
index 0000000..e7ee2cb
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/CppTarget.java
@@ -0,0 +1,22 @@
+/*
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants;
+
+public abstract class CppTarget extends DefaultTarget implements ICppTarget {
+
+ @Override
+ public Map getProperties() {
+ HashMap buildInfos = new HashMap();
+ buildInfos.put(IModelXMLConstants.A_ADDITIONAL_CLASSPATH, getCompilerOptions());
+ buildInfos.put(IModelXMLConstants.A_MACROS, getMacros());
+ buildInfos.put(IModelXMLConstants.A_INCLUDE_PATHS, getIncludeDirs());
+ return buildInfos;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java
new file mode 100644
index 0000000..a6eb060
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DefaultTarget.java
@@ -0,0 +1,35 @@
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class DefaultTarget implements ISASTTarget {
+
+ Set m_exclusionPatterns;
+ Set m_inclusionPatterns;
+
+ public DefaultTarget() {
+ m_exclusionPatterns = new HashSet();
+ m_inclusionPatterns = new HashSet();
+ }
+
+ @Override
+ public String getTarget() {
+ return getTargetFile().getAbsolutePath();
+ }
+
+ @Override
+ public Set getExclusionPatterns() {
+ return m_exclusionPatterns;
+ }
+
+ @Override
+ public Set getInclusionPatterns() {
+ return m_inclusionPatterns;
+ }
+
+ @Override
+ public boolean outputsOnly() {
+ return false;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java
new file mode 100644
index 0000000..4cbdd94
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/DotNetTarget.java
@@ -0,0 +1,21 @@
+/*
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants;
+
+public abstract class DotNetTarget extends DefaultTarget implements IDotNetTarget {
+
+ @Override
+ public Map getProperties() {
+ HashMap buildInfos = new HashMap();
+ buildInfos.put(IModelXMLConstants.A_REFERENCES, getReferences());
+ buildInfos.put(IModelXMLConstants.A_FRAMEWORK, getFrameworkVersion());
+ return buildInfos;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java
new file mode 100644
index 0000000..ee0aea0
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ICppTarget.java
@@ -0,0 +1,26 @@
+/*
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+public interface ICppTarget extends ISASTTarget {
+
+ /**
+ * Gets the compiler options used to build the target.
+ * @return
+ */
+ String getCompilerOptions();
+
+ /**
+ * Gets the macros defined for the target.
+ * @return
+ */
+ String getMacros();
+
+ /**
+ * Gets the include directories for the target.
+ * @return
+ */
+ String getIncludeDirs();
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java
new file mode 100644
index 0000000..7d1e0a9
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IDotNetTarget.java
@@ -0,0 +1,21 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+public interface IDotNetTarget extends ISASTTarget {
+
+ /**
+ * Gets the dependencies of this target as a string.
+ * @return
+ */
+ String getReferences();
+
+ /**
+ * Gets the targeted framework version of this target.
+ * @return
+ */
+ String getFrameworkVersion();
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java
new file mode 100644
index 0000000..e302bd2
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJEETarget.java
@@ -0,0 +1,16 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+public interface IJEETarget extends IJavaTarget {
+
+ /**
+ * Gets the jsp compiler that should be used for this target.
+ * @return
+ */
+ String getJSPCompiler();
+
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java
new file mode 100644
index 0000000..e2f6d81
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/IJavaTarget.java
@@ -0,0 +1,21 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+public interface IJavaTarget extends ISASTTarget {
+
+ /**
+ * Gets the classpath for this target as a String.
+ * @return
+ */
+ String getClasspath();
+
+ /**
+ * Gets the jre/jdk associated with this target.
+ * @return
+ */
+ String getJava();
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java
new file mode 100644
index 0000000..58a2077
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/ISASTTarget.java
@@ -0,0 +1,46 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+
+import com.ibm.appscan.plugin.core.scan.ITarget;
+
+public interface ISASTTarget extends ITarget{
+
+ /**
+ * Gets the target file.
+ * @return The target file.
+ */
+ File getTargetFile();
+
+ /**
+ * Gets a map of properties associated with the target.
+ * @return The Map of properties.
+ */
+ Map getProperties();
+
+ /**
+ * Gets a list of exclusion patterns for this target.
+ * @return A list of patterns to exclude.
+ */
+ Set getExclusionPatterns();
+
+ /**
+ * Gets a list of inclusion patterns for this target.
+ * @return A list of patterns to include.
+ */
+ Set getInclusionPatterns();
+
+ /**
+ * Whether this target is only associated with build output files (e.g. .jar, .dll, etc.)
+ * @return false if this target includes non-build outputs.
+ */
+ boolean outputsOnly();
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java
new file mode 100644
index 0000000..5cf6186
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JEETarget.java
@@ -0,0 +1,15 @@
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+import java.util.Map;
+
+import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants;
+
+public abstract class JEETarget extends JavaTarget implements IJEETarget {
+
+ @Override
+ public Map getProperties() {
+ Map buildInfos = super.getProperties();
+ buildInfos.put(IModelXMLConstants.A_JSP_COMPILER, getJSPCompiler());
+ return buildInfos;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java
new file mode 100644
index 0000000..f155cff
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/target/JavaTarget.java
@@ -0,0 +1,17 @@
+package com.ibm.appscan.plugin.core.scanners.sast.target;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.ibm.appscan.plugin.core.scanners.sast.xml.IModelXMLConstants;
+
+public abstract class JavaTarget extends DefaultTarget implements IJavaTarget {
+
+ @Override
+ public Map getProperties() {
+ HashMap buildInfos = new HashMap();
+ buildInfos.put(IModelXMLConstants.A_ADDITIONAL_CLASSPATH, getClasspath());
+ buildInfos.put(IModelXMLConstants.A_JDK_PATH, getJava());
+ return buildInfos;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java
new file mode 100644
index 0000000..7d8a40f
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/DOMWriter.java
@@ -0,0 +1,255 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.xml;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.ibm.appscan.plugin.core.scanners.Messages;
+
+/**
+ * Helper class for constructing and writing a DOM document.
+ */
+public final class DOMWriter {
+
+ private File m_file;
+ private DocumentBuilder m_builder;
+ private Document m_doc;
+ private OutputStream m_stream;
+ private Element m_current = null;
+
+ /**
+ * Constructor.
+ *
+ * @param file The file to write.
+ * @param builder A document builder.
+ * @param append If file exist, setting this to true appends to the file.
+ * @throws IOException If the file already exists, append is false, and the file could not be deleted.
+ * Or if file already exists, append is true, but there is an error parsing the existing file.
+ */
+ public DOMWriter(File file, DocumentBuilder builder, boolean append) throws IOException {
+ m_file = file;
+ m_builder = builder;
+
+ if (m_file.exists()) {
+
+ if (append) {
+ try {
+ m_doc = builder.parse(file);
+ m_current = m_doc.getDocumentElement();
+ return;
+ }
+ catch (SAXException e) {
+ throw new IOException(e);
+ }
+ }
+
+ if (!m_file.delete())
+ throw new IOException(Messages.getMessage("error.delete", m_file)); //$NON-NLS-1$
+ }
+ else
+ m_file.getParentFile().mkdirs();
+
+ m_doc = builder.newDocument();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param file The file to write.
+ * @param builder A document builder.
+ * @throws IOException If the file already exists and could not be deleted.
+ */
+ public DOMWriter(File file, DocumentBuilder builder) throws IOException {
+ this(file, builder, false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param directory Directory to contain the written file.
+ * @param file The name of the file to write.
+ * @param builder A document builder.
+ * @throws IOException If the file already exists and could not be deleted.
+ */
+ public DOMWriter(File directory, String file, DocumentBuilder builder) throws IOException {
+ this(new File(directory, file), builder, false);
+ }
+
+ /**
+ * Constructor.
+ * Makes a new DOMWriter
+ */
+ public DOMWriter(OutputStream stream,DocumentBuilder builder) {
+ m_stream=stream;
+ m_builder = builder;
+ m_doc = builder.newDocument();
+ }
+
+ /**
+ * Create an attribute for the current element.
+ *
+ * @param name The attribute name.
+ * @param value The attribute value.
+ */
+ //@SuppressSecurityTrace
+ public void setAttribute(String name, String value) {
+ try {
+ m_current.setAttribute(name, value);
+ }
+ catch (DOMException e) {
+ if (e.code != DOMException.INVALID_CHARACTER_ERR)
+ throw e;
+ }
+ }
+
+ /**
+ * Append a document fragment to the current element.
+ *
+ * @param fragment The document fragment to append.
+ */
+ public void appendFragment(DocumentFragment fragment) {
+ if (fragment != null) {
+ Node newFragment = m_doc.importNode(fragment, true);
+ m_current.appendChild(newFragment);
+ }
+ }
+
+ /**
+ * Append the XML string as a document fragment to the current element.
+ *
+ * @param xml The XML string.
+ * @throws IOException If any IO errors occur.
+ * @throws SAXException If any parse errors occur.
+ */
+ public void appendFragment(String xml) throws IOException, SAXException {
+ if (xml != null) {
+ Document document = m_builder.parse(new InputSource(new StringReader(xml)));
+ DocumentFragment fragment = document.createDocumentFragment();
+ fragment.appendChild(document.getDocumentElement());
+ appendFragment(fragment);
+ }
+ }
+
+ /**
+ * Append a DOM node to the current element.
+ *
+ * @param node The DOM node to append.
+ */
+ public void appendNode(Node node) {
+ if (node != null) {
+ m_current.appendChild(node);
+ }
+ }
+
+ /**
+ * Begin a new element.
+ *
+ * @param name The name of the element.
+ */
+ public void beginElement(String name) {
+ Element child = m_doc.createElement(name);
+ if (m_current == null)
+ m_doc.appendChild(child);
+ else
+ m_current.appendChild(child);
+ m_current = child;
+ }
+
+ /**
+ * Close off the current element.
+ */
+ public void endElement() {
+ Node parent = m_current.getParentNode();
+ if (parent instanceof Element)
+ m_current = (Element) parent;
+ }
+
+ /**
+ * Write some data and close off the element. The data is treated as
+ * CData if {@code isCData} is true. An IllegalStateException is thrown
+ * if the current element has child elements.
+ *
+ * @param data The text.
+ * @param isCData True if the data is CData.
+ */
+ public void endElement(String data, boolean isCData) {
+ if (data != null) {
+ if (m_current.hasChildNodes())
+ throw new IllegalStateException(Messages.getMessage("error.dom.state")); //$NON-NLS-1$
+ m_current.appendChild(isCData ? m_doc.createCDATASection(data) : m_doc.createTextNode(data));
+ }
+ endElement();
+ }
+
+ /**
+ * Write some text data and close off the element. An
+ * IllegalStateException is thrown if the current element
+ * has child elements.
+ *
+ * @param data The text.
+ */
+ public void endElement(String data) {
+ endElement(data, false);
+ }
+
+ /**
+ * Write the document to disk.
+ *
+ * @param transformer A transformer.
+ * @throws TransformerException If an error occurs during the write operation.
+ */
+ public void write(Transformer transformer) throws TransformerException {
+ DOMSource source = new DOMSource(m_doc);
+ boolean shouldCloseAfter = false;
+ try {
+ StreamResult result;
+ if (m_stream==null) {
+ m_stream = new FileOutputStream(m_file);
+ shouldCloseAfter = true;
+ }
+ result = new StreamResult(m_stream);
+ transformer.transform(source, result);
+ } catch (IOException e) {
+ throw new TransformerException(e);
+ } finally {
+ if (m_stream!=null && shouldCloseAfter) {
+ try {
+ m_stream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ m_stream = null;
+ }
+ }
+ }
+
+ /**
+ * Returns the Document object.
+ *
+ * @return The Document object.
+ */
+ public Document getDocument() {
+ return m_doc;
+ }
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java
new file mode 100644
index 0000000..ef2f98e
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/IModelXMLConstants.java
@@ -0,0 +1,39 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.xml;
+
+public interface IModelXMLConstants {
+
+ String APPSCAN_CONFIG = "appscan-config"; //$NON-NLS-1$
+ String DOT_XML = ".xml"; //$NON-NLS-1$
+
+ String E_CONFIGURATION = "Configuration"; //$NON-NLS-1$
+ String E_TARGETS = "Targets"; //$NON-NLS-1$
+ String E_TARGET = "Target"; //$NON-NLS-1$
+ String E_TARGET_SETTINGS = "TargetSettings"; //$NON-NLS-1$
+ String E_CUSTOM_BUILD_INFO = "CustomBuildInfo"; //$NON-NLS-1$
+ String E_INCLUDE = "Include"; //$NON-NLS-1$
+ String E_EXCLUDE = "Exclude"; //$NON-NLS-1$
+
+ //Java
+ String A_PATH = "path"; //$NON-NLS-1$
+ String A_SRC_PATH = "src_path"; //$NON-NLS-1$
+ String A_SRC_ROOT = "src_root"; //$NON-NLS-1$
+ String A_JDK_PATH = "jdk_path"; //$NON-NLS-1$
+ String A_JSP_COMPILER = "jsp_compiler"; //$NON-NLS-1$
+ String A_ADDITIONAL_CLASSPATH = "additional_classpath"; //$NON-NLS-1$
+ String A_OUTPUTS_ONLY = "outputs-only"; //$NON-NLS-1$
+
+ //C++
+ String A_COMPILER_OPTS = "compiler_opts"; //$NON-NLS-1$
+ String A_MACROS = "macros"; //$NON-NLS-1$
+ String A_INCLUDE_PATHS = "include_paths"; //$NON-NLS-1$
+ String A_BUILD_CONFIG = "build_configuration"; //$NON-NLS-1$
+
+ //.NET
+ String A_REFERENCES = "references"; //$NON-NLS-1$
+ String A_FRAMEWORK = "framework_version"; //$NON-NLS-1$
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java
new file mode 100644
index 0000000..82a0a3b
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/ModelWriter.java
@@ -0,0 +1,123 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+
+import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget;
+
+
+/**
+ * Base implementation of a model writer. Subclasses define the logic to write
+ * specific fragments of the scan model to disk.
+ */
+public abstract class ModelWriter {
+ /**
+ * Instance of a document builder, initialized only after {@link #initialize(File)} is called.
+ */
+ protected DocumentBuilder m_builder;
+
+ /**
+ * Instance of a transformer, initialized only after {@link #initialize(File)} is called.
+ */
+ protected Transformer m_transformer;
+
+ /**
+ * Initializes this model writer.
+ *
+ * @param directory The directory where the scan is stored.
+ * @throws ParserConfigurationException If a problem occurs initializing the document builder
+ * @throws TransformerConfigurationException If a problem occurs initializing the transformer
+ * @throws IOException If a problem occurs initializing the internal writers.
+ */
+ public final void initialize(File directory)
+ throws ParserConfigurationException , TransformerConfigurationException, IOException {
+
+ initDocumentBuilder();
+ initTransformer();
+ //initWriters(directory);
+ }
+ /**
+ * Subclasses can override this to configure the document builder factory.
+ * The default implementation does nothing.
+ *
+ * @param factory The document builder factory.
+ */
+ protected void configureDocumentBuilderFactory(DocumentBuilderFactory factory) {
+ // subclass to override
+ }
+
+
+ /**
+ * Subclasses can override this to configure the transformer factory.
+ * The default implementation does nothing.
+ *
+ * @param factory The transformer factory.
+ */
+ protected void configureTransformerFactory(TransformerFactory factory) {
+ // subclass to override
+ }
+
+ /**
+ * Subclasses can override this to configure the transformer.
+ */
+ protected void configureTransformer() {
+ m_transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
+ m_transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ m_transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * Initializes the transformer.
+ */
+ private void initTransformer() throws TransformerConfigurationException {
+ TransformerFactory factory = TransformerFactory.newInstance();
+ configureTransformerFactory(factory);
+ m_transformer = factory.newTransformer();
+ configureTransformer();
+ }
+
+ /*
+ * Initializes the document builder.
+ */
+ private void initDocumentBuilder() throws ParserConfigurationException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ configureDocumentBuilderFactory(factory);
+ m_builder = factory.newDocumentBuilder();
+ }
+
+
+ /**
+ * Initializes the internal writers typically there is one writer for each fragment of the
+ * scan model to write.
+ *
+ * @param directory The directory where the model files are.
+ * @throws IOException If a problem occurs initializing the internal writers.
+ */
+ public abstract void initWriters(File directory) throws IOException;
+
+ /**
+ * Write out to disk.
+ *
+ * @throws TransformerException If a problem occurs during the write.
+ */
+ public abstract void write() throws TransformerException;
+
+ public abstract String getOutputLocation() ;
+
+ public abstract void visit(List targets) ;
+}
diff --git a/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java
new file mode 100644
index 0000000..b28bae3
--- /dev/null
+++ b/src/main/java/com/ibm/appscan/plugin/core/scanners/sast/xml/XmlWriter.java
@@ -0,0 +1,95 @@
+/*
+ * (c) Copyright IBM Corp. 2016.
+ * (c) Copyright HCL Technologies Ltd. 2017.
+*/
+
+package com.ibm.appscan.plugin.core.scanners.sast.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import com.ibm.appscan.plugin.core.scanners.sast.target.ISASTTarget;
+
+public class XmlWriter extends ModelWriter
+implements IModelXMLConstants
+{
+
+ private DOMWriter m_config;
+ private String m_configOutputDirectory = null;
+ private String m_configFileName = APPSCAN_CONFIG + DOT_XML;
+
+ @Override
+ public void initWriters(File directory) throws IOException {
+ m_configOutputDirectory = directory.getCanonicalPath();
+ try {
+ initialize(directory);
+ } catch (TransformerConfigurationException e) {
+ e.printStackTrace();
+ } catch (ParserConfigurationException e) {
+ e.printStackTrace();
+ }
+ m_config = new DOMWriter(directory, m_configFileName, m_builder);
+ }
+
+ @Override
+ public void visit(List targets) {
+ m_config.beginElement(E_CONFIGURATION);
+ m_config.beginElement(E_TARGETS);
+
+ for (ISASTTarget target: targets){
+ //Add Target
+ m_config.beginElement(E_TARGET);
+ m_config.setAttribute(A_PATH, target.getTargetFile().getAbsolutePath());
+ if(target.outputsOnly())
+ m_config.setAttribute(A_OUTPUTS_ONLY, "true");
+
+ //Add CustomBuildInfo
+ if(target.getProperties().size() > 0) {
+ m_config.beginElement(E_CUSTOM_BUILD_INFO);
+
+ for (Entry buildInfo : target.getProperties().entrySet())
+ m_config.setAttribute(buildInfo.getKey(), buildInfo.getValue());
+
+ m_config.endElement();
+ }
+
+ //Add Include patterns
+ for(String include : target.getInclusionPatterns()) {
+ m_config.beginElement(E_INCLUDE);
+ m_config.endElement(include);
+ }
+
+ //Add Exclude patterns
+ for(String exclude : target.getExclusionPatterns()) {
+ m_config.beginElement(E_EXCLUDE);
+ m_config.endElement(exclude);
+ }
+
+ m_config.endElement(); //
+ }
+
+ m_config.endElement(); //
+ }
+
+ @Override
+ public void write() throws TransformerException {
+ m_transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); //$NON-NLS-1$
+ m_config.write(m_transformer);
+ }
+
+ /**
+ * Returns the location of the generated configuration file.
+ * @return
+ */
+ @Override
+ public String getOutputLocation() {
+ return m_configOutputDirectory+File.separator+m_configFileName;
+ }
+}