webtier@glassfish.java.net

valve-patch

From: Wolfram Rittmeyer <w.rittmeyer_at_jsptutorial.org>
Date: Wed, 04 Feb 2009 08:37:47 +0100

Hello,

the patches to enable valves with properties for the projects
"deployment" and "web" are in the attached files "deployment.diff" and
"web.diff". These patches are based on SVN-revision 24578.

I have also written a devtest "valveWithParams" though I do not know
whether it would be ok to send a valveWithParams.tgz as attachment to
this list. Please let me know how to submit this gzipped tar file.

I'm looking forward to getting your comments to these patches. It has
been fun digging into GlassFish's inner workings ;-)


--
Wolfram Rittmeyer



Property changes on: javaee-core
___________________________________________________________________
Added: svn:ignore
   + target


Index: dol/src/main/java/com/sun/enterprise/deployment/runtime/web/SunWebApp.java
===================================================================
--- dol/src/main/java/com/sun/enterprise/deployment/runtime/web/SunWebApp.java (revision 24578)
+++ dol/src/main/java/com/sun/enterprise/deployment/runtime/web/SunWebApp.java (working copy)
@@ -62,7 +62,7 @@
     public static final String IDEMPOTENT_URL_PATTERN = "IdempotentUrlPattern";
     public static final String ERROR_URL = "ErrorUrl";
     public static final String HTTPSERVLET_SECURITY_PROVIDER = "HttpServletSecurityProvider";
-
+ public static final String VALVE = "Valve";
     
     public SunWebApp()
     {
@@ -424,4 +424,50 @@
         }
         return ret.booleanValue();
     }
+
+ // This attribute is an array, possibly empty
+ public void setValve(int index, Valve value)
+ {
+ this.setValue(VALVE, index, value);
+ }
+
+ //
+ public Valve getValve(int index)
+ {
+ return (Valve)this.getValue(VALVE, index);
+ }
+
+ // This attribute is an array, possibly empty
+ public void setValve(Valve[] value)
+ {
+ this.setValue(VALVE, value);
+ }
+
+ //
+ public Valve[] getValve()
+ {
+ return (Valve[])this.getValues(VALVE);
+ }
+
+ // Return the number of properties
+ public int sizeValve()
+ {
+ return this.size(VALVE);
+ }
+
+ // Add a new element returning its index in the list
+ public int addValve(Valve value)
+ {
+ return this.addValue(VALVE, value);
+ }
+
+ //
+ // Remove an element using its reference
+ // Returns the index the element had in the list
+ //
+ public int removeValve(Valve value)
+ {
+ return this.removeValue(VALVE, value);
+ }
+
 }
Index: dol/src/main/java/com/sun/enterprise/deployment/node/runtime/RuntimeDescriptorFactory.java
===================================================================
--- dol/src/main/java/com/sun/enterprise/deployment/node/runtime/RuntimeDescriptorFactory.java (revision 24578)
+++ dol/src/main/java/com/sun/enterprise/deployment/node/runtime/RuntimeDescriptorFactory.java (working copy)
@@ -108,6 +108,7 @@
         //common
         register(new XMLElement(RuntimeTagNames.PRINCIPAL_NAME), PrincipalNameDescriptor.class);
         register(new XMLElement(RuntimeTagNames.SECURITY_ROLE_MAPPING), SecurityRoleMapping.class);
+ register(new XMLElement(RuntimeTagNames.VALVE), Valve.class);
      }
     /**
      * register a new descriptor class handling a particular XPATH in the DTD.
Index: dol/src/main/java/com/sun/enterprise/deployment/node/runtime/web/WebBundleRuntimeNode.java
===================================================================
--- dol/src/main/java/com/sun/enterprise/deployment/node/runtime/web/WebBundleRuntimeNode.java (revision 24578)
+++ dol/src/main/java/com/sun/enterprise/deployment/node/runtime/web/WebBundleRuntimeNode.java (working copy)
@@ -131,6 +131,9 @@
                                 MessageDestinationRuntimeNode.class);
         registerElementHandler(new XMLElement(WebServicesTagNames.WEB_SERVICE),
                                      WebServiceRuntimeNode.class);
+ registerElementHandler(new XMLElement(RuntimeTagNames.VALVE),
+ ValveNode.class);
+
     }
     
     /**
@@ -296,6 +299,9 @@
         } else if (newDescriptor instanceof WebProperty) {
             descriptor.getSunDescriptor().addWebProperty(
                 (WebProperty)newDescriptor);
+ } else if (newDescriptor instanceof Valve) {
+ descriptor.getSunDescriptor().addValve(
+ (Valve)newDescriptor);
         }
         else super.addDescriptor(descriptor);
     }
@@ -501,6 +507,12 @@
             props.writeDescriptor(web, RuntimeTagNames.PROPERTY, sunWebApp.getWebProperty());
         }
         
+ // valve*
+ if (sunWebApp.getValve()!=null) {
+ ValveNode valve = new ValveNode();
+ valve.writeDescriptor(web, RuntimeTagNames.VALVE, sunWebApp.getValve());
+ }
+
         // message-destination*
         RuntimeDescriptorNode.writeMessageDestinationInfo(web, bundleDescriptor);
 
Index: dol/src/main/java/com/sun/enterprise/deployment/xml/RuntimeTagNames.java
===================================================================
--- dol/src/main/java/com/sun/enterprise/deployment/xml/RuntimeTagNames.java (revision 24578)
+++ dol/src/main/java/com/sun/enterprise/deployment/xml/RuntimeTagNames.java (working copy)
@@ -286,6 +286,9 @@
     public static final String JAVA_METHOD = "java-method";
     public final static String METHOD_PARAMS = "method-params";
     public final static String METHOD_PARAM = "method-param";
+
+ public final static String VALVE = "valve";
+ public final static String CLASSNAME = "classname";
     
     // Java Web Start-support related
     public final static String JAVA_WEB_START_ACCESS = "java-web-start-access";
Index: dtds/src/main/resources/glassfish/lib/dtds/sun-web-app_2_5-0.dtd
===================================================================
--- dtds/src/main/resources/glassfish/lib/dtds/sun-web-app_2_5-0.dtd (revision 24578)
+++ dtds/src/main/resources/glassfish/lib/dtds/sun-web-app_2_5-0.dtd (working copy)
@@ -16,7 +16,7 @@
                        ejb-ref*, resource-ref*, resource-env-ref*, service-ref*,
                        message-destination-ref*, cache?, class-loader?,
                        jsp-config?, locale-charset-info?, parameter-encoding?,
- property*, message-destination*, webservice-description*)>
+ property*, valve*, message-destination*, webservice-description*)>
 <!ATTLIST sun-web-app error-url CDATA ""
                       httpservlet-security-provider CDATA #IMPLIED>
 
@@ -320,6 +320,9 @@
 -->
 <!ELEMENT value (#PCDATA)>
 
+<!ELEMENT valve (description?, property*)>
+<!ATTLIST property classname CDATA #REQUIRED
+ name CDATA #REQUIRED>
 
 <!--
                                           W E B S E R V I C E S


Index: war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties
===================================================================
--- war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties (revision 24578)
+++ war-util/src/main/resources/com/sun/logging/enterprise/system/container/web/LogStrings.properties (working copy)
@@ -203,6 +203,11 @@
 peaccesslogvalve.notStarted=WEB0351: Access logger has not yet been started
 pewebcontainer.invalidMaxPendingCount=WEB0352: Invalid max-pending-count attribute value: ({0}). Using default {1}.
 pewebcontainer.invalid_accessLog_bufferSize=WEB0353: Invalid accessLogBufferSize value ({0}).
+pewebcontainer.specifiedMethodMissing=There is no method [{0}(java.lang.String)] in the valve named [{1}]
+pewebcontainer.valveSetterCausedException=The method [{0}] in the valve [{1}] caused an exception
+pewebcontainer.noNameForValve=No name for one of the valves given
+pewebcontainer.noClassnameForValve=No classname for the valve [{0}] given
+pewebcontainer.noNameForProperty=No name for a property of the valve [{0}] given
 
 #
 # com.sun.enterprise.web.connector.coyote
Index: web-glue/src/main/java/com/sun/enterprise/web/WebModule.java
===================================================================
--- web-glue/src/main/java/com/sun/enterprise/web/WebModule.java (revision 24578)
+++ web-glue/src/main/java/com/sun/enterprise/web/WebModule.java (working copy)
@@ -85,6 +85,8 @@
 import com.sun.enterprise.web.session.PersistenceType;
 import com.sun.enterprise.web.session.SessionCookieConfig;
 import com.sun.logging.LogDomains;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import org.apache.catalina.Container;
 import org.apache.catalina.ContainerListener;
 import org.apache.catalina.InstanceListener;
@@ -467,6 +469,9 @@
         // Configure catalina listeners and valves. This can only happen
         // after this web module has been started, in order to be able to
         // load the specified listener and valve classes.
+
+ configureValves();
+
         configureCatalinaProperties();
 
         webModuleStartedEvent();
@@ -869,7 +874,21 @@
     }
     
    
+
     /**
+ * Configure the <code>WebModule</code> valves.
+ */
+ protected void configureValves(){
+ if (iasBean.getValve() != null && iasBean.sizeValve() > 0) {
+ com.sun.enterprise.deployment.runtime.web.Valve[] valves = iasBean.getValve();
+ for (com.sun.enterprise.deployment.runtime.web.Valve valve: valves) {
+ addValve(valve);
+ }
+ }
+
+ }
+
+ /**
      * Configure the <code>WebModule</code< properties.
      */
     protected void configureCatalinaProperties(){
@@ -935,7 +954,71 @@
         }
     }
     
+ /**
+ * Add a <code>Valve</code> to a <code>VirtualServer</code> pipeline.
+ * @param valveDescriptor the object containing the information to create the valve.
+ */
+ protected void addValve(com.sun.enterprise.deployment.runtime.web.Valve valveDescriptor) {
+ String valveName = valveDescriptor.getAttributeValue(
+ com.sun.enterprise.deployment.runtime.web.Valve.NAME);
+ String className = valveDescriptor.getAttributeValue(
+ com.sun.enterprise.deployment.runtime.web.Valve.CLASSNAME);
+ if (valveName == null) {
+ logger.log(Level.WARNING, rb.getString("pewebcontainer.noNameForValve"));
+ return;
+ }
+ if (className == null) {
+ String msg = rb.getString("pewebcontainer.noClassnameForValve");
+ msg = MessageFormat.format(msg, new Object[] {valveName});
+ logger.log(Level.WARNING, msg);
+ return;
+ }
+ Object valve = loadInstance(className);
+ if (valve == null) {
+ return;
+ }
+ WebProperty[] props = valveDescriptor.getWebProperty();
+ if (props != null && props.length > 0) {
+ for (WebProperty property: props) {
+ String propName = getSetterName(property.getAttributeValue(WebProperty.NAME));
+ if (propName != null && propName.length() != 0) {
+ String value = property.getAttributeValue(WebProperty.VALUE);
+ try {
+ Method method = valve.getClass().getMethod(propName, String.class);
+ method.invoke(valve, value);
+ } catch (NoSuchMethodException ex) {
+ String msg = rb.getString("pewebcontainer.specifiedMethodMissing");
+ msg = MessageFormat.format(msg, new Object[] { propName,
+ valveName});
+ logger.log(Level.SEVERE, msg, ex);
+ } catch (Throwable t) {
+ String msg = rb.getString("pewebcontainer.valveSetterCausedException");
+ msg = MessageFormat.format(msg, new Object[] { propName,
+ valveName});
+ logger.log(Level.SEVERE, msg, t);
+ }
+ }
+ else {
+ String msg = rb.getString("pewebcontainer.noNameForProperty");
+ msg = MessageFormat.format(msg, new Object[] {valveName});
+ logger.log(Level.WARNING, msg);
+ return;
+ }
+ }
+ }
+ if (valve instanceof Valve) {
+ super.addValve((Valve) valve);
+ } else if (valve instanceof GlassFishValve) {
+ super.addValve((GlassFishValve) valve);
+ } else {
+ logger.log(Level.WARNING,
+ "Object of type classname " + className +
+ " not an instance of Valve or GlassFishValve");
+ }
+ }
     
+
+
     /**
      * Add a Catalina listener to a <code>ContractProvider</code>
      * @param listenerName the fully qualified class name of the listener.
@@ -971,6 +1054,19 @@
         return null;
     }
 
+
+ private String getSetterName(String propName) {
+ if (propName != null) {
+ if (propName.length() > 1) {
+ propName = "set" + Character.toUpperCase(propName.charAt(0)) +
+ propName.substring(1);
+ }
+ else {
+ propName = "set" + Character.toUpperCase(propName.charAt(0));
+ }
+ }
+ return propName;
+ }
     
     public com.sun.enterprise.config.serverbeans.WebModule getBean() {
         return bean;