EXTSCRIPT-154: Code Rewrite/Refactoring, adding the utils classes for the testases


git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/scripting/trunk@1300010 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/AbstractGeneratorTestCase.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/AbstractGeneratorTestCase.java
new file mode 100644
index 0000000..679bcca
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/AbstractGeneratorTestCase.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import junit.framework.TestCase;
+import org.apache.myfaces.extensions.scripting.api.CompilationException;
+import org.apache.myfaces.extensions.scripting.api.CompilationResult;
+import org.apache.myfaces.extensions.scripting.sandbox.compiler.Compiler;
+import org.apache.myfaces.extensions.scripting.sandbox.compiler.CompilerFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * <p>Base class for test cases that generate Java source files.</p>
+ */
+public abstract class AbstractGeneratorTestCase extends TestCase {
+
+    /**
+     * The temporary test directory where test cases store generated Java source files, etc.
+     */
+    private File testDirectory;
+
+    // ------------------------------------------ Test lifecycle methods
+
+    /**
+     * <p>Creates a temporary directory that can be used to store
+     * generated source files and compiled class files within it.</p>
+     */
+    @Override
+    public void setUp() throws Exception {
+        // Create the test directory within the directory that the class file of this test case is located in
+        testDirectory =
+                new File(getClass().getResource(".").toURI().getPath(), "test");
+        if (!testDirectory.mkdirs() && !testDirectory.exists()) {
+            throw new IllegalStateException(
+                    "Couldn't setup the test case for the test case '" + getClass().getName()
+                            + "'. It wasn't possible to create a temporary test folder.");
+        }
+    }
+
+    /**
+     * <p>Deletes the temporary directory including all subdirectories
+     * and files within it.</p>
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        deleteDirectory(testDirectory);
+
+        if (!testDirectory.delete()) {
+            System.err.println("Couldn't delete the temporary test directory '" + testDirectory.getAbsolutePath() + "'.");
+        }
+    }
+
+    // ------------------------------------------ Protected methods
+
+    /**
+     * <p>Writes the given file content to the specified file. Use this method in order to
+     * persist dynamically generated Java code. Note that this method assumes that the given
+     * file name is a relative path to the test directory.</p>
+     *
+     * @param fileName    the Java source file that you want to save
+     * @param fileContent the content that you want to save, i.e. the Java code
+     * @throws java.io.IOException if an I/O-error occurs
+     */
+    protected void writeFile(String fileName, String[] fileContent) throws IOException {
+        writeFile(new File(testDirectory, fileName), fileContent);
+    }
+
+    /**
+     * <p>Writes the given file content to the specified file. Use this method in order to
+     * persist dynamically generated Java code.</p>
+     *
+     * @param file        the Java source file that you want to save
+     * @param fileContent the content that you want to save, i.e. the Java code
+     * @throws java.io.IOException if an I/O-error occurs
+     */
+    protected void writeFile(File file, String[] fileContent) throws IOException {
+        if (!file.getParentFile().exists() && !file.getParentFile().mkdirs() && !!file.createNewFile()) {
+            throw new IllegalStateException("Couldn't create the file '" + file.getAbsolutePath() + "'.");
+        }
+
+        PrintWriter writer = new PrintWriter(new FileOutputStream(file));
+        for (String line : fileContent) {
+            writer.println(line);
+        }
+
+        writer.flush();
+        writer.close();
+
+        // Wait a little bit so that the system updates the timestamps
+        try {
+            Thread.sleep(100);
+        }
+        catch (InterruptedException ex) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    protected CompilationResult compileFile(String sourcePath, String targetPath, String fileName, String[] fileContent)
+            throws IOException, CompilationException {
+        return compileFile(CompilerFactory.createCompiler(),
+                new File(buildAbsolutePath(sourcePath)), new File(buildAbsolutePath(targetPath)), fileName, fileContent);
+    }
+
+    protected CompilationResult compileFile(String sourcePath, String targetPath, String fileName, String[] fileContent, ClassLoader classLoader)
+            throws IOException, CompilationException {
+        return compileFile(CompilerFactory.createCompiler(),
+                new File(buildAbsolutePath(sourcePath)), new File(buildAbsolutePath(targetPath)), fileName, fileContent, classLoader);
+    }
+
+    protected CompilationResult compileFile(Compiler compiler, String sourcePath, String targetPath, String fileName, String[] fileContent)
+            throws IOException, CompilationException {
+        return compileFile(compiler,
+                new File(buildAbsolutePath(sourcePath)), new File(buildAbsolutePath(targetPath)), fileName, fileContent);
+    }
+
+    protected CompilationResult compileFile(Compiler compiler, File sourcePath, File targetPath, String fileName, String[] fileContent)
+            throws IOException, CompilationException {
+        return compileFile(compiler, sourcePath, targetPath, fileName, fileContent, getClass().getClassLoader());
+    }
+
+    protected CompilationResult compileFile(Compiler compiler, File sourcePath, File targetPath, String fileName, String[] fileContent, ClassLoader classLoader)
+            throws IOException, CompilationException {
+        writeFile(new File(sourcePath, fileName), fileContent);
+
+        CompilationResult result = compiler.compile(sourcePath, targetPath, fileName, classLoader);
+        assertFalse("Compilation errors: " + result.getErrors().toString(), result.hasErrors());
+
+        return result;
+    }
+
+    /**
+     * <p>Concatenates the given relative path and the path of the test directory. In doing so
+     * an absolute path will be created that you can use to access the according file.</p>
+     *
+     * @param relativePath the relative path of the file that you want to access
+     * @return the absolute path of the file that you want to access
+     */
+    protected String buildAbsolutePath(String relativePath) {
+        return buildAbsoluteFile(relativePath).getAbsolutePath();
+    }
+
+    /**
+     * <p>Concatenates the given relative path and the path of the test directory. In doing so
+     * an absolute file will be created that you can use to access the according file.</p>
+     *
+     * @param relativePath the relative path of the file that you want to access
+     * @return the absolute File object of the file that you want to access
+     */
+    protected File buildAbsoluteFile(String relativePath) {
+        File file = new File(testDirectory, relativePath);
+        if (!file.exists() && !file.mkdirs()) {
+            throw new IllegalStateException("Couldn't create the directory '" + file.getAbsolutePath() + "'.");
+        }
+
+        return file;
+    }
+
+    // ------------------------------------------ Private utility methods
+
+    /**
+     * <p>Deletes all subdirectories and files within the given directory.</p>
+     *
+     * @param directory the directory you want to delete
+     */
+    public static void deleteDirectory(File directory) {
+        for (File file : directory.listFiles()) {
+            if (file.isDirectory()) {
+                deleteDirectory(file);
+            }
+
+            if (!file.delete()) {
+                System.err.println("Couldn't delete the file or directory '" + file.getAbsolutePath() + "'.");
+            }
+        }
+    }
+
+}
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/Consts.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/Consts.java
new file mode 100644
index 0000000..c2ca8c9
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/Consts.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import static org.apache.myfaces.extensions.scripting.api.ScriptingConst.*;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class Consts {
+    public static final String PROBE2 = "org.apache.myfaces.extensions.scripting.core.classIdentifier.Probe2";
+    public static String JAVA_FILE_ENDING = ".java";
+    public static final int[] ARTIFACT_TYPES = {
+            ARTIFACT_TYPE_UNKNOWN,
+            ARTIFACT_TYPE_MANAGEDBEAN,
+            ARTIFACT_TYPE_MANAGEDPROPERTY,
+            ARTIFACT_TYPE_RENDERKIT,
+            ARTIFACT_TYPE_VIEWHANDLER,
+            ARTIFACT_TYPE_RENDERER,
+            ARTIFACT_TYPE_COMPONENT,
+            ARTIFACT_TYPE_VALIDATOR,
+            ARTIFACT_TYPE_BEHAVIOR,
+            ARTIFACT_TYPE_APPLICATION,
+            ARTIFACT_TYPE_ELCONTEXTLISTENER,
+            ARTIFACT_TYPE_ACTIONLISTENER,
+            ARTIFACT_TYPE_VALUECHANGELISTENER,
+            ARTIFACT_TYPE_CONVERTER,
+            ARTIFACT_TYPE_LIFECYCLE,
+            ARTIFACT_TYPE_PHASELISTENER,
+            ARTIFACT_TYPE_FACESCONTEXT,
+            ARTIFACT_TYPE_NAVIGATIONHANDLER,
+            ARTIFACT_TYPE_RESPONSEWRITER,
+            ARTIFACT_TYPE_RESPONSESTREAM,
+            ARTIFACT_TYPE_RESOURCEHANDLER,
+            ARTIFACT_TYPE_CLIENTBEHAVIORRENDERER,
+            ARTIFACT_TYPE_SYSTEMEVENTLISTENER,
+    };
+    public static final String JAVA_LANG = "java.lang";
+}
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/ContextUtils.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/ContextUtils.java
new file mode 100644
index 0000000..1672b27
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/ContextUtils.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.myfaces.extensions.scripting.api.DynamicCompiler;
+import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;
+import org.apache.myfaces.extensions.scripting.core.util.WeavingContextInitializer;
+import org.apache.myfaces.extensions.scripting.loaders.java.compiler.CompilerFacade;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Context utils which store the reusable test code
+ *
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class ContextUtils {
+
+    /**
+     * locking monitor for the compile/load parts
+     */
+    public static volatile Boolean COMPILE_LOAD_MONITOR = new Boolean(true);
+
+    /**
+     * A startup routine shared by many tests
+     * to do the basic weaving initialization
+     *
+     * @return the mockup servlet context
+     */
+    public static MockServletContext startupSystem() {
+        MockServletContext context = new MockServletContext();
+        WeavingContextInitializer.initWeavingContext(context);
+        return context;
+    }
+
+    /**
+     * same as the other one but with a web.xml path being possible
+     *
+     * @param webXmlPath the path to the web.xml
+     * @return the servlet context
+     */
+    public static MockServletContext startupSystem(String webXmlPath) {
+        MockServletContext context = new MockServletContext(webXmlPath);
+        WeavingContextInitializer.initWeavingContext(context);
+        return context;
+    }
+
+    public static File doJavaRecompile(String sourceRoot) throws ClassNotFoundException {
+        synchronized (COMPILE_LOAD_MONITOR) {
+
+            DynamicCompiler compiler = new CompilerFacade(false);
+            try {
+                FileUtils.deleteDirectory(WeavingContext.getConfiguration().getCompileTarget());
+            } catch (IOException e) {
+                fail(e.getMessage());
+            }
+            WeavingContext.getConfiguration().getCompileTarget().mkdirs();
+            return compiler.compileAllFiles(sourceRoot, "");
+        }
+    }
+
+}
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/LoggingHandler.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/LoggingHandler.java
new file mode 100644
index 0000000..814e2e4
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/LoggingHandler.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+
+/**
+ * A logging handler which can capture our internal logging output
+ *
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class LoggingHandler extends Handler {
+    StringBuilder _output = new StringBuilder();
+
+    @Override
+    public void publish(LogRecord record) {
+        _output.append(record.getMessage());
+    }
+
+    public StringBuilder getOutput() {
+        return _output;
+    }
+
+    public void setOutput(StringBuilder output) {
+        _output = output;
+    }
+
+    @Override
+    public void flush() {
+
+    }
+
+    @Override
+    public void close() throws SecurityException {
+
+    }
+}
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/MockServletContext.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/MockServletContext.java
new file mode 100644
index 0000000..8e28aca
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/MockServletContext.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import org.apache.myfaces.extensions.scripting.api.ScriptingConst;
+import org.apache.myfaces.extensions.scripting.servlet.StartupServletContextPluginChainLoader;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Basic unit testing servlet context mock
+ *
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class MockServletContext extends org.apache.myfaces.test.mock.MockServletContext {
+
+    Map<String, Object> _attributes = new HashMap<String, Object>();
+    Map<String, String> _initParameters = new HashMap<String, String>();
+    String _resourceRoot = "../../src/test/resources/webapp";
+
+    public MockServletContext() {
+        setResourceRoot(_resourceRoot);
+        addInitParameter(ScriptingConst.INIT_PARAM_MYFACES_PLUGIN, StartupServletContextPluginChainLoader.class.getName());
+    }
+
+    public MockServletContext(String resourceRoot) {
+        setResourceRoot(resourceRoot);
+        addInitParameter(ScriptingConst.INIT_PARAM_MYFACES_PLUGIN, StartupServletContextPluginChainLoader.class.getName());
+    }
+
+    public void setResourceRoot(String newRoot) {
+        _resourceRoot = newRoot;
+        super.setDocumentRoot(new File(Thread.currentThread().getContextClassLoader().getResource("./").getPath() + _resourceRoot));
+    }
+
+}
diff --git a/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/PathUtils.java b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/PathUtils.java
new file mode 100644
index 0000000..ab634f9
--- /dev/null
+++ b/extscript-core-root/extscript-core/src/test/java/rewrite/org/apache/myfaces/extensions/scripting/scanningcore/support/PathUtils.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 rewrite.org.apache.myfaces.extensions.scripting.scanningcore.support;
+
+import java.io.File;
+
+/**
+ * Supportive utils to access the source
+ * probes directly
+ *
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+public class PathUtils {
+
+    String _currentPath;
+    String _resourceRoot;
+
+    public PathUtils() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        //we use a location relative to our current root one to reach the sources
+        //because the test also has to be performed outside of maven
+        //and the ide cannot cope with resource paths for now
+        _currentPath = loader.getResource("./").getPath();
+        _resourceRoot = _currentPath + "../../src/test/resources";
+    }
+
+    /**
+     * Resource root dir getter
+     *
+     * @return the resource root dir (from our source package)
+     */
+    public String getResourceRoot() {
+        return _resourceRoot;
+    }
+
+    public String getResource(String in) {
+        if (in.startsWith("//") || in.startsWith("\\")) {
+            in = in.substring(1);
+        }
+        return _resourceRoot + File.separator + in;
+    }
+
+    /**
+     * Simulates the Unix touch statement on a relative pathed source file
+     *
+     * @param relativeSourceFile the relative path to the resource file
+     */
+    public void touch(String relativeSourceFile) {
+        File resource = new File(getResource(relativeSourceFile));
+        touch(resource);
+    }
+
+    /**
+     * Unix touch on a file object
+     *
+     * @param resource the file object to be touched
+     */
+    public void touch(File resource) {
+        if (resource.exists()) {
+            resource.setLastModified(System.currentTimeMillis());
+        }
+    }
+
+}