You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2009/12/04 11:16:28 UTC

svn commit: r887146 - in /tomcat/trunk/java/org/apache/catalina/startup: ContextConfig.java LocalStrings.properties

Author: markt
Date: Fri Dec  4 10:16:27 2009
New Revision: 887146

URL: http://svn.apache.org/viewvc?rev=887146&view=rev
Log:
Adding the plumbing to get inputstreams for class files. These will be passed BCEL for annotation scanning.

Modified:
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties

Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=887146&r1=887145&r2=887146&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Fri Dec  4 10:16:27 2009
@@ -26,7 +26,10 @@
 import java.io.InputStream;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.net.URL;
+import java.net.URLConnection;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -60,6 +63,8 @@
 import org.apache.catalina.deploy.SecurityConstraint;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.naming.resources.DirContextURLConnection;
+import org.apache.naming.resources.ResourceAttributes;
 import org.apache.tomcat.JarScanner;
 import org.apache.tomcat.JarScannerCallback;
 import org.apache.tomcat.util.res.StringManager;
@@ -1241,8 +1246,15 @@
         
         if (!webXml.isMetadataComplete()) {
             // Process /WEB-INF/classes for annotations
-            // TODO SERVLET3
-
+            URL webinfClasses;
+            try {
+                webinfClasses =
+                    context.getServletContext().getResource("/WEB-INF/classes");
+                processAnnotationsUrl(webinfClasses, webXml);
+            } catch (MalformedURLException e) {
+                log.error(sm.getString("contextConfig.webinfClassesUrl"), e);
+            }
+            
             // Have to process JARs for fragments
             Map<String,WebXml> fragments = processJarsForWebFragments();
             
@@ -1252,7 +1264,7 @@
 
             // Process JARs for annotations - only need to process those
             // fragments we are going to use
-            processAnnotationsInJars(orderedFragments);
+            processAnnotations(orderedFragments);
 
             // Merge fragment into application
             if (ok) {
@@ -1476,6 +1488,173 @@
         return callback.getFragments();
     }
 
+    protected void processAnnotations(Set<WebXml> fragments) {
+        for(WebXml fragment : fragments) {
+            if (!fragment.isMetadataComplete()) {
+                URL url = fragment.getURL();
+                processAnnotationsUrl(url, fragment);
+            }
+        }
+    }
+
+    protected void processAnnotationsUrl(URL url, WebXml fragment) {
+        if (url == null) {
+            // Nothing to do.
+            return;
+        } else if ("jar".equals(url.getProtocol())) {
+            processAnnotationsJar(url, fragment);
+        } else if ("jndi".equals(url.getProtocol())) {
+            processAnnotationsJndi(url, fragment);
+        } else if ("file".equals(url.getProtocol())) {
+            try {
+                processAnnotationsFile(new File(url.toURI()), fragment);
+            } catch (URISyntaxException e) {
+                log.error(sm.getString("contextConfig.fileUrl", url), e);
+            }
+        } else {
+            log.error(sm.getString("contextConfig.unknownUrlProtocol",
+                    url.getProtocol(), url));
+        }
+        
+    }
+
+
+    protected void processAnnotationsJar(URL url, WebXml fragment) {
+        JarFile jarFile = null;
+        
+        try {
+            URLConnection urlConn = url.openConnection();
+            JarURLConnection jarUrlConn;
+            if (!(urlConn instanceof JarURLConnection)) {
+                // This should never happen
+                sm.getString("contextConfig.jarUrl", url);
+                return;
+            }
+            
+            jarUrlConn = (JarURLConnection) urlConn;
+            jarUrlConn.setUseCaches(false);
+            jarFile = jarUrlConn.getJarFile();
+            
+            Enumeration<JarEntry> jarEntries = jarFile.entries();
+            while (jarEntries.hasMoreElements()) {
+                JarEntry jarEntry = jarEntries.nextElement();
+                String entryName = jarEntry.getName();
+                if (entryName.endsWith(".class")) {
+                    InputStream is = null;
+                    try {
+                        is = jarFile.getInputStream(jarEntry);
+                        processAnnotationsStream(is, fragment);
+                    } catch (IOException e) {
+                        log.error(sm.getString("contextConfig.inputStreamJar",
+                                entryName, url),e);
+                    } finally {
+                        if (is != null) {
+                            try {
+                                is.close();
+                            } catch (Throwable t) {
+                                // ignore
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            log.error(sm.getString("contextConfig.jarFile", url), e);
+        } finally {
+            if (jarFile != null) {
+                try {
+                    jarFile.close();
+                } catch (Throwable t) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    
+    protected void processAnnotationsJndi(URL url, WebXml fragment) {
+        try {
+            URLConnection urlConn = url.openConnection();
+            DirContextURLConnection dcUrlConn;
+            if (!(urlConn instanceof DirContextURLConnection)) {
+                // This should never happen
+                sm.getString("contextConfig.jndiUrl", url);
+                return;
+            }
+            
+            dcUrlConn = (DirContextURLConnection) urlConn;
+            dcUrlConn.setUseCaches(false);
+            
+            String ct = dcUrlConn.getContentType();
+            if (ResourceAttributes.COLLECTION_TYPE.equals(ct)) {
+                // Collection
+                Enumeration<String> dirs = dcUrlConn.list();
+                while (dirs.hasMoreElements()) {
+                    String dir = dirs.nextElement();
+                    URL dirUrl = new URL(url.toString() + '/' + dir);
+                    processAnnotationsJndi(dirUrl, fragment);
+                }
+                
+            } else {
+                // Single file
+                if (url.getPath().endsWith(".class")) {
+                    InputStream is = null;
+                    try {
+                        is = dcUrlConn.getInputStream();
+                        processAnnotationsStream(is, fragment);
+                    } catch (IOException e) {
+                        log.error(sm.getString("contextConfig.inputStreamJndi",
+                                url),e);
+                    } finally {
+                        if (is != null) {
+                            try {
+                                is.close();
+                            } catch (Throwable t) {
+                                // ignore
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+            log.error(sm.getString("contextConfig.jarFile", url), e);
+        }
+    }
+    
+    
+    protected void processAnnotationsFile(File file, WebXml fragment) {
+        
+        if (file.isDirectory()) {
+            String[] dirs = file.list();
+            for (String dir : dirs) {
+                processAnnotationsFile(new File(file,dir), fragment);
+            }
+        } else if (file.canRead() && file.getName().endsWith(".class")) {
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(file);
+                processAnnotationsStream(fis, fragment);
+            } catch (IOException e) {
+                log.error(sm.getString("contextConfig.inputStreamFile",
+                        file.getAbsolutePath()),e);
+            } finally {
+                if (fis != null) {
+                    try {
+                        fis.close();
+                    } catch (Throwable t) {
+                        // ignore
+                    }
+                }
+            }
+        }
+    }
+
+
+    protected void processAnnotationsStream(InputStream is, WebXml fragment) {
+        // TODO SERVLET 3
+    }
+
+    
     private class FragmentJarScannerCallback implements JarScannerCallback {
 
         private static final String FRAGMENT_LOCATION =
@@ -1567,16 +1746,6 @@
     }
 
 
-    protected void processAnnotationsInJars(Set<WebXml> fragments) {
-        for(WebXml fragment : fragments) {
-            if (!fragment.isMetadataComplete()) {
-                // Scan jar for annotations, add to fragment
-                // TODO SERVLET3
-            }
-        }
-    }
-
-
     protected static class ContextErrorHandler
         implements ErrorHandler {
 

Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=887146&r1=887145&r2=887146&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Fri Dec  4 10:16:27 2009
@@ -33,8 +33,16 @@
 contextConfig.defaultMissing=No global web.xml found
 contextConfig.defaultPosition=Occurred at line {0} column {1}
 contextConfig.destroy=ContextConfig: Destroying
+contextConfig.fileUrl=Unable to create a File object from the URL [{0}]
 contextConfig.fixDocBase=Exception fixing docBase for context [{0}] 
 contextConfig.init=ContextConfig: Initializing
+contextConfig.inputStreamFile=Unable to process file [{0}] for annotations
+contextConfig.inputStreamJar=Unable to process Jar entry [{0}] from Jar [{1}] for annotations
+contextConfig.inputStreamJndi=Unable to process resource element [{0}] for annotations
+contextConfig.jarFile=Unable to process Jar [{0}] for annotations
+contextConfig.jarUrl=The connection created for URL [{0}] was not a JarUrlConnection
+contextConfig.jar=Unable to process resource [{0}] for annotations
+contextConfig.jndiUrl=The connection created for URL [{0}] was not a DirContextURLConnection
 contextConfig.missingRealm=No Realm has been configured to authenticate against
 contextConfig.role.auth=WARNING: Security role name {0} used in an <auth-constraint> without being defined in a <security-role>
 contextConfig.role.link=WARNING: Security role name {0} used in a <role-link> without being defined in a <security-role>
@@ -42,6 +50,8 @@
 contextConfig.start=ContextConfig: Processing START
 contextConfig.stop=ContextConfig: Processing STOP
 contextConfig.unavailable=Marking this application unavailable due to previous error(s)
+contextConfig.unknownUrlProtocol=The URL protocol [{0}] was not recognised during annotation processing. URL [{1}] was ignored.
+contextConfig.webinfClassesUrl=Unable to determine URL for WEB-INF/classes
 contextConfig.xmlSettings=Context [{0}] will parse web.xml and web-fragment.xml files with validation:{1} and namespaceAware:{2}
 embedded.alreadyStarted=Embedded service has already been started
 embedded.noEngines=No engines have been defined yet



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org