JBossWeb SVN: r1029 - in trunk/java/org/apache/catalina: core and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-24 22:54:08 -0400 (Fri, 24 Apr 2009)
New Revision: 1029
Modified:
trunk/java/org/apache/catalina/JarRepository.java
trunk/java/org/apache/catalina/core/ContextJarRepository.java
trunk/java/org/apache/catalina/startup/BaseContextScanner.java
Log:
- JarRepository should also hold the class folder, otherwise it's not consistent. This now takes over all the temping
code from WebappLoader. This could also allow specifying shared JARs of interest rather than use the great "scan
URL CLs but avoid known JARs" technique.
- ContextConfig, WebappLoader and WebappClassLoader will need updates to use JarRepository.
Modified: trunk/java/org/apache/catalina/JarRepository.java
===================================================================
--- trunk/java/org/apache/catalina/JarRepository.java 2009-04-24 19:33:12 UTC (rev 1028)
+++ trunk/java/org/apache/catalina/JarRepository.java 2009-04-25 02:54:08 UTC (rev 1029)
@@ -23,11 +23,13 @@
package org.apache.catalina;
+import java.io.File;
+import java.util.Map;
import java.util.jar.JarFile;
/**
- * A JARRepository manages a set of JARs associated with a Context, and
+ * A JarRepository manages a set of Jars associated with a Context, and
* allows efficient access to them.
*
* @author Remy Maucherat
@@ -73,15 +75,22 @@
/**
- * Get a JarFile with the specified name.
+ * Get the JarFile map.
*
- * @param name
- * @return
+ * @return the JarFile map, associating logical name with JarFile
*/
- public JarFile getJar(String name);
+ public Map<String, JarFile> getJars();
/**
+ * Find the JarFile corresponding to the path.
+ *
+ * @return the JarFile, or null if not found
+ */
+ public JarFile findJar(String path);
+
+
+ /**
* Find all JarFile managed by the JARRepository.
*
* @return All JarFile
@@ -89,4 +98,20 @@
public JarFile[] findJars();
+ /**
+ * Find all exploded Jars managed by the JARRepository.
+ *
+ * @return All exploded File
+ */
+ public File[] findExplodedJars();
+
+
+ /**
+ * Get the exploded Jar map.
+ *
+ * @return the Jar map, associating logical name with File
+ */
+ public Map<String, File> getExplodedJars();
+
+
}
Modified: trunk/java/org/apache/catalina/core/ContextJarRepository.java
===================================================================
--- trunk/java/org/apache/catalina/core/ContextJarRepository.java 2009-04-24 19:33:12 UTC (rev 1028)
+++ trunk/java/org/apache/catalina/core/ContextJarRepository.java 2009-04-25 02:54:08 UTC (rev 1029)
@@ -53,11 +53,11 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.jar.JarFile;
import javax.naming.Binding;
+import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
@@ -151,6 +151,12 @@
/**
+ * Classes path, which is essentially an exploded Jar.
+ */
+ protected String classesPath = "/WEB-INF/classes";
+
+
+ /**
* Library path.
*/
protected String libPath = "/WEB-INF/lib";
@@ -168,6 +174,30 @@
protected JarFile[] jarFilesArray = new JarFile[0];
+ /**
+ * Map for the File instances.
+ */
+ protected Map<String, File> explodedJars = new HashMap<String, File>();
+
+
+ /**
+ * Array of the exploded Jars, as convenience.
+ */
+ protected File[] explodedJarsArray = new File[0];
+
+
+ /**
+ * Delete temp Jars.
+ */
+ protected boolean tempJars = false;
+
+
+ /**
+ * Delete temp exploded Jars.
+ */
+ protected boolean tempExplodedJars = false;
+
+
// --------------------------------------------------------- Public Methods
@@ -270,37 +300,34 @@
if (servletContext == null)
return;
- // Check JARs from Context
- File workDir =
- (File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
+ // Access work directory
+ File workDir = (File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
if (workDir == null) {
+ // FIXME: this is actually an error
log.info("No work dir for " + servletContext);
}
+ // Looking up directory /WEB-INF/lib in the context
NamingEnumeration<Binding> libPathListing = null;
- // Looking up directory /WEB-INF/lib in the context
try {
libPathListing = resources.listBindings(libPath);
} catch (NamingException e) {
- // Silent catch: it's valid that no /WEB-INF/lib collection
- // exists
+ // Silent catch: it's valid that no /WEB-INF/lib collection exists
}
-
if (libPathListing != null) {
- boolean copyJars = false;
String absoluteLibPath = servletContext.getRealPath(libPath);
File destDir = null;
if (absoluteLibPath != null) {
destDir = new File(absoluteLibPath);
} else {
- copyJars = true;
+ tempJars = true;
destDir = new File(workDir, libPath);
destDir.mkdirs();
}
while (libPathListing.hasMoreElements()) {
Binding binding = libPathListing.nextElement();
- String filename = libPath + "/" + binding.getName();
- if (!filename.endsWith(".jar"))
+ String logicalName = libPath + "/" + binding.getName();
+ if (!logicalName.endsWith(".jar"))
continue;
// Copy JAR in the work directory, always (the JAR file
// would get locked otherwise, which would make it
@@ -311,7 +338,7 @@
continue;
Resource jarResource = (Resource) obj;
try {
- if (copyJars) {
+ if (tempJars) {
InputStream is = null;
OutputStream os = null;
try {
@@ -333,17 +360,54 @@
}
}
JarFile jarFile = new JarFile(destFile);
- jarFiles.put(destFile.getAbsolutePath(), jarFile);
+ jarFiles.put(logicalName, jarFile);
} catch (IOException ex) {
// Catch the exception if there is an empty jar file,
// or if the JAR cannot be copied to temp
- // FIXME: throw an error, as webapp will not run
+ // FIXME: throw an error, as the webapp will not run
}
}
}
jarFilesArray = jarFiles.values().toArray(jarFilesArray);
+ // Setting up the class repository (/WEB-INF/classes), if it exists
+ DirContext classes = null;
+ try {
+ Object object = resources.lookup(classesPath);
+ if (object instanceof DirContext) {
+ classes = (DirContext) object;
+ }
+ } catch(NamingException e) {
+ // Silent catch: it's valid that no /WEB-INF/classes collection
+ // exists
+ }
+ if (classes != null) {
+ File classRepository = null;
+ String absoluteClassesPath = servletContext.getRealPath(classesPath);
+ if (absoluteClassesPath != null) {
+ classRepository = new File(absoluteClassesPath);
+ } else {
+ classRepository = new File(workDir, classesPath);
+ classRepository.mkdirs();
+ tempExplodedJars = true;
+ try {
+ copyDirContext(classes, classRepository);
+ } catch (NamingException ex) {
+ // Catch the exception if there is an empty jar file,
+ // or if the JAR cannot be copied to temp
+ // FIXME: throw an error, as the webapp will not run
+ } catch (IOException ex) {
+ // Catch the exception if there is an empty jar file,
+ // or if the JAR cannot be copied to temp
+ // FIXME: throw an error, as the webapp will not run
+ }
+ }
+ // Adding the repository to the class loader
+ explodedJarsArray = new File[] { classRepository };
+ explodedJars.put(classesPath + "/", classRepository);
+ }
+
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
@@ -364,7 +428,7 @@
// Validate and update our current component state
if (!started) {
if(log.isDebugEnabled())
- log.debug(sm.getString("standardPipeline.notStarted"));
+ log.debug(sm.getString("contextJarRepository.notStarted"));
return;
}
@@ -379,12 +443,10 @@
try {
for (int i = 0; i < jarFilesArray.length; i++) {
jarFilesArray[i].close();
+ if (tempJars) {
+ (new File(jarFilesArray[i].getName())).delete();
+ }
}
- Iterator<String> jarFilesNames = jarFiles.keySet().iterator();
- while (jarFilesNames.hasNext()) {
- File jarFile = new File(jarFilesNames.next());
- jarFile.delete();
- }
} catch (IOException ex) {
// Catch the exception if there is an empty jar file,
// or if the JAR cannot be copied to temp
@@ -392,6 +454,11 @@
}
jarFiles.clear();
jarFilesArray = new JarFile[0];
+ tempJars = false;
+ explodedJars.clear();
+ explodedJarsArray = new File[0];
+ // FIXME: delete exploded copy
+ tempExplodedJars = false;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
@@ -412,17 +479,31 @@
/**
- * Get a JarFile with the specified name.
+ * Get the JarFile map.
*
- * @param name
- * @return
+ * @return the JarFile map, associating logical name with JarFile
*/
- public JarFile getJar(String name) {
- return jarFiles.get(name);
+ public Map<String, JarFile> getJars() {
+ return jarFiles;
}
/**
+ * Find the JarFile corresponding to the path.
+ *
+ * @return the JarFile, or null if not found
+ */
+ public JarFile findJar(String path) {
+ for (int i = 0; i < jarFilesArray.length; i++) {
+ if (jarFilesArray[i].getName().equals(path)) {
+ return jarFilesArray[i];
+ }
+ }
+ return null;
+ }
+
+
+ /**
* Find all JarFile managed by the JARRepository.
*
* @return All JarFile
@@ -432,4 +513,81 @@
}
+ /**
+ * Get the exploded Jar map.
+ *
+ * @return the Jar map, associating logical name with File
+ */
+ public Map<String, File> getExplodedJars() {
+ return explodedJars;
+ }
+
+
+ /**
+ * Find all exploded Jars managed by the JARRepository.
+ *
+ * @return All exploded File
+ */
+ public File[] findExplodedJars() {
+ return explodedJarsArray;
+ }
+
+
+ /**
+ * Copy directory.
+ */
+ protected void copyDirContext(DirContext srcDir, File destDir)
+ throws IOException, NamingException {
+ InputStream is = null;
+ OutputStream os = null;
+ NamingEnumeration<NameClassPair> enumeration = srcDir.list("");
+ while (enumeration.hasMoreElements()) {
+ NameClassPair ncPair = enumeration.nextElement();
+ String name = ncPair.getName();
+ Object object = srcDir.lookup(name);
+ File currentFile = new File(destDir, name);
+ if (object instanceof Resource) {
+ try {
+ is = ((Resource) object).streamContent();
+ os = new FileOutputStream(currentFile);
+ IOTools.flow(is, os);
+ // Don't catch IOE - let the outer try/catch handle it
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ try {
+ if (os != null) os.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ }
+ } else if (object instanceof InputStream) {
+ try {
+ is = (InputStream) object;
+ os = new FileOutputStream(currentFile);
+ IOTools.flow(is, os);
+ // Don't catch IOE - let the outer try/catch handle it
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ try {
+ if (os != null) os.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ }
+ } else if (object instanceof DirContext) {
+ currentFile.mkdir();
+ copyDirContext((DirContext) object, currentFile);
+ }
+ }
+ }
+
+
}
Modified: trunk/java/org/apache/catalina/startup/BaseContextScanner.java
===================================================================
--- trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-24 19:33:12 UTC (rev 1028)
+++ trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-25 02:54:08 UTC (rev 1029)
@@ -24,9 +24,6 @@
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;
@@ -45,6 +42,7 @@
import org.apache.catalina.Context;
import org.apache.catalina.ContextScanner;
import org.apache.catalina.Globals;
+import org.apache.catalina.JarRepository;
public abstract class BaseContextScanner
implements ContextScanner {
@@ -137,21 +135,30 @@
* @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]), "");
- }
+ JarRepository jarRepository = context.getJarRepository();
+ if (jarRepository != null) {
+ JarFile[] jars = jarRepository.findJars();
+ for (int i = 0; i < jars.length; i++) {
+ scanJar(context, jars[i]);
}
+ File[] explodedJars = jarRepository.findExplodedJars();
+ for (int i = 0; i < explodedJars.length; i++) {
+ scanClasses(context, explodedJars[i], "");
+ }
}
+ // Do the same for the context parent
+ jarRepository = context.getParent().getJarRepository();
+ if (jarRepository != null) {
+ JarFile[] jars = jarRepository.findJars();
+ for (int i = 0; i < jars.length; i++) {
+ scanJar(context, jars[i]);
+ }
+ File[] explodedJars = jarRepository.findExplodedJars();
+ for (int i = 0; i < explodedJars.length; i++) {
+ scanClasses(context, explodedJars[i], "");
+ }
+ }
+ /*
ClassLoader loader = context.getLoader().getClassLoader().getParent();
while (loader != null) {
if (loader instanceof URLClassLoader) {
@@ -182,10 +189,8 @@
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
- */
+ // 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 {
@@ -198,6 +203,7 @@
}
loader = loader.getParent();
}
+ */
HashSet<String> warTLDs = new HashSet<String>();
@@ -391,11 +397,6 @@
if (jarTLDs.size() > 0) {
TLDs.put(file.getName(), jarTLDs);
}
- try {
- file.close();
- } catch (IOException e) {
- // Ignore
- }
}
16 years, 6 months
JBossWeb SVN: r1028 - in trunk/java/org/apache/catalina: connector and 3 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-24 15:33:12 -0400 (Fri, 24 Apr 2009)
New Revision: 1028
Added:
trunk/java/org/apache/catalina/JarRepository.java
trunk/java/org/apache/catalina/core/ContextJarRepository.java
Modified:
trunk/java/org/apache/catalina/Container.java
trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
trunk/java/org/apache/catalina/core/ContainerBase.java
trunk/java/org/apache/catalina/core/LocalStrings.properties
trunk/java/org/apache/catalina/deploy/WebOrdering.java
trunk/java/org/apache/catalina/startup/ContextConfig.java
Log:
- Given the amount of JAR open/close needed, add a new JarRespository contained object.
- Existing code (including the CL) will be refactored to use it.
Modified: trunk/java/org/apache/catalina/Container.java
===================================================================
--- trunk/java/org/apache/catalina/Container.java 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/Container.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -335,6 +335,23 @@
public void setResources(DirContext resources);
+ /**
+ * Return the JarRepository with which this Container is associated.
+ * If there is no associated JarRepository, return the JarRepository
+ * associated with our parent Container (if any);
+ * otherwise return <code>null</code>.
+ */
+ public JarRepository getJarRepository();
+
+
+ /**
+ * Set the JarRepository with which this Container is associated.
+ *
+ * @param jarRepository The newly associated JarRepository
+ */
+ public void setJarRepository(JarRepository jarRepository);
+
+
// --------------------------------------------------------- Public Methods
Added: trunk/java/org/apache/catalina/JarRepository.java
===================================================================
--- trunk/java/org/apache/catalina/JarRepository.java (rev 0)
+++ trunk/java/org/apache/catalina/JarRepository.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -0,0 +1,92 @@
+/*
+ * 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 java.util.jar.JarFile;
+
+
+/**
+ * A JARRepository manages a set of JARs associated with a Context, and
+ * allows efficient access to them.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 515 $ $Date: 2008-03-17 22:02:23 +0100 (Mon, 17 Mar 2008) $
+ */
+public interface JarRepository {
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Return the Container with which this JARRepository has been associated.
+ */
+ public Container getContainer();
+
+
+ /**
+ * Set the Container with which this JARRepository has been associated.
+ *
+ * @param container The associated Container
+ */
+ public void setContainer(Container container);
+
+
+ /**
+ * Return descriptive information about this JARRepository implementation and
+ * the corresponding version number, in the format
+ * <code><description>/<version></code>.
+ */
+ public String getInfo();
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Execute a periodic task, such as reloading, etc. This method will be
+ * invoked inside the classloading context of this container. Unexpected
+ * throwables will be caught and logged.
+ */
+ public void backgroundProcess();
+
+
+ /**
+ * Get a JarFile with the specified name.
+ *
+ * @param name
+ * @return
+ */
+ public JarFile getJar(String name);
+
+
+ /**
+ * Find all JarFile managed by the JARRepository.
+ *
+ * @return All JarFile
+ */
+ public JarFile[] findJars();
+
+
+}
Modified: trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
===================================================================
--- trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -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.
*/
@@ -20,8 +48,6 @@
import java.io.IOException;
-import javax.servlet.SessionTrackingMode;
-
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
Modified: trunk/java/org/apache/catalina/core/ContainerBase.java
===================================================================
--- trunk/java/org/apache/catalina/core/ContainerBase.java 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/core/ContainerBase.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -43,6 +43,7 @@
import org.apache.catalina.ContainerEvent;
import org.apache.catalina.ContainerListener;
import org.apache.catalina.Globals;
+import org.apache.catalina.JarRepository;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
@@ -255,6 +256,12 @@
/**
+ * The JarRepository with which this Container is associated.
+ */
+ protected JarRepository jarRepository = null;
+
+
+ /**
* The string manager for this package.
*/
protected static StringManager sm =
@@ -722,6 +729,63 @@
/**
+ * Return the JarRepository with which this Container is associated. If there is
+ * no associated JarRepository, return the JarRepository associated with our parent
+ * Container (if any); otherwise return <code>null</code>.
+ */
+ public JarRepository getJarRepository() {
+
+ if (jarRepository != null)
+ return (jarRepository);
+ if (parent != null)
+ return (parent.getJarRepository());
+ return (null);
+
+ }
+
+
+ /**
+ * Set the JarRepository with which this Container is associated.
+ *
+ * @param jarRepository The newly associated JarRepository
+ */
+ public synchronized void setJarRepository(JarRepository jarRepository) {
+
+ // Change components if necessary
+ JarRepository oldJarRepository = this.jarRepository;
+ if (oldJarRepository == jarRepository)
+ return;
+ this.jarRepository = jarRepository;
+
+ // Stop the old component if necessary
+ if (started && (oldJarRepository != null) &&
+ (oldJarRepository instanceof Lifecycle)) {
+ try {
+ ((Lifecycle) oldJarRepository).stop();
+ } catch (LifecycleException e) {
+ log.error("ContainerBase.setJarRepository: stop: ", e);
+ }
+ }
+
+ // Start the new component if necessary
+ if (jarRepository != null)
+ jarRepository.setContainer(this);
+ if (started && (jarRepository != null) &&
+ (jarRepository instanceof Lifecycle)) {
+ try {
+ ((Lifecycle) jarRepository).start();
+ } catch (LifecycleException e) {
+ log.error("ContainerBase.setJarRepository: start: ", e);
+ }
+ }
+
+ // Report this property change to interested listeners
+ support.firePropertyChange("jarRepository", oldJarRepository, this.jarRepository);
+
+ }
+
+
+ /**
* Return the resources DirContext object with which this Container is
* associated. If there is no associated resources object, return the
* resources associated with our parent Container (if any); otherwise
@@ -1022,6 +1086,8 @@
started = true;
// Start our subordinate components, if any
+ if ((jarRepository != null) && (jarRepository instanceof Lifecycle))
+ ((Lifecycle) jarRepository).start();
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start();
logger = null;
@@ -1121,6 +1187,9 @@
if ((loader != null) && (loader instanceof Lifecycle)) {
((Lifecycle) loader).stop();
}
+ if ((jarRepository != null) && (jarRepository instanceof Lifecycle)) {
+ ((Lifecycle) jarRepository).stop();
+ }
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
@@ -1324,6 +1393,13 @@
log.warn(sm.getString("containerBase.backgroundProcess.realm", realm), e);
}
}
+ if (jarRepository != null) {
+ try {
+ jarRepository.backgroundProcess();
+ } catch (Exception e) {
+ log.warn(sm.getString("containerBase.backgroundProcess.jarRepository", jarRepository), e);
+ }
+ }
Valve current = pipeline.getFirst();
while (current != null) {
try {
Added: trunk/java/org/apache/catalina/core/ContextJarRepository.java
===================================================================
--- trunk/java/org/apache/catalina/core/ContextJarRepository.java (rev 0)
+++ trunk/java/org/apache/catalina/core/ContextJarRepository.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -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.
+ *
+ *
+ * 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.core;
+
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.jar.JarFile;
+
+import javax.naming.Binding;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.servlet.ServletContext;
+
+import org.apache.catalina.Contained;
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.JarRepository;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.util.IOTools;
+import org.apache.catalina.util.LifecycleSupport;
+import org.apache.catalina.util.StringManager;
+import org.apache.naming.resources.Resource;
+import org.jboss.logging.Logger;
+
+
+/**
+ * Context specific implementation for a JAR repository, which will manage
+ * JARs from /WEB-INF/lib in an efficient way.
+ *
+ * @author Remy Maucherat
+ */
+public class ContextJarRepository
+ implements JarRepository, Contained, Lifecycle {
+
+ private static Logger log = Logger.getLogger(ContextJarRepository.class);
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Construct a new ContextJarRepository instance with no associated Container.
+ */
+ public ContextJarRepository() {
+
+ this(null);
+
+ }
+
+
+ /**
+ * Construct a new ContextJarRepository instance that is associated with the
+ * specified Container.
+ *
+ * @param container The container we should be associated with
+ */
+ public ContextJarRepository(Container container) {
+
+ super();
+ setContainer(container);
+
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The Container with which this Pipeline is associated.
+ */
+ protected Container container = null;
+
+
+ /**
+ * Descriptive information about this implementation.
+ */
+ protected String info = "org.apache.catalina.core.ContextJarRepository/1.0";
+
+
+ /**
+ * The lifecycle event support for this component.
+ */
+ protected LifecycleSupport lifecycle = new LifecycleSupport(this);
+
+
+ /**
+ * The string manager for this package.
+ */
+ protected static StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
+ * Has this component been started yet?
+ */
+ protected boolean started = false;
+
+
+ /**
+ * Library path.
+ */
+ protected String libPath = "/WEB-INF/lib";
+
+
+ /**
+ * Map for the JarFile instances.
+ */
+ protected Map<String, JarFile> jarFiles = new HashMap<String, JarFile>();
+
+
+ /**
+ * Array of the JarFiles, as convenience.
+ */
+ protected JarFile[] jarFilesArray = new JarFile[0];
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Return descriptive information about this implementation class.
+ */
+ public String getInfo() {
+
+ return (this.info);
+
+ }
+
+
+ // ------------------------------------------------------ Contained Methods
+
+
+ /**
+ * Return the Container with which this Pipeline is associated.
+ */
+ public Container getContainer() {
+
+ return (this.container);
+
+ }
+
+
+ /**
+ * Set the Container with which this Pipeline is associated.
+ *
+ * @param container The new associated container
+ */
+ public void setContainer(Container container) {
+
+ this.container = container;
+
+ }
+
+
+ // ------------------------------------------------------ Lifecycle Methods
+
+
+ /**
+ * Add a lifecycle event listener to this component.
+ *
+ * @param listener The listener to add
+ */
+ public void addLifecycleListener(LifecycleListener listener) {
+
+ lifecycle.addLifecycleListener(listener);
+
+ }
+
+
+ /**
+ * Get the lifecycle listeners associated with this lifecycle. If this
+ * Lifecycle has no listeners registered, a zero-length array is returned.
+ */
+ public LifecycleListener[] findLifecycleListeners() {
+
+ return lifecycle.findLifecycleListeners();
+
+ }
+
+
+ /**
+ * Remove a lifecycle event listener from this component.
+ *
+ * @param listener The listener to remove
+ */
+ public void removeLifecycleListener(LifecycleListener listener) {
+
+ lifecycle.removeLifecycleListener(listener);
+
+ }
+
+ /**
+ * Prepare for active use of the public methods of this Component.
+ *
+ * @exception LifecycleException if this component detects a fatal error
+ * that prevents it from being started
+ */
+ public synchronized void start() throws LifecycleException {
+
+ // Validate and update our current component state
+ if (started) {
+ if(log.isDebugEnabled())
+ log.debug(sm.getString("contextJarRepository.alreadyStarted"));
+ return;
+ }
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
+
+ started = true;
+
+ if (!(container instanceof Context))
+ throw new IllegalStateException("");
+ DirContext resources = container.getResources();
+ ServletContext servletContext = ((Context) container).getServletContext();
+ if (servletContext == null)
+ return;
+
+ // Check JARs from Context
+ File workDir =
+ (File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
+ if (workDir == null) {
+ log.info("No work dir for " + servletContext);
+ }
+
+ NamingEnumeration<Binding> libPathListing = null;
+ // Looking up directory /WEB-INF/lib in the context
+ try {
+ libPathListing = resources.listBindings(libPath);
+ } catch (NamingException e) {
+ // Silent catch: it's valid that no /WEB-INF/lib collection
+ // exists
+ }
+
+ if (libPathListing != null) {
+ boolean copyJars = false;
+ String absoluteLibPath = servletContext.getRealPath(libPath);
+ File destDir = null;
+ if (absoluteLibPath != null) {
+ destDir = new File(absoluteLibPath);
+ } else {
+ copyJars = true;
+ destDir = new File(workDir, libPath);
+ destDir.mkdirs();
+ }
+ while (libPathListing.hasMoreElements()) {
+ Binding binding = libPathListing.nextElement();
+ String filename = libPath + "/" + binding.getName();
+ if (!filename.endsWith(".jar"))
+ continue;
+ // Copy JAR in the work directory, always (the JAR file
+ // would get locked otherwise, which would make it
+ // impossible to update it or remove it at runtime)
+ File destFile = new File(destDir, binding.getName());
+ Object obj = binding.getObject();
+ if (!(obj instanceof Resource))
+ continue;
+ Resource jarResource = (Resource) obj;
+ try {
+ if (copyJars) {
+ InputStream is = null;
+ OutputStream os = null;
+ try {
+ is = jarResource.streamContent();
+ os = new FileOutputStream(destFile);
+ IOTools.flow(is, os);
+ // Don't catch IOE - let the outer try/catch handle it
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ try {
+ if (os != null) os.close();
+ } catch (IOException e){
+ // Ignore
+ }
+ }
+ }
+ JarFile jarFile = new JarFile(destFile);
+ jarFiles.put(destFile.getAbsolutePath(), jarFile);
+ } catch (IOException ex) {
+ // Catch the exception if there is an empty jar file,
+ // or if the JAR cannot be copied to temp
+ // FIXME: throw an error, as webapp will not run
+ }
+ }
+
+ }
+ jarFilesArray = jarFiles.values().toArray(jarFilesArray);
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(START_EVENT, null);
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
+
+ }
+
+
+ /**
+ * Gracefully shut down active use of the public methods of this Component.
+ *
+ * @exception LifecycleException if this component detects a fatal error
+ * that needs to be reported
+ */
+ public synchronized void stop() throws LifecycleException {
+
+ // Validate and update our current component state
+ if (!started) {
+ if(log.isDebugEnabled())
+ log.debug(sm.getString("standardPipeline.notStarted"));
+ return;
+ }
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(STOP_EVENT, null);
+ started = false;
+
+ // Close JARs and delete temporary copies if needed
+ try {
+ for (int i = 0; i < jarFilesArray.length; i++) {
+ jarFilesArray[i].close();
+ }
+ Iterator<String> jarFilesNames = jarFiles.keySet().iterator();
+ while (jarFilesNames.hasNext()) {
+ File jarFile = new File(jarFilesNames.next());
+ jarFile.delete();
+ }
+ } catch (IOException ex) {
+ // Catch the exception if there is an empty jar file,
+ // or if the JAR cannot be copied to temp
+ // FIXME: throw an error, as webapp will not run
+ }
+ jarFiles.clear();
+ jarFilesArray = new JarFile[0];
+
+ // Notify our interested LifecycleListeners
+ lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
+ }
+
+
+ // -------------------------------------------------- JarRepository Methods
+
+
+ /**
+ * Execute a periodic task, such as reloading, etc. This method will be
+ * invoked inside the classloading context of this container. Unexpected
+ * throwables will be caught and logged.
+ */
+ public void backgroundProcess() {
+
+ }
+
+
+ /**
+ * Get a JarFile with the specified name.
+ *
+ * @param name
+ * @return
+ */
+ public JarFile getJar(String name) {
+ return jarFiles.get(name);
+ }
+
+
+ /**
+ * Find all JarFile managed by the JARRepository.
+ *
+ * @return All JarFile
+ */
+ public JarFile[] findJars() {
+ return jarFilesArray;
+ }
+
+
+}
Modified: trunk/java/org/apache/catalina/core/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/core/LocalStrings.properties 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/core/LocalStrings.properties 2009-04-24 19:33:12 UTC (rev 1028)
@@ -51,6 +51,7 @@
containerBase.backgroundProcess.manager=Exception processing manager {0} background process
containerBase.backgroundProcess.realm=Exception processing realm {0} background process
containerBase.backgroundProcess.valve=Exception processing valve {0} background process
+containerBase.backgroundProcess.jarRepository=Exception processing jar repository {0} background process
fastEngineMapper.alreadyStarted=FastEngineMapper {0} has already been started
fastEngineMapper.notStarted=FastEngineMapper {0} has not yet been started
filterChain.filter=Filter execution threw an exception
Modified: trunk/java/org/apache/catalina/deploy/WebOrdering.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/WebOrdering.java 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/deploy/WebOrdering.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -28,6 +28,7 @@
public class WebOrdering implements Serializable {
+ protected String jar = null;
protected String name = null;
protected List<String> after = new ArrayList<String>();
protected List<String> before = new ArrayList<String>();
@@ -54,5 +55,11 @@
public void addBefore(String name) {
before.add(name);
}
+ public String getJar() {
+ return jar;
+ }
+ public void setJar(String jar) {
+ this.jar = jar;
+ }
}
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-24 15:11:36 UTC (rev 1027)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-24 19:33:12 UTC (rev 1028)
@@ -53,12 +53,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
@@ -83,6 +85,7 @@
import org.apache.catalina.Valve;
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.ContainerBase;
+import org.apache.catalina.core.ContextJarRepository;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
@@ -91,6 +94,8 @@
import org.apache.catalina.deploy.FilterMap;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.catalina.deploy.WebAbsoluteOrdering;
+import org.apache.catalina.deploy.WebOrdering;
import org.apache.catalina.util.StringManager;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.RuleSet;
@@ -955,11 +960,131 @@
* Process additional descriptors: TLDs, web fragments, and map overlays.
*/
protected void applicationExtraDescriptorsConfig() {
- // FIXME: Read order from web.xml and fragments (note: if no fragments, skip)
+ // Read order from web.xml and fragments (note: if no fragments, skip)
+ WebAbsoluteOrdering absoluteOrdering = null;
+ List<WebOrdering> orderings = new ArrayList<WebOrdering>();
Iterator<String> jarsWithWebFragments = scanner.getWebFragments();
+
+ /*
+ String altDDName = null;
+
+ // Open the application web.xml file, if it exists
+ InputStream stream = null;
+ ServletContext servletContext = context.getServletContext();
+ if (servletContext != null) {
+ altDDName = (String)servletContext.getAttribute(
+ Globals.ALT_DD_ATTR);
+ if (altDDName != null) {
+ try {
+ stream = new FileInputStream(altDDName);
+ } catch (FileNotFoundException e) {
+ log.error(sm.getString("contextConfig.altDDNotFound",
+ altDDName));
+ }
+ }
+ else {
+ stream = servletContext.getResourceAsStream
+ (Constants.ApplicationWebXml);
+ }
+ }
+ if (stream == null) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("contextConfig.applicationMissing") + " " + context);
+ }
+ return;
+ }
+
+ URL url = null;
+
+ // Process the application web.xml file
+ synchronized (orderingDigester) {
+ try {
+ if (altDDName != null) {
+ url = new File(altDDName).toURI().toURL();
+ } else {
+ url = servletContext.getResource(Constants.ApplicationWebXml);
+ }
+ if (url != null) {
+ InputSource is = new InputSource(url.toExternalForm());
+ is.setByteStream(stream);
+ orderingDigester.parse(is);
+ absoluteOrdering = (WebAbsoluteOrdering) orderingDigester.peek();
+ }
+ } catch (SAXParseException e) {
+ log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
+ log.error(sm.getString("contextConfig.applicationPosition",
+ "" + e.getLineNumber(),
+ "" + e.getColumnNumber()));
+ ok = false;
+ } catch (Exception e) {
+ log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e);
+ ok = false;
+ } finally {
+ orderingDigester.reset();
+ try {
+ if (stream != null) {
+ stream.close();
+ }
+ } catch (IOException e) {
+ log.error(sm.getString("contextConfig.applicationClose"), e);
+ }
+ }
+ }
+ */
+
+ // Process the web fragments
+ // FIXME: Do only if no absolute ordering
+ while (jarsWithWebFragments.hasNext()) {
+ String jar = jarsWithWebFragments.next();
+ JarFile jarFile = null;
+ InputStream is = null;
+ try {
+ jarFile = new JarFile(jar);
+ ZipEntry entry = jarFile.getEntry(Globals.WEB_FRAGMENT_PATH);
+ if (entry != null) {
+ is = jarFile.getInputStream(entry);
+ InputSource input = new InputSource((new File(jar)).toURI().toURL().toExternalForm());
+ input.setByteStream(is);
+ synchronized (fragmentOrderingDigester) {
+ try {
+ fragmentOrderingDigester.parse(input);
+ WebOrdering ordering = (WebOrdering) fragmentOrderingDigester.peek();
+ if (ordering != null) {
+ ordering.setJar(jar);
+ orderings.add(ordering);
+ }
+ } finally {
+ fragmentOrderingDigester.reset();
+ }
+ }
+ }
+ } catch (Exception e) {
+ // FIXME: error message
+ log.error(sm.getString("contextConfig.applicationParse", jar), e);
+ ok = false;
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ // Ignore
+ }
+ try {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+ // FIXME: Generate final web fragments order
+ if (absoluteOrdering != null || (orderings.size() > 0)) {
+
+ }
- // FIXME: Generate final web descriptor order
-
// FIXME: Add overlays
scanner.getOverlays();
}
@@ -984,6 +1109,10 @@
if (context.getConfigFile() != null)
processContextConfig(new File(context.getConfigFile()), null);
+ if (context.getJarRepository() == null) {
+ context.setJarRepository(new ContextJarRepository());
+ }
+
}
@@ -1306,8 +1435,8 @@
defaultWebConfig();
scanner.scan(context);
// FIXME: look where to place it according to the merging rules
+ applicationWebConfig();
applicationExtraDescriptorsConfig();
- applicationWebConfig();
if (!context.getIgnoreAnnotations()) {
applicationAnnotationsConfig();
}
16 years, 6 months
JBossWeb SVN: r1027 - branches/2.1.x/webapps/docs.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-24 11:11:36 -0400 (Fri, 24 Apr 2009)
New Revision: 1027
Modified:
branches/2.1.x/webapps/docs/changelog.xml
Log:
- Update version number.
Modified: branches/2.1.x/webapps/docs/changelog.xml
===================================================================
--- branches/2.1.x/webapps/docs/changelog.xml 2009-04-23 16:36:32 UTC (rev 1026)
+++ branches/2.1.x/webapps/docs/changelog.xml 2009-04-24 15:11:36 UTC (rev 1027)
@@ -16,7 +16,7 @@
<body>
-<section name="JBoss Web 2.1.3.CR1 (remm)">
+<section name="JBoss Web 2.1.3.GA (remm)">
<subsection name="General">
<changelog>
</changelog>
16 years, 6 months
JBossWeb SVN: r1026 - in trunk: java/org/apache/catalina/deploy and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-23 12:36:32 -0400 (Thu, 23 Apr 2009)
New Revision: 1026
Added:
trunk/java/org/apache/catalina/deploy/WebAbsoluteOrdering.java
trunk/java/org/apache/catalina/deploy/WebOrder.java
trunk/java/org/apache/catalina/deploy/WebOrdering.java
trunk/java/org/apache/catalina/startup/WebAbsoluteOrderingRuleSet.java
trunk/java/org/apache/catalina/startup/WebOrderingRuleSet.java
Modified:
trunk/ROADMAP.txt
trunk/java/org/apache/catalina/startup/ContextConfig.java
trunk/webapps/docs/changelog.xml
Log:
- Add some code which will parse the ordering elements.
Modified: trunk/ROADMAP.txt
===================================================================
--- trunk/ROADMAP.txt 2009-04-22 17:47:49 UTC (rev 1025)
+++ trunk/ROADMAP.txt 2009-04-23 16:36:32 UTC (rev 1026)
@@ -10,6 +10,7 @@
- ServletContainerInitializer support
- JSP 2.2 changes
- EL 1.1 changes
+- Jasper plugin for TLD metadata
- Setup standalone TCK environment for testing compliance with the new features
- Javassist annotation scanning impl for JBoss Web standalone
- Coordinate with AS 6 to implement new web.xml parsing (out of tree)
Added: trunk/java/org/apache/catalina/deploy/WebAbsoluteOrdering.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/WebAbsoluteOrdering.java (rev 0)
+++ trunk/java/org/apache/catalina/deploy/WebAbsoluteOrdering.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -0,0 +1,49 @@
+/*
+ * 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.deploy;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WebAbsoluteOrdering implements Serializable {
+
+ protected String name = null;
+ protected List<String> order = new ArrayList<String>();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<String> getOrder() {
+ return order;
+ }
+
+ public void addName(String name) {
+ order.add(name);
+ }
+}
Added: trunk/java/org/apache/catalina/deploy/WebOrder.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/WebOrder.java (rev 0)
+++ trunk/java/org/apache/catalina/deploy/WebOrder.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -0,0 +1,47 @@
+/*
+ * 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.deploy;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WebOrder implements Serializable {
+
+ protected WebAbsoluteOrdering web = null;
+ protected Map<String, WebOrdering> fragments = new HashMap<String, WebOrdering>();
+
+ public Map<String, WebOrdering> getFragments() {
+ return fragments;
+ }
+ public void setFragments(Map<String, WebOrdering> fragments) {
+ this.fragments = fragments;
+ }
+ public WebAbsoluteOrdering getWeb() {
+ return web;
+ }
+ public void addFragment(String name, WebOrdering ordering) {
+ fragments.put(name, ordering);
+ }
+
+}
Added: trunk/java/org/apache/catalina/deploy/WebOrdering.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/WebOrdering.java (rev 0)
+++ trunk/java/org/apache/catalina/deploy/WebOrdering.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -0,0 +1,58 @@
+/*
+ * 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.deploy;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class WebOrdering implements Serializable {
+
+ protected String name = null;
+ protected List<String> after = new ArrayList<String>();
+ protected List<String> before = new ArrayList<String>();
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<String> getAfter() {
+ return after;
+ }
+
+ public void addAfter(String name) {
+ after.add(name);
+ }
+
+ public List<String> getBefore() {
+ return before;
+ }
+
+ public void addBefore(String name) {
+ before.add(name);
+ }
+
+}
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-22 17:47:49 UTC (rev 1025)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -54,6 +54,7 @@
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -194,6 +195,18 @@
/**
+ * The <code>Digester</code> we will use to parse fragment ordering.
+ */
+ protected static Digester fragmentOrderingDigester = null;
+
+
+ /**
+ * The <code>Digester</code> we will use to parse absolute ordering in web.xml.
+ */
+ protected static Digester orderingDigester = null;
+
+
+ /**
* The <code>Rule</code> used to parse the web.xml
*/
protected static WebRuleSet webRuleSet = new WebRuleSet();
@@ -746,6 +759,25 @@
/**
+ * Create (if necessary) and return a Digester configured to process web fragments ordering.
+ */
+ protected static Digester createFragmentOrderingDigester() {
+ return DigesterFactory.newDigester(Globals.XML_NAMESPACE_AWARE,
+ Globals.XML_VALIDATION, new WebOrderingRuleSet());
+ }
+
+
+ /**
+ * Create (if necessary) and return a Digester configured to process web.xml
+ * absolute ordering.
+ */
+ protected static Digester createOrderingDigester() {
+ return DigesterFactory.newDigester(Globals.XML_NAMESPACE_AWARE,
+ Globals.XML_VALIDATION, new WebAbsoluteOrderingRuleSet());
+ }
+
+
+ /**
* Create (if necessary) and return a Digester configured to process the
* context configuration descriptor for an application.
*/
@@ -924,11 +956,12 @@
*/
protected void applicationExtraDescriptorsConfig() {
// FIXME: Read order from web.xml and fragments (note: if no fragments, skip)
+ Iterator<String> jarsWithWebFragments = scanner.getWebFragments();
// FIXME: Generate final web descriptor order
// FIXME: Add overlays
-
+ scanner.getOverlays();
}
@@ -1219,6 +1252,16 @@
tldDigester.getParser();
}
+ if (fragmentOrderingDigester == null){
+ fragmentOrderingDigester = createFragmentOrderingDigester();
+ fragmentOrderingDigester.getParser();
+ }
+
+ if (orderingDigester == null){
+ orderingDigester = createOrderingDigester();
+ orderingDigester.getParser();
+ }
+
if (contextDigester == null){
contextDigester = createContextDigester();
contextDigester.getParser();
Added: trunk/java/org/apache/catalina/startup/WebAbsoluteOrderingRuleSet.java
===================================================================
--- trunk/java/org/apache/catalina/startup/WebAbsoluteOrderingRuleSet.java (rev 0)
+++ trunk/java/org/apache/catalina/startup/WebAbsoluteOrderingRuleSet.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -0,0 +1,116 @@
+/*
+ * 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 org.apache.catalina.deploy.WebAbsoluteOrdering;
+import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.digester.Rule;
+import org.apache.tomcat.util.digester.RuleSetBase;
+import org.xml.sax.Attributes;
+
+
+/**
+ * <p><strong>RuleSet</strong> for processing the absolute-ordering element
+ * of web.xml.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 515 $ $Date: 2008-03-17 22:02:23 +0100 (Mon, 17 Mar 2008) $
+ */
+
+public class WebAbsoluteOrderingRuleSet extends RuleSetBase {
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The matching pattern prefix to use for recognizing our elements.
+ */
+ protected String prefix = null;
+
+
+ // ------------------------------------------------------------ Constructor
+
+
+ /**
+ * Construct an instance of this <code>RuleSet</code> with the default
+ * matching pattern prefix.
+ */
+ public WebAbsoluteOrderingRuleSet() {
+
+ this("");
+
+ }
+
+
+ /**
+ * Construct an instance of this <code>RuleSet</code> with the specified
+ * matching pattern prefix.
+ *
+ * @param prefix Prefix for matching pattern rules (including the
+ * trailing slash character)
+ */
+ public WebAbsoluteOrderingRuleSet(String prefix) {
+
+ super();
+ this.namespaceURI = null;
+ this.prefix = prefix;
+
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * <p>Add the set of Rule instances defined in this RuleSet to the
+ * specified <code>Digester</code> instance, associating them with
+ * our namespace URI (if any). This method should only be called
+ * by a Digester instance.</p>
+ *
+ * @param digester Digester instance to which the new Rule instances
+ * should be added.
+ */
+ public void addRuleInstances(Digester digester) {
+
+ digester.addObjectCreate(prefix + "web-app",
+ "org.apache.catalina.deploy.WebAbsoluteOrdering");
+ digester.addCallMethod(prefix + "web-app/name",
+ "setName", 0);
+ digester.addCallMethod(prefix + "web-app/absolute-ordering/name",
+ "addName", 0);
+ digester.addRule(prefix + "web-app/absolute-ordering/others",
+ new AddOthersRule());
+
+ }
+
+
+ final class AddOthersRule extends Rule {
+ public AddOthersRule() {
+ }
+
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ WebAbsoluteOrdering ordering = (WebAbsoluteOrdering) digester.peek();
+ ordering.addName("");
+ }
+
+ }
+}
Added: trunk/java/org/apache/catalina/startup/WebOrderingRuleSet.java
===================================================================
--- trunk/java/org/apache/catalina/startup/WebOrderingRuleSet.java (rev 0)
+++ trunk/java/org/apache/catalina/startup/WebOrderingRuleSet.java 2009-04-23 16:36:32 UTC (rev 1026)
@@ -0,0 +1,122 @@
+/*
+ * 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 org.apache.catalina.deploy.WebOrdering;
+import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.digester.Rule;
+import org.apache.tomcat.util.digester.RuleSetBase;
+import org.xml.sax.Attributes;
+
+
+/**
+ * <p><strong>RuleSet</strong> for processing the absolute-ordering element
+ * of web.xml.</p>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 515 $ $Date: 2008-03-17 22:02:23 +0100 (Mon, 17 Mar 2008) $
+ */
+
+public class WebOrderingRuleSet extends RuleSetBase {
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The matching pattern prefix to use for recognizing our elements.
+ */
+ protected String prefix = null;
+
+
+ // ------------------------------------------------------------ Constructor
+
+
+ /**
+ * Construct an instance of this <code>RuleSet</code> with the default
+ * matching pattern prefix.
+ */
+ public WebOrderingRuleSet() {
+
+ this("");
+
+ }
+
+
+ /**
+ * Construct an instance of this <code>RuleSet</code> with the specified
+ * matching pattern prefix.
+ *
+ * @param prefix Prefix for matching pattern rules (including the
+ * trailing slash character)
+ */
+ public WebOrderingRuleSet(String prefix) {
+
+ super();
+ this.namespaceURI = null;
+ this.prefix = prefix;
+
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * <p>Add the set of Rule instances defined in this RuleSet to the
+ * specified <code>Digester</code> instance, associating them with
+ * our namespace URI (if any). This method should only be called
+ * by a Digester instance.</p>
+ *
+ * @param digester Digester instance to which the new Rule instances
+ * should be added.
+ */
+ public void addRuleInstances(Digester digester) {
+
+ digester.addObjectCreate(prefix + "web-app",
+ "org.apache.catalina.deploy.WebOrdering");
+ digester.addCallMethod(prefix + "web-app/name",
+ "setName", 0);
+ digester.addCallMethod(prefix + "web-app/ordering/after/name",
+ "addAfter", 0);
+ digester.addCallMethod(prefix + "web-app/ordering/before/name",
+ "addBefore", 0);
+ digester.addRule(prefix + "web-app/ordering/after/others",
+ new AddOthersAfterRule());
+ digester.addRule(prefix + "web-app/ordering/before/name",
+ new AddOthersBeforeRule());
+
+ }
+
+ final class AddOthersAfterRule extends Rule {
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ WebOrdering ordering = (WebOrdering) digester.peek();
+ ordering.addAfter("");
+ }
+ }
+ final class AddOthersBeforeRule extends Rule {
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ WebOrdering ordering = (WebOrdering) digester.peek();
+ ordering.addBefore("");
+ }
+ }
+}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2009-04-22 17:47:49 UTC (rev 1025)
+++ trunk/webapps/docs/changelog.xml 2009-04-23 16:36:32 UTC (rev 1026)
@@ -108,7 +108,7 @@
</subsection>
</section>
-<section name="JBoss Web 2.1.3.CR1 (remm)">
+<section name="JBoss Web 2.1.3.GA (remm)">
<subsection name="General">
<changelog>
</changelog>
16 years, 6 months
JBossWeb SVN: r1025 - in trunk/java: javax/servlet/http and 6 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-22 13:47:49 -0400 (Wed, 22 Apr 2009)
New Revision: 1025
Added:
trunk/java/org/apache/catalina/deploy/Multipart.java
Modified:
trunk/java/javax/servlet/annotation/WebListener.java
trunk/java/javax/servlet/http/HttpServletRequest.java
trunk/java/javax/servlet/http/HttpServletRequestWrapper.java
trunk/java/javax/servlet/http/Part.java
trunk/java/org/apache/catalina/Authenticator.java
trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/connector/RequestFacade.java
trunk/java/org/apache/catalina/core/DummyRequest.java
trunk/java/org/apache/catalina/startup/BaseContextScanner.java
trunk/java/org/apache/catalina/startup/ContextConfig.java
Log:
- Update API and minor cleanups.
Modified: trunk/java/javax/servlet/annotation/WebListener.java
===================================================================
--- trunk/java/javax/servlet/annotation/WebListener.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/javax/servlet/annotation/WebListener.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -44,7 +44,7 @@
/**
* This annotation is used to declare a WebListener
*
- *@since Servlet 3.0
+ * @since Servlet 3.0
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
Modified: trunk/java/javax/servlet/http/HttpServletRequest.java
===================================================================
--- trunk/java/javax/servlet/http/HttpServletRequest.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/javax/servlet/http/HttpServletRequest.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -738,7 +738,7 @@
* HTTP status code to be returned
* to the user).
*/
- public boolean login(HttpServletResponse response)
+ public boolean authenticate(HttpServletResponse response)
throws IOException,ServletException;
Modified: trunk/java/javax/servlet/http/HttpServletRequestWrapper.java
===================================================================
--- trunk/java/javax/servlet/http/HttpServletRequestWrapper.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/javax/servlet/http/HttpServletRequestWrapper.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -301,12 +301,12 @@
/**
- * The default behavior of this method is to call login on the wrapped
- * request object.
+ * The default behavior of this method is to call authenticate on the
+ * wrapped request object.
*/
- public boolean login(HttpServletResponse response)
+ public boolean authenticate(HttpServletResponse response)
throws IOException, ServletException {
- return this._getHttpServletRequest().login(response);
+ return this._getHttpServletRequest().authenticate(response);
}
Modified: trunk/java/javax/servlet/http/Part.java
===================================================================
--- trunk/java/javax/servlet/http/Part.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/javax/servlet/http/Part.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -44,6 +44,7 @@
* <p> This class represents a part or form item that was received within a
* <code>multipart/form-data</code> POST request.
*
+ * @since Servlet 3.0
*/
public interface Part {
Modified: trunk/java/org/apache/catalina/Authenticator.java
===================================================================
--- trunk/java/org/apache/catalina/Authenticator.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/Authenticator.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -35,6 +35,6 @@
*/
public interface Authenticator {
- public boolean login(Request request, HttpServletResponse response)
+ public boolean authenticate(Request request, HttpServletResponse response)
throws IOException, ServletException;
}
Modified: trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java
===================================================================
--- trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -379,7 +379,7 @@
*
* @exception IOException if an input/output error occurs
*/
- public boolean login(Request request, HttpServletResponse response)
+ public boolean authenticate(Request request, HttpServletResponse response)
throws IOException, ServletException {
return authenticate(request, response, this.context.getLoginConfig());
}
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -2994,10 +2994,10 @@
return asyncContext;
}
- public boolean login(HttpServletResponse response) throws IOException,
+ public boolean authenticate(HttpServletResponse response) throws IOException,
ServletException {
if (context.getAuthenticator() != null) {
- return context.getAuthenticator().login(this, response);
+ return context.getAuthenticator().authenticate(this, response);
} else {
throw new ServletException(sm.getString("coyoteRequest.noAuthenticator"));
}
Modified: trunk/java/org/apache/catalina/connector/RequestFacade.java
===================================================================
--- trunk/java/org/apache/catalina/connector/RequestFacade.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/connector/RequestFacade.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -1091,14 +1091,14 @@
}
- public boolean login(HttpServletResponse response) throws IOException,
+ public boolean authenticate(HttpServletResponse response) throws IOException,
ServletException {
if (request == null) {
throw new IllegalStateException(
sm.getString("requestFacade.nullRequest"));
}
- return request.login(response);
+ return request.authenticate(response);
}
Modified: trunk/java/org/apache/catalina/core/DummyRequest.java
===================================================================
--- trunk/java/org/apache/catalina/core/DummyRequest.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/core/DummyRequest.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -285,7 +285,7 @@
ServletResponse servletResponse) throws IllegalStateException { return null; }
public DispatcherType getDispatcherType() { return null; }
public ServletResponse getServletResponse() { return null; }
- public boolean login(HttpServletResponse response) throws IOException,
+ public boolean authenticate(HttpServletResponse response) throws IOException,
ServletException { return false; }
public void login(String username, String password) throws ServletException {}
public void logout() throws ServletException {}
Added: trunk/java/org/apache/catalina/deploy/Multipart.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/Multipart.java (rev 0)
+++ trunk/java/org/apache/catalina/deploy/Multipart.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -0,0 +1,58 @@
+/*
+ * 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.deploy;
+
+import java.io.Serializable;
+
+public class Multipart implements Serializable {
+
+ protected String location = null;
+ protected long maxFileSize = 0;
+ protected long maxRequestSize = 0;
+ protected int fileSizeThreshold = 0;
+
+ public String getLocation() {
+ return location;
+ }
+ public void setLocation(String location) {
+ this.location = location;
+ }
+ public long getMaxFileSize() {
+ return maxFileSize;
+ }
+ public void setMaxFileSize(long maxFileSize) {
+ this.maxFileSize = maxFileSize;
+ }
+ public long getMaxRequestSize() {
+ return maxRequestSize;
+ }
+ public void setMaxRequestSize(long maxRequestSize) {
+ this.maxRequestSize = maxRequestSize;
+ }
+ public int getFileSizeThreshold() {
+ return fileSizeThreshold;
+ }
+ public void setFileSizeThreshold(int fileSizeThreshold) {
+ this.fileSizeThreshold = fileSizeThreshold;
+ }
+}
Modified: trunk/java/org/apache/catalina/startup/BaseContextScanner.java
===================================================================
--- trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -251,9 +251,9 @@
String rootPath,
HashSet<String> tldPaths) {
try {
- NamingEnumeration items = resources.list(rootPath);
+ NamingEnumeration<NameClassPair> items = resources.list(rootPath);
while (items.hasMoreElements()) {
- NameClassPair item = (NameClassPair) items.nextElement();
+ NameClassPair item = items.nextElement();
String resourcePath = rootPath + "/" + item.getName();
if (!resourcePath.endsWith(".tld")
&& (resourcePath.startsWith("/WEB-INF/classes")
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-22 16:31:48 UTC (rev 1024)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-22 17:47:49 UTC (rev 1025)
@@ -53,18 +53,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.util.Enumeration;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebFilter;
16 years, 6 months
JBossWeb SVN: r1024 - branches/2.1.x/webapps/docs and 2 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-22 12:31:48 -0400 (Wed, 22 Apr 2009)
New Revision: 1024
Modified:
branches/2.1.x/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
branches/2.1.x/webapps/docs/changelog.xml
trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
trunk/webapps/docs/changelog.xml
Log:
- JBAS-6814: Fixes caused by the event changes for non blocking.
- end(), which will read until the end chunk, cannot get 0 as a doRead result, since there's no non blocking at that point
(not really useful given the other change, but it is the correct check).
- parseChunkHeader should return false when doRead returns 0 (only possible in non blocking mode),
but an exception if negative.
Modified: branches/2.1.x/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
===================================================================
--- branches/2.1.x/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2009-04-22 14:31:47 UTC (rev 1023)
+++ branches/2.1.x/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2009-04-22 16:31:48 UTC (rev 1024)
@@ -19,13 +19,12 @@
import java.io.IOException;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.HexUtils;
-
import org.apache.coyote.InputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.http11.Constants;
import org.apache.coyote.http11.InputFilter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.HexUtils;
/**
* Chunked input filter. Parses chunked data according to
@@ -188,7 +187,7 @@
throws IOException {
// Consume extra bytes : parse the stream until the end chunk is found
- while (doRead(readChunk, null) >= 0) {
+ while (doRead(readChunk, null) > 0) {
}
// Return the number of extra bytes which were consumed
@@ -274,8 +273,12 @@
if (pos >= lastValid) {
// In non blocking mode, no new chunk follows, even if data was present
- if (readBytes() <= 0)
+ int n = readBytes();
+ if (n < 0) {
+ throw new IOException("Invalid chunk header");
+ } else if (n == 0) {
return false;
+ }
}
if (buf[pos] == Constants.CR) {
Modified: branches/2.1.x/webapps/docs/changelog.xml
===================================================================
--- branches/2.1.x/webapps/docs/changelog.xml 2009-04-22 14:31:47 UTC (rev 1023)
+++ branches/2.1.x/webapps/docs/changelog.xml 2009-04-22 16:31:48 UTC (rev 1024)
@@ -36,6 +36,9 @@
<fix>
Remove useless instanceof in the HTTP protocol. (markt)
</fix>
+ <fix>
+ <jboss-jira>JBAS-6814</jboss-jira>: Fix looping when parsing bad end chunk, caused by the non blocking changes. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
Modified: trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
===================================================================
--- trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2009-04-22 14:31:47 UTC (rev 1023)
+++ trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2009-04-22 16:31:48 UTC (rev 1024)
@@ -19,13 +19,12 @@
import java.io.IOException;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.HexUtils;
-
import org.apache.coyote.InputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.http11.Constants;
import org.apache.coyote.http11.InputFilter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.buf.HexUtils;
/**
* Chunked input filter. Parses chunked data according to
@@ -188,7 +187,7 @@
throws IOException {
// Consume extra bytes : parse the stream until the end chunk is found
- while (doRead(readChunk, null) >= 0) {
+ while (doRead(readChunk, null) > 0) {
}
// Return the number of extra bytes which were consumed
@@ -274,8 +273,12 @@
if (pos >= lastValid) {
// In non blocking mode, no new chunk follows, even if data was present
- if (readBytes() <= 0)
+ int n = readBytes();
+ if (n < 0) {
+ throw new IOException("Invalid chunk header");
+ } else if (n == 0) {
return false;
+ }
}
if (buf[pos] == Constants.CR) {
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2009-04-22 14:31:47 UTC (rev 1023)
+++ trunk/webapps/docs/changelog.xml 2009-04-22 16:31:48 UTC (rev 1024)
@@ -125,6 +125,12 @@
</subsection>
<subsection name="Coyote">
<changelog>
+ <fix>
+ Remove useless instanceof in the HTTP protocol. (markt)
+ </fix>
+ <fix>
+ <jboss-jira>JBAS-6814</jboss-jira>: Fix looping when parsing bad end chunk, caused by the non blocking changes. (remm)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
16 years, 6 months
JBossWeb SVN: r1023 - trunk/java/org/apache/catalina/startup.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-22 10:31:47 -0400 (Wed, 22 Apr 2009)
New Revision: 1023
Modified:
trunk/java/org/apache/catalina/startup/ContextConfig.java
Log:
- Fix order.
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-21 18:15:22 UTC (rev 1022)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-22 14:31:47 UTC (rev 1023)
@@ -1265,10 +1265,10 @@
// Process the default and application web.xml files
defaultWebConfig();
- applicationWebConfig();
scanner.scan(context);
// FIXME: look where to place it according to the merging rules
applicationExtraDescriptorsConfig();
+ applicationWebConfig();
if (!context.getIgnoreAnnotations()) {
applicationAnnotationsConfig();
}
16 years, 6 months
JBossWeb SVN: r1022 - in trunk/java/org/apache: catalina/core and 4 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-21 14:15:22 -0400 (Tue, 21 Apr 2009)
New Revision: 1022
Modified:
trunk/java/org/apache/catalina/Host.java
trunk/java/org/apache/catalina/core/StandardHost.java
trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java
trunk/java/org/apache/catalina/mbeans/MBeanFactory.java
trunk/java/org/apache/catalina/startup/BaseContextScanner.java
trunk/java/org/apache/catalina/startup/ContextConfig.java
trunk/java/org/apache/catalina/startup/HostConfig.java
trunk/java/org/apache/catalina/startup/WarScanner.java
trunk/java/org/apache/tomcat/WarComponents.java
Log:
- Remove XML properties from the host as well.
- Refactor TLD parsing.
Modified: trunk/java/org/apache/catalina/Host.java
===================================================================
--- trunk/java/org/apache/catalina/Host.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/Host.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -149,38 +149,6 @@
public void setName(String name);
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- *
- */
- public boolean getXmlNamespaceAware();
-
-
- /**
- * Get the server.xml <host> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getXmlValidation();
-
-
- /**
- * 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);
-
-
// --------------------------------------------------------- Public Methods
Modified: trunk/java/org/apache/catalina/core/StandardHost.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardHost.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/core/StandardHost.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -150,18 +150,6 @@
private String workDir = null;
- /**
- * Attribute value used to turn on/off XML validation
- */
- private boolean xmlValidation = false;
-
-
- /**
- * Attribute value used to turn on/off XML namespace awarenes.
- */
- private boolean xmlNamespaceAware = false;
-
-
// ------------------------------------------------------------- Properties
@@ -421,46 +409,7 @@
}
- /**
- * 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){
-
- this.xmlValidation = xmlValidation;
-
- }
-
/**
- * Get the server.xml <host> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getXmlValidation(){
- return xmlValidation;
- }
-
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- *
- */
- public boolean getXmlNamespaceAware(){
- return xmlNamespaceAware;
- }
-
-
- /**
- * 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){
- this.xmlNamespaceAware=xmlNamespaceAware;
- }
-
- /**
* Host work directory base.
*/
public String getWorkDir() {
@@ -705,12 +654,7 @@
errorReportValveClass), t);
}
}
- if(log.isDebugEnabled()) {
- if (xmlValidation)
- log.debug(sm.getString("standardHost.validationEnabled"));
- else
- log.debug(sm.getString("standardHost.validationDisabled"));
- }
+
super.start();
}
Modified: trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java
===================================================================
--- trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -455,8 +455,6 @@
host.setDeployOnStartup(deployOnStartup);
host.setDeployXML(deployXML);
host.setUnpackWARs(unpackWARs);
- host.setXmlNamespaceAware(xmlNamespaceAware);
- host.setXmlValidation(xmlValidation);
// Add new host
try {
Modified: trunk/java/org/apache/catalina/mbeans/MBeanFactory.java
===================================================================
--- trunk/java/org/apache/catalina/mbeans/MBeanFactory.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/mbeans/MBeanFactory.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -720,8 +720,6 @@
host.setDeployOnStartup(deployOnStartup);
host.setDeployXML(deployXML);
host.setUnpackWARs(unpackWARs);
- host.setXmlNamespaceAware(xmlNamespaceAware);
- host.setXmlValidation(xmlValidation);
// add HostConfig for active reloading
HostConfig hostConfig = new HostConfig();
Modified: trunk/java/org/apache/catalina/startup/BaseContextScanner.java
===================================================================
--- trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/startup/BaseContextScanner.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -32,8 +32,8 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -108,7 +108,7 @@
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>>();
+ protected Map<String, Set<String>> TLDs = new HashMap<String, Set<String>>();
public Iterator<Class<?>> getAnnotatedClasses() {
@@ -126,7 +126,7 @@
}
- public Map<String, List<String>> getTLDs() {
+ public Map<String, Set<String>> getTLDs() {
return TLDs;
}
@@ -199,26 +199,14 @@
loader = loader.getParent();
}
- ArrayList<String> warTLDs = new ArrayList<String>();
+ HashSet<String> warTLDs = new HashSet<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);
- }
+ TLDs.put("", warTLDs);
/*
DirContext resources = context.getResources();
@@ -261,7 +249,7 @@
*/
protected void tldScanResourcePathsWebInf(DirContext resources,
String rootPath,
- ArrayList<String> tldPaths) {
+ HashSet<String> tldPaths) {
try {
NamingEnumeration items = resources.list(rootPath);
while (items.hasMoreElements()) {
@@ -386,7 +374,7 @@
if (file.getEntry(Globals.OVERLAY_PATH) != null) {
overlays.add(file.getName());
}
- ArrayList<String> jarTLDs = new ArrayList<String>();
+ HashSet<String> jarTLDs = new HashSet<String>();
Enumeration<JarEntry> entries = file.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -53,12 +53,18 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import java.util.Enumeration;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebFilter;
@@ -185,6 +191,13 @@
/**
+ * The <code>Digester</code> we will use to process tag library
+ * descriptor files.
+ */
+ protected static Digester tldDigester = null;
+
+
+ /**
* The <code>Rule</code> used to parse the web.xml
*/
protected static WebRuleSet webRuleSet = new WebRuleSet();
@@ -417,6 +430,9 @@
*/
protected void applicationWebConfig() {
+ // FIXME: Parse web fragments here
+ // FIXME: Parse according to the configured order
+
String altDDName = null;
// Open the application web.xml file, if it exists
@@ -489,6 +505,7 @@
ok = false;
} finally {
webDigester.reset();
+ webRuleSet.recycle();
parseException = null;
try {
if (stream != null) {
@@ -499,15 +516,105 @@
}
}
}
- webRuleSet.recycle();
+ // Add all TLDs from explicit web config
+ Map<String, Set<String>> TLDs = scanner.getTLDs();
+ Set<String> warTLDs = TLDs.get("");
+ 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);
+ }
+
+ // Parse all TLDs from the WAR
+ Iterator<String> warTLDsIterator = warTLDs.iterator();
+ while (warTLDsIterator.hasNext()) {
+ String tldPath = warTLDsIterator.next();
+ try {
+ stream = context.getServletContext().getResourceAsStream(tldPath);
+ if (stream == null) {
+ log.error(sm.getString("contextConfig.tldResourcePath", tldPath));
+ ok = false;
+ } else {
+ synchronized (tldDigester) {
+ try {
+ tldDigester.push(context);
+ tldDigester.parse(new InputSource(stream));
+ } finally {
+ tldDigester.reset();
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error(sm.getString("contextConfig.tldFileException", tldPath,
+ context.getPath()), e);
+ ok = false;
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+
+ }
+
+ // Parse all TLDs from JARs
+ Iterator<String> jarPaths = TLDs.keySet().iterator();
+ while (jarPaths.hasNext()) {
+ String jarPath = jarPaths.next();
+ if (jarPath.equals("")) {
+ continue;
+ }
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(jarPath);
+ Iterator<String> jarTLDsIterator = TLDs.get(jarPath).iterator();
+ while (jarTLDsIterator.hasNext()) {
+ stream = jarFile.getInputStream(jarFile.getEntry(jarTLDsIterator.next()));
+ synchronized (tldDigester) {
+ try {
+ tldDigester.push(context);
+ tldDigester.parse(new InputSource(stream));
+ } finally {
+ tldDigester.reset();
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error(sm.getString("contextConfig.tldJarException",
+ jarPath, context.getPath()), e);
+ ok = false;
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ }
+ }
+ }
+
long t2=System.currentTimeMillis();
if (context instanceof StandardContext) {
((StandardContext) context).setStartupTime(t2-t1);
}
}
+
-
/**
* Set up an Authenticator automatically if required, and one has not
* already been configured.
@@ -629,25 +736,24 @@
* web application deployment descriptor (web.xml).
*/
protected static Digester createWebDigester() {
- return createWebXmlDigester(Globals.XML_NAMESPACE_AWARE, Globals.XML_VALIDATION);
+ return DigesterFactory.newDigester(Globals.XML_NAMESPACE_AWARE, Globals.XML_VALIDATION, webRuleSet);
}
/**
- * Create (if necessary) and return a Digester configured to process the
- * web application deployment descriptor (web.xml).
+ * Create (if necessary) and return a Digester configured to process tag
+ * library descriptors.
*/
- public static Digester createWebXmlDigester(boolean namespaceAware,
- boolean validation) {
- return DigesterFactory.newDigester(validation, namespaceAware, webRuleSet);
+ protected static Digester createTldDigester() {
+ return DigesterFactory.newDigester(Globals.XML_NAMESPACE_AWARE, Globals.XML_VALIDATION, new TldRuleSet());
}
-
+
/**
* Create (if necessary) and return a Digester configured to process the
* context configuration descriptor for an application.
*/
- protected Digester createContextDigester() {
+ protected static Digester createContextDigester() {
Digester digester = new Digester();
digester.setValidating(false);
RuleSet contextRuleSet = new ContextRuleSet("", false);
@@ -820,36 +926,13 @@
/**
* Process additional descriptors: TLDs, web fragments, and map overlays.
*/
- // FIXME: Processing of web fragments
- // FIXME: Map overlays
protected void applicationExtraDescriptorsConfig() {
- WarScanner tldConfig = new WarScanner();
- tldConfig.setContext(context);
+ // FIXME: Read order from web.xml and fragments (note: if no fragments, skip)
- /*
- // (1) check if the attribute has been defined
- // on the context element.
- tldConfig.setTldValidation(context.getTldValidation());
- tldConfig.setTldNamespaceAware(context.getTldNamespaceAware());
-
- // (2) if the attribute wasn't defined on the context
- // try the host.
- if (!context.getTldValidation()) {
- tldConfig.setTldValidation
- (((StandardHost) context.getParent()).getXmlValidation());
- }
-
- if (!context.getTldNamespaceAware()) {
- tldConfig.setTldNamespaceAware
- (((StandardHost) context.getParent()).getXmlNamespaceAware());
- }*/
-
- try {
- tldConfig.execute();
- } catch (Exception ex) {
- log.error("Error reading tld listeners "
- + ex.toString(), ex);
- }
+ // FIXME: Generate final web descriptor order
+
+ // FIXME: Add overlays
+
}
@@ -1135,6 +1218,11 @@
webDigester.getParser();
}
+ if (tldDigester == null){
+ tldDigester = createTldDigester();
+ tldDigester.getParser();
+ }
+
if (contextDigester == null){
contextDigester = createContextDigester();
contextDigester.getParser();
@@ -1173,14 +1261,14 @@
if (log.isDebugEnabled())
log.debug(sm.getString("contextConfig.start"));
- ContextScanner scanner = new ClassLoadingContextScanner();
+ scanner = new ClassLoadingContextScanner();
// Process the default and application web.xml files
defaultWebConfig();
+ applicationWebConfig();
+ scanner.scan(context);
// FIXME: look where to place it according to the merging rules
applicationExtraDescriptorsConfig();
- applicationWebConfig();
- scanner.scan(context);
if (!context.getIgnoreAnnotations()) {
applicationAnnotationsConfig();
}
Modified: trunk/java/org/apache/catalina/startup/HostConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/HostConfig.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/startup/HostConfig.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -137,18 +137,6 @@
/**
- * Attribute value used to turn on/off XML validation
- */
- protected boolean xmlValidation = false;
-
-
- /**
- * Attribute value used to turn on/off XML namespace awarenes.
- */
- protected boolean xmlNamespaceAware = false;
-
-
- /**
* The <code>Digester</code> instance used to parse context descriptors.
*/
protected static Digester digester = createDigester();
@@ -245,44 +233,6 @@
}
- /**
- * 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){
- this.xmlValidation = xmlValidation;
- }
-
- /**
- * Get the server.xml <host> attribute's xmlValidation.
- * @return true if validation is enabled.
- *
- */
- public boolean getXmlValidation(){
- return xmlValidation;
- }
-
- /**
- * Get the server.xml <host> attribute's xmlNamespaceAware.
- * @return true if namespace awarenes is enabled.
- *
- */
- public boolean getXmlNamespaceAware(){
- return xmlNamespaceAware;
- }
-
-
- /**
- * 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){
- this.xmlNamespaceAware=xmlNamespaceAware;
- }
-
-
// --------------------------------------------------------- Public Methods
@@ -302,8 +252,6 @@
if (host instanceof StandardHost) {
setDeployXML(((StandardHost) host).isDeployXML());
setUnpackWARs(((StandardHost) host).isUnpackWARs());
- setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware());
- setXmlValidation(((StandardHost) host).getXmlValidation());
}
} catch (ClassCastException e) {
log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
Modified: trunk/java/org/apache/catalina/startup/WarScanner.java
===================================================================
--- trunk/java/org/apache/catalina/startup/WarScanner.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/catalina/startup/WarScanner.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -86,6 +86,7 @@
* @author Jean-Francois Arcand
* @author Costin Manolache
* @author Remy Maucherat
+ * @deprecated No longer used
*/
public final class WarScanner {
Modified: trunk/java/org/apache/tomcat/WarComponents.java
===================================================================
--- trunk/java/org/apache/tomcat/WarComponents.java 2009-04-21 03:39:25 UTC (rev 1021)
+++ trunk/java/org/apache/tomcat/WarComponents.java 2009-04-21 18:15:22 UTC (rev 1022)
@@ -24,8 +24,8 @@
package org.apache.tomcat;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
+import java.util.Set;
public interface WarComponents {
@@ -50,6 +50,6 @@
/**
* Find TLDs.
*/
- public Map<String, List<String>> getTLDs();
+ public Map<String, Set<String>> getTLDs();
}
16 years, 6 months
JBossWeb SVN: r1021 - in trunk: java/org/apache/catalina and 6 other directories.
by jbossweb-commits@lists.jboss.org
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">
16 years, 6 months
JBossWeb SVN: r1020 - in trunk: java/org/apache/catalina and 5 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2009-04-20 11:51:08 -0400 (Mon, 20 Apr 2009)
New Revision: 1020
Modified:
trunk/ROADMAP.txt
trunk/java/org/apache/catalina/Wrapper.java
trunk/java/org/apache/catalina/connector/Request.java
trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java
trunk/java/org/apache/catalina/core/StandardWrapper.java
trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
trunk/java/org/apache/catalina/core/StandardWrapperValve.java
trunk/java/org/apache/catalina/deploy/FilterDef.java
trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java
trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
Log:
- Add the new features to roadmap (ordering and many new annotations: ouch ...).
- Fix return types.
- Fix some issues with fileupload: getName renaming due to conflict with Part.getName :(
Modified: trunk/ROADMAP.txt
===================================================================
--- trunk/ROADMAP.txt 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/ROADMAP.txt 2009-04-20 15:51:08 UTC (rev 1020)
@@ -2,10 +2,11 @@
Main development:
- Update digester XML parsing rules for web.xml updates
-- web.xml fragments scanning (merge with Catalina .tld scanning)
+- web.xml fragments scanning and merging rules
+- web.xml fragments ordering
- Resources overlay
- Session tracking configuration
-- Multipart support (and remove fileupload)
+- Access control annotations
- JSP 2.2 changes
- EL 1.1 changes
- Setup standalone TCK environment for testing compliance with the new features
Modified: trunk/java/org/apache/catalina/Wrapper.java
===================================================================
--- trunk/java/org/apache/catalina/Wrapper.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/Wrapper.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -23,6 +23,7 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.UnavailableException;
+import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.util.InstanceSupport;
@@ -153,8 +154,20 @@
*/
public void setLoadOnStartup(int value);
+
+ /**
+ * Multipart configuration for this Servlet.
+ */
+ public MultipartConfig getMultipartConfig();
+
/**
+ * Set the multipart configuration for this Servlet.
+ */
+ public void setMultipartConfig(MultipartConfig multipartConfig);
+
+
+ /**
* Return the run-as identity for this servlet.
*/
public String getRunAs();
Modified: trunk/java/org/apache/catalina/connector/Request.java
===================================================================
--- trunk/java/org/apache/catalina/connector/Request.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/connector/Request.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -58,7 +58,6 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
@@ -77,6 +76,7 @@
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletResponse;
+import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -2660,8 +2660,13 @@
} else {
contentType = contentType.trim();
}
- if (!("application/x-www-form-urlencoded".equals(contentType)))
+ if (!("application/x-www-form-urlencoded".equals(contentType))) {
+ // Check for multipart as an alternate way to send parameters
+ if (parts == null) {
+ parseMultipart();
+ }
return;
+ }
int len = getContentLength();
@@ -2704,21 +2709,49 @@
*/
protected void parseMultipart() {
- // FIXME: Stub configuration from the example
+ MultipartConfig config = wrapper.getMultipartConfig();
+ if (config == null) {
+ return;
+ }
+
+ if (usingInputStream || usingReader)
+ return;
+
+ if (!getMethod().equalsIgnoreCase("POST"))
+ return;
+
+ String contentType = getContentType();
+ if (contentType == null)
+ contentType = "";
+ int semicolon = contentType.indexOf(';');
+ if (semicolon >= 0) {
+ contentType = contentType.substring(0, semicolon).trim();
+ } else {
+ contentType = contentType.trim();
+ }
+ if (!("multipart/form-data".equals(contentType)))
+ return;
+
DiskFileUpload fu = new DiskFileUpload();
- // maximum size before a FileUploadException will be thrown
- fu.setSizeMax(1000000);
- // maximum size that will be stored in memory
- fu.setSizeThreshold(4096);
- // the location for saving data that is larger than getSizeThreshold()
- fu.setRepositoryPath("/tmp");
+ // FIXME: set default values
+ fu.setRepositoryPath(config.location());
+ if (config.fileSizeThreshold() > 0) {
+ fu.setSizeThreshold(config.fileSizeThreshold());
+ }
+ if (config.maxRequestSize() > 0) {
+ fu.setSizeMax(config.maxRequestSize());
+ }
+ // FIXME: Unimplemented per file max size: fu.setSizeFileMax(config.maxFileSize());
parts = new HashMap<String, Part>();
try {
Iterator<FileItem> items = fu.parseRequest(getRequest()).iterator();
while (items.hasNext()) {
FileItem fileItem = items.next();
- parts.put(fileItem.getName(), fileItem);
+ if (fileItem.getFileName() == null) {
+ coyoteRequest.getParameters().addParameterValues(fileItem.getName(), new String[] {fileItem.getString()});
+ }
+ parts.put(fileItem.getFieldName(), fileItem);
}
} catch (IOException e) {
// Client disconnect
@@ -2953,19 +2986,12 @@
}
setTimeout(timeout);
if (asyncContext == null) {
- asyncContext = new AsyncContextImpl
- ((servletRequest == null) ? getRequest() : servletRequest,
- (servletResponse == null) ? response.getResponse() : servletResponse);
+ asyncContext = new AsyncContextImpl();
eventMode = true;
} else {
- if (servletRequest != null) {
- asyncContext.setRequest(servletRequest);
- }
- if (servletResponse != null) {
- asyncContext.setResponse(servletResponse);
- }
asyncContext.reset();
}
+ asyncContext.setRequestAndResponse(servletRequest, servletResponse);
return asyncContext;
}
@@ -3090,13 +3116,9 @@
protected String path = null;
protected Runnable runnable = null;
protected boolean useAttributes = false;
+ protected boolean original = true;
protected boolean ready = true;
- public AsyncContextImpl(ServletRequest request, ServletResponse response) {
- this.request = request;
- this.response = response;
- }
-
public void complete() {
setEventMode(false);
resume();
@@ -3131,11 +3153,19 @@
}
public ServletRequest getRequest() {
- return request;
+ if (request != null) {
+ return request;
+ } else {
+ return getRequestFacade();
+ }
}
public ServletResponse getResponse() {
- return response;
+ if (response != null) {
+ return response;
+ } else {
+ return getResponseFacade();
+ }
}
public boolean hasOriginalRequestAndResponse() {
@@ -3151,11 +3181,15 @@
return ready;
}
- public void setRequest(ServletRequest request) {
- this.request = request;
+ public void done() {
+ ready = false;
}
- public void setResponse(ServletResponse response) {
+ public void setRequestAndResponse(ServletRequest request, ServletResponse response) {
+ if (request == null && response == null) {
+
+ }
+ this.request = request;
this.response = response;
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterConfig.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -53,8 +53,10 @@
import java.util.EnumSet;
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 javax.naming.NamingException;
import javax.servlet.DispatcherType;
@@ -304,19 +306,28 @@
public boolean setInitParameter(String name, String value) {
+ if (filterDef.getInitParameter(name) != null) {
+ return false;
+ }
filterDef.addInitParameter(name, value);
context.addFilterDef(filterDef);
return true;
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters) {
+ Set<String> conflicts = new HashSet<String>();
Iterator<String> parameterNames = initParameters.keySet().iterator();
while (parameterNames.hasNext()) {
String parameterName = parameterNames.next();
- filterDef.addInitParameter(parameterName, initParameters.get(parameterName));
+ if (filterDef.getInitParameter(parameterName) != null) {
+ conflicts.add(parameterName);
+ } else {
+ filterDef.addInitParameter(parameterName, initParameters.get(parameterName));
+ }
}
- return true;
+ context.addFilterDef(filterDef);
+ return conflicts;
}
Modified: trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/ApplicationFilterConfigFacade.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -53,6 +53,7 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.naming.NamingException;
import javax.servlet.DispatcherType;
@@ -160,17 +161,17 @@
}
- public boolean addMappingForServletNames(
+ public void addMappingForServletNames(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... servletNames) {
- return config.addMappingForServletNames(dispatcherTypes, isMatchAfter, servletNames);
+ config.addMappingForServletNames(dispatcherTypes, isMatchAfter, servletNames);
}
- public boolean addMappingForUrlPatterns(
+ public void addMappingForUrlPatterns(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... urlPatterns) {
- return config.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns);
+ config.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns);
}
@@ -179,7 +180,7 @@
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters) {
return config.setInitParameters(initParameters);
}
Modified: trunk/java/org/apache/catalina/core/StandardWrapper.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapper.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapper.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -43,6 +43,7 @@
import javax.servlet.ServletResponse;
import javax.servlet.SingleThreadModel;
import javax.servlet.UnavailableException;
+import javax.servlet.annotation.MultipartConfig;
import org.apache.catalina.Container;
import org.apache.catalina.ContainerServlet;
@@ -181,6 +182,12 @@
/**
+ * The multipart config annotation configured on this servlet.
+ */
+ protected MultipartConfig multipartConfig = null;
+
+
+ /**
* Mappings associated with the wrapper.
*/
protected ArrayList mappings = new ArrayList();
@@ -509,6 +516,22 @@
/**
+ * Multipart configuration for this Servlet.
+ */
+ public MultipartConfig getMultipartConfig() {
+ return multipartConfig;
+ }
+
+
+ /**
+ * Set the multipart configuration for this Servlet.
+ */
+ public void setMultipartConfig(MultipartConfig multipartConfig) {
+ this.multipartConfig = multipartConfig;
+ }
+
+
+ /**
* Return maximum number of instances that will be allocated when a single
* thread model servlet is used.
*/
Modified: trunk/java/org/apache/catalina/core/StandardWrapperFacade.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapperFacade.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -48,8 +48,10 @@
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -144,17 +146,22 @@
}
- public boolean addMapping(String... urlPatterns) {
+ public Set<String> addMapping(String... urlPatterns) {
+ Set<String> conflicts = new HashSet<String>();
if (((Context) wrapper.getParent()).isInitialized()) {
throw new IllegalStateException(sm.getString
("servletRegistration.addServletMapping.ise", ((Context) wrapper.getParent()).getPath()));
}
if (urlPatterns != null) {
for (int i = 0; i < urlPatterns.length; i++) {
- ((Context) wrapper.getParent()).addServletMapping(urlPatterns[i], wrapper.getName());
+ if (((Context) wrapper.getParent()).findServletMapping(urlPatterns[i]) != null) {
+ conflicts.add(urlPatterns[i]);
+ } else {
+ ((Context) wrapper.getParent()).addServletMapping(urlPatterns[i], wrapper.getName());
+ }
}
}
- return true;
+ return conflicts;
}
@@ -174,13 +181,18 @@
}
- public boolean setInitParameters(Map<String, String> initParameters) {
+ public Set<String> setInitParameters(Map<String, String> initParameters) {
+ Set<String> conflicts = new HashSet<String>();
Iterator<String> parameterNames = initParameters.keySet().iterator();
while (parameterNames.hasNext()) {
String parameterName = parameterNames.next();
- wrapper.addInitParameter(parameterName, initParameters.get(parameterName));
+ if (wrapper.findInitParameter(parameterName) != null) {
+ conflicts.add(parameterName);
+ } else {
+ wrapper.addInitParameter(parameterName, initParameters.get(parameterName));
+ }
}
- return true;
+ return conflicts;
}
Modified: trunk/java/org/apache/catalina/core/StandardWrapperValve.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/core/StandardWrapperValve.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -407,6 +407,9 @@
// Invoke the listeners with onComplete or onTimeout
boolean timeout = (event.getType() == EventType.TIMEOUT) ? true : false;
Iterator<AsyncEvent> asyncEvents = asyncContext.getAsyncListeners().keySet().iterator();
+ if (timeout && !asyncEvents.hasNext()) {
+ // FIXME: MUST do an ERROR dispatch to the original URI and MUST set the response code to 500
+ }
while (asyncEvents.hasNext()) {
AsyncEvent asyncEvent = asyncEvents.next();
AsyncListener asyncListener = asyncContext.getAsyncListeners().get(asyncEvent);
@@ -432,6 +435,8 @@
exception(request, response, e);
}
} else if (asyncContext.getPath() != null) {
+ // We executed the dispatch
+ asyncContext.done();
// Remap the request, set the dispatch attributes, create the filter chain
// and invoke the Servlet
Context context = (Context) getContainer().getParent();
@@ -453,6 +458,9 @@
}
// If there is no new startAsync, then close the response
if (!asyncContext.isReady()) {
+ // FIXME: see which one is the right one to close the response
+ asyncContext.complete();
+ /*
if (asyncContext.getResponse() instanceof ResponseFacade) {
response.setSuspended(true);
} else {
@@ -474,6 +482,7 @@
}
}
event.close();
+ */
}
} else {
throw new IllegalStateException(sm.getString("standardWrapper.async.invalidContext"));
Modified: trunk/java/org/apache/catalina/deploy/FilterDef.java
===================================================================
--- trunk/java/org/apache/catalina/deploy/FilterDef.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/deploy/FilterDef.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -130,12 +130,10 @@
* The set of initialization parameters for this filter, keyed by
* parameter name.
*/
- private Map parameters = new HashMap();
+ private Map<String, String> parameters = new HashMap<String, String>();
- public Map getParameterMap() {
-
+ public Map<String, String> getParameterMap() {
return (this.parameters);
-
}
@@ -164,9 +162,18 @@
* @param value The initialization parameter value
*/
public void addInitParameter(String name, String value) {
-
parameters.put(name, value);
+ }
+
+ /**
+ * Add an initialization parameter to the set of parameters associated
+ * with this filter.
+ *
+ * @param name The initialization parameter name
+ */
+ public String getInitParameter(String name) {
+ return parameters.get(name);
}
Modified: trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java
===================================================================
--- trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -207,7 +207,7 @@
("htmlManagerServlet.deployUploadNoFile");
break;
}
- war = warUpload.getName();
+ war = warUpload.getFileName();
if (!war.toLowerCase().endsWith(".war")) {
message = sm.getString
("htmlManagerServlet.deployUploadNotWar",war);
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/DefaultFileItem.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -202,7 +202,7 @@
*
* @return The original filename in the client's filesystem.
*/
- public String getName()
+ public String getFileName()
{
return fileName;
}
@@ -459,6 +459,12 @@
}
+ public String getName()
+ {
+ return fieldName;
+ }
+
+
/**
* Sets the field name used to reference this file item.
*
Modified: trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
===================================================================
--- trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java 2009-04-20 09:49:53 UTC (rev 1019)
+++ trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java 2009-04-20 15:51:08 UTC (rev 1020)
@@ -127,6 +127,14 @@
/**
+ * Returns the original filename in the client's filesystem.
+ *
+ * @return The original filename in the client's filesystem.
+ */
+ String getFileName();
+
+
+ /**
* Returns the name of the field in the multipart form corresponding to
* this file item.
*
16 years, 6 months