improve classpath building and add test for JSTL

git-svn-id: https://svn.apache.org/repos/asf/struts/sandbox/trunk@801835 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/struts2-jsp-plugin/pom.xml b/struts2-jsp-plugin/pom.xml
index 94695ba..0562e3b 100644
--- a/struts2-jsp-plugin/pom.xml
+++ b/struts2-jsp-plugin/pom.xml
@@ -79,6 +79,19 @@
             <version>1.0</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>taglibs</groupId>
+            <artifactId>standard</artifactId>
+            <version>1.1.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jstl</artifactId>
+            <version>1.1.2</version>
+            <scope>test</scope>
+        </dependency>
+        
     </dependencies>
 
     <!--<build>
diff --git a/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java b/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
index 3fa97c4..75e3bc7 100644
--- a/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
+++ b/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
@@ -21,8 +21,10 @@
 package org.apache.struts2;

 

 import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;

+import com.opensymphony.xwork2.util.finder.UrlSet;

 import com.opensymphony.xwork2.util.logging.Logger;

 import com.opensymphony.xwork2.util.logging.LoggerFactory;

+import com.opensymphony.xwork2.util.URLUtil;

 import org.apache.commons.io.FileUtils;

 import org.apache.commons.lang.xwork.StringUtils;

 import org.apache.struts2.compiler.MemoryClassLoader;

@@ -45,7 +47,11 @@
 import java.util.*;

 

 /**

- * Uses jasper to extract a JSP from the classpath to a file and compile it

+ * Uses jasper to extract a JSP from the classpath to a file and compile it. The classpathc used for

+ * compilation is built by finding all the jar files using the current class loader (Thread), then adding

+ * the plugin jar and the jars that contain these classes:

+ * javax.servlet.Servlet

+ * javax.servlet.jsp.JspPage

  */

 public class JSPLoader {

     private static final Logger LOG = LoggerFactory.getLogger(JSPLoader.class);

@@ -95,7 +101,7 @@
      * Compiles the given source code into java bytecode

      *

      */

-    private void compileJava(String className, final String source, Set<String> extraClassPath) {

+    private void compileJava(String className, final String source, Set<String> extraClassPath) throws IOException {

         JavaCompiler compiler =

                 ToolProvider.getSystemJavaCompiler();

 

@@ -133,28 +139,34 @@
 

         //build classpath

         List<String> optionList = new ArrayList<String>();

-        StringBuilder classPath = new StringBuilder();

-        //this jar

-        classPath.append(getJarUrl(EmbeddedJSPResult.class));

-        classPath.append(";");

-        //servlet api

-        classPath.append(getJarUrl(Servlet.class));

-        classPath.append(";");

-        //jsp api

-        classPath.append(getJarUrl(JspPage.class));

+        Set<String> classPath = new HashSet<String>();

 

-        if (!extraClassPath.isEmpty())

-            classPath.append(";");

+        //find available jars

+        UrlSet urlSet = new UrlSet(getClassLoaderInterface());

+        urlSet = urlSet.matching(".*?\\.jar(!/)?$");

+        List<URL> urls = urlSet.getUrls();

+        if (urls != null) {

+            for (URL url : urls) {

+                File file = FileUtils.toFile(URLUtil.normalizeToFileProtocol(url));

+                classPath.add(file.getAbsolutePath());

+            }

+        }

+

+

+        //this jar

+        classPath.add(getJarUrl(EmbeddedJSPResult.class));

+        //servlet api

+        classPath.add(getJarUrl(Servlet.class));

+        //jsp api

+        classPath.add(getJarUrl(JspPage.class));

 

         //add extra classpath entries (jars where tlds were found will be here)

         for (Iterator<String> iterator = extraClassPath.iterator(); iterator.hasNext();) {

             String entry = iterator.next();

-            classPath.append(entry);

-            if (iterator.hasNext())

-                classPath.append(";");

+            classPath.add(entry);

         }

 

-        optionList.addAll(Arrays.asList("-classpath", classPath.toString()));

+        optionList.addAll(Arrays.asList("-classpath", StringUtils.join(classPath, ";")));

 

 

         //compile

@@ -177,8 +189,7 @@
 

     private JspC compileJSP(String location) throws JasperException {

         JspC jspC = new JspC();

-        //TODO: get this from context so OSGI works

-        jspC.setClassLoaderInterface(new ClassLoaderInterfaceDelegate(Thread.currentThread().getContextClassLoader()));

+        jspC.setClassLoaderInterface(getClassLoaderInterface());

         jspC.setCompile(false);

         jspC.setJspFiles(location);

         jspC.setPackage(DEFAULT_PACKAGE);

@@ -186,6 +197,11 @@
         return jspC;

     }

 

+    private ClassLoaderInterfaceDelegate getClassLoaderInterface() {

+        //TODO: get this from context so OSGI works

+        return new ClassLoaderInterfaceDelegate(Thread.currentThread().getContextClassLoader());

+    }

+

     private static URI toURI(String name) {

         try {

             return new URI(name);

diff --git a/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java b/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
index 025a0ee..6663842 100644
--- a/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
+++ b/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
@@ -95,6 +95,13 @@
         }

     }

 

+    public void testJSTL() throws Exception {

+           result.setLocation("org/apache/struts2/jstl.jsp");

+           result.execute(null);

+

+           assertEquals("XXXXXXXXXXX", cleanup(response.getContentAsString()));

+       }

+

 

      public void testCachedInstances() throws InterruptedException {

         ServletCache cache = new ServletCache();

diff --git a/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp b/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp
new file mode 100644
index 0000000..63b586a
--- /dev/null
+++ b/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp
@@ -0,0 +1,6 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

+

+<c:set var="number" value="10"/>

+<c:forEach begin="0" end="${number}">

+X    

+</c:forEach>
\ No newline at end of file