You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cr...@apache.org on 2002/09/25 19:10:26 UTC

cvs commit: xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/cache DeploymentDescriptor.wsdd Cache.java

crafterm    2002/09/25 10:10:23

  Modified:    .        changes.xml
               src/scratchpad/src/org/apache/cocoon/components/axis
                        SoapServer.java SoapServerImpl.java
               src/scratchpad/src/org/apache/cocoon/reading
                        AxisRPCReader.java
               src/scratchpad/src/org/apache/cocoon/webservices
                        AbstractComposableService.java
                        AbstractLogEnabledService.java
               src/scratchpad/src/org/apache/cocoon/webservices/cache
                        DeploymentDescriptor.wsdd
  Added:       src/scratchpad/src/org/apache/cocoon/components/axis/providers
                        AvalonProvider.java
  Removed:     src/scratchpad/src/org/apache/cocoon/webservices/cache
                        Cache.java
  Log:
  * Added new AvalonProvider class, which allows you to specify Avalon
    components by role name as Axis service objects (currently in Axis
    bugzilla #12903).
  
    To access an Avalon component as a Service object, use the 'Handler'
    provider, and specify the AvalonProvider as the 'handlerClass' parameter. eg:
  
    <service name="Cocoon-Cache" provider="Handler">
      <parameter name="role" value="org.apache.excalibur.store.Store/TransientStore"/>
      <parameter name="className" value="org.apache.excalibur.store.Store"/>
      <parameter name="handlerClass" value="org.apache.cocoon.components.axis.providers.AvalonProvider"/>
      <parameter name="allowedMethods" value="clear size"/>
    </service>
  
  * Updated SoapServer component to support the new provider.
  
  * Fixed unused imports in AxisRPCReader.
  
  * Updated Cache webservice to use the AvalonProvider, now it accesses Cocoon's
    Store object directly from the ComponentManager instead of via a
    separate class.
  
  * Removed Cache service java source file, as it is no longer needed (same
    functionality is better achieved above)
  
  Revision  Changes    Path
  1.261     +5 -1      xml-cocoon2/changes.xml
  
  Index: changes.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/changes.xml,v
  retrieving revision 1.260
  retrieving revision 1.261
  diff -u -r1.260 -r1.261
  --- changes.xml	25 Sep 2002 13:48:40 -0000	1.260
  +++ changes.xml	25 Sep 2002 17:10:19 -0000	1.261
  @@ -40,6 +40,10 @@
    </devs>
   
    <release version="@version@" date="@date@">
  +  <action dev="MC" type="update">
  +   Added support for using Avalon components as Axis service objects
  +   with the AxisRPCReader.
  +  </action>
     <action dev="CZ" type="update">
      Enhancing cinclude transformer with configuration possiblities, lie
      POST requests and flexible parameter handling.
  
  
  
  1.2       +1 -6      xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/axis/SoapServer.java
  
  Index: SoapServer.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/axis/SoapServer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SoapServer.java	9 Sep 2002 17:53:17 -0000	1.1
  +++ SoapServer.java	25 Sep 2002 17:10:22 -0000	1.2
  @@ -95,11 +95,6 @@
       String LOGGER = "axis-message-context-logger";
   
       /**
  -     * Constant used to key message context entries for a component manager
  -     */
  -    String COMPONENT_MANAGER = "axis-message-context-cm";
  -
  -    /**
        * Invoke a particular message context on this server. This method
        * takes the given message, invokes it on the server and sets
        * the response inside it for the caller to retrieve.
  
  
  
  1.2       +6 -4      xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/axis/SoapServerImpl.java
  
  Index: SoapServerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/axis/SoapServerImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SoapServerImpl.java	9 Sep 2002 17:53:17 -0000	1.1
  +++ SoapServerImpl.java	25 Sep 2002 17:10:22 -0000	1.2
  @@ -88,6 +88,7 @@
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceResolver;
   
  +import org.apache.cocoon.components.axis.providers.AvalonProvider;
   import org.apache.cocoon.util.IOUtils;
   
   import org.apache.axis.AxisEngine;
  @@ -546,6 +547,10 @@
           // Set the Transport
           msgContext.setTransportName(m_transportName);
   
  +        // Add Avalon specifics to MessageContext
  +        msgContext.setProperty(LOGGER, getLogger());
  +        msgContext.setProperty(AvalonProvider.COMPONENT_MANAGER, m_manager);
  +
           // Save some HTTP specific info in the bag in case someone needs it
           msgContext.setProperty(Constants.MC_JWS_CLASSDIR, m_jwsClassDir);
           msgContext.setProperty(Constants.MC_HOME_DIR, homeDir);
  @@ -560,9 +565,6 @@
                                  req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));
           msgContext.setProperty(Constants.MC_REMOTE_ADDR, req.getRemoteAddr());
   
  -        // Add Avalon specifics to MessageContext
  -        msgContext.setProperty(LOGGER, getLogger());
  -        msgContext.setProperty(COMPONENT_MANAGER, m_manager);
   
           // Set up a javax.xml.rpc.server.ServletEndpointContext
           ServletEndpointContextImpl sec =
  
  
  
  1.1                  xml-cocoon2/src/scratchpad/src/org/apache/cocoon/components/axis/providers/AvalonProvider.java
  
  Index: AvalonProvider.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  // package org.apache.axis.providers.java;
  // currently part of Cocoon until it's officially in Axis CVS (BZ#12903)
  package org.apache.cocoon.components.axis.providers;
  
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  
  import org.apache.axis.AxisFault;
  import org.apache.axis.MessageContext;
  import org.apache.axis.providers.java.RPCProvider;
  import org.apache.axis.handlers.soap.SOAPService;
  
  import java.lang.reflect.Method;
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  
  import javax.xml.rpc.server.ServiceLifecycle;
  
  /**
   * Provider class which allows you to specify an Avalon <b>ROLE</b> for
   * servicing Axis SOAP requests.
   *
   * <p>
   *  The specified <b>ROLE</b> corresponds to a particular implementation
   *  which is retrieved by a given Avalon <code>ComponentManager</code>.
   *  For more information about Avalon, see the Avalon.
   *  <a href="http://jakarta.apache.org/avalon">website</a>.
   * </p>
   *
   * <p>
   *  To use this class, you need to add your Avalon <code>ComponentManager</code>
   *  instance to the <code>MessageContext</code> that is Axis uses to process
   *  messages with.
   * </p>
   *
   * <p>
   *  To do this you could for example subclass the AxisServlet and override the
   *  <code>createMessageContext()</code> method adding the ComponentManager, eg:
   *
   *  <pre>
   *   protected MessageContext createMessageContext(...)
   *   {
   *      MessageContext context = super.createMessageContext();
   *      context.setProperty(AvalonProvider.COMPONENT_MANAGER, m_manager);
   *      return context;
   *   }
   *  </pre>
   *
   *  and appropriately add the AvalonProvider to the list of handlers in your
   *  server-config.wsdd (suggestions on how to improve this are welcomed)
   * </p>
   *
   * <p>
   *  This provider will use that <code>ComponentManager</code> reference to
   *  retrieve objects.
   * </p>
   *
   * <p>
   *  In your deployment descriptor use the following syntax:
   *
   * <pre>
   *  &lt;service name="myservice" provider="java:Avalon"&gt;
   *    &lt;parameter name="role" value="my.avalon.role.name"/&gt;
   *    &lt;parameter name="className" value="my.avalon.roles.interface.name"/&gt;
   *    &lt;parameter name="allowedMethods" value="allowed.methods"/&gt;
   *  &lt;/service&gt;
   * </pre>
   *
   * </p>
   *
   * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
   * @revision CVS $Id: AvalonProvider.java,v 1.1 2002/09/25 17:10:22 crafterm Exp $
   */
  public class AvalonProvider extends RPCProvider
  {
      /**
       * Constant used to retrieve the ComponentManager reference
       * from the MessageContext object.
       */
      public static final String COMPONENT_MANAGER = "component-manager";
  
      /**
       * Constant which represents the name of the ROLE this
       * provider should <i>lookup</i> to service a request with. This is
       * specified in the &lt;parameter name="" value=""/&gt; part of the
       * deployment xml.
       */
      public static final String ROLE = "role";
  
      /**
       * Returns the service object.
       * 
       * @param msgContext the message context
       * @param role the Avalon ROLE to lookup to find the service object implementation
       * @return an object that implements the service
       * @exception Exception if an error occurs
       */
      protected Object makeNewServiceObject(
          MessageContext msgContext, String role
      )
          throws Exception
      {
          ComponentManager manager =
              (ComponentManager) msgContext.getProperty(COMPONENT_MANAGER);
  
          if (manager == null)
              throw new AxisFault("Could not access Avalon ComponentManager");
  
          return decorate(manager.lookup(role), manager);
      }
  
      /**
       * Helper method for decorating a <code>Component</code> with a Handler
       * proxy (see below).
       *
       * @param object a <code>Component</code> instance
       * @param manager a <code>ComponentManager</code> instance
       * @return the <code>Proxy</code> wrapped <code>Component</code> instance
       * @exception Exception if an error occurs
       */
      private Object decorate(final Component object, final ComponentManager manager)
          throws Exception
      {
          // obtain a list of all interfaces this object implements
          Class[] interfaces = object.getClass().getInterfaces();
  
          // add ServiceLifecycle to it
          Class[] adjusted = new Class[ interfaces.length + 1 ];
          System.arraycopy(interfaces, 0, adjusted, 0, interfaces.length);
          adjusted[interfaces.length] = ServiceLifecycle.class;
  
          // create a proxy implementing those interfaces
          Object proxy =
              Proxy.newProxyInstance(
                  this.getClass().getClassLoader(),
                  adjusted,
                  new Handler(object, manager)
              );
  
          // return the proxy
          return proxy;
      }
  
      /**
       * Return the option in the configuration that contains the service class
       * name. In the Avalon case, it is the ROLE name to lookup.
       */
      protected String getServiceClassNameOptionName()
      {
          return ROLE;
      }
  
      /**
       * Get the service class description
       * 
       * @param role the Avalon ROLE name
       * @param service a <code>SOAPService</code> instance
       * @param msgContext the message context
       * @return service class description
       * @exception AxisFault if an error occurs
       */
      protected Class getServiceClass(
          String role, SOAPService service, MessageContext msgContext
      )
          throws AxisFault
      {
          // Assuming ExcaliburComponentManager semantics the ROLE name is
          // actually the class name, potentially with a variant following
          // the class name with a '/' separator
  
          try
          {
              int i;
  
              if ((i = role.indexOf('/')) != -1)
              {
                  return Class.forName(role.substring(0, i));
              }
              else
              {
                  return Class.forName(role);
              }
          }
          catch (ClassNotFoundException e)
          {
              throw new AxisFault("Couldn't create class object for role " + role, e);
          }
      }
  
      /**
       * <code>InvocationHandler</code> class for managing Avalon
       * <code>Components</code>.
       *
       * <p>
       *  Components retrieved from an Avalon ComponentManager must be
       *  returned to the manager when they are no longer required.
       * </p>
       *
       * <p>
       *  The returning of Components to their ComponentManager is handled
       *  by a Proxy class which uses the following InvocationHandler.
       * </p>
       *
       * <p>
       *  Each Component returned by this Provider is wrapped inside a 
       *  Proxy class which implements all of the Component's interfaces
       *  including javax.xml.rpc.server.ServiceLifecycle.
       * </p>
       *
       * <p>
       *  When Axis is finished with the object returned by this provider,
       *  it invokes ServiceLifecycle.destroy(). This is intercepted by the
       *  InvocationHandler and the Component is returned at this time back
       *  to the ComponentManager it was retrieved from.
       * </p>
       *
       * <p>
       *  <b>Note</b>, when Axis invokes ServiceLifecycle.destroy() is dependant
       *  on the scope of the service (ie. Request, Session & Application).
       * </p>
       */
      final class Handler implements InvocationHandler
      {
          // Constants describing the ServiceLifecycle.destroy method
          private final String SL_DESTROY = "destroy";
          private final Class  SL_CLASS = ServiceLifecycle.class;
  
          // Component & ComponentManager references
          private final Component m_object;
          private final ComponentManager m_manager;
  
          /**
           * Simple constructor, sets all internal references
           *
           * @param object a <code>Component</code> instance
           * @param manager a <code>ComponentManager</code> instance
           * @param log a <code>Logger</code> instance
           */
          public Handler(final Component object, final ComponentManager manager)
          {
              m_object = object;
              m_manager = manager;
          }
  
          /**
           * <code>invoke</code> method, handles all method invocations for this
           * particular proxy.
           *
           * <p>
           *  Usually the invocation is passed through to the
           *  actual component the proxy wraps, unless the method belongs to
           *  the <code>ServiceLifecycle</code> interface where it is handled
           *  locally.
           * </p>
           *
           * @param proxy the <code>Proxy</code> instance the method was invoked on
           * @param method the invoked method <code>Method</code> object
           * @param args an <code>Object[]</code> array of arguments
           * @return an <code>Object</code> value or null if none
           * @exception Throwable if an error occurs
           */
          public Object invoke(Object proxy, Method method, Object[] args)
              throws Throwable
          {
              // if ServiceLifecycle.destroy() called, return to CM
              if (method.getDeclaringClass().equals(SL_CLASS))
              {
                  if (method.getName().equals(SL_DESTROY))
                  {
                      m_manager.release(m_object);
                  }
  
                  return null;
              }
              else // otherwise pass call to the real object
              {
                  return method.invoke(m_object, args);
              }
          }
      }
  }
  
  
  
  1.3       +3 -3      xml-cocoon2/src/scratchpad/src/org/apache/cocoon/reading/AxisRPCReader.java
  
  Index: AxisRPCReader.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/reading/AxisRPCReader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AxisRPCReader.java	10 Sep 2002 15:15:33 -0000	1.2
  +++ AxisRPCReader.java	25 Sep 2002 17:10:22 -0000	1.3
  @@ -48,6 +48,7 @@
    Software Foundation, please see <http://www.apache.org/>.
   
   */
  +
   package org.apache.cocoon.reading;
   
   import java.io.ByteArrayOutputStream;
  @@ -70,12 +71,11 @@
   import org.apache.avalon.framework.parameters.Parameters;
   
   import org.apache.avalon.excalibur.xml.Parser;
  -import org.apache.excalibur.source.Source;
  -import org.apache.excalibur.source.SourceResolver;
   
   import org.apache.cocoon.components.axis.SoapServer;
   import org.apache.cocoon.environment.http.HttpEnvironment;
   import org.apache.cocoon.environment.ObjectModelHelper;
  +import org.apache.cocoon.environment.SourceResolver;
   import org.apache.cocoon.ProcessingException;
   
   import org.apache.axis.AxisFault;
  @@ -152,7 +152,7 @@
        * @exception SAXException if an error occurs
        */
       public void setup(
  -        final org.apache.cocoon.environment.SourceResolver resolver, 
  +        final SourceResolver resolver, 
           final Map objectModel,
           final String src,
           final Parameters parameters
  
  
  
  1.2       +14 -6     xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/AbstractComposableService.java
  
  Index: AbstractComposableService.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/AbstractComposableService.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractComposableService.java	9 Sep 2002 17:53:17 -0000	1.1
  +++ AbstractComposableService.java	25 Sep 2002 17:10:23 -0000	1.2
  @@ -55,12 +55,20 @@
   import org.apache.avalon.framework.component.ComponentException;
   import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.avalon.framework.component.Composable;
  -
  -// FIXME(MC) or use Constants ?
  -import org.apache.cocoon.components.axis.SoapServer;
  +import org.apache.cocoon.components.axis.providers.AvalonProvider;
   
   /**
  - * Base class for providing Composable SOAP services
  + * Base class for providing Composable SOAP services.
  + *
  + * <p>
  + *  Note, this class is intended to be used in SOAP Services that require
  + *  references to Component's provided by the Cocoon Component Manager.
  + * </p>
  + *
  + * <p>
  + *  If you require full Avalon support in your SOAP Service, consider using
  + *  the AvalonProvider support built into Axis itself.
  + * </p>
    *
    * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
    * @version CVS $Id$
  @@ -110,7 +118,7 @@
       private void setComponentManager() throws ComponentException {
           compose(
               (ComponentManager) m_context.getProperty(
  -                SoapServer.COMPONENT_MANAGER
  +                AvalonProvider.COMPONENT_MANAGER
               )
           );
       }
  
  
  
  1.2       +12 -2     xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/AbstractLogEnabledService.java
  
  Index: AbstractLogEnabledService.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/AbstractLogEnabledService.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractLogEnabledService.java	9 Sep 2002 17:53:17 -0000	1.1
  +++ AbstractLogEnabledService.java	25 Sep 2002 17:10:23 -0000	1.2
  @@ -61,7 +61,17 @@
   import org.apache.cocoon.components.axis.SoapServer; // or use Constants ?
   
   /**
  - * Base class for providing LogEnabled SOAP services
  + * Base class for providing LogEnabled SOAP services.
  + *
  + * <p>
  + *  Note, this class is intended to be used for SOAP Services that require
  + *  accessing to a logging object for reporting purposes only.
  + * </p>
  + *
  + * <p>
  + *  If you require full Avalon support for your SOAP Service, then consider
  + *  using the AvalonProvider support built into Axis itself.
  + * </p>
    *
    * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
    * @version CVS $Id$
  
  
  
  1.2       +5 -3      xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/cache/DeploymentDescriptor.wsdd
  
  Index: DeploymentDescriptor.wsdd
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/webservices/cache/DeploymentDescriptor.wsdd,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeploymentDescriptor.wsdd	9 Sep 2002 17:53:18 -0000	1.1
  +++ DeploymentDescriptor.wsdd	25 Sep 2002 17:10:23 -0000	1.2
  @@ -1,9 +1,11 @@
   <deployment xmlns="http://xml.apache.org/axis/wsdd/"
               xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
   
  - <service name="Cocoon-Cache" provider="java:RPC">
  -  <parameter name="className" value="org.apache.cocoon.webservices.cache.Cache"/>
  -  <parameter name="allowedMethods" value="clear getSize"/>
  + <service name="Cocoon-Cache" provider="Handler">
  +  <parameter name="role" value="org.apache.excalibur.store.Store/TransientStore"/>
  +  <parameter name="className" value="org.apache.excalibur.store.Store"/>
  +  <parameter name="handlerClass" value="org.apache.cocoon.components.axis.providers.AvalonProvider"/>
  +  <parameter name="allowedMethods" value="clear size"/>
    </service>
   
   </deployment>
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org