Author: richard.opalka(a)jboss.com
Date: 2009-09-29 08:50:46 -0400 (Tue, 29 Sep 2009)
New Revision: 10788
Added:
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandler.java
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandlerJSE.java
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXRPC.java
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXWS.java
Log:
[JBWS-2674][JBWS-2754] refactoring (WIP)
Added:
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandler.java
===================================================================
---
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandler.java
(rev 0)
+++
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandler.java 2009-09-29
12:50:46 UTC (rev 10788)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jboss.wsf.common.invocation;
+
+import java.lang.reflect.Method;
+
+import org.jboss.logging.Logger;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.invocation.Invocation;
+import org.jboss.wsf.spi.invocation.InvocationHandler;
+
+/**
+ * Base class for all Web Service invocation handlers inside AS.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
+ */
+public abstract class AbstractInvocationHandler extends InvocationHandler
+{
+
+ /** Logger. */
+ protected final Logger log = Logger.getLogger(this.getClass());
+
+ /**
+ * Constructor.
+ */
+ protected AbstractInvocationHandler()
+ {
+ super();
+ }
+
+ /**
+ * Creates invocation.
+ *
+ * @return invocation instance
+ */
+ public final Invocation createInvocation()
+ {
+ return new Invocation();
+ }
+
+ /**
+ * Initialization method.
+ *
+ * @param endpoint endpoint
+ */
+ public void init(final Endpoint endpoint)
+ {
+ // does nothing
+ }
+
+ /**
+ * Returns implementation method that will be used for invocation.
+ *
+ * @param implClass implementation endpoint class
+ * @param seiMethod SEI interface method used for method finding algorithm
+ * @return implementation method
+ * @throws NoSuchMethodException if implementation method wasn't found
+ */
+ protected final Method getImplMethod(final Class<?> implClass, final Method
seiMethod) throws NoSuchMethodException
+ {
+ final String methodName = seiMethod.getName();
+ final Class<?>[] paramTypes = seiMethod.getParameterTypes();
+
+ return implClass.getMethod(methodName, paramTypes);
+ }
+
+}
Added:
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandlerJSE.java
===================================================================
---
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandlerJSE.java
(rev 0)
+++
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/AbstractInvocationHandlerJSE.java 2009-09-29
12:50:46 UTC (rev 10788)
@@ -0,0 +1,181 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jboss.wsf.common.invocation;
+
+import java.lang.reflect.Method;
+
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.invocation.Invocation;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+
+/**
+ * Handles invocations on JSE endpoints.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
+ */
+public abstract class AbstractInvocationHandlerJSE extends AbstractInvocationHandler
+{
+
+ /**
+ * Constructor.
+ */
+ protected AbstractInvocationHandlerJSE()
+ {
+ super();
+ }
+
+ /**
+ * Retrieves endpoint implementation bean that will be used in invocation process.
+ *
+ * This method does the following steps:
+ *
+ * <ul>
+ * <li>tries to retrieve endpoint instance from invocation
context,</li>
+ * <li>if endpoint instance is not found it's created and instantiated
(lazy initialization)</li>
+ * <li>
+ * if endpoint instance was created all subclasses will be notified about this
event
+ * (using {@link #onEndpointInstantiated(Endpoint, Invocation)} template method).
+ * </li>
+ * </ul>
+ *
+ * @param endpoint to lookup implementation instance for
+ * @param invocation current invocation
+ * @return endpoint implementation
+ * @throws Exception if any error occurs
+ */
+ protected final Object getTargetBean(final Endpoint endpoint, final Invocation
invocation) throws Exception
+ {
+ final InvocationContext invocationContext = invocation.getInvocationContext();
+ Object targetBean = invocationContext.getTargetBean();
+
+ if (targetBean == null)
+ {
+ try
+ {
+ // create endpoint instance
+ final Class<?> endpointImplClass = endpoint.getTargetBeanClass();
+ targetBean = endpointImplClass.newInstance();
+ invocationContext.setTargetBean(targetBean);
+
+ // notify subclasses
+ this.onEndpointInstantiated(endpoint, invocation);
+ }
+ catch (Exception ex)
+ {
+ throw new IllegalStateException("Cannot create endpoint instance:
", ex);
+ }
+ }
+
+ return targetBean;
+ }
+
+ /**
+ * Invokes method on endpoint implementation.
+ *
+ * This method does the following steps:
+ *
+ * <ul>
+ * <li>lookups endpoint implementation method to be invoked,</li>
+ * <li>
+ * notifies all subclasses about endpoint method is going to be
invoked<br/>
+ * (using {@link #onBeforeInvocation(Invocation)} template method),
+ * </li>
+ * <li>endpoint implementation method is invoked,</li>
+ * <li>
+ * notifies all subclasses about endpoint method invocation was
completed<br/>
+ * (using {@link #onAfterInvocation(Invocation)} template method).
+ * </li>
+ * </ul>
+ *
+ * @param endpoint which method is going to be invoked
+ * @param invocation current invocation
+ * @throws Exception if any error occurs
+ */
+ public final void invoke(final Endpoint endpoint, final Invocation invocation) throws
Exception
+ {
+ try
+ {
+ // prepare for invocation
+ final Object targetBean = this.getTargetBean(endpoint, invocation);
+ final Class<?> implClass = targetBean.getClass();
+ final Method seiMethod = invocation.getJavaMethod();
+ final Method implMethod = this.getImplMethod(implClass, seiMethod);
+ final Object[] args = invocation.getArgs();
+
+ // notify subclasses
+ this.onBeforeInvocation(invocation);
+
+ // invoke implementation method
+ final Object retObj = implMethod.invoke(targetBean, args);
+
+ // set invocation result
+ invocation.setReturnValue(retObj);
+ }
+ catch (Exception e)
+ {
+ this.log.error("Method invocation failed with exception: " +
e.getMessage(), e);
+ // propagate exception
+ this.handleInvocationException(e);
+ }
+ finally
+ {
+ // notify subclasses
+ this.onAfterInvocation(invocation);
+ }
+ }
+
+ /**
+ * Template method for notifying subclasses that endpoint instance have been
instantiated.
+ *
+ * @param endpoint instantiated endpoint
+ * @param invocation current invocation
+ * @throws Exception subclasses have to throw exception on any failure
+ */
+ protected void onEndpointInstantiated(final Endpoint endpoint, final Invocation
invocation) throws Exception
+ {
+ // does nothing
+ }
+
+ /**
+ * Template method for notifying subclasses that endpoint method is going to be
invoked.
+ *
+ * @param invocation current invocation
+ * @throws Exception subclasses have to throw exception on any failure
+ */
+ protected void onBeforeInvocation(final Invocation invocation) throws Exception
+ {
+ // does nothing
+ }
+
+ /**
+ * Template method for notifying subclasses that endpoint method invocation was
completed.
+ *
+ * @param invocation current invocation
+ * @throws Exception subclasses have to throw exception on any failure
+ */
+ protected void onAfterInvocation(final Invocation invocation) throws Exception
+ {
+ // does nothing
+ }
+
+}
Added:
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXRPC.java
===================================================================
---
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXRPC.java
(rev 0)
+++
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXRPC.java 2009-09-29
12:50:46 UTC (rev 10788)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jboss.wsf.common.invocation;
+
+import javax.xml.rpc.server.ServiceLifecycle;
+import javax.xml.rpc.server.ServletEndpointContext;
+
+import org.jboss.wsf.spi.invocation.Invocation;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+
+/**
+ * Handles invocations on JAXRPC endpoints.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
+ */
+public final class InvocationHandlerJAXRPC extends AbstractInvocationHandlerJSE
+{
+
+ /**
+ * Constructor.
+ */
+ public InvocationHandlerJAXRPC()
+ {
+ super();
+ }
+
+ /**
+ * Calls {@link javax.xml.rpc.server.ServiceLifecycle#init(Object)}
+ * method on target bean if this bean implements
+ * {@link javax.xml.rpc.server.ServiceLifecycle} interface.
+ *
+ * @param invocation current invocation
+ * @throws Exception if any error occurs
+ */
+ @Override
+ protected void onBeforeInvocation(final Invocation invocation) throws Exception
+ {
+ final InvocationContext invocationContext = invocation.getInvocationContext();
+ final Object targetBean = invocationContext.getTargetBean();
+ final boolean isJaxrpcLifecycleBean = targetBean instanceof ServiceLifecycle;
+
+ if (isJaxrpcLifecycleBean)
+ {
+ final ServletEndpointContext sepContext =
invocationContext.getAttachment(ServletEndpointContext.class);
+ ((ServiceLifecycle) targetBean).init(sepContext);
+ }
+ }
+
+ /**
+ * Calls {@link javax.xml.rpc.server.ServiceLifecycle#destroy()}
+ * method on target bean if this bean implements
+ * {@link javax.xml.rpc.server.ServiceLifecycle} interface.
+ *
+ * @param invocation current invocation
+ * @throws Exception if any error occurs
+ */
+ @Override
+ protected void onAfterInvocation(final Invocation invocation) throws Exception
+ {
+ final InvocationContext invocationContext = invocation.getInvocationContext();
+ final Object targetBean = invocationContext.getTargetBean();
+ final boolean isJaxrpcLifecycleBean = targetBean instanceof ServiceLifecycle;
+
+ if (isJaxrpcLifecycleBean)
+ {
+ ((ServiceLifecycle) targetBean).destroy();
+ }
+ }
+
+}
Added:
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXWS.java
===================================================================
---
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXWS.java
(rev 0)
+++
common/branches/ropalka/src/main/java/org/jboss/wsf/common/invocation/InvocationHandlerJAXWS.java 2009-09-29
12:50:46 UTC (rev 10788)
@@ -0,0 +1,143 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jboss.wsf.common.invocation;
+
+import javax.xml.ws.WebServiceContext;
+
+import org.jboss.wsf.common.injection.InjectionHelper;
+import org.jboss.wsf.common.injection.PreDestroyHolder;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.invocation.Invocation;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+import org.jboss.wsf.spi.invocation.ResourceInjector;
+import org.jboss.wsf.spi.invocation.ResourceInjectorFactory;
+import org.jboss.wsf.spi.metadata.injection.InjectionsMetaData;
+
+/**
+ * Handles invocations on JAXWS endpoints.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
+ */
+public final class InvocationHandlerJAXWS extends AbstractInvocationHandlerJSE
+{
+
+ /** WebServiceContext injector. */
+ private final ResourceInjector wsContextInjector;
+
+ /**
+ * Constructor.
+ */
+ public InvocationHandlerJAXWS()
+ {
+ super();
+
+ final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
+ final ResourceInjectorFactory resourceInjectorFactory =
spiProvider.getSPI(ResourceInjectorFactory.class);
+ this.wsContextInjector = resourceInjectorFactory.newResourceInjector();
+ }
+
+ /**
+ * Injects resources on target bean and calls post construct method.
+ * Finally it registers target bean for predestroy phase.
+ *
+ * @param endpoint used for predestroy phase registration process
+ * @param invocation current invocation
+ */
+ @Override
+ protected void onEndpointInstantiated(final Endpoint endpoint, final Invocation
invocation)
+ {
+ final InjectionsMetaData injectionsMD =
endpoint.getAttachment(InjectionsMetaData.class);
+ final Object targetBean = this.getTargetBean(invocation);
+
+ this.log.debug("Injecting resources on JAXWS JSE endpoint: " +
targetBean);
+ InjectionHelper.injectResources(targetBean, injectionsMD);
+ this.log.debug("Calling postConstruct method on JAXWS JSE endpoint: " +
targetBean);
+ InjectionHelper.callPostConstructMethod(targetBean);
+
+ endpoint.addAttachment(PreDestroyHolder.class, new PreDestroyHolder(targetBean));
+ }
+
+ /**
+ * Injects webservice context on target bean.
+ *
+ * @param invocation current invocation
+ */
+ @Override
+ protected void onBeforeInvocation(final Invocation invocation)
+ {
+ final WebServiceContext wsContext = this.getWebServiceContext(invocation);
+
+ if (wsContext != null)
+ {
+ final Object targetBean = this.getTargetBean(invocation);
+ this.wsContextInjector.inject(targetBean, wsContext);
+ }
+ }
+
+ /**
+ * Cleanups injected webservice context on target bean.
+ *
+ * @param invocation current invocation
+ */
+ @Override
+ protected void onAfterInvocation(final Invocation invocation)
+ {
+ final WebServiceContext wsContext = this.getWebServiceContext(invocation);
+
+ if (wsContext != null)
+ {
+ final Object targetBean = this.getTargetBean(invocation);
+
+ this.wsContextInjector.inject(targetBean, null);
+ }
+ }
+
+ /**
+ * Returns WebServiceContext associated with this invocation.
+ *
+ * @param invocation current invocation
+ * @return web service context or null if not available
+ */
+ private WebServiceContext getWebServiceContext(final Invocation invocation)
+ {
+ final InvocationContext invocationContext = invocation.getInvocationContext();
+
+ return invocationContext.getAttachment(WebServiceContext.class);
+ }
+
+ /**
+ * Returns endpoint instance associated with current invocation.
+ *
+ * @param invocation current invocation
+ * @return target bean in invocation
+ */
+ private Object getTargetBean(final Invocation invocation)
+ {
+ final InvocationContext invocationContext = invocation.getInvocationContext();
+
+ return invocationContext.getTargetBean();
+ }
+
+}