Author: remy.maucherat(a)jboss.com
Date: 2009-04-20 23:39:25 -0400 (Mon, 20 Apr 2009)
New Revision: 1021
Added:
trunk/java/org/apache/catalina/ContextScanner.java
trunk/java/org/apache/catalina/startup/BaseContextScanner.java
trunk/java/org/apache/catalina/startup/ClassLoadingContextScanner.java
trunk/java/org/apache/catalina/startup/JavassistContextScanner.java
trunk/java/org/apache/catalina/startup/WarScanner.java
trunk/java/org/apache/tomcat/WarComponents.java
Removed:
trunk/java/org/apache/catalina/AnnotationScanner.java
trunk/java/org/apache/catalina/core/BaseAnnotationScanner.java
trunk/java/org/apache/catalina/core/ClassLoadingAnnotationScanner.java
trunk/java/org/apache/catalina/core/JavassistAnnotationScanner.java
trunk/java/org/apache/catalina/startup/TldConfig.java
Modified:
trunk/ROADMAP.txt
trunk/java/org/apache/catalina/Context.java
trunk/java/org/apache/catalina/Globals.java
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/StandardContext.java
trunk/java/org/apache/catalina/mbeans/MBeanFactory.java
trunk/java/org/apache/catalina/startup/ContextConfig.java
trunk/webapps/docs/changelog.xml
Log:
- Some WIP on a scanner for the WAR.
- Remove the faked XML validation flag.
Modified: trunk/ROADMAP.txt
===================================================================
--- trunk/ROADMAP.txt 2009-04-20 15:51:08 UTC (rev 1020)
+++ trunk/ROADMAP.txt 2009-04-21 03:39:25 UTC (rev 1021)
@@ -7,6 +7,7 @@
- Resources overlay
- Session tracking configuration
- Access control annotations
+- ServletContainerInitializer support
- JSP 2.2 changes
- EL 1.1 changes
- Setup standalone TCK environment for testing compliance with the new features
Deleted: trunk/java/org/apache/catalina/AnnotationScanner.java
===================================================================
--- trunk/java/org/apache/catalina/AnnotationScanner.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/AnnotationScanner.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -1,33 +0,0 @@
-/*
- * 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 org.apache.catalina;
-
-import java.util.List;
-
-public interface AnnotationScanner {
-
- /**
- * Scan the given context's default locations for annotations.
- *
- * @param context
- */
- public List<Class<?>> scan(Context context);
-
-
-}
Modified: trunk/java/org/apache/catalina/Context.java
===================================================================
--- trunk/java/org/apache/catalina/Context.java 2009-04-20 15:51:08 UTC (rev 1020)
+++ trunk/java/org/apache/catalina/Context.java 2009-04-21 03:39:25 UTC (rev 1021)
@@ -1020,22 +1020,6 @@
/**
- * Get the server.xml <context> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- *
- */
- public boolean getXmlNamespaceAware();
-
-
- /**
- * Get the server.xml <context> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getXmlValidation();
-
-
- /**
* Return true if the Context has been initialized. This is lifecycle-ish, but
* needed by more and more Servlet API operations which are only permitted until
* the Context is initialized.
@@ -1045,56 +1029,5 @@
public boolean isInitialized();
- /**
- * Set the validation feature of the XML parser used when
- * parsing xml instances.
- * @param xmlValidation true to enable xml instance validation
- */
- public void setXmlValidation(boolean xmlValidation);
-
-
- /**
- * Set the namespace aware feature of the XML parser used when
- * parsing xml instances.
- * @param xmlNamespaceAware true to enable namespace awareness
- */
- public void setXmlNamespaceAware(boolean xmlNamespaceAware);
- /**
- * Get the server.xml <context> attribute's xmlValidation.
- * @return true if validation is enabled.
- */
-
-
- /**
- * Set the validation feature of the XML parser used when
- * parsing tlds files.
- * @param tldValidation true to enable xml instance validation
- */
- public void setTldValidation(boolean tldValidation);
-
-
- /**
- * Get the server.xml <context> attribute's webXmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getTldValidation();
-
-
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- */
- public boolean getTldNamespaceAware();
-
-
- /**
- * Set the namespace aware feature of the XML parser used when
- * parsing xml instances.
- * @param tldNamespaceAware true to enable namespace awareness
- */
- public void setTldNamespaceAware(boolean tldNamespaceAware);
-
-
}
Copied: trunk/java/org/apache/catalina/ContextScanner.java (from rev 972,
trunk/java/org/apache/catalina/AnnotationScanner.java)
===================================================================
--- trunk/java/org/apache/catalina/ContextScanner.java (rev 0)
+++ trunk/java/org/apache/catalina/ContextScanner.java 2009-04-21 03:39:25 UTC (rev 1021)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+
+package org.apache.catalina;
+
+import org.apache.tomcat.WarComponents;
+
+public interface ContextScanner extends WarComponents {
+
+ /**
+ * Scan the given context's default locations for annotations, overlays
+ * and web.xml fragments.
+ *
+ * @param context
+ */
+ public void scan(Context context);
+
+
+}
Modified: trunk/java/org/apache/catalina/Globals.java
===================================================================
--- trunk/java/org/apache/catalina/Globals.java 2009-04-20 15:51:08 UTC (rev 1020)
+++ trunk/java/org/apache/catalina/Globals.java 2009-04-21 03:39:25 UTC (rev 1021)
@@ -339,4 +339,32 @@
(System.getSecurityManager() != null);
+ /**
+ * The folder used for JAR overlays.
+ */
+ public static final String OVERLAY_PATH =
+ System.getProperty("org.apache.catalina.OVERLAY_PATH",
"/META-INF/resources/");
+
+
+ /**
+ * The path used for web fragments.
+ */
+ public static final String WEB_FRAGMENT_PATH =
+ System.getProperty("org.apache.catalina.WEB_FRAGMENT_PATH",
"/META-INF/web-fragment.xml");
+
+
+ /**
+ * The master flag which controls XML validation.
+ */
+ public static final boolean XML_VALIDATION =
+
Boolean.valueOf(System.getProperty("org.apache.catalina.XML_VALIDATION",
"false")).booleanValue();
+
+
+ /**
+ * The master flag which controls namespace awareness when parsing XML.
+ */
+ public static final boolean XML_NAMESPACE_AWARE =
+
Boolean.valueOf(System.getProperty("org.apache.catalina.XML_NAMESPACE_AWARE",
"false")).booleanValue();
+
+
}
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -2733,7 +2733,6 @@
return;
DiskFileUpload fu = new DiskFileUpload();
- // FIXME: set default values
fu.setRepositoryPath(config.location());
if (config.fileSizeThreshold() > 0) {
fu.setSizeThreshold(config.fileSizeThreshold());
Deleted: trunk/java/org/apache/catalina/core/BaseAnnotationScanner.java
===================================================================
--- trunk/java/org/apache/catalina/core/BaseAnnotationScanner.java 2009-04-20 15:51:08 UTC
(rev 1020)
+++ trunk/java/org/apache/catalina/core/BaseAnnotationScanner.java 2009-04-21 03:39:25 UTC
(rev 1021)
@@ -1,226 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-
-package org.apache.catalina.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-import javax.naming.directory.DirContext;
-
-import org.apache.catalina.AnnotationScanner;
-import org.apache.catalina.Context;
-
-public abstract class BaseAnnotationScanner
- implements AnnotationScanner {
-
- /**
- * Scan the given context's default locations for annotations.
- *
- * @param context
- */
- public List<Class<?>> scan(Context context) {
- ArrayList<Class<?>> result = new ArrayList<Class<?>>();
-
- if (context.getLoader().findLoaderRepositories() != null) {
- String[] repositories = context.getLoader().findLoaderRepositories();
- for (int i = 0; i < repositories.length; i++) {
- if (repositories[i].endsWith(".jar")) {
- try {
- scanJar(result, context, new JarFile(repositories[i]));
- } catch (IOException e) {
- // Ignore
- }
- } else {
- scanClasses(result, context, new File(repositories[i]),
"");
- }
- }
- }
-
- return result;
- /*
- DirContext resources = context.getResources();
- DirContext webInfClasses = null;
- DirContext webInfLib = null;
-
- try {
- webInfClasses = (DirContext) resources.lookup("/WEB-INF/classes");
- } catch (Exception e) {
- // Ignore, /WEB-INF/classes not found, or not a folder
- }
- if (webInfClasses != null) {
- scanClasses(context, webInfClasses, "");
- }
-
- try {
- webInfLib = (DirContext) resources.lookup("/WEB-INF/lib");
- } catch (Exception e) {
- // Ignore, /WEB-INF/classes not found, or not a folder
- }
- if (webInfLib != null) {
- scanJars(context, webInfLib);
- }*/
-
- }
-
-
- /**
- * Scan folder containing class files.
- */
- public void scanClasses(List<Class<?>> result, Context context, File
folder, String path) {
- String[] files = folder.list();
- for (int i = 0; i < files.length; i++) {
- File file = new File(folder, files[i]);
- if (file.isDirectory()) {
- scanClasses(result, context, file, path + "/" + files[i]);
- } else if (files[i].endsWith(".class")) {
- String className = getClassName(path + "/" + files[i]);
- Class<?> annotated = scanClass(context, className, file, null);
- if (annotated != null) {
- result.add(annotated);
- }
- }
- }
- }
-
-
- /**
- * Scan folder containing class files.
- */
- /*
- public static void scanClasses(Context context, DirContext folder, String path) {
- try {
- NamingEnumeration<Binding> enumeration = folder.listBindings(path);
- while (enumeration.hasMore()) {
- Binding binding = enumeration.next();
- Object object = binding.getObject();
-
- if (object instanceof Resource) {
- // This is a class, so we should load it
- String className = getClassName(path + "/" +
binding.getName());
- scanClass(context, className, (Resource) object, null, null);
- } else if (object instanceof DirContext) {
- scanClasses(context, folder, path + "/" +
binding.getName());
- }
-
- }
- } catch (NamingException e) {
- // Ignore for now
- e.printStackTrace();
- }
- }*/
-
-
- /**
- * Scan folder containing JAR files.
- */
- public void scanJars(List<Class<?>> result, Context context, DirContext
folder) {
- if (context.getLoader().findLoaderRepositories() != null) {
- String[] repositories = context.getLoader().findLoaderRepositories();
- for (int i = 0; i < repositories.length; i++) {
- if (repositories[i].endsWith(".jar")) {
- try {
- scanJar(result, context, new JarFile(repositories[i]));
- } catch (IOException e) {
- // Ignore
- }
- }
- }
- }
- /*else {
- try {
- NamingEnumeration<Binding> enumeration =
folder.listBindings("");
- while (enumeration.hasMore()) {
- Binding binding = enumeration.next();
- Object object = binding.getObject();
-
- if (object instanceof Resource &&
binding.getName().endsWith(".jar")) {
- // This is normally a JAR, put it in the work folder
- File destDir = null;
- File workDir =
- (File)
context.getServletContext().getAttribute(Globals.WORK_DIR_ATTR);
- destDir = new File(workDir, "WEB-INF/lib");
- destDir.mkdirs();
- File destFile = new File(destDir, binding.getName());
-
- scanJar(context, (Resource) object);
- }
-
- }
- } catch (NamingException e) {
- // Ignore for now
- e.printStackTrace();
- }
- }*/
- }
-
-
- /**
- * Scan all class files in the given JAR.
- */
- public void scanJar(List<Class<?>> result, Context context, JarFile file)
{
- Enumeration<JarEntry> entries = file.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- if (entry.getName().endsWith(".class")) {
- Class<?> annotated = scanClass(context,
getClassName(entry.getName()), null, entry);
- if (annotated != null) {
- result.add(annotated);
- }
- }
- }
- try {
- file.close();
- } catch (IOException e) {
- // Ignore
- }
- }
-
-
- /**
- * Get class name given a path to a classfile.
- * /my/class/MyClass.class -> my.class.MyClass
- */
- public String getClassName(String filePath) {
- if (filePath.startsWith("/")) {
- filePath = filePath.substring(1);
- }
- if (filePath.endsWith(".class")) {
- filePath = filePath.substring(0, filePath.length() -
".class".length());
- }
- return filePath.replace('/', '.');
- }
-
-
- /**
- * Scan class for interesting annotations.
- */
- public abstract Class<?> scanClass(Context context, String className, File
file, JarEntry entry);
-
-
-}
Deleted: trunk/java/org/apache/catalina/core/ClassLoadingAnnotationScanner.java
===================================================================
--- trunk/java/org/apache/catalina/core/ClassLoadingAnnotationScanner.java 2009-04-20
15:51:08 UTC (rev 1020)
+++ trunk/java/org/apache/catalina/core/ClassLoadingAnnotationScanner.java 2009-04-21
03:39:25 UTC (rev 1021)
@@ -1,58 +0,0 @@
-/*
- * 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 org.apache.catalina.core;
-
-import java.io.File;
-import java.util.jar.JarEntry;
-
-import javax.servlet.annotation.HandlesTypes;
-import javax.servlet.annotation.MultipartConfig;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.annotation.WebInitParam;
-import javax.servlet.annotation.WebListener;
-import javax.servlet.annotation.WebServlet;
-
-import org.apache.catalina.Context;
-
-public class ClassLoadingAnnotationScanner
- extends BaseAnnotationScanner {
-
- /**
- * Scan class for interesting annotations.
- */
- public Class<?> scanClass(Context context, String className, File file,
JarEntry entry) {
- // Load the class using the classloader, and see if it implements one of the web
annotations
- try {
- Class<?> clazz =
context.getLoader().getClassLoader().loadClass(className);
- if (clazz.isAnnotationPresent(HandlesTypes.class)
- || clazz.isAnnotationPresent(MultipartConfig.class)
- || clazz.isAnnotationPresent(WebFilter.class)
- || clazz.isAnnotationPresent(WebInitParam.class)
- || clazz.isAnnotationPresent(WebListener.class)
- || clazz.isAnnotationPresent(WebServlet.class)) {
- return clazz;
- }
- } catch (Throwable t) {
- // Ignore classloading errors here
- }
- return null;
- }
-
-
-}
Deleted: trunk/java/org/apache/catalina/core/JavassistAnnotationScanner.java
===================================================================
--- trunk/java/org/apache/catalina/core/JavassistAnnotationScanner.java 2009-04-20
15:51:08 UTC (rev 1020)
+++ trunk/java/org/apache/catalina/core/JavassistAnnotationScanner.java 2009-04-21
03:39:25 UTC (rev 1021)
@@ -1,38 +0,0 @@
-/*
- * 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 org.apache.catalina.core;
-
-import java.io.File;
-import java.util.jar.JarEntry;
-
-import org.apache.catalina.Context;
-
-public class JavassistAnnotationScanner
- extends BaseAnnotationScanner {
-
- /**
- * Scan class for interesting annotations.
- */
- public Class<?> scanClass(Context context, String className, File file,
JarEntry entry) {
- // FIXME: Javassist impl
- return null;
- }
-
-
-}
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -692,40 +692,6 @@
protected String j2EEServer="none";
- /**
- * Attribute value used to turn on/off XML validation
- */
- protected boolean webXmlValidation = false;
-
-
- /**
- * Attribute value used to turn on/off XML namespace validation
- */
- protected boolean webXmlNamespaceAware = false;
-
- /**
- * Attribute value used to turn on/off TLD processing
- */
- protected boolean processTlds = true;
-
- /**
- * Attribute value used to turn on/off XML validation
- */
- protected boolean tldValidation = false;
-
-
- /**
- * Attribute value used to turn on/off TLD XML namespace validation
- */
- protected boolean tldNamespaceAware = false;
-
-
- /**
- * Should we save the configuration.
- */
- protected boolean saveConfig = true;
-
-
// ----------------------------------------------------- Context Properties
@@ -1922,22 +1888,6 @@
}
- /**
- * Save config ?
- */
- public boolean isSaveConfig() {
- return saveConfig;
- }
-
-
- /**
- * Set save config flag.
- */
- public void setSaveConfig(boolean saveConfig) {
- this.saveConfig = saveConfig;
- }
-
-
// -------------------------------------------------------- Context Methods
@@ -4613,9 +4563,7 @@
if (host != null) {
configBase = new File(configBase, host.getName());
}
- if (saveConfig) {
- configBase.mkdirs();
- }
+ configBase.mkdirs();
return configBase;
}
@@ -5268,86 +5216,6 @@
}
- /**
- * Set the validation feature of the XML parser used when
- * parsing xml instances.
- * @param webXmlValidation true to enable xml instance validation
- */
- public void setXmlValidation(boolean webXmlValidation){
-
- this.webXmlValidation = webXmlValidation;
-
- }
-
- /**
- * Get the server.xml <context> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getXmlValidation(){
- return webXmlValidation;
- }
-
-
- /**
- * Get the server.xml <context> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- */
- public boolean getXmlNamespaceAware(){
- return webXmlNamespaceAware;
- }
-
-
- /**
- * Set the namespace aware feature of the XML parser used when
- * parsing xml instances.
- * @param webXmlNamespaceAware true to enable namespace awareness
- */
- public void setXmlNamespaceAware(boolean webXmlNamespaceAware){
- this.webXmlNamespaceAware= webXmlNamespaceAware;
- }
-
-
- /**
- * Set the validation feature of the XML parser used when
- * parsing tlds files.
- * @param tldValidation true to enable xml instance validation
- */
- public void setTldValidation(boolean tldValidation){
-
- this.tldValidation = tldValidation;
-
- }
-
- /**
- * Get the server.xml <context> attribute's webXmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getTldValidation(){
- return tldValidation;
- }
-
-
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- */
- public boolean getTldNamespaceAware(){
- return tldNamespaceAware;
- }
-
-
- /**
- * Set the namespace aware feature of the XML parser used when
- * parsing xml instances.
- * @param tldNamespaceAware true to enable namespace awareness
- */
- public void setTldNamespaceAware(boolean tldNamespaceAware){
- this.tldNamespaceAware= tldNamespaceAware;
- }
-
-
/**
* Support for "stateManageable" JSR77
*/
Modified: trunk/java/org/apache/catalina/mbeans/MBeanFactory.java
===================================================================
--- trunk/java/org/apache/catalina/mbeans/MBeanFactory.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/mbeans/MBeanFactory.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -604,10 +604,6 @@
path = getPathStr(path);
context.setPath(path);
context.setDocBase(docBase);
- context.setXmlValidation(xmlValidation);
- context.setXmlNamespaceAware(xmlNamespaceAware);
- context.setTldValidation(tldValidation);
- context.setTldNamespaceAware(tldNamespaceAware);
ContextConfig contextConfig = new ContextConfig();
context.addLifecycleListener(contextConfig);
Copied: trunk/java/org/apache/catalina/startup/BaseContextScanner.java (from rev 972,
trunk/java/org/apache/catalina/core/BaseAnnotationScanner.java)
===================================================================
--- trunk/java/org/apache/catalina/startup/BaseContextScanner.java
(rev 0)
+++ trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-21 03:39:25 UTC
(rev 1021)
@@ -0,0 +1,435 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+
+package org.apache.catalina.startup;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.ContextScanner;
+import org.apache.catalina.Globals;
+
+public abstract class BaseContextScanner
+ implements ContextScanner {
+
+
+ /**
+ * Names of JARs that are known not to contain any descriptors or annotations.
+ */
+ protected static HashSet<String> skipJars;
+
+ /**
+ * Initializes the set of JARs that are known not to contain any descriptors.
+ */
+ static {
+ skipJars = new HashSet<String>();
+ // Bootstrap JARs
+ skipJars.add("bootstrap.jar");
+ skipJars.add("commons-daemon.jar");
+ skipJars.add("tomcat-juli.jar");
+ // Main JARs
+ skipJars.add("annotations-api.jar");
+ skipJars.add("catalina.jar");
+ skipJars.add("catalina-ant.jar");
+ skipJars.add("el-api.jar");
+ skipJars.add("jasper.jar");
+ skipJars.add("jasper-el.jar");
+ skipJars.add("jasper-jdt.jar");
+ skipJars.add("jsp-api.jar");
+ skipJars.add("servlet-api.jar");
+ skipJars.add("tomcat-coyote.jar");
+ skipJars.add("tomcat-dbcp.jar");
+ // i18n JARs
+ skipJars.add("tomcat-i18n-en.jar");
+ skipJars.add("tomcat-i18n-es.jar");
+ skipJars.add("tomcat-i18n-fr.jar");
+ skipJars.add("tomcat-i18n-ja.jar");
+ // Misc JARs not included with Tomcat
+ skipJars.add("ant.jar");
+ skipJars.add("commons-dbcp.jar");
+ skipJars.add("commons-beanutils.jar");
+ skipJars.add("commons-fileupload-1.0.jar");
+ skipJars.add("commons-pool.jar");
+ skipJars.add("commons-digester.jar");
+ skipJars.add("commons-logging.jar");
+ skipJars.add("commons-collections.jar");
+ skipJars.add("jmx.jar");
+ skipJars.add("jmx-tools.jar");
+ skipJars.add("xercesImpl.jar");
+ skipJars.add("xmlParserAPIs.jar");
+ skipJars.add("xml-apis.jar");
+ // JARs from J2SE runtime
+ skipJars.add("sunjce_provider.jar");
+ skipJars.add("ldapsec.jar");
+ skipJars.add("localedata.jar");
+ skipJars.add("dnsns.jar");
+ skipJars.add("tools.jar");
+ skipJars.add("sunpkcs11.jar");
+ }
+
+
+ protected ArrayList<Class<?>> annotatedClasses = new
ArrayList<Class<?>>();
+ protected ArrayList<String> overlays = new ArrayList<String>();
+ protected ArrayList<String> webFragments = new ArrayList<String>();
+ protected Map<String, List<String>> TLDs = new HashMap<String,
List<String>>();
+
+
+ public Iterator<Class<?>> getAnnotatedClasses() {
+ return annotatedClasses.iterator();
+ }
+
+
+ public Iterator<String> getOverlays() {
+ return overlays.iterator();
+ }
+
+
+ public Iterator<String> getWebFragments() {
+ return webFragments.iterator();
+ }
+
+
+ public Map<String, List<String>> getTLDs() {
+ return TLDs;
+ }
+
+
+ /**
+ * Scan the given context's default locations for annotations.
+ *
+ * @param context
+ */
+ public void scan(Context context) {
+
+ if (context.getLoader().findLoaderRepositories() != null) {
+ String[] repositories = context.getLoader().findLoaderRepositories();
+ for (int i = 0; i < repositories.length; i++) {
+ if (repositories[i].endsWith(".jar")) {
+ try {
+ scanJar(context, new JarFile(repositories[i]));
+ } catch (IOException e) {
+ // Ignore
+ }
+ } else {
+ scanClasses(context, new File(repositories[i]), "");
+ }
+ }
+ }
+ ClassLoader loader = context.getLoader().getClassLoader().getParent();
+ while (loader != null) {
+ if (loader instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader) loader).getURLs();
+ for (int i=0; i<urls.length; i++) {
+ // Expect file URLs, these are %xx encoded or not depending on
+ // the class loader
+ // This is definitely not as clean as using JAR URLs either
+ // over file or the custom jndi handler, but a lot less
+ // buggy overall
+ File file = null;
+ try {
+ file = new File(urls[i].toURI());
+ } catch (Exception e) {
+ // Ignore, probably an unencoded char or non file URL,
+ // attempt direct access
+ file = new File(urls[i].getFile());
+ }
+ try {
+ file = file.getCanonicalFile();
+ } catch (IOException e) {
+ // Ignore
+ }
+ if (!file.exists()) {
+ continue;
+ }
+ String path = file.getAbsolutePath();
+ if (!path.endsWith(".jar")) {
+ continue;
+ }
+ /*
+ * Scan all JARs from WEB-INF/lib, plus any shared JARs
+ * that are not known not to contain any TLDs
+ */
+ if (skipJars == null
+ || !skipJars.contains(file.getName())) {
+ try {
+ scanJar(context, new JarFile(path));
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+ loader = loader.getParent();
+ }
+
+ ArrayList<String> warTLDs = new ArrayList<String>();
+
+ // Find taglibs from web.xml
+ // FIXME: move this elsewhere, this should be done last when parsing TLDs
+ String taglibs[] = context.findTaglibs();
+ for (int i = 0; i < taglibs.length; i++) {
+ String resourcePath = context.findTaglib(taglibs[i]);
+ if (!resourcePath.startsWith("/")) {
+ resourcePath = "/WEB-INF/" + resourcePath;
+ }
+ warTLDs.add(resourcePath);
+ }
+ // Find any TLD file in /WEB-INF
+ DirContext resources = context.getResources();
+ if (resources != null) {
+ tldScanResourcePathsWebInf(resources, "/WEB-INF", warTLDs);
+ }
+ if (warTLDs.size() > 0) {
+ TLDs.put("", warTLDs);
+ }
+
+ /*
+ DirContext resources = context.getResources();
+ DirContext webInfClasses = null;
+ DirContext webInfLib = null;
+
+ try {
+ webInfClasses = (DirContext) resources.lookup("/WEB-INF/classes");
+ } catch (Exception e) {
+ // Ignore, /WEB-INF/classes not found, or not a folder
+ }
+ if (webInfClasses != null) {
+ scanClasses(context, webInfClasses, "");
+ }
+
+ try {
+ webInfLib = (DirContext) resources.lookup("/WEB-INF/lib");
+ } catch (Exception e) {
+ // Ignore, /WEB-INF/classes not found, or not a folder
+ }
+ if (webInfLib != null) {
+ scanJars(context, webInfLib);
+ }*/
+
+ }
+
+
+ /**
+ * Scans the web application's subdirectory identified by rootPath,
+ * along with its subdirectories, for TLDs.
+ *
+ * Initially, rootPath equals /WEB-INF. The /WEB-INF/classes and
+ * /WEB-INF/lib subdirectories are excluded from the search, as per the
+ * JSP 2.0 spec.
+ *
+ * @param resources The web application's resources
+ * @param rootPath The path whose subdirectories are to be searched for
+ * TLDs
+ * @param tldPaths The set of TLD resource paths to add to
+ */
+ protected void tldScanResourcePathsWebInf(DirContext resources,
+ String rootPath,
+ ArrayList<String> tldPaths) {
+ try {
+ NamingEnumeration items = resources.list(rootPath);
+ while (items.hasMoreElements()) {
+ NameClassPair item = (NameClassPair) items.nextElement();
+ String resourcePath = rootPath + "/" + item.getName();
+ if (!resourcePath.endsWith(".tld")
+ &&
(resourcePath.startsWith("/WEB-INF/classes")
+ || resourcePath.startsWith("/WEB-INF/lib"))) {
+ continue;
+ }
+ if (resourcePath.endsWith(".tld")) {
+ tldPaths.add(resourcePath);
+ } else {
+ tldScanResourcePathsWebInf(resources, resourcePath,
+ tldPaths);
+ }
+ }
+ } catch (NamingException e) {
+ ; // Silent catch: it's valid that no /WEB-INF directory exists
+ }
+ }
+
+
+ /**
+ * Scan folder containing class files.
+ */
+ public void scanClasses(Context context, File folder, String path) {
+ String[] files = folder.list();
+ for (int i = 0; i < files.length; i++) {
+ File file = new File(folder, files[i]);
+ if (file.isDirectory()) {
+ scanClasses(context, file, path + "/" + files[i]);
+ } else if (files[i].endsWith(".class")) {
+ String className = getClassName(path + "/" + files[i]);
+ Class<?> annotated = scanClass(context, className, file, null);
+ if (annotated != null) {
+ annotatedClasses.add(annotated);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Scan folder containing class files.
+ */
+ /*
+ public static void scanClasses(Context context, DirContext folder, String path) {
+ try {
+ NamingEnumeration<Binding> enumeration = folder.listBindings(path);
+ while (enumeration.hasMore()) {
+ Binding binding = enumeration.next();
+ Object object = binding.getObject();
+
+ if (object instanceof Resource) {
+ // This is a class, so we should load it
+ String className = getClassName(path + "/" +
binding.getName());
+ scanClass(context, className, (Resource) object, null, null);
+ } else if (object instanceof DirContext) {
+ scanClasses(context, folder, path + "/" +
binding.getName());
+ }
+
+ }
+ } catch (NamingException e) {
+ // Ignore for now
+ e.printStackTrace();
+ }
+ }*/
+
+
+ /**
+ * Scan folder containing JAR files.
+ */
+ //public void scanJars(Context context, DirContext folder) {
+ /*if (context.getLoader().findLoaderRepositories() != null) {
+ String[] repositories = context.getLoader().findLoaderRepositories();
+ for (int i = 0; i < repositories.length; i++) {
+ if (repositories[i].endsWith(".jar")) {
+ try {
+ scanJar(context, new JarFile(repositories[i]));
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ }*/
+ /*else {
+ try {
+ NamingEnumeration<Binding> enumeration =
folder.listBindings("");
+ while (enumeration.hasMore()) {
+ Binding binding = enumeration.next();
+ Object object = binding.getObject();
+
+ if (object instanceof Resource &&
binding.getName().endsWith(".jar")) {
+ // This is normally a JAR, put it in the work folder
+ File destDir = null;
+ File workDir =
+ (File)
context.getServletContext().getAttribute(Globals.WORK_DIR_ATTR);
+ destDir = new File(workDir, "WEB-INF/lib");
+ destDir.mkdirs();
+ File destFile = new File(destDir, binding.getName());
+
+ scanJar(context, (Resource) object);
+ }
+
+ }
+ } catch (NamingException e) {
+ // Ignore for now
+ e.printStackTrace();
+ }
+ }*/
+ //}
+
+
+ /**
+ * Scan all class files in the given JAR.
+ */
+ public void scanJar(Context context, JarFile file) {
+ if (file.getEntry(Globals.WEB_FRAGMENT_PATH) != null) {
+ webFragments.add(file.getName());
+ }
+ if (file.getEntry(Globals.OVERLAY_PATH) != null) {
+ overlays.add(file.getName());
+ }
+ ArrayList<String> jarTLDs = new ArrayList<String>();
+ Enumeration<JarEntry> entries = file.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ String name = entry.getName();
+ if (!context.getIgnoreAnnotations() &&
name.endsWith(".class")) {
+ Class<?> annotated = scanClass(context,
getClassName(entry.getName()), null, entry);
+ if (annotated != null) {
+ annotatedClasses.add(annotated);
+ }
+ } else if (name.startsWith("META-INF/") &&
name.endsWith(".tld")) {
+ jarTLDs.add(name);
+ }
+ }
+ if (jarTLDs.size() > 0) {
+ TLDs.put(file.getName(), jarTLDs);
+ }
+ try {
+ file.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+
+
+ /**
+ * Get class name given a path to a classfile.
+ * /my/class/MyClass.class -> my.class.MyClass
+ */
+ public String getClassName(String filePath) {
+ if (filePath.startsWith("/")) {
+ filePath = filePath.substring(1);
+ }
+ if (filePath.endsWith(".class")) {
+ filePath = filePath.substring(0, filePath.length() -
".class".length());
+ }
+ return filePath.replace('/', '.');
+ }
+
+
+ /**
+ * Scan class for interesting annotations.
+ */
+ public abstract Class<?> scanClass(Context context, String className, File
file, JarEntry entry);
+
+
+}
Copied: trunk/java/org/apache/catalina/startup/ClassLoadingContextScanner.java (from rev
1017, trunk/java/org/apache/catalina/core/ClassLoadingAnnotationScanner.java)
===================================================================
--- trunk/java/org/apache/catalina/startup/ClassLoadingContextScanner.java
(rev 0)
+++ trunk/java/org/apache/catalina/startup/ClassLoadingContextScanner.java 2009-04-21
03:39:25 UTC (rev 1021)
@@ -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 org.apache.catalina.startup;
+
+import java.io.File;
+import java.util.jar.JarEntry;
+
+import javax.servlet.annotation.HandlesTypes;
+import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebListener;
+import javax.servlet.annotation.WebServlet;
+
+import org.apache.catalina.Context;
+
+public class ClassLoadingContextScanner
+ extends BaseContextScanner {
+
+ /**
+ * Scan class for interesting annotations.
+ */
+ public Class<?> scanClass(Context context, String className, File file,
JarEntry entry) {
+ // Load the class using the classloader, and see if it implements one of the web
annotations
+ try {
+ Class<?> clazz =
context.getLoader().getClassLoader().loadClass(className);
+ if (clazz.isAnnotationPresent(HandlesTypes.class)
+ || clazz.isAnnotationPresent(MultipartConfig.class)
+ || clazz.isAnnotationPresent(WebFilter.class)
+ || clazz.isAnnotationPresent(WebInitParam.class)
+ || clazz.isAnnotationPresent(WebListener.class)
+ || clazz.isAnnotationPresent(WebServlet.class)) {
+ return clazz;
+ }
+ } catch (Throwable t) {
+ // Ignore classloading errors here
+ }
+ return null;
+ }
+
+
+}
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -1,18 +1,46 @@
/*
- * 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
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
*
- *
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.
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 1999-2009 The Apache Software Foundation
+ *
+ * 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.
*/
@@ -29,7 +57,6 @@
import java.util.Map;
import java.util.Properties;
-import javax.jws.soap.InitParam;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.annotation.HandlesTypes;
@@ -42,6 +69,7 @@
import org.apache.catalina.Authenticator;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
+import org.apache.catalina.ContextScanner;
import org.apache.catalina.Engine;
import org.apache.catalina.Globals;
import org.apache.catalina.Host;
@@ -51,7 +79,6 @@
import org.apache.catalina.Pipeline;
import org.apache.catalina.Valve;
import org.apache.catalina.Wrapper;
-import org.apache.catalina.core.ClassLoadingAnnotationScanner;
import org.apache.catalina.core.ContainerBase;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
@@ -162,18 +189,13 @@
*/
protected static WebRuleSet webRuleSet = new WebRuleSet();
- /**
- * Attribute value used to turn on/off XML validation
- */
- protected static boolean xmlValidation = false;
-
/**
- * Attribute value used to turn on/off XML namespace awarenes.
+ * Scanner for annotations, etc.
*/
- protected static boolean xmlNamespaceAware = false;
-
+ protected ContextScanner scanner = null;
+
/**
* Deployment count.
*/
@@ -304,7 +326,7 @@
long t1=System.currentTimeMillis();
- Iterator<Class<?>> annotatedClasses = (new
ClassLoadingAnnotationScanner()).scan(context).iterator();
+ Iterator<Class<?>> annotatedClasses = scanner.getAnnotatedClasses();
while (annotatedClasses.hasNext()) {
Class<?> clazz = annotatedClasses.next();
if (clazz.isAnnotationPresent(WebInitParam.class)) {
@@ -607,9 +629,7 @@
* web application deployment descriptor (web.xml).
*/
protected static Digester createWebDigester() {
- Digester webDigester =
- createWebXmlDigester(xmlNamespaceAware, xmlValidation);
- return webDigester;
+ return createWebXmlDigester(Globals.XML_NAMESPACE_AWARE,
Globals.XML_VALIDATION);
}
@@ -619,11 +639,7 @@
*/
public static Digester createWebXmlDigester(boolean namespaceAware,
boolean validation) {
-
- Digester webDigester = DigesterFactory.newDigester(xmlValidation,
- xmlNamespaceAware,
- webRuleSet);
- return webDigester;
+ return DigesterFactory.newDigester(validation, namespaceAware, webRuleSet);
}
@@ -807,9 +823,10 @@
// FIXME: Processing of web fragments
// FIXME: Map overlays
protected void applicationExtraDescriptorsConfig() {
- TldConfig tldConfig = new TldConfig();
+ WarScanner tldConfig = new WarScanner();
tldConfig.setContext(context);
-
+
+ /*
// (1) check if the attribute has been defined
// on the context element.
tldConfig.setTldValidation(context.getTldValidation());
@@ -825,7 +842,7 @@
if (!context.getTldNamespaceAware()) {
tldConfig.setTldNamespaceAware
(((StandardHost) context.getParent()).getXmlNamespaceAware());
- }
+ }*/
try {
tldConfig.execute();
@@ -1156,32 +1173,14 @@
if (log.isDebugEnabled())
log.debug(sm.getString("contextConfig.start"));
- // Set properties based on DefaultContext
- Container container = context.getParent();
- if( !context.getOverride() ) {
- if( container instanceof Host ) {
- // Reset the value only if the attribute wasn't
- // set on the context.
- xmlValidation = context.getXmlValidation();
- if (!xmlValidation) {
- xmlValidation = ((Host)container).getXmlValidation();
- }
-
- xmlNamespaceAware = context.getXmlNamespaceAware();
- if (!xmlNamespaceAware){
- xmlNamespaceAware
- = ((Host)container).getXmlNamespaceAware();
- }
+ ContextScanner scanner = new ClassLoadingContextScanner();
- container = container.getParent();
- }
- }
-
// Process the default and application web.xml files
defaultWebConfig();
// FIXME: look where to place it according to the merging rules
applicationExtraDescriptorsConfig();
applicationWebConfig();
+ scanner.scan(context);
if (!context.getIgnoreAnnotations()) {
applicationAnnotationsConfig();
}
@@ -1227,6 +1226,8 @@
if (log.isDebugEnabled())
log.debug(sm.getString("contextConfig.stop"));
+ scanner = null;
+
int i;
// Removing children
Copied: trunk/java/org/apache/catalina/startup/JavassistContextScanner.java (from rev 972,
trunk/java/org/apache/catalina/core/JavassistAnnotationScanner.java)
===================================================================
--- trunk/java/org/apache/catalina/startup/JavassistContextScanner.java
(rev 0)
+++ trunk/java/org/apache/catalina/startup/JavassistContextScanner.java 2009-04-21
03:39:25 UTC (rev 1021)
@@ -0,0 +1,38 @@
+/*
+ * 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 org.apache.catalina.startup;
+
+import java.io.File;
+import java.util.jar.JarEntry;
+
+import org.apache.catalina.Context;
+
+public class JavassistContextScanner
+ extends BaseContextScanner {
+
+ /**
+ * Scan class for interesting annotations.
+ */
+ public Class<?> scanClass(Context context, String className, File file,
JarEntry entry) {
+ // FIXME: Javassist impl
+ return null;
+ }
+
+
+}
Deleted: trunk/java/org/apache/catalina/startup/TldConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/TldConfig.java 2009-04-20 15:51:08 UTC (rev
1020)
+++ trunk/java/org/apache/catalina/startup/TldConfig.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -1,693 +0,0 @@
-/*
- * 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 org.apache.catalina.startup;
-
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-import javax.naming.NameClassPair;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-import javax.servlet.ServletException;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Globals;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.util.StringManager;
-import org.apache.tomcat.util.digester.Digester;
-import org.xml.sax.InputSource;
-
-/**
- * Startup event listener for a <b>Context</b> that configures the
properties
- * of that Context, and the associated defined servlets.
- *
- * @author Craig R. McClanahan
- * @author Jean-Francois Arcand
- * @author Costin Manolache
- */
-public final class TldConfig {
-
- // Names of JARs that are known not to contain any TLDs
- private static HashSet<String> noDescriptorsJars;
-
- private static org.jboss.logging.Logger log=
- org.jboss.logging.Logger.getLogger(TldConfig.class);
-
- /*
- * Initializes the set of JARs that are known not to contain any descriptors.
- */
- static {
- noDescriptorsJars = new HashSet<String>();
- // Bootstrap JARs
- noDescriptorsJars.add("bootstrap.jar");
- noDescriptorsJars.add("commons-daemon.jar");
- noDescriptorsJars.add("tomcat-juli.jar");
- // Main JARs
- noDescriptorsJars.add("annotations-api.jar");
- noDescriptorsJars.add("catalina.jar");
- noDescriptorsJars.add("catalina-ant.jar");
- noDescriptorsJars.add("el-api.jar");
- noDescriptorsJars.add("jasper.jar");
- noDescriptorsJars.add("jasper-el.jar");
- noDescriptorsJars.add("jasper-jdt.jar");
- noDescriptorsJars.add("jsp-api.jar");
- noDescriptorsJars.add("servlet-api.jar");
- noDescriptorsJars.add("tomcat-coyote.jar");
- noDescriptorsJars.add("tomcat-dbcp.jar");
- // i18n JARs
- noDescriptorsJars.add("tomcat-i18n-en.jar");
- noDescriptorsJars.add("tomcat-i18n-es.jar");
- noDescriptorsJars.add("tomcat-i18n-fr.jar");
- noDescriptorsJars.add("tomcat-i18n-ja.jar");
- // Misc JARs not included with Tomcat
- noDescriptorsJars.add("ant.jar");
- noDescriptorsJars.add("commons-dbcp.jar");
- noDescriptorsJars.add("commons-beanutils.jar");
- noDescriptorsJars.add("commons-fileupload-1.0.jar");
- noDescriptorsJars.add("commons-pool.jar");
- noDescriptorsJars.add("commons-digester.jar");
- noDescriptorsJars.add("commons-logging.jar");
- noDescriptorsJars.add("commons-collections.jar");
- noDescriptorsJars.add("jmx.jar");
- noDescriptorsJars.add("jmx-tools.jar");
- noDescriptorsJars.add("xercesImpl.jar");
- noDescriptorsJars.add("xmlParserAPIs.jar");
- noDescriptorsJars.add("xml-apis.jar");
- // JARs from J2SE runtime
- noDescriptorsJars.add("sunjce_provider.jar");
- noDescriptorsJars.add("ldapsec.jar");
- noDescriptorsJars.add("localedata.jar");
- noDescriptorsJars.add("dnsns.jar");
- noDescriptorsJars.add("tools.jar");
- noDescriptorsJars.add("sunpkcs11.jar");
- }
-
-
- // ----------------------------------------------------- Instance Variables
-
- /**
- * The Context we are associated with.
- */
- private Context context = null;
-
-
- /**
- * The string resources for this package.
- */
- private static final StringManager sm =
- StringManager.getManager(Constants.Package);
-
- /**
- * The <code>Digester</code> we will use to process tag library
- * descriptor files.
- */
- private static Digester tldDigester = null;
-
-
- /**
- * Attribute value used to turn on/off TLD validation
- */
- private static boolean tldValidation = false;
-
-
- /**
- * Attribute value used to turn on/off TLD namespace awarenes.
- */
- private static boolean tldNamespaceAware = false;
-
- private boolean rescan=true;
-
- private ArrayList<String> listeners = new ArrayList<String>();
-
- // --------------------------------------------------------- Public Methods
-
- /**
- * Sets the list of JARs that are known not to contain any TLDs.
- *
- * @param jarNames List of comma-separated names of JAR files that are
- * known not to contain any TLDs
- */
- public static void setNoTldJars(String jarNames) {
- if (jarNames != null) {
- noDescriptorsJars.clear();
- StringTokenizer tokenizer = new StringTokenizer(jarNames, ",");
- while (tokenizer.hasMoreElements()) {
- noDescriptorsJars.add(tokenizer.nextToken());
- }
- }
- }
-
- /**
- * Set the validation feature of the XML parser used when
- * parsing xml instances.
- * @param tldValidation true to enable xml instance validation
- */
- public void setTldValidation(boolean tldValidation){
- TldConfig.tldValidation = tldValidation;
- }
-
- /**
- * Get the server.xml <host> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getTldValidation(){
- return tldValidation;
- }
-
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- *
- */
- public boolean getTldNamespaceAware(){
- return tldNamespaceAware;
- }
-
-
- /**
- * Set the namespace aware feature of the XML parser used when
- * parsing xml instances.
- * @param tldNamespaceAware true to enable namespace awareness
- */
- public void setTldNamespaceAware(boolean tldNamespaceAware){
- TldConfig.tldNamespaceAware = tldNamespaceAware;
- }
-
-
- public boolean isRescan() {
- return rescan;
- }
-
- public void setRescan(boolean rescan) {
- this.rescan = rescan;
- }
-
- public Context getContext() {
- return context;
- }
-
- public void setContext(Context context) {
- this.context = context;
- }
-
- public void addApplicationListener( String s ) {
- //if(log.isDebugEnabled())
- log.debug( "Add tld listener " + s);
- listeners.add(s);
- }
-
- public String[] getTldListeners() {
- String result[]=new String[listeners.size()];
- listeners.toArray(result);
- return result;
- }
-
-
- /**
- * Scan for and configure all tag library descriptors found in this
- * web application.
- *
- * @exception Exception if a fatal input/output or parsing error occurs
- */
- public void execute() throws Exception {
- long t1=System.currentTimeMillis();
-
- /*
- * Acquire the list of TLD resource paths, possibly embedded in JAR
- * files, to be processed
- */
- Set resourcePaths = tldScanResourcePaths();
- Map<String, File> jarPaths = getJarPaths();
-
- // Scan each accumulated resource path for TLDs to be processed
- Iterator paths = resourcePaths.iterator();
- while (paths.hasNext()) {
- String path = (String) paths.next();
- if (path.endsWith(".jar")) {
- tldScanJar(path);
- } else {
- tldScanTld(path);
- }
- }
- if (jarPaths != null) {
- paths = jarPaths.values().iterator();
- while (paths.hasNext()) {
- tldScanJar((File) paths.next());
- }
- }
-
- String list[] = getTldListeners();
-
- if( log.isDebugEnabled() )
- log.debug( "Adding tld listeners:" + list.length);
- for( int i=0; list!=null && i<list.length; i++ ) {
- context.addApplicationListener(list[i]);
- }
-
- long t2=System.currentTimeMillis();
- if( context instanceof StandardContext ) {
- ((StandardContext)context).setTldScanTime(t2-t1);
- }
-
- }
-
- // -------------------------------------------------------- Private Methods
-
- /*
- * Returns the last modification date of the given sets of resources.
- *
- * @param resourcePaths
- * @param jarPaths
- *
- * @return Last modification date
- */
- private long getLastModified(Set resourcePaths, Map jarPaths)
- throws Exception {
-
- long lastModified = 0;
-
- Iterator paths = resourcePaths.iterator();
- while (paths.hasNext()) {
- String path = (String) paths.next();
- URL url = context.getServletContext().getResource(path);
- if (url == null) {
- log.debug( "Null url "+ path );
- break;
- }
- long lastM = url.openConnection().getLastModified();
- if (lastM > lastModified) lastModified = lastM;
- if (log.isDebugEnabled()) {
- log.debug( "Last modified " + path + " " + lastM);
- }
- }
-
- if (jarPaths != null) {
- paths = jarPaths.values().iterator();
- while (paths.hasNext()) {
- File jarFile = (File) paths.next();
- long lastM = jarFile.lastModified();
- if (lastM > lastModified) lastModified = lastM;
- if (log.isDebugEnabled()) {
- log.debug("Last modified " + jarFile.getAbsolutePath()
- + " " + lastM);
- }
- }
- }
-
- return lastModified;
- }
-
- private void processCache(File tldCache ) throws IOException {
- // read the cache and return;
- try {
- FileInputStream in=new FileInputStream(tldCache);
- ObjectInputStream ois=new ObjectInputStream( in );
- String list[]=(String [])ois.readObject();
- if( log.isDebugEnabled() )
- log.debug("Reusing tldCache " + tldCache + " " +
list.length);
- for( int i=0; list!=null && i<list.length; i++ ) {
- context.addApplicationListener(list[i]);
- }
- ois.close();
- } catch( ClassNotFoundException ex ) {
- ex.printStackTrace();
- }
- }
-
- /**
- * Create (if necessary) and return a Digester configured to process a tag
- * library descriptor, looking for additional listener classes to be
- * registered.
- */
- private static Digester createTldDigester() {
-
- return DigesterFactory.newDigester(tldValidation,
- tldNamespaceAware,
- new TldRuleSet());
-
- }
-
-
- /**
- * Scan the JAR file at the specified resource path for TLDs in the
- * <code>META-INF</code> subdirectory, and scan each TLD for application
- * event listeners that need to be registered.
- *
- * @param resourcePath Resource path of the JAR file to scan
- *
- * @exception Exception if an exception occurs while scanning this JAR
- */
- private void tldScanJar(String resourcePath) throws Exception {
-
- if (log.isDebugEnabled()) {
- log.debug(" Scanning JAR at resource path '" + resourcePath +
"'");
- }
-
- URL url = context.getServletContext().getResource(resourcePath);
- if (url == null) {
- throw new IllegalArgumentException
- (sm.getString("contextConfig.tldResourcePath",
- resourcePath));
- }
-
- File file = null;
- try {
- file = new File(url.toURI());
- } catch (URISyntaxException e) {
- // Ignore, probably an unencoded char
- file = new File(url.getFile());
- }
- try {
- file = file.getCanonicalFile();
- } catch (IOException e) {
- // Ignore
- }
- tldScanJar(file);
-
- }
-
- /**
- * Scans all TLD entries in the given JAR for application listeners.
- *
- * @param file JAR file whose TLD entries are scanned for application
- * listeners
- */
- private void tldScanJar(File file) throws Exception {
-
- JarFile jarFile = null;
- String name = null;
-
- String jarPath = file.getAbsolutePath();
-
- try {
- jarFile = new JarFile(file);
- Enumeration entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = (JarEntry) entries.nextElement();
- name = entry.getName();
- if (!name.startsWith("META-INF/")) {
- continue;
- }
- if (!name.endsWith(".tld")) {
- continue;
- }
- if (log.isTraceEnabled()) {
- log.trace(" Processing TLD at '" + name +
"'");
- }
- try {
- tldScanStream(new InputSource(jarFile.getInputStream(entry)));
- } catch (Exception e) {
- log.error(sm.getString("contextConfig.tldEntryException",
- name, jarPath, context.getPath()),
- e);
- }
- }
- } catch (Exception e) {
- log.error(sm.getString("contextConfig.tldJarException",
- jarPath, context.getPath()),
- e);
- } finally {
- if (jarFile != null) {
- try {
- jarFile.close();
- } catch (Throwable t) {
- // Ignore
- }
- }
- }
- }
-
- /**
- * Scan the TLD contents in the specified input stream, and register
- * any application event listeners found there. <b>NOTE</b> - It is
- * the responsibility of the caller to close the InputStream after this
- * method returns.
- *
- * @param resourceStream InputStream containing a tag library descriptor
- *
- * @exception Exception if an exception occurs while scanning this TLD
- */
- private void tldScanStream(InputSource resourceStream)
- throws Exception {
-
- if (tldDigester == null){
- tldDigester = createTldDigester();
- }
-
- synchronized (tldDigester) {
- try {
- tldDigester.push(this);
- tldDigester.parse(resourceStream);
- } finally {
- tldDigester.reset();
- }
- }
-
- }
-
- /**
- * Scan the TLD contents at the specified resource path, and register
- * any application event listeners found there.
- *
- * @param resourcePath Resource path being scanned
- *
- * @exception Exception if an exception occurs while scanning this TLD
- */
- private void tldScanTld(String resourcePath) throws Exception {
-
- if (log.isDebugEnabled()) {
- log.debug(" Scanning TLD at resource path '" + resourcePath +
"'");
- }
-
- InputSource inputSource = null;
- try {
- InputStream stream =
- context.getServletContext().getResourceAsStream(resourcePath);
- if (stream == null) {
- throw new IllegalArgumentException
- (sm.getString("contextConfig.tldResourcePath",
- resourcePath));
- }
- inputSource = new InputSource(stream);
- if (inputSource == null) {
- throw new IllegalArgumentException
- (sm.getString("contextConfig.tldResourcePath",
- resourcePath));
- }
- tldScanStream(inputSource);
- } catch (Exception e) {
- throw new ServletException
- (sm.getString("contextConfig.tldFileException", resourcePath,
- context.getPath()),
- e);
- }
-
- }
-
- /**
- * Accumulate and return a Set of resource paths to be analyzed for
- * tag library descriptors. Each element of the returned set will be
- * the context-relative path to either a tag library descriptor file,
- * or to a JAR file that may contain tag library descriptors in its
- * <code>META-INF</code> subdirectory.
- *
- * @exception IOException if an input/output error occurs while
- * accumulating the list of resource paths
- */
- private Set<String> tldScanResourcePaths() throws IOException {
- if (log.isDebugEnabled()) {
- log.debug(" Accumulating TLD resource paths");
- }
- Set<String> resourcePaths = new HashSet<String>();
-
- // Accumulate resource paths explicitly listed in the web application
- // deployment descriptor
- if (log.isTraceEnabled()) {
- log.trace(" Scanning <taglib> elements in web.xml");
- }
- String taglibs[] = context.findTaglibs();
- for (int i = 0; i < taglibs.length; i++) {
- String resourcePath = context.findTaglib(taglibs[i]);
- // FIXME - Servlet 2.4 DTD implies that the location MUST be
- // a context-relative path starting with '/'?
- if (!resourcePath.startsWith("/")) {
- resourcePath = "/WEB-INF/" + resourcePath;
- }
- if (log.isTraceEnabled()) {
- log.trace(" Adding path '" + resourcePath +
- "' for URI '" + taglibs[i] + "'");
- }
- resourcePaths.add(resourcePath);
- }
-
- DirContext resources = context.getResources();
- if (resources != null) {
- tldScanResourcePathsWebInf(resources, "/WEB-INF", resourcePaths);
- }
-
- // Return the completed set
- return (resourcePaths);
-
- }
-
- /*
- * Scans the web application's subdirectory identified by rootPath,
- * along with its subdirectories, for TLDs.
- *
- * Initially, rootPath equals /WEB-INF. The /WEB-INF/classes and
- * /WEB-INF/lib subdirectories are excluded from the search, as per the
- * JSP 2.0 spec.
- *
- * @param resources The web application's resources
- * @param rootPath The path whose subdirectories are to be searched for
- * TLDs
- * @param tldPaths The set of TLD resource paths to add to
- */
- private void tldScanResourcePathsWebInf(DirContext resources,
- String rootPath,
- Set tldPaths)
- throws IOException {
-
- if (log.isTraceEnabled()) {
- log.trace(" Scanning TLDs in " + rootPath + "
subdirectory");
- }
-
- try {
- NamingEnumeration items = resources.list(rootPath);
- while (items.hasMoreElements()) {
- NameClassPair item = (NameClassPair) items.nextElement();
- String resourcePath = rootPath + "/" + item.getName();
- if (!resourcePath.endsWith(".tld")
- &&
(resourcePath.startsWith("/WEB-INF/classes")
- || resourcePath.startsWith("/WEB-INF/lib"))) {
- continue;
- }
- if (resourcePath.endsWith(".tld")) {
- if (log.isTraceEnabled()) {
- log.trace(" Adding path '" + resourcePath +
"'");
- }
- tldPaths.add(resourcePath);
- } else {
- tldScanResourcePathsWebInf(resources, resourcePath,
- tldPaths);
- }
- }
- } catch (NamingException e) {
- ; // Silent catch: it's valid that no /WEB-INF directory exists
- }
- }
-
- /**
- * Returns a map of the paths to all JAR files that are accessible to the
- * webapp and will be scanned for TLDs.
- *
- * The map always includes all the JARs under WEB-INF/lib, as well as
- * shared JARs in the classloader delegation chain of the webapp's
- * classloader.
- *
- * The latter constitutes a Tomcat-specific extension to the TLD search
- * order defined in the JSP spec. It allows tag libraries packaged as JAR
- * files to be shared by web applications by simply dropping them in a
- * location that all web applications have access to (e.g.,
- * <CATALINA_HOME>/common/lib).
- *
- * The set of shared JARs to be scanned for TLDs is narrowed down by
- * the <tt>noTldJars</tt> class variable, which contains the names of
JARs
- * that are known not to contain any TLDs.
- *
- * @return Map of JAR file paths
- */
- private Map<String, File> getJarPaths() {
-
- HashMap<String, File> jarPathMap = null;
-
- ClassLoader webappLoader = Thread.currentThread().getContextClassLoader();
- ClassLoader loader = webappLoader;
- while (loader != null) {
- if (loader instanceof URLClassLoader) {
- URL[] urls = ((URLClassLoader) loader).getURLs();
- for (int i=0; i<urls.length; i++) {
- // Expect file URLs, these are %xx encoded or not depending on
- // the class loader
- // This is definitely not as clean as using JAR URLs either
- // over file or the custom jndi handler, but a lot less
- // buggy overall
- File file = null;
- try {
- file = new File(urls[i].toURI());
- } catch (Exception e) {
- // Ignore, probably an unencoded char or non file URL,
- // attempt direct access
- file = new File(urls[i].getFile());
- }
- try {
- file = file.getCanonicalFile();
- } catch (IOException e) {
- // Ignore
- }
- if (!file.exists()) {
- continue;
- }
- String path = file.getAbsolutePath();
- if (!path.endsWith(".jar")) {
- continue;
- }
- /*
- * Scan all JARs from WEB-INF/lib, plus any shared JARs
- * that are not known not to contain any TLDs
- */
- if (loader == webappLoader
- || noDescriptorsJars == null
- || !noDescriptorsJars.contains(file.getName())) {
- if (jarPathMap == null) {
- jarPathMap = new HashMap();
- jarPathMap.put(path, file);
- } else if (!jarPathMap.containsKey(path)) {
- jarPathMap.put(path, file);
- }
- }
- }
- }
- loader = loader.getParent();
- }
-
- return jarPathMap;
- }
-}
Copied: trunk/java/org/apache/catalina/startup/WarScanner.java (from rev 1017,
trunk/java/org/apache/catalina/startup/TldConfig.java)
===================================================================
--- trunk/java/org/apache/catalina/startup/WarScanner.java (rev
0)
+++ trunk/java/org/apache/catalina/startup/WarScanner.java 2009-04-21 03:39:25 UTC (rev
1021)
@@ -0,0 +1,721 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ *
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 1999-2009 The Apache Software Foundation
+ *
+ * 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 org.apache.catalina.startup;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.util.StringManager;
+import org.apache.tomcat.util.digester.Digester;
+import org.xml.sax.InputSource;
+
+/**
+ * Startup event listener for a <b>Context</b> that configures the
properties
+ * of that Context, and the associated defined servlets.
+ *
+ * @author Craig R. McClanahan
+ * @author Jean-Francois Arcand
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ */
+public final class WarScanner {
+
+ private static org.jboss.logging.Logger log=
+ org.jboss.logging.Logger.getLogger(WarScanner.class);
+
+ /**
+ * Names of JARs that are known not to contain any descriptors.
+ */
+ private static HashSet<String> noDescriptorsJars;
+
+ /**
+ * Initializes the set of JARs that are known not to contain any descriptors.
+ */
+ static {
+ noDescriptorsJars = new HashSet<String>();
+ // Bootstrap JARs
+ noDescriptorsJars.add("bootstrap.jar");
+ noDescriptorsJars.add("commons-daemon.jar");
+ noDescriptorsJars.add("tomcat-juli.jar");
+ // Main JARs
+ noDescriptorsJars.add("annotations-api.jar");
+ noDescriptorsJars.add("catalina.jar");
+ noDescriptorsJars.add("catalina-ant.jar");
+ noDescriptorsJars.add("el-api.jar");
+ noDescriptorsJars.add("jasper.jar");
+ noDescriptorsJars.add("jasper-el.jar");
+ noDescriptorsJars.add("jasper-jdt.jar");
+ noDescriptorsJars.add("jsp-api.jar");
+ noDescriptorsJars.add("servlet-api.jar");
+ noDescriptorsJars.add("tomcat-coyote.jar");
+ noDescriptorsJars.add("tomcat-dbcp.jar");
+ // i18n JARs
+ noDescriptorsJars.add("tomcat-i18n-en.jar");
+ noDescriptorsJars.add("tomcat-i18n-es.jar");
+ noDescriptorsJars.add("tomcat-i18n-fr.jar");
+ noDescriptorsJars.add("tomcat-i18n-ja.jar");
+ // Misc JARs not included with Tomcat
+ noDescriptorsJars.add("ant.jar");
+ noDescriptorsJars.add("commons-dbcp.jar");
+ noDescriptorsJars.add("commons-beanutils.jar");
+ noDescriptorsJars.add("commons-fileupload-1.0.jar");
+ noDescriptorsJars.add("commons-pool.jar");
+ noDescriptorsJars.add("commons-digester.jar");
+ noDescriptorsJars.add("commons-logging.jar");
+ noDescriptorsJars.add("commons-collections.jar");
+ noDescriptorsJars.add("jmx.jar");
+ noDescriptorsJars.add("jmx-tools.jar");
+ noDescriptorsJars.add("xercesImpl.jar");
+ noDescriptorsJars.add("xmlParserAPIs.jar");
+ noDescriptorsJars.add("xml-apis.jar");
+ // JARs from J2SE runtime
+ noDescriptorsJars.add("sunjce_provider.jar");
+ noDescriptorsJars.add("ldapsec.jar");
+ noDescriptorsJars.add("localedata.jar");
+ noDescriptorsJars.add("dnsns.jar");
+ noDescriptorsJars.add("tools.jar");
+ noDescriptorsJars.add("sunpkcs11.jar");
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+ /**
+ * The Context we are associated with.
+ */
+ private Context context = null;
+
+
+ /**
+ * The string resources for this package.
+ */
+ private static final StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+ /**
+ * The <code>Digester</code> we will use to process tag library
+ * descriptor files.
+ */
+ private static Digester tldDigester = null;
+
+
+ /**
+ * Attribute value used to turn on/off TLD validation
+ */
+ private static boolean tldValidation = false;
+
+
+ /**
+ * Attribute value used to turn on/off TLD namespace awarenes.
+ */
+ private static boolean tldNamespaceAware = false;
+
+ private boolean rescan=true;
+
+ private ArrayList<String> listeners = new ArrayList<String>();
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Sets the list of JARs that are known not to contain any TLDs.
+ *
+ * @param jarNames List of comma-separated names of JAR files that are
+ * known not to contain any TLDs
+ */
+ public static void setNoTldJars(String jarNames) {
+ if (jarNames != null) {
+ noDescriptorsJars.clear();
+ StringTokenizer tokenizer = new StringTokenizer(jarNames, ",");
+ while (tokenizer.hasMoreElements()) {
+ noDescriptorsJars.add(tokenizer.nextToken());
+ }
+ }
+ }
+
+ /**
+ * Set the validation feature of the XML parser used when
+ * parsing xml instances.
+ * @param tldValidation true to enable xml instance validation
+ */
+ public void setTldValidation(boolean tldValidation){
+ WarScanner.tldValidation = tldValidation;
+ }
+
+ /**
+ * Get the server.xml <host> attribute's xmlValidation.
+ * @return true if validation is enabled.
+ *
+ */
+ public boolean getTldValidation(){
+ return tldValidation;
+ }
+
+ /**
+ * Get the server.xml <host> attribute's xmlNamespaceAware.
+ * @return true if namespace awarenes is enabled.
+ *
+ */
+ public boolean getTldNamespaceAware(){
+ return tldNamespaceAware;
+ }
+
+
+ /**
+ * Set the namespace aware feature of the XML parser used when
+ * parsing xml instances.
+ * @param tldNamespaceAware true to enable namespace awareness
+ */
+ public void setTldNamespaceAware(boolean tldNamespaceAware){
+ WarScanner.tldNamespaceAware = tldNamespaceAware;
+ }
+
+
+ public boolean isRescan() {
+ return rescan;
+ }
+
+ public void setRescan(boolean rescan) {
+ this.rescan = rescan;
+ }
+
+ public Context getContext() {
+ return context;
+ }
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public void addApplicationListener( String s ) {
+ //if(log.isDebugEnabled())
+ log.debug( "Add tld listener " + s);
+ listeners.add(s);
+ }
+
+ public String[] getTldListeners() {
+ String result[]=new String[listeners.size()];
+ listeners.toArray(result);
+ return result;
+ }
+
+
+ /**
+ * Scan for and configure all tag library descriptors found in this
+ * web application.
+ *
+ * @exception Exception if a fatal input/output or parsing error occurs
+ */
+ public void execute() throws Exception {
+ long t1=System.currentTimeMillis();
+
+ /*
+ * Acquire the list of TLD resource paths, possibly embedded in JAR
+ * files, to be processed
+ */
+ Set resourcePaths = tldScanResourcePaths();
+ Map<String, File> jarPaths = getJarPaths();
+
+ // Scan each accumulated resource path for TLDs to be processed
+ Iterator paths = resourcePaths.iterator();
+ while (paths.hasNext()) {
+ String path = (String) paths.next();
+ if (path.endsWith(".jar")) {
+ tldScanJar(path);
+ } else {
+ tldScanTld(path);
+ }
+ }
+ if (jarPaths != null) {
+ paths = jarPaths.values().iterator();
+ while (paths.hasNext()) {
+ tldScanJar((File) paths.next());
+ }
+ }
+
+ String list[] = getTldListeners();
+
+ if( log.isDebugEnabled() )
+ log.debug( "Adding tld listeners:" + list.length);
+ for( int i=0; list!=null && i<list.length; i++ ) {
+ context.addApplicationListener(list[i]);
+ }
+
+ long t2=System.currentTimeMillis();
+ if( context instanceof StandardContext ) {
+ ((StandardContext)context).setTldScanTime(t2-t1);
+ }
+
+ }
+
+ // -------------------------------------------------------- Private Methods
+
+ /*
+ * Returns the last modification date of the given sets of resources.
+ *
+ * @param resourcePaths
+ * @param jarPaths
+ *
+ * @return Last modification date
+ */
+ private long getLastModified(Set resourcePaths, Map jarPaths)
+ throws Exception {
+
+ long lastModified = 0;
+
+ Iterator paths = resourcePaths.iterator();
+ while (paths.hasNext()) {
+ String path = (String) paths.next();
+ URL url = context.getServletContext().getResource(path);
+ if (url == null) {
+ log.debug( "Null url "+ path );
+ break;
+ }
+ long lastM = url.openConnection().getLastModified();
+ if (lastM > lastModified) lastModified = lastM;
+ if (log.isDebugEnabled()) {
+ log.debug( "Last modified " + path + " " + lastM);
+ }
+ }
+
+ if (jarPaths != null) {
+ paths = jarPaths.values().iterator();
+ while (paths.hasNext()) {
+ File jarFile = (File) paths.next();
+ long lastM = jarFile.lastModified();
+ if (lastM > lastModified) lastModified = lastM;
+ if (log.isDebugEnabled()) {
+ log.debug("Last modified " + jarFile.getAbsolutePath()
+ + " " + lastM);
+ }
+ }
+ }
+
+ return lastModified;
+ }
+
+ private void processCache(File tldCache ) throws IOException {
+ // read the cache and return;
+ try {
+ FileInputStream in=new FileInputStream(tldCache);
+ ObjectInputStream ois=new ObjectInputStream( in );
+ String list[]=(String [])ois.readObject();
+ if( log.isDebugEnabled() )
+ log.debug("Reusing tldCache " + tldCache + " " +
list.length);
+ for( int i=0; list!=null && i<list.length; i++ ) {
+ context.addApplicationListener(list[i]);
+ }
+ ois.close();
+ } catch( ClassNotFoundException ex ) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Create (if necessary) and return a Digester configured to process a tag
+ * library descriptor, looking for additional listener classes to be
+ * registered.
+ */
+ private static Digester createTldDigester() {
+
+ return DigesterFactory.newDigester(tldValidation,
+ tldNamespaceAware,
+ new TldRuleSet());
+
+ }
+
+
+ /**
+ * Scan the JAR file at the specified resource path for TLDs in the
+ * <code>META-INF</code> subdirectory, and scan each TLD for application
+ * event listeners that need to be registered.
+ *
+ * @param resourcePath Resource path of the JAR file to scan
+ *
+ * @exception Exception if an exception occurs while scanning this JAR
+ */
+ private void tldScanJar(String resourcePath) throws Exception {
+
+ if (log.isDebugEnabled()) {
+ log.debug(" Scanning JAR at resource path '" + resourcePath +
"'");
+ }
+
+ URL url = context.getServletContext().getResource(resourcePath);
+ if (url == null) {
+ throw new IllegalArgumentException
+ (sm.getString("contextConfig.tldResourcePath",
+ resourcePath));
+ }
+
+ File file = null;
+ try {
+ file = new File(url.toURI());
+ } catch (URISyntaxException e) {
+ // Ignore, probably an unencoded char
+ file = new File(url.getFile());
+ }
+ try {
+ file = file.getCanonicalFile();
+ } catch (IOException e) {
+ // Ignore
+ }
+ tldScanJar(file);
+
+ }
+
+ /**
+ * Scans all TLD entries in the given JAR for application listeners.
+ *
+ * @param file JAR file whose TLD entries are scanned for application
+ * listeners
+ */
+ private void tldScanJar(File file) throws Exception {
+
+ JarFile jarFile = null;
+ String name = null;
+
+ String jarPath = file.getAbsolutePath();
+
+ try {
+ jarFile = new JarFile(file);
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ name = entry.getName();
+ if (!name.startsWith("META-INF/")) {
+ continue;
+ }
+ if (!name.endsWith(".tld")) {
+ continue;
+ }
+ if (log.isTraceEnabled()) {
+ log.trace(" Processing TLD at '" + name +
"'");
+ }
+ try {
+ tldScanStream(new InputSource(jarFile.getInputStream(entry)));
+ } catch (Exception e) {
+ log.error(sm.getString("contextConfig.tldEntryException",
+ name, jarPath, context.getPath()),
+ e);
+ }
+ }
+ } catch (Exception e) {
+ log.error(sm.getString("contextConfig.tldJarException",
+ jarPath, context.getPath()),
+ e);
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan the TLD contents in the specified input stream, and register
+ * any application event listeners found there. <b>NOTE</b> - It is
+ * the responsibility of the caller to close the InputStream after this
+ * method returns.
+ *
+ * @param resourceStream InputStream containing a tag library descriptor
+ *
+ * @exception Exception if an exception occurs while scanning this TLD
+ */
+ private void tldScanStream(InputSource resourceStream)
+ throws Exception {
+
+ if (tldDigester == null){
+ tldDigester = createTldDigester();
+ }
+
+ synchronized (tldDigester) {
+ try {
+ tldDigester.push(this);
+ tldDigester.parse(resourceStream);
+ } finally {
+ tldDigester.reset();
+ }
+ }
+
+ }
+
+ /**
+ * Scan the TLD contents at the specified resource path, and register
+ * any application event listeners found there.
+ *
+ * @param resourcePath Resource path being scanned
+ *
+ * @exception Exception if an exception occurs while scanning this TLD
+ */
+ private void tldScanTld(String resourcePath) throws Exception {
+
+ if (log.isDebugEnabled()) {
+ log.debug(" Scanning TLD at resource path '" + resourcePath +
"'");
+ }
+
+ InputSource inputSource = null;
+ try {
+ InputStream stream =
+ context.getServletContext().getResourceAsStream(resourcePath);
+ if (stream == null) {
+ throw new IllegalArgumentException
+ (sm.getString("contextConfig.tldResourcePath",
+ resourcePath));
+ }
+ inputSource = new InputSource(stream);
+ if (inputSource == null) {
+ throw new IllegalArgumentException
+ (sm.getString("contextConfig.tldResourcePath",
+ resourcePath));
+ }
+ tldScanStream(inputSource);
+ } catch (Exception e) {
+ throw new ServletException
+ (sm.getString("contextConfig.tldFileException", resourcePath,
+ context.getPath()),
+ e);
+ }
+
+ }
+
+ /**
+ * Accumulate and return a Set of resource paths to be analyzed for
+ * tag library descriptors. Each element of the returned set will be
+ * the context-relative path to either a tag library descriptor file,
+ * or to a JAR file that may contain tag library descriptors in its
+ * <code>META-INF</code> subdirectory.
+ *
+ * @exception IOException if an input/output error occurs while
+ * accumulating the list of resource paths
+ */
+ private Set<String> tldScanResourcePaths() throws IOException {
+ if (log.isDebugEnabled()) {
+ log.debug(" Accumulating TLD resource paths");
+ }
+ Set<String> resourcePaths = new HashSet<String>();
+
+ // Accumulate resource paths explicitly listed in the web application
+ // deployment descriptor
+ if (log.isTraceEnabled()) {
+ log.trace(" Scanning <taglib> elements in web.xml");
+ }
+ String taglibs[] = context.findTaglibs();
+ for (int i = 0; i < taglibs.length; i++) {
+ String resourcePath = context.findTaglib(taglibs[i]);
+ // FIXME - Servlet 2.4 DTD implies that the location MUST be
+ // a context-relative path starting with '/'?
+ if (!resourcePath.startsWith("/")) {
+ resourcePath = "/WEB-INF/" + resourcePath;
+ }
+ if (log.isTraceEnabled()) {
+ log.trace(" Adding path '" + resourcePath +
+ "' for URI '" + taglibs[i] + "'");
+ }
+ resourcePaths.add(resourcePath);
+ }
+
+ DirContext resources = context.getResources();
+ if (resources != null) {
+ tldScanResourcePathsWebInf(resources, "/WEB-INF", resourcePaths);
+ }
+
+ // Return the completed set
+ return (resourcePaths);
+
+ }
+
+ /*
+ * Scans the web application's subdirectory identified by rootPath,
+ * along with its subdirectories, for TLDs.
+ *
+ * Initially, rootPath equals /WEB-INF. The /WEB-INF/classes and
+ * /WEB-INF/lib subdirectories are excluded from the search, as per the
+ * JSP 2.0 spec.
+ *
+ * @param resources The web application's resources
+ * @param rootPath The path whose subdirectories are to be searched for
+ * TLDs
+ * @param tldPaths The set of TLD resource paths to add to
+ */
+ private void tldScanResourcePathsWebInf(DirContext resources,
+ String rootPath,
+ Set tldPaths)
+ throws IOException {
+
+ if (log.isTraceEnabled()) {
+ log.trace(" Scanning TLDs in " + rootPath + "
subdirectory");
+ }
+
+ try {
+ NamingEnumeration items = resources.list(rootPath);
+ while (items.hasMoreElements()) {
+ NameClassPair item = (NameClassPair) items.nextElement();
+ String resourcePath = rootPath + "/" + item.getName();
+ if (!resourcePath.endsWith(".tld")
+ &&
(resourcePath.startsWith("/WEB-INF/classes")
+ || resourcePath.startsWith("/WEB-INF/lib"))) {
+ continue;
+ }
+ if (resourcePath.endsWith(".tld")) {
+ if (log.isTraceEnabled()) {
+ log.trace(" Adding path '" + resourcePath +
"'");
+ }
+ tldPaths.add(resourcePath);
+ } else {
+ tldScanResourcePathsWebInf(resources, resourcePath,
+ tldPaths);
+ }
+ }
+ } catch (NamingException e) {
+ ; // Silent catch: it's valid that no /WEB-INF directory exists
+ }
+ }
+
+ /**
+ * Returns a map of the paths to all JAR files that are accessible to the
+ * webapp and will be scanned for TLDs.
+ *
+ * The map always includes all the JARs under WEB-INF/lib, as well as
+ * shared JARs in the classloader delegation chain of the webapp's
+ * classloader.
+ *
+ * The latter constitutes a Tomcat-specific extension to the TLD search
+ * order defined in the JSP spec. It allows tag libraries packaged as JAR
+ * files to be shared by web applications by simply dropping them in a
+ * location that all web applications have access to (e.g.,
+ * <CATALINA_HOME>/common/lib).
+ *
+ * The set of shared JARs to be scanned for TLDs is narrowed down by
+ * the <tt>noTldJars</tt> class variable, which contains the names of
JARs
+ * that are known not to contain any TLDs.
+ *
+ * @return Map of JAR file paths
+ */
+ private Map<String, File> getJarPaths() {
+
+ HashMap<String, File> jarPathMap = null;
+
+ ClassLoader webappLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader loader = webappLoader;
+ while (loader != null) {
+ if (loader instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader) loader).getURLs();
+ for (int i=0; i<urls.length; i++) {
+ // Expect file URLs, these are %xx encoded or not depending on
+ // the class loader
+ // This is definitely not as clean as using JAR URLs either
+ // over file or the custom jndi handler, but a lot less
+ // buggy overall
+ File file = null;
+ try {
+ file = new File(urls[i].toURI());
+ } catch (Exception e) {
+ // Ignore, probably an unencoded char or non file URL,
+ // attempt direct access
+ file = new File(urls[i].getFile());
+ }
+ try {
+ file = file.getCanonicalFile();
+ } catch (IOException e) {
+ // Ignore
+ }
+ if (!file.exists()) {
+ continue;
+ }
+ String path = file.getAbsolutePath();
+ if (!path.endsWith(".jar")) {
+ continue;
+ }
+ /*
+ * Scan all JARs from WEB-INF/lib, plus any shared JARs
+ * that are not known not to contain any TLDs
+ */
+ if (loader == webappLoader
+ || noDescriptorsJars == null
+ || !noDescriptorsJars.contains(file.getName())) {
+ if (jarPathMap == null) {
+ jarPathMap = new HashMap();
+ jarPathMap.put(path, file);
+ } else if (!jarPathMap.containsKey(path)) {
+ jarPathMap.put(path, file);
+ }
+ }
+ }
+ }
+ loader = loader.getParent();
+ }
+
+ return jarPathMap;
+ }
+}
Added: trunk/java/org/apache/tomcat/WarComponents.java
===================================================================
--- trunk/java/org/apache/tomcat/WarComponents.java (rev 0)
+++ trunk/java/org/apache/tomcat/WarComponents.java 2009-04-21 03:39:25 UTC (rev 1021)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+
+package org.apache.tomcat;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public interface WarComponents {
+
+ /**
+ * Find annotated classes for this context.
+ */
+ public Iterator<Class<?>> getAnnotatedClasses();
+
+
+ /**
+ * Find JAR files containing an overlay.
+ */
+ public Iterator<String> getOverlays();
+
+
+ /**
+ * Find JAR files containing a web fragment.
+ */
+ public Iterator<String> getWebFragments();
+
+
+ /**
+ * Find TLDs.
+ */
+ public Map<String, List<String>> getTLDs();
+
+}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2009-04-20 15:51:08 UTC (rev 1020)
+++ trunk/webapps/docs/changelog.xml 2009-04-21 03:39:25 UTC (rev 1021)
@@ -68,6 +68,12 @@
<fix>
<bug>46562</bug>: In SSI, close the reader when done. (markt)
</fix>
+ <add>
+ AsyncContext implementation. (remm)
+ </add>
+ <add>
+ Multipart implementation. (remm)
+ </add>
</changelog>
</subsection>
<subsection name="Coyote">