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 [EMAIL PROTECTED] * * 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> * <service name="myservice" provider="java:Avalon"> * <parameter name="role" value="my.avalon.role.name"/> * <parameter name="className" value="my.avalon.roles.interface.name"/> * <parameter name="allowedMethods" value="allowed.methods"/> * </service> * </pre> * * </p> * * @author <a href="mailto:[EMAIL PROTECTED]">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 <parameter name="" value=""/> 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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]