You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2005/07/08 22:50:40 UTC
svn commit: r209887 - in /geronimo/trunk/modules:
jetty-builder/src/java/org/apache/geronimo/jetty/deployment/
jetty-builder/src/test/org/apache/geronimo/jetty/deployment/
jetty/src/java/org/apache/geronimo/jetty/
Author: djencks
Date: Fri Jul 8 13:50:39 2005
New Revision: 209887
URL: http://svn.apache.org/viewcvs?rev=209887&view=rev
Log:
GERONIMO-645 Respect load-on-startup tags in jetty
Added:
geronimo/trunk/modules/jetty-builder/src/test/org/apache/geronimo/jetty/deployment/StartupOrderComparatorTest.java
Modified:
geronimo/trunk/modules/jetty-builder/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java
geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java
Modified: geronimo/trunk/modules/jetty-builder/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty-builder/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java?rev=209887&r1=209886&r2=209887&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty-builder/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java (original)
+++ geronimo/trunk/modules/jetty-builder/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java Fri Jul 8 13:50:39 2005
@@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -38,6 +39,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import javax.management.MalformedObjectNameException;
@@ -731,10 +733,8 @@
ServletType[] servletTypes = webApp.getServletArray();
Map portMap = webModule.getPortMap();
- for (int i = 0; i < servletTypes.length; i++) {
- ServletType servletType = servletTypes[i];
- addServlet(webModuleName, webModule.getModuleFile(), servletType, servletMappings, securityRoles, rolePermissions, portMap, webClassLoader, moduleJ2eeContext, earContext);
- }
+ addServlets(webModuleName, webModule.getModuleFile(), servletTypes, servletMappings, securityRoles, rolePermissions, portMap, webClassLoader, moduleJ2eeContext, earContext);
+
if (jettyWebApp.isSetSecurityRealmName()) {
String securityRealmName = jettyWebApp.getSecurityRealmName().trim();
webModuleData.setAttribute("securityRealmName", securityRealmName);
@@ -801,8 +801,63 @@
return webClassLoader;
}
+
+ /**
+ * Adds the provided servlets, taking into account the load-on-startup ordering.
+ *
+ * @param webModuleName an <code>ObjectName</code> value
+ * @param moduleFile a <code>JarFile</code> value
+ * @param servletTypes a <code>ServletType[]</code> value, contains the <code>servlet</code> entries from <code>web.xml</code>.
+ * @param servletMappings a <code>Map</code> value
+ * @param securityRoles a <code>Set</code> value
+ * @param rolePermissions a <code>Map</code> value
+ * @param portMap a <code>Map</code> value
+ * @param webClassLoader a <code>ClassLoader</code> value
+ * @param moduleJ2eeContext a <code>J2eeContext</code> value
+ * @param earContext an <code>EARContext</code> value
+ * @exception MalformedObjectNameException if an error occurs
+ * @exception DeploymentException if an error occurs
+ */
+ private void addServlets(ObjectName webModuleName,
+ JarFile moduleFile,
+ ServletType[] servletTypes,
+ Map servletMappings,
+ Set securityRoles,
+ Map rolePermissions, Map portMap,
+ ClassLoader webClassLoader,
+ J2eeContext moduleJ2eeContext,
+ EARContext earContext) throws MalformedObjectNameException, DeploymentException {
+
+ // this TreeSet will order the ServletTypes based on whether
+ // they have a load-on-startup element and what its value is
+ TreeSet loadOrder = new TreeSet(new StartupOrderComparator());
+
+ // add all of the servlets to the sorted set
+ for (int i = 0; i < servletTypes.length; i++) {
+ loadOrder.add(servletTypes[i]);
+ }
+
+ // now that they're sorted, read them in order and add them to
+ // the context. we'll use a GBean reference to enforce the
+ // load order. Each servlet GBean (except the first) has a
+ // reference to the previous GBean. The kernel will ensure
+ // that each "previous" GBean is running before it starts any
+ // other GBeans that reference it. See also
+ // o.a.g.jetty.JettyFilterMapping which provided the example
+ // of how to do this.
+ // http://issues.apache.org/jira/browse/GERONIMO-645
+ ServletType previousServlet = null;
+ for (Iterator servlets = loadOrder.iterator(); servlets.hasNext(); ) {
+ ServletType servletType = (ServletType)servlets.next();
+ addServlet(webModuleName, moduleFile, previousServlet, servletType, servletMappings, securityRoles, rolePermissions, portMap, webClassLoader, moduleJ2eeContext, earContext);
+ previousServlet = servletType;
+ }
+ }
+
+
private void addServlet(ObjectName webModuleName,
JarFile moduleFile,
+ ServletType previousServlet,
ServletType servletType,
Map servletMappings,
Set securityRoles,
@@ -852,6 +907,16 @@
} else {
throw new DeploymentException("Neither servlet class nor jsp file is set for " + servletName);
}
+
+ // link to previous servlet, if there is one, so that we
+ // preserve the <load-on-startup> ordering.
+ // http://issues.apache.org/jira/browse/GERONIMO-645
+ if (null != previousServlet) {
+ String name = previousServlet.getServletName().getStringValue().trim();
+ ObjectName oName = NameFactory.getWebComponentName(null, null, null, null, name, NameFactory.SERVLET, moduleJ2eeContext);
+ servletData.setReferencePattern("Previous", oName);
+ }
+
//TODO in init param setter, add classpath if jspFile is not null.
servletData.setReferencePattern("JettyServletRegistration", webModuleName);
servletData.setAttribute("servletName", servletName);
@@ -1287,4 +1352,46 @@
return GBEAN_INFO;
}
+ static class StartupOrderComparator implements Comparator {
+ /**
+ * comparator that compares first on the basis of startup order, and then on the lexicographical
+ * ordering of servlet name. Since the servlet names have a uniqueness constraint, this should
+ * provide a total ordering consistent with equals. All servlets with no startup order are after
+ * all servlets with a startup order.
+ *
+ * @param o1 first ServletType object
+ * @param o2 second ServletType object
+ * @return an int < 0 if o1 precedes o2, 0 if they are equal, and > 0 if o2 preceeds o1.
+ */
+ public int compare(Object o1, Object o2) {
+ ServletType s1 = (ServletType)o1;
+ ServletType s2 = (ServletType)o2;
+
+ // load-on-startup is set for neither. the
+ // ordering at this point doesn't matter, but we
+ // should return "0" only if the two objects say
+ // they are equal
+ if (!s1.isSetLoadOnStartup() && !s2.isSetLoadOnStartup()) {
+ return s1.equals(s2) ? 0 : s1.getServletName().getStringValue().trim().compareTo(s2.getServletName().getStringValue().trim());
+ }
+
+ // load-on-startup is set for one but not the
+ // other. whichever one is set will be "less
+ // than", i.e. it will be loaded first
+ if (s1.isSetLoadOnStartup() && !s2.isSetLoadOnStartup()) {
+ return -1;
+ }
+ if (!s1.isSetLoadOnStartup() && s2.isSetLoadOnStartup()) {
+ return 1;
+ }
+
+ // load-on-startup is set for both. whichever one
+ // has a smaller value is "less than"
+ int comp = s1.getLoadOnStartup().getBigIntegerValue().compareTo(s2.getLoadOnStartup().getBigIntegerValue());
+ if (comp == 0) {
+ return s1.getServletName().getStringValue().trim().compareTo(s2.getServletName().getStringValue().trim());
+ }
+ return comp;
+ }
+ }
}
Added: geronimo/trunk/modules/jetty-builder/src/test/org/apache/geronimo/jetty/deployment/StartupOrderComparatorTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty-builder/src/test/org/apache/geronimo/jetty/deployment/StartupOrderComparatorTest.java?rev=209887&view=auto
==============================================================================
--- geronimo/trunk/modules/jetty-builder/src/test/org/apache/geronimo/jetty/deployment/StartupOrderComparatorTest.java (added)
+++ geronimo/trunk/modules/jetty-builder/src/test/org/apache/geronimo/jetty/deployment/StartupOrderComparatorTest.java Fri Jul 8 13:50:39 2005
@@ -0,0 +1,85 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.geronimo.jetty.deployment;
+
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+import org.apache.geronimo.xbeans.j2ee.ServletType;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public class StartupOrderComparatorTest extends TestCase {
+
+ private final JettyModuleBuilder.StartupOrderComparator c = new JettyModuleBuilder.StartupOrderComparator();
+
+ public void testNoOrders() throws Exception {
+ ServletType s1 = makeServletType("a", -1);
+ ServletType s2 = makeServletType("b", -1);
+ ServletType s3 = makeServletType("c", -1);
+ checkOrdering(s1, s2, s3);
+ }
+
+ public void testIdenticalOrders() throws Exception {
+ ServletType s1 = makeServletType("a", 1);
+ ServletType s2 = makeServletType("b", 1);
+ ServletType s3 = makeServletType("c", 1);
+ checkOrdering(s1, s2, s3);
+ }
+
+ public void testDistinctOrders() throws Exception {
+ ServletType s1 = makeServletType("c", 1);
+ ServletType s2 = makeServletType("b", 2);
+ ServletType s3 = makeServletType("a", 3);
+ checkOrdering(s1, s2, s3);
+ }
+
+ public void testMixedOrders1() throws Exception {
+ ServletType s1 = makeServletType("c", 1);
+ ServletType s2 = makeServletType("b", 2);
+ ServletType s3 = makeServletType("a", -1);
+ checkOrdering(s1, s2, s3);
+ }
+
+ public void testMixedOrders2() throws Exception {
+ ServletType s1 = makeServletType("c", 1);
+ ServletType s2 = makeServletType("a", -1);
+ ServletType s3 = makeServletType("b", -1);
+ checkOrdering(s1, s2, s3);
+ }
+
+ private void checkOrdering(ServletType s1, ServletType s2, ServletType s3) {
+ //symmetric
+ assertTrue(c.compare(s1, s2) < 0);
+ assertTrue(c.compare(s2, s1) > 0);
+ //reflexive
+ assertTrue(c.compare(s1, s1) == 0);
+ //transitive
+ assertTrue(c.compare(s2, s3) < 0);
+ assertTrue(c.compare(s1, s3) < 0);
+ }
+
+ private ServletType makeServletType(String servletName, int order) {
+ ServletType s1 = ServletType.Factory.newInstance();
+ s1.addNewServletName().setStringValue(servletName);
+ if (order > -1) {
+ s1.addNewLoadOnStartup().setBigIntegerValue(BigInteger.valueOf(order));
+ }
+ return s1;
+ }
+}
Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java?rev=209887&r1=209886&r2=209887&view=diff
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java (original)
+++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java Fri Jul 8 13:50:39 2005
@@ -45,10 +45,11 @@
*/
public class JettyServletHolder extends ServletHolder {
private static final ThreadLocal currentServletName = new ThreadLocal();
+ private final JettyServletHolder previous;
//todo consider interface instead of this constructor for endpoint use.
public JettyServletHolder() {
-
+ this.previous = null;
}
public JettyServletHolder(String servletName,
@@ -58,10 +59,13 @@
Integer loadOnStartup,
Set servletMappings,
Map webRoleRefPermissions,
+ JettyServletHolder previous,
JettyServletRegistration context) throws Exception {
super(context == null? null: context.getServletHandler(), servletName, servletClassName, jspFile);
//context will be null only for use as "default servlet info holder" in deployer.
+ this.previous = previous;
+
if (context != null) {
putAll(initParams);
if (loadOnStartup != null) {
@@ -80,6 +84,10 @@
return getName();
}
+ public JettyServletHolder getPrevious() {
+ return previous;
+ }
+
/**
* Service a request with this servlet. Set the ThreadLocal to hold the
* current JettyServletHolder.
@@ -120,6 +128,8 @@
infoBuilder.addAttribute("loadOnStartup", Integer.class, true);
infoBuilder.addAttribute("servletMappings", Set.class, true);
infoBuilder.addAttribute("webRoleRefPermissions", Map.class, true);
+
+ infoBuilder.addReference("Previous", JettyServletHolder.class, NameFactory.DEFAULT_SERVLET);
infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class, NameFactory.WEB_MODULE);
infoBuilder.setConstructor(new String[] {"servletName",
@@ -129,6 +139,7 @@
"loadOnStartup",
"servletMappings",
"webRoleRefPermissions",
+ "Previous",
"JettyServletRegistration"});
GBEAN_INFO = infoBuilder.getBeanInfo();