You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2011/07/26 05:06:02 UTC
svn commit: r1150977 [2/5] - in /geronimo/bundles/trunk/axis2: ./
src/main/java/org/apache/axis2/handlers/
src/main/java/org/apache/axis2/handlers/addressing/
src/main/java/org/apache/axis2/jaxws/
src/main/java/org/apache/axis2/jaxws/addressing/factory...
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws;
+
+import org.apache.axiom.om.OMException;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.ws.ProtocolException;
+import javax.xml.ws.WebServiceException;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * ExceptionFactory is used to create exceptions within the JAX-WS implementation. There are several
+ * reasons for using a factory to create exceptions. 1. We can intercept all exception creation and
+ * add the appropriate logging/serviceability. 2. Exceptions are chained. ExceptionFactory can
+ * lengthen or reduce the cause chains as necessary to support the JAX-WS programming model. 3.
+ * Prevents construction of the same exception. Uses similar principles as
+ * AxisFault.makeException.
+ * <p/>
+ * Example Usage: // Example usage
+ * <p/>
+ * public fooMethod() throws WebServiceException { try{ ... } catch(Exception e){ throw
+ * ExceptionFactory.makeWebServiceException(e); } }
+ */
+public class ExceptionFactory {
+
+ protected static Log log =
+ LogFactory.getLog(ExceptionFactory.class.getName());
+
+ /** Private Constructor All methods are static. The private constructor prevents instantiation. */
+ private ExceptionFactory() {
+ }
+
+ /**
+ * Create a WebServiceException using the information from a given Throwable instance and message
+ *
+ * @param message
+ * @param throwable
+ * @return WebServiceException
+ */
+ public static WebServiceException makeWebServiceException(String message, Throwable throwable) {
+ try {
+ // See if there is already a WebServiceException (Note that the returned exception could be a ProtocolException or
+ // other kind of exception)
+ WebServiceException e =
+ (WebServiceException)findException(throwable, WebServiceException.class);
+ if (e == null) {
+ e = createWebServiceException(message, throwable);
+ }
+ return e;
+ } catch (RuntimeException re) {
+ // TODO
+ // This is not a good situation, an exception occurred while building the exception.
+ // This should never occur! For now log the problem and rethrow...we may revisit this later
+ if (log.isDebugEnabled()) {
+ log.debug(Messages.getMessage("exceptionDuringExceptionFlow"), re);
+ }
+ throw re;
+ }
+ }
+
+ /**
+ * Create a ProtocolException using the information from a Throwable and message
+ *
+ * @param message
+ * @param throwable
+ * @return ProtocolException
+ */
+ public static ProtocolException makeProtocolException(String message, Throwable throwable) {
+ try {
+ // See if there is already a ProtocolException
+ ProtocolException e =
+ (ProtocolException)findException(throwable, ProtocolException.class);
+ if (e == null) {
+ e = createProtocolException(message, throwable);
+ }
+ return e;
+ } catch (RuntimeException re) {
+ // TODO
+ // This is not a good situation, an exception occurred while building the exception.
+ // This should never occur! For now log the problem and rethrow...we may revisit this later
+ if (log.isDebugEnabled()) {
+ log.debug(Messages.getMessage("exceptionDuringExceptionFlow"), re);
+ }
+ throw re;
+ }
+ }
+
+ /**
+ * Make a WebServiceException with a given message
+ *
+ * @param message
+ * @return WebServiceException
+ */
+ public static WebServiceException makeWebServiceException(String message) {
+ return makeWebServiceException(message, null);
+ }
+
+ /**
+ * Create a WebServiceException using the information from a given Throwable instance
+ *
+ * @param throwable
+ * @return WebServiceException
+ */
+ public static WebServiceException makeWebServiceException(Throwable throwable) {
+ return makeWebServiceException(null, throwable);
+ }
+
+
+ /**
+ * Create a WebServiceException
+ *
+ * @param message
+ * @param t Throwable
+ * @return WebServiceException
+ */
+ private static WebServiceException createWebServiceException(String message, Throwable t) {
+
+ // We might have an embedded WebServiceException that has a good message on it
+ WebServiceException me = (WebServiceException)findException(t, WebServiceException.class);
+ if (me != null) {
+ String meMessage = me.getMessage();
+ if (meMessage != null) {
+ if (message == null) {
+ message = meMessage;
+ } else {
+ message = message + ": " + meMessage;
+ }
+ }
+ }
+
+ // Get the root cause. We want to strip out the intermediate exceptions (like AxisFault) because
+ // these won't make sense to the user.
+ Throwable rootCause = null;
+ if (t != null) {
+ rootCause = getRootCause(t);
+ }
+ rootCause = rootCause == null ? t : rootCause;
+ WebServiceException e = null;
+
+ // The root cause may not have a good message. We might want to enhance it
+ String enhancedMessage = enhanceMessage(rootCause);
+ if (enhancedMessage != null) {
+ if (message != null)
+ message = message + ": " + enhancedMessage;
+ else
+ message = enhancedMessage;
+ }
+
+ if (message != null) {
+ e = new WebServiceException(message, rootCause);
+ } else {
+ e = new WebServiceException(rootCause);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Create Exception:", e);
+ }
+ return e;
+ }
+
+ /**
+ * Create a ProtocolException
+ *
+ * @param message
+ * @param t Throwable
+ * @return ProtocolException
+ */
+ private static ProtocolException createProtocolException(String message, Throwable t) {
+ Throwable rootCause = null;
+ if (t != null) {
+ rootCause = getRootCause(t);
+ }
+ rootCause = rootCause == null ? t : rootCause;
+ ProtocolException e = null;
+ if (message != null) {
+ e = new ProtocolException(message, rootCause);
+ } else {
+ e = new ProtocolException(rootCause);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("create Exception:", e);
+ }
+ return e;
+ }
+
+ /**
+ * Return the exception or nested cause that is assignable from the specified class
+ *
+ * @param t Throwable
+ * @param cls
+ * @return Exception or null
+ */
+ private static Exception findException(Throwable t, Class cls) {
+ while (t != null) {
+ if (cls.isAssignableFrom(t.getClass())) {
+ return (Exception)t;
+ }
+ t = getCause(t);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the Throwable cause of the Exception. Some exceptions store the cause in a different
+ * field, which is why this method should be used when walking the causes.
+ *
+ * @param t Throwable
+ * @return Throwable or null
+ */
+ private static Throwable getCause(Throwable t) {
+ Throwable cause = null;
+
+ // Look for a specific cause for this kind of exception
+ if (t instanceof InvocationTargetException) {
+ cause = ((InvocationTargetException)t).getTargetException();
+ }
+
+ // If no specific cause, fall back to the general cause.
+ if (cause == null) {
+ cause = t.getCause();
+ }
+ return cause;
+ }
+
+ /**
+ * This method searches the causes of the specified throwable until it finds one that is
+ * acceptable as a "root" cause.
+ * <p/>
+ * Example: If t is an AxisFault, the code traverses to the next cause.
+ *
+ * @param t Throwable
+ * @return Throwable root cause
+ */
+ private static Throwable getRootCause(Throwable t) {
+ while (t != null) {
+ Throwable nextCause = null;
+ if (t instanceof InvocationTargetException ||
+ t instanceof OMException ||
+ t instanceof AxisFault) {
+ // Skip over this cause
+ nextCause = getCause(t);
+ if (nextCause == null) {
+ logRootCause(t);
+ return t;
+ }
+ t = nextCause;
+ } else {
+ // This is the root cause
+ logRootCause(t);
+ return t;
+ }
+ }
+ logRootCause(t);
+ return t;
+ }
+
+ /**
+ * Other developers may add additional criteria to give better error messages back to the user.
+ *
+ * @param t Throwable
+ * @return String a message that helps the user understand what caused the exception
+ */
+ private static String enhanceMessage(Throwable t) {
+ if (t == null)
+ return null;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos, true);
+ t.printStackTrace(ps);
+ String stackTrace = baos.toString();
+
+ // TODO better criteria
+ if ((t instanceof StackOverflowError) && (stackTrace.contains("JAXB")))
+ return Messages.getMessage("JABGraphProblem");
+
+ return null;
+ }
+ /**
+ * Log the root cause
+ * @param t
+ */
+ private static void logRootCause(Throwable t) {
+ // TODO Should certain throwables be logged elsewhere
+ if (log.isDebugEnabled()) {
+ log.debug("Root Cause:" + t.toString());
+ log.debug("stack:" + stackToString(t));
+ }
+ }
+
+ /**
+ * Get a string containing the stack of the specified exception
+ * @param e
+ * @return
+ */
+ public static String stackToString(Throwable e) {
+ java.io.StringWriter sw= new java.io.StringWriter();
+ java.io.BufferedWriter bw = new java.io.BufferedWriter(sw);
+ java.io.PrintWriter pw= new java.io.PrintWriter(bw);
+ e.printStackTrace(pw);
+ pw.close();
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * Give a target Throwable, set the initialCause Throwable as the initial cause on the target.
+ * @param target The throwable on which to set the initial cause
+ * @param initialCause The initial cause to set on the target Throwable.
+ */
+ public static void setInitialCause(Throwable target, Throwable initialCause) {
+ if (target != null && initialCause != null) {
+ // Create a WebServiceException from the initialCause throwable. This skips over things like
+ // AxisFault as a cause. Set the result on the target throwable.
+ try {
+ WebServiceException localException = ExceptionFactory.makeWebServiceException(initialCause);
+ target.initCause(localException.getCause());
+ } catch (Throwable t) {
+ // If the cause had already been set, then it can't be set again; it throws an exception.
+ if (log.isDebugEnabled()) {
+ log.debug("Caught exception trying to set initial cause on: " + target +". Initial cause: " +
+ initialCause + ". Caught: " + t);
+ }
+ }
+ }
+ }
+}
+
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/ExceptionFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws;
+
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.utility.JavaUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Controls error logging of exceptions thrown by the WebService application (provider, impl, etc.)
+ *
+ * This class logs errors for all non-checked exceptions.
+ * This class logs extensive debug information for all exceptions.
+ */
+public class WebServiceExceptionLogger {
+ private static final Log log = LogFactory.getLog(WebServiceExceptionLogger.class);
+
+ /**
+ * Logs an error if the exception thrown by @WebMethod m is not a checked exception.
+ * If debug logging is enabled, all exceptions are logged.
+ * @param method
+ * @param throwable
+ * @param logFully (if true then the exception is logged, otherwise only the class and stack is logged)
+ * @param serviceImplClass class of service implementation
+ * @param serviceInstance
+ * @param args Object[] arguments pass to method
+ */
+ public static void log(Method method,
+ Throwable throwable,
+ boolean logFully,
+ Class serviceImplClass,
+ Object serviceInstance,
+ Object[] args) {
+
+ // No matter what happens in this logging method, do not surface that exception. We don't want a logging
+ // failure to mask the real exception we are trying to log or affect subsequent processing.
+ try {
+
+ // Must have debug or error logging enabled
+ if (!log.isDebugEnabled() && !log.isErrorEnabled()) {
+ return;
+ }
+
+ // Get the root of the exception
+ Throwable rootT = null;
+ if (throwable instanceof InvocationTargetException) {
+ rootT = ((InvocationTargetException) throwable).getTargetException();
+ } else {
+ rootT = throwable;
+ }
+
+ String name = rootT.getClass().getName();
+ log.debug("693210: root Throwable, may cause index error: " + rootT.toString(), rootT);
+ String stack = stackToString(rootT);
+
+ // Determine if this is a checked exception or non-checked exception
+ Class checkedException = JavaUtils.getCheckedException(rootT, method);
+
+ if (checkedException == null) {
+ // Only log errors for non-checked exceptions
+ if (log.isErrorEnabled()) {
+ String text = "";
+ if (logFully) {
+ text = Messages.getMessage("failureLogger", name, rootT.toString());
+
+ } else {
+ text = Messages.getMessage("failureLogger", name, stack);
+ }
+ log.error(text);
+ }
+
+ }
+
+ // Full logging if debug is enabled.
+ if (log.isDebugEnabled()) {
+ log.debug("Exception invoking a method of " + serviceImplClass.toString()
+ + " of instance " + serviceInstance.toString());
+ log.debug("Exception type thrown: " + throwable.getClass().getName());
+ if (rootT != null) {
+ log.debug("Root Exception type thrown: " + rootT.getClass().getName());
+ }
+ if (checkedException != null) {
+ log.debug("The exception is an instance of checked exception: " +
+ checkedException.getName());
+ }
+
+ // Extra trace if ElementNSImpl incompatibility problem.
+ // The incompatibility exception occurs if the JAXB Unmarshaller
+ // unmarshals to a dom element instead of a generated object. This can
+ // result in class cast exceptions. The solution is usually a missing
+ // @XmlSeeAlso annotation in the jaxws or jaxb classes.
+ if (rootT.toString().contains("org.apache.xerces.dom.ElementNSImpl incompatible")) {
+ log.debug("This exception may be due to a missing @XmlSeeAlso in the client's jaxws or" +
+ " jaxb classes.");
+ }
+ log.debug("Method = " + method.toGenericString());
+ for (int i = 0; i < args.length; i++) {
+ String value =
+ (args[i] == null) ? "null"
+ : args[i].getClass().toString();
+ log.debug(" Argument[" + i + "] is " + value);
+ }
+ }
+ } catch (Throwable t) {
+ if (log.isDebugEnabled()) {
+ log.debug("Caught throwable in logger", t);
+ log.debug("While attempting to log original exception", throwable);
+ }
+ }
+ return;
+
+ }
+
+ /**
+ * Get a string containing the stack of the specified exception
+ *
+ * @param e
+ * @return
+ */
+ static String stackToString(Throwable e) {
+ java.io.StringWriter sw = new java.io.StringWriter();
+ java.io.BufferedWriter bw = new java.io.BufferedWriter(sw);
+ java.io.PrintWriter pw = new java.io.PrintWriter(bw);
+ e.printStackTrace(pw);
+ pw.close();
+ String text = sw.getBuffer().toString();
+ // Jump past the name of the throwable cause in the stack
+ int indexOfThrowable = text.indexOf("at");
+ if (indexOfThrowable > 0) {
+ text = text.substring(indexOfThrowable);
+ }
+ return text;
+ }
+
+
+}
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/WebServiceExceptionLogger.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws.addressing.factory.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.addressing.factory.Axis2EndpointReferenceFactory;
+import org.apache.axis2.jaxws.addressing.util.EndpointContextMap;
+import org.apache.axis2.jaxws.addressing.util.EndpointContextMapManager;
+import org.apache.axis2.jaxws.addressing.util.EndpointKey;
+import org.apache.axis2.jaxws.addressing.util.EndpointReferenceUtils;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.util.WSDL4JWrapper;
+import org.apache.axis2.jaxws.util.WSDLWrapper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class produces instances of {@link EndpointReference}.
+ *
+ */
+public class Axis2EndpointReferenceFactoryImpl implements Axis2EndpointReferenceFactory {
+
+ private static final Log log = LogFactory.getLog(Axis2EndpointReferenceFactoryImpl.class);
+
+ public Axis2EndpointReferenceFactoryImpl() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.addressing.factory.Axis2EndpointReferenceFactory#createEndpointReference(java.lang.String)
+ */
+ public EndpointReference createEndpointReference(String address) {
+ if (address == null)
+ throw new IllegalStateException("The endpoint address URI is null.");
+
+ return new EndpointReference(address);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.addressing.factory.Axis2EndpointReferenceFactory#createEndpointReference(javax.xml.namespace.QName, javax.xml.namespace.QName)
+ */
+ public EndpointReference createEndpointReference(QName serviceName, QName endpoint) {
+ EndpointKey key = new EndpointKey(serviceName, endpoint);
+ EndpointContextMap map = EndpointContextMapManager.getEndpointContextMap();
+
+ if (!map.containsKey(key))
+ throw new IllegalStateException("Unable to locate a deployed service that maps to the requested endpoint, " + key);
+
+ AxisService axisService = (AxisService) map.get(key);
+ String address = null;
+
+ try {
+ address = axisService.getEPRs()[0];
+ }
+ catch (Exception e) {
+ //do nothing
+ }
+
+ return createEndpointReference(address);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.addressing.factory.Axis2EndpointReferenceFactory#createEndpointReference(java.lang.String, javax.xml.namespace.QName, javax.xml.namespace.QName, java.lang.String, java.lang.String)
+ */
+ public EndpointReference createEndpointReference(String address, QName serviceName, QName portName, String wsdlDocumentLocation, String addressingNamespace) {
+ EndpointReference axis2EPR = null;
+
+ if (address != null) {
+ if (serviceName == null && portName != null) {
+ throw new IllegalStateException(
+ Messages.getMessage("axisEndpointReferenceFactoryErr",
+ portName.toString()));
+ }
+ axis2EPR = createEndpointReference(address);
+ }
+ else if (serviceName != null && portName != null) {
+ axis2EPR = createEndpointReference(serviceName, portName);
+ }
+ else {
+ throw new IllegalStateException(
+ Messages.getMessage("axisEndpointReferenceFactoryErr2"));
+ }
+
+ //TODO If no service name and port name are specified, but the wsdl location is
+ //specified, and the WSDL only contains one service and one port then maybe we
+ //should simply use those.
+ try {
+ //This code is locate here instead of in the createEndpointReference(QName, QName)
+ //method so that if the address is also specified the EPR metadata will still be
+ //filled in correctly.
+ EndpointReferenceUtils.addService(axis2EPR, serviceName, portName, addressingNamespace);
+
+ if (wsdlDocumentLocation != null) {
+
+ URL wsdlURL;
+ try {
+ wsdlURL = new URL(wsdlDocumentLocation);
+ } catch (MalformedURLException e) {
+ // just to keep it clean:
+ if (axis2EPR.getAddress().endsWith("/") && wsdlDocumentLocation.startsWith("/")) {
+ wsdlDocumentLocation = axis2EPR.getAddress() + wsdlDocumentLocation.substring(1);
+ } else {
+ wsdlDocumentLocation = axis2EPR.getAddress() + wsdlDocumentLocation;
+ }
+ }
+
+ wsdlURL = new URL(wsdlDocumentLocation);
+ // This is a temporary usage, so use a memory sensitive wrapper
+ WSDLWrapper wrapper = new WSDL4JWrapper(wsdlURL, true, 2);
+
+ if (serviceName != null) {
+
+ QName serviceNameNoTrailingSlash = new QName("");
+ // TODO: why in the world would we have to do this?
+ if (serviceName.getNamespaceURI().endsWith("/")) {
+ String ns = serviceName.getNamespaceURI();
+ serviceNameNoTrailingSlash = new QName(ns.substring(0, ns.length()-1), serviceName.getLocalPart());
+ }
+
+ if ((wrapper.getService(serviceName) == null) && (wrapper.getService(serviceNameNoTrailingSlash) == null)) {
+ throw new IllegalStateException(
+ Messages.getMessage("MissingServiceName",
+ serviceName.toString(),
+ wsdlDocumentLocation));
+ }
+ if (portName != null) {
+ String[] ports = wrapper.getPorts(serviceName);
+ // search the other name. TODO: again, why do we have to do this?
+ if (ports == null) {
+ ports = wrapper.getPorts(serviceNameNoTrailingSlash);
+ }
+ String portLocalName = portName.getLocalPart();
+ boolean found = false;
+
+ if (ports != null) {
+ for (String port : ports) {
+ // TODO: axis2 perhaps is deploying with "TypeImplPort" appended, but not reading/honoring the WSDL?
+ if (port.equals(portLocalName) || (port + "TypeImplPort").equals(portLocalName)) {
+ log.debug("found port: " + port);
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ throw new IllegalStateException(
+ Messages.getMessage("MissingPortName",
+ portName.toString(),
+ wsdlDocumentLocation));
+ }
+ log.debug("Setting wsdlDocumentLocation to " + wsdlDocumentLocation + " for EndpointReference at port " + portName);
+ EndpointReferenceUtils.addLocation(axis2EPR, portName.getNamespaceURI(), wsdlDocumentLocation, addressingNamespace);
+ }
+ }
+ }
+ }
+ catch (IllegalStateException ise) {
+ throw ise;
+ }
+ catch (Exception e) {
+ throw ExceptionFactory.
+ makeWebServiceException(Messages.getMessage("endpointRefCreationError"), e);
+ }
+ return axis2EPR;
+ }
+}
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/addressing/factory/impl/Axis2EndpointReferenceFactoryImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java?rev=1150977&r1=1150976&r2=1150977&view=diff
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java (original)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java Tue Jul 26 03:06:00 2011
@@ -849,6 +849,11 @@ public abstract class BaseDispatch<T> ex
// 4.3.2 conformance bullet 1 requires a ProtocolException here
ProtocolException pe =
MethodMarshallerUtils.createSystemException(msg.getXMLFault(), msg);
+ if (msgCtx.getLocalException() != null) {
+ // If a local exception occured, set it as the initial cause of the
+ // exception that will be returned
+ ExceptionFactory.setInitialCause(pe, msgCtx.getLocalException());
+ }
return pe;
} else if (msgCtx.getLocalException() != null) {
// use the factory, it'll throw the right thing:
Modified: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java?rev=1150977&r1=1150976&r2=1150977&view=diff
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java (original)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java Tue Jul 26 03:06:00 2011
@@ -401,6 +401,7 @@ public class JAXWSProxyHandler extends B
}
}
} catch (Exception ignore) {
+ ignore.printStackTrace();
}
}
}
@@ -594,7 +595,11 @@ public class JAXWSProxyHandler extends B
log.debug("Throwing a fault of type: " + object.getClass().getName() +
" back to the clent.");
}
-
+ if (msgCtx.getLocalException() != null) {
+ // If a local exception occured, set it as the initial cause of the
+ // exception that will be returned
+ ExceptionFactory.setInitialCause((Throwable) object, msgCtx.getLocalException());
+ }
return (Throwable)object;
} else if (msgCtx.getLocalException() != null) {
// use the factory, it'll throw the right thing:
@@ -669,7 +674,7 @@ public class JAXWSProxyHandler extends B
log.debug("Context ClassLoader is " + contextCL);
log.debug("Class ClassLoader is " + classCL);
}
-
+
if (classCL == null ||
contextCL == classCL) {
// Normal case: Use the context ClassLoader
@@ -678,37 +683,37 @@ public class JAXWSProxyHandler extends B
// Choose the better of the JAXBContexts
MarshalServiceRuntimeDescription marshalDesc =
MarshalServiceRuntimeDescriptionFactory.get(serviceDesc);
-
- // Get the JAXBContext for the context classloader
- Holder<JAXBUtils.CONSTRUCTION_TYPE> holder_contextCL = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
+
+ // Get the JAXBContext for the context classloader
+ Holder<JAXBUtils.CONSTRUCTION_TYPE> holder_contextCL = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
JAXBContext jbc_contextCL = null;
try {
- jbc_contextCL = JAXBUtils.getJAXBContext(marshalDesc.getPackages(),
+ jbc_contextCL = JAXBUtils.getJAXBContext(marshalDesc.getPackages(),
holder_contextCL,
- marshalDesc.getPackagesKey(),
- contextCL,
+ marshalDesc.getPackagesKey(),
+ contextCL,
null);
} catch (Throwable t) {
if (log.isDebugEnabled()) {
log.debug("Error occured..Processing continues " + t);
}
}
-
+
// Get the JAXBContext using the class's ClassLoader
- Holder<JAXBUtils.CONSTRUCTION_TYPE> holder_classCL = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
+ Holder<JAXBUtils.CONSTRUCTION_TYPE> holder_classCL = new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
JAXBContext jbc_classCL = null;
try {
- jbc_classCL = JAXBUtils.getJAXBContext(marshalDesc.getPackages(),
+ jbc_classCL = JAXBUtils.getJAXBContext(marshalDesc.getPackages(),
holder_classCL,
- marshalDesc.getPackagesKey(),
- classCL,
+ marshalDesc.getPackagesKey(),
+ classCL,
null);
} catch (Throwable t) {
if (log.isDebugEnabled()) {
log.debug("Error occured..Processing continues " + t);
}
}
-
+
List<String> classRefs = JAXBUtils.pruneDirectives(new TreeSet<String>(marshalDesc.getPackages()));
// Heuristic to choose the better classloader to marshal the
// data. Slight priority given to the classloader that loaded
@@ -731,7 +736,7 @@ public class JAXWSProxyHandler extends B
cl = classCL;
} else if (JAXBUtils.containsClasses(jbc_contextCL, classRefs)) {
cl = contextCL;
- } else if (holder_contextCL.value == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH &&
+ }else if (holder_contextCL.value == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH &&
holder_classCL.value == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
// Both were successfully built with the context path.
// Choose the one associated with the proxy class
@@ -758,15 +763,13 @@ public class JAXWSProxyHandler extends B
cl = classCL;
}
}
-
-
-
+
if (log.isDebugEnabled()) {
log.debug("Chosen ClassLoader is " + cls);
}
return cl;
}
-
+
private static ClassLoader getContextClassLoader() {
// NOTE: This method must remain private because it uses AccessController
ClassLoader cl = null;
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws.context;
+
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.addressing.util.EndpointReferenceUtils;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Element;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.namespace.QName;
+import javax.xml.ws.EndpointReference;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import java.net.URI;
+import java.security.Principal;
+
+public class WebServiceContextImpl implements WebServiceContext {
+
+ private static final Log log = LogFactory.getLog(WebServiceContext.class);
+
+ private MessageContext soapMessageContext;
+
+ public WebServiceContextImpl() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.ws.WebServiceContext#getMessageContext()
+ */
+ public MessageContext getMessageContext() {
+
+ // Note that the MessageContext might not be set up yet, or it
+ // may have been released because the lifetime of the WebServiceContext is completed.
+ if (log.isDebugEnabled()) {
+ if (soapMessageContext == null) {
+ log.debug("The MessageContext is not available");
+ }
+ }
+ return soapMessageContext;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.ws.WebServiceContext#getUserPrincipal()
+ */
+ public Principal getUserPrincipal() {
+
+ // Note that the MessageContext might not be set up yet, or it
+ // may have been released because the lifetime of the WebServiceContext is completed.
+ if (log.isDebugEnabled()) {
+ if (soapMessageContext == null) {
+ log.debug("The MessageContext is not available");
+ }
+ }
+
+ if (soapMessageContext != null) {
+ HttpServletRequest request = (HttpServletRequest) soapMessageContext.get(MessageContext.SERVLET_REQUEST);
+ if (request != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Access to the user Principal was requested.");
+ }
+ return request.getUserPrincipal();
+ }
+ else {
+ if (log.isDebugEnabled()) {
+ log.debug("No HttpServletRequest object was found, so no Principal can be found.");
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.ws.WebServiceContext#isUserInRole(java.lang.String)
+ */
+ public boolean isUserInRole(String user) {
+
+ // Note that the MessageContext might not be set up yet, or it
+ // may have been released because the lifetime of the WebServiceContext is completed.
+ if (log.isDebugEnabled()) {
+ if (soapMessageContext == null) {
+ log.debug("The MessageContext is not available");
+ }
+ }
+
+ if (soapMessageContext != null) {
+ HttpServletRequest request = (HttpServletRequest) soapMessageContext.get(MessageContext.SERVLET_REQUEST);
+ if (request != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Checking to see if the user in the role.");
+ }
+ return request.isUserInRole(user);
+ }
+ else {
+ if (log.isDebugEnabled()) {
+ log.debug("No HttpServletRequest object was found, so no role check can be performed.");
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public void setSoapMessageContext(MessageContext soapMessageContext) {
+ this.soapMessageContext = soapMessageContext;
+ }
+
+ public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element... referenceParameters) {
+
+ // Note that the MessageContext might not be set up yet, or it
+ // may have been released because the lifetime of the WebServiceContext is completed.
+ if (log.isDebugEnabled()) {
+ if (soapMessageContext == null) {
+ log.debug("The MessageContext is not available");
+ }
+ }
+
+ EndpointReference jaxwsEPR = null;
+ String addressingNamespace = EndpointReferenceUtils.getAddressingNamespace(clazz);
+
+ if (soapMessageContext != null) {
+ QName service = (QName) soapMessageContext.get(MessageContext.WSDL_SERVICE);
+ QName endpoint = (QName) soapMessageContext.get(MessageContext.WSDL_PORT);
+ String wsdlLocation = "?wsdl"; // let the webcontainer redirect us to the real WSDL URL; it knows where it is
+
+ org.apache.axis2.addressing.EndpointReference axis2EPR =
+ EndpointReferenceUtils.createAxis2EndpointReference(null, service, endpoint, wsdlLocation, addressingNamespace);
+
+ try {
+ EndpointReferenceUtils.addReferenceParameters(axis2EPR, referenceParameters);
+ jaxwsEPR = EndpointReferenceUtils.convertFromAxis2(axis2EPR, addressingNamespace);
+ }
+ catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(
+ Messages.getMessage("endpointRefConstructionFailure3", e.toString()));
+ }
+ }
+ else {
+ throw new IllegalStateException(
+ Messages.getMessage("webServiceContextErr1"));
+ }
+
+ return clazz.cast(jaxwsEPR);
+ }
+
+ public EndpointReference getEndpointReference(Element... referenceParameters) {
+ return getEndpointReference(W3CEndpointReference.class, referenceParameters);
+ }
+
+ /**
+ * Release objects held by WebServiceContext so that they can be garbage collected.
+ */
+ public void releaseResources() {
+ if (log.isDebugEnabled()) {
+ log.debug("Releasing WebServiceContextImpl resources");
+ }
+ soapMessageContext = null; // unlink the soapMessageContxt so that it can be gc'd
+ }
+}
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/context/WebServiceContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,697 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws.core.controller.impl;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants.Configuration;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.client.OperationClient;
+import org.apache.axis2.client.Options;
+import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.jaxws.BindingProvider;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.client.ClientUtils;
+import org.apache.axis2.jaxws.client.async.AsyncResponse;
+import org.apache.axis2.jaxws.client.async.CallbackFuture;
+import org.apache.axis2.jaxws.client.async.PollingFuture;
+import org.apache.axis2.jaxws.client.dispatch.XMLDispatch;
+import org.apache.axis2.jaxws.core.InvocationContext;
+import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.description.builder.MDQConstants;
+import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.factory.MessageFactory;
+import org.apache.axis2.jaxws.message.util.MessageUtils;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.util.Constants;
+import org.apache.axis2.jaxws.utility.ClassUtils;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.transport.http.HttpTransportProperties;
+import org.apache.axis2.util.ThreadContextMigratorUtil;
+import org.apache.axis2.wsdl.WSDLConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Response;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.Service.Mode;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.Future;
+
+/**
+ * The <tt>AxisInvocationController</tt> is an implementation of the {@link
+ * org.apache.axis2.jaxws.core.controller.InvocationController} interface. This implemenation uses
+ * the Axis2 engine to drive the request to the target service.
+ * <p/>
+ * For more information on how to invoke this class, please see the InvocationController interface
+ * comments.
+ */
+public class AxisInvocationController extends InvocationControllerImpl {
+
+ private static Log log = LogFactory.getLog(AxisInvocationController.class);
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#invoke(org.apache.axis2.jaxws.core.InvocationContext)
+ */
+ public MessageContext doInvoke(MessageContext request) {
+
+
+ // We need the qname of the operation being invoked to know which
+ // AxisOperation the OperationClient should be based on.
+ // Note that the OperationDesc is only set through use of the Proxy. Dispatch
+ // clients do not use operations, so the operationDesc will be null. In this
+ // case an anonymous AxisService with anoymouns AxisOperations for the supported
+ // MEPs will be created; and it is that anonymous operation name which needs to
+ // be specified
+ QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);
+
+ // TODO: Will the ServiceClient stick around on the InvocationContext
+ // or will we need some other mechanism of creating this?
+ // Try to create an OperationClient from the passed in ServiceClient
+ InvocationContext ic = request.getInvocationContext();
+ ServiceClient svcClient = ic.getServiceClient();
+ OperationClient opClient = createOperationClient(svcClient, operationName);
+
+ initOperationClient(opClient, request);
+
+ // Setup the client so that it knows whether the underlying call to
+ // Axis2 knows whether or not to start a listening port for an
+ // asynchronous response.
+ Boolean useAsyncMep = (Boolean)request.getProperty(Constants.USE_ASYNC_MEP);
+ if ((useAsyncMep != null && useAsyncMep.booleanValue())
+ || opClient.getOptions().isUseSeparateListener()) {
+ configureAsyncListener(opClient);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "Asynchronous message exchange not enabled. The invocation will be synchronous.");
+ }
+ }
+
+ org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
+ org.apache.axis2.context.MessageContext axisResponseMsgCtx = null;
+
+ MessageContext response = null;
+
+ AxisFault faultexception =
+ null; // don't let the keyword "fault" confuse you. This is an exception class.
+ try {
+ execute(opClient, true, axisRequestMsgCtx);
+ } catch (AxisFault af) {
+ // If an AxisFault was thrown, we need to cleanup the original OperationContext.
+ // Failure to do so results in a memory leak.
+ opClient.getOperationContext().cleanup();
+ // save the fault in case it didn't come from the endpoint, and thus
+ // there would be no message on the MessageContext
+ faultexception = af;
+ if (log.isDebugEnabled()) {
+ log.debug(axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " +
+ af.getMessage());
+ }
+ }
+
+ try {
+ // Collect the response MessageContext and envelope
+ axisResponseMsgCtx = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+ response = new MessageContext(axisResponseMsgCtx);
+ response.setMEPContext(request.getMEPContext());
+
+ // If there was a local exception caught and either there is no response message
+ // OR the response message exists but is not a fault, then set the local exception
+ // on the response and determine how to set the response message to correspond to
+ // the local exception
+ if ((faultexception != null) && ((response.getMessage() == null)
+ || (!response.getMessage().isFault()))) {
+ // Unless this behavior is disabled, convert the local exception to SOAPFaultException
+ // and set it on the response message. This will also cause the JAX-WS application handler
+ // handleFault() methods to be called.
+ if (!isSOAPFaultForLocalExceptionDisabled(response)) {
+ HandlerChainProcessor.convertToFaultMessage(request.getMEPContext(), faultexception,
+ request.getMessage().getProtocol());
+ response.setLocalException(faultexception);
+ } else {
+ // The behavior was disabled, so instead of creating a SOAPFaultException
+ // just create an empty message and set the local exception on it. This will cause the
+ // JAX-WS application handler handleMessage() methods to be called with the empty message.
+ MessageFactory factory =
+ (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+ Message message = factory.create(request.getMessage().getProtocol());
+ response.setLocalException(faultexception);
+ response.setMessage(message);
+ }
+ }
+
+ // This assumes that we are on the ultimate execution thread
+ ThreadContextMigratorUtil.performMigrationToThread(
+ Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx);
+ } catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+
+ return response;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeOneWay(org.apache.axis2.jaxws.core.InvocationContext)
+ */
+ public void doInvokeOneWay(MessageContext request) throws WebServiceException {
+ // Make sure that a one-way invocation does not attempt to use a separate channel
+ // for the response.
+ Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP);
+ if (useAsyncMep != null && useAsyncMep.booleanValue()) {
+ throw ExceptionFactory.makeWebServiceException(Messages.getMessage("onewayAsync"));
+ }
+
+ // We need the qname of the operation being invoked to know which
+ // AxisOperation the OperationClient should be based on.
+ // Note that the OperationDesc is only set through use of the Proxy. Dispatch
+ // clients do not use operations, so the operationDesc will be null. In this
+ // case an anonymous AxisService with anoymouns AxisOperations for the supported
+ // MEPs will be created; and it is that anonymous operation name which needs to
+ // be specified
+ QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_ONLY_OP);
+
+ InvocationContext ic = request.getInvocationContext();
+ ServiceClient svcClient = ic.getServiceClient();
+ OperationClient opClient = createOperationClient(svcClient, operationName);
+
+ initOperationClient(opClient, request);
+
+ org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
+
+ try {
+ execute(opClient, true, axisRequestMsgCtx);
+ } catch (AxisFault af) {
+ // JAXWS 6.4.2 says to throw it...
+ // Whatever exception we get here will not be from the server since a one-way
+ // invocation has no response. This will always be a SENDER fault
+ if (log.isDebugEnabled()) {
+ log.debug(axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " +
+ af.getMessage());
+ }
+ throw ExceptionFactory.makeWebServiceException(ClassUtils.getRootCause(af));
+ }
+
+ return;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext, javax.xml.ws.AsyncHandler)
+ */
+ public Future<?> doInvokeAsync(MessageContext request, AsyncHandler callback) {
+ // We need the qname of the operation being invoked to know which
+ // AxisOperation the OperationClient should be based on.
+ // Note that the OperationDesc is only set through use of the Proxy. Dispatch
+ // clients do not use operations, so the operationDesc will be null. In this
+ // case an anonymous AxisService with anoymouns AxisOperations for the supported
+ // MEPs will be created; and it is that anonymous operation name which needs to
+ // be specified
+ QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);
+
+ // TODO: Will the ServiceClient stick around on the InvocationContext
+ // or will we need some other mechanism of creating this?
+ // Try to create an OperationClient from the passed in ServiceClient
+ InvocationContext ic = request.getInvocationContext();
+ ServiceClient svcClient = ic.getServiceClient();
+ OperationClient opClient = createOperationClient(svcClient, operationName);
+
+ initOperationClient(opClient, request);
+
+ // Setup the client so that it knows whether the underlying call to
+ // Axis2 knows whether or not to start a listening port for an
+ // asynchronous response.
+ Boolean useAsyncMep = (Boolean)request.getProperty(Constants.USE_ASYNC_MEP);
+ if ((useAsyncMep != null && useAsyncMep.booleanValue())
+ || opClient.getOptions().isUseSeparateListener()) {
+ configureAsyncListener(opClient);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "Asynchronous message exchange not enabled. The invocation will be synchronous.");
+ }
+ }
+
+
+ CallbackFuture cbf = null;
+ if (callback != null) {
+ cbf = new CallbackFuture(ic, callback);
+ } else {
+ throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr4"));
+ }
+
+ opClient.setCallback(cbf);
+
+ org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
+ try {
+ execute(opClient, false, axisRequestMsgCtx);
+ } catch (AxisFault af) {
+ if (log.isDebugEnabled()) {
+ log.debug(axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " +
+ af.getMessage());
+ }
+ /*
+ * Save the exception on the callback. The client will learn about the error when they try to
+ * retrieve the async results via the Response.get(). "Errors that occur during the invocation
+ * are reported via an exception when the client attempts to retrieve the results of the operation."
+ * -- JAXWS 4.3.3
+ */
+
+ /*
+ * TODO: This is the appropriate thing to do here since the thrown exception may occur before
+ * we switch threads to the async thread. But... what happens if we've already switched over
+ * to the async thread? So far, it appears that the exception gets set on the FutureTask
+ * Concurrent object, and we never hit this scope. This means that later, when the client
+ * calls future.get(), no exception will be thrown despite what the spec says. The client can,
+ * however, retrieve errors via it's AsyncHandler.
+ */
+ cbf.onError(af);
+ }
+
+ return cbf.getFutureTask();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext)
+ */
+ public Response doInvokeAsync(MessageContext request) {
+ // We need the qname of the operation being invoked to know which
+ // AxisOperation the OperationClient should be based on.
+ // Note that the OperationDesc is only set through use of the Proxy. Dispatch
+ // clients do not use operations, so the operationDesc will be null. In this
+ // case an anonymous AxisService with anoymouns AxisOperations for the supported
+ // MEPs will be created; and it is that anonymous operation name which needs to
+ // be specified
+ QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP);
+
+ // TODO: Will the ServiceClient stick around on the InvocationContext
+ // or will we need some other mechanism of creating this?
+ // Try to create an OperationClient from the passed in ServiceClient
+ InvocationContext ic = request.getInvocationContext();
+ ServiceClient svcClient = ic.getServiceClient();
+ OperationClient opClient = createOperationClient(svcClient, operationName);
+
+ initOperationClient(opClient, request);
+
+ // Setup the client so that it knows whether the underlying call to
+ // Axis2 knows whether or not to start a listening port for an
+ // asynchronous response.
+ Boolean useAsyncMep = (Boolean)request.getProperty(Constants.USE_ASYNC_MEP);
+ if ((useAsyncMep != null && useAsyncMep.booleanValue())
+ || opClient.getOptions().isUseSeparateListener()) {
+ configureAsyncListener(opClient);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "Asynchronous message exchange not enabled. The invocation will be synchronous.");
+ }
+ }
+
+ AsyncResponse resp = ic.getAsyncResponseListener();
+ PollingFuture pf = new PollingFuture(ic);
+ opClient.setCallback(pf);
+
+ org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext();
+ try {
+ execute(opClient, false, axisRequestMsgCtx);
+ } catch (AxisFault af) {
+ if (log.isDebugEnabled()) {
+ log.debug(axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " +
+ af.getMessage());
+ }
+ /*
+ * Save the exception on the callback. The client will learn about the error when they try to
+ * retrieve the async results via the Response.get(). "Errors that occur during the invocation
+ * are reported via an exception when the client attempts to retrieve the results of the operation."
+ * -- JAXWS 4.3.3
+ */
+ pf.onError(af);
+ }
+
+ return resp;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#prepareRequest(org.apache.axis2.jaxws.core.MessageContext)
+ */
+ protected void prepareRequest(MessageContext requestMsgCtx) {
+ try {
+ if (requestMsgCtx == null) {
+ //throw an exception
+ }
+
+ org.apache.axis2.context.MessageContext axisRequestMsgCtx =
+ requestMsgCtx.getAxisMessageContext();
+
+ // The MessageContext will contain a Message object with the
+ // contents that need to be sent. We need to get those contents
+ // in a form that Axis2 can consume them, an AXIOM SOAPEnvelope.
+ MessageUtils.putMessageOnMessageContext(
+ requestMsgCtx.getMessage(), // JAX-WS Message
+ axisRequestMsgCtx // Axis 2 MessageContext
+ );
+
+ if (log.isDebugEnabled()) {
+ log.debug("Properties: " + axisRequestMsgCtx.getProperties().toString());
+ }
+ } catch (WebServiceException e) {
+ throw ExceptionFactory
+ .makeWebServiceException(Messages.getMessage("prepareRequestFail"));
+ } catch (AxisFault e) {
+ throw ExceptionFactory
+ .makeWebServiceException(Messages.getMessage("prepareRequestFail"), e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.core.controller.InvocationController#prepareResponse(org.apache.axis2.jaxws.core.MessageContext)
+ */
+ protected void prepareResponse(MessageContext responseMsgCtx) {
+
+ }
+
+ private void initOperationClient(OperationClient opClient, MessageContext requestMsgCtx) {
+ org.apache.axis2.context.MessageContext axisRequest = requestMsgCtx.getAxisMessageContext();
+ setupProperties(requestMsgCtx);//, axisRequest.getOptions());
+
+ if (opClient != null) {
+ Options options = opClient.getOptions();
+
+ // Get the target endpoint address and setup the TO endpoint
+ // reference. This tells us where the request is going.
+ EndpointReference toEPR = axisRequest.getTo();
+
+ if (toEPR == null) {
+ String targetUrl = (String)requestMsgCtx.getProperty(
+ BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
+ toEPR = new EndpointReference(targetUrl);
+ }
+
+ options.setTo(toEPR);
+
+ // Get the SOAP Action (if needed)
+ String soapAction = ClientUtils.findSOAPAction(requestMsgCtx);
+ options.setAction(soapAction);
+ // get the timeout from the request message context options as it may have been
+ // set by the user; if it was not set by the user we will just be setting the
+ // timeout on the operation client to the default so it will not have a negative
+ // effect; this logic is reliant on the fact the JAX-WS MessageContext is delegating
+ // to the Axis2 Options object and not storing its own property bag
+ long timeout = axisRequest.getOptions().getTimeOutInMilliSeconds();
+ options.setTimeOutInMilliSeconds(timeout);
+
+ // Use the OperationClient to send the request and put the contents
+ // of the response in the response MessageContext.
+ try {
+ // Set the Axis2 request MessageContext
+ opClient.addMessageContext(axisRequest);
+ }
+ catch (Exception e) {
+ //TODO: Do something
+ }
+ }
+ }
+
+ /**
+ * Use the provided ServiceClient instance to create an OperationClient identified by the
+ * operation QName provided.
+ *
+ * @param sc
+ * @param operation
+ * @return
+ */
+ private OperationClient createOperationClient(ServiceClient sc, QName operation) {
+ if (sc == null) {
+ throw ExceptionFactory
+ .makeWebServiceException(Messages.getMessage("ICCreateOpClientErr1"));
+ }
+ if (operation == null) {
+ throw ExceptionFactory
+ .makeWebServiceException(Messages.getMessage("ICCreateOpClientErr2"));
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Creating OperationClient for operation: " + operation);
+ }
+
+ try {
+ OperationClient client = sc.createClient(operation);
+ return client;
+ } catch (AxisFault e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+ }
+
+ private void configureAsyncListener(OperationClient client) {
+ client.getOptions().setUseSeparateListener(true);
+ }
+
+ /*
+ * TODO: This is a first pass at filtering the properties that are set on the
+ * RequestContext. Right now it's called during the invoke, but needs to be
+ * moved over to when the property is set. This should not be in the path
+ * of performance.
+ */
+ private void setupProperties(MessageContext mc) {//, Options ops) {
+
+ // Enable MTOM
+ Message msg = mc.getMessage();
+ if (msg.isMTOMEnabled()) {
+ mc.setProperty(Configuration.ENABLE_MTOM, "true");
+ }
+
+ // Enable session management
+ if (mc.isMaintainSession()) {
+ mc.getAxisMessageContext().getOptions().setManageSession(true);
+ }
+
+ // Check to see if BASIC_AUTH is enabled. If so, make sure
+ // the properties are setup correctly.
+ if (mc.containsKey(BindingProvider.USERNAME_PROPERTY) ||
+ mc.containsKey(BindingProvider.PASSWORD_PROPERTY)) {
+
+ String userId = (String)mc.getProperty(BindingProvider.USERNAME_PROPERTY);
+ if (userId == null || userId == "") {
+ throw ExceptionFactory
+ .makeWebServiceException(Messages.getMessage("checkUserName"));
+ }
+
+ String password = null;
+ if (mc.containsKey(BindingProvider.PASSWORD_PROPERTY)) {
+ password = (String) mc.getProperty(BindingProvider.PASSWORD_PROPERTY);
+ }
+
+ URL url = null;
+ try {
+ url = new URL((String)mc
+ .getProperty(BindingProvider.ENDPOINT_ADDRESS_PROPERTY));
+ }
+ catch (MalformedURLException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+
+ HttpTransportProperties.Authenticator basicAuthentication =
+ new HttpTransportProperties.Authenticator();
+ basicAuthentication.setUsername(userId);
+ basicAuthentication.setPassword(password);
+ basicAuthentication.setHost(url.getHost());
+ basicAuthentication.setPort(url.getPort());
+ basicAuthentication.setPreemptiveAuthentication(true);
+
+ mc.setProperty(HTTPConstants.AUTHENTICATE, basicAuthentication);
+ }
+ }
+
+ private static QName getOperationNameToUse(MessageContext requestMsgCtx, QName defaultOpName) {
+ // We need the qname of the operation being invoked to know which
+ // AxisOperation the OperationClient should be based on.
+ // Note that the OperationDesc is only set through use of the Proxy. Dispatch
+ // clients do not use operations, so the operationDesc will be null. In this
+ // case an anonymous AxisService with anonymous AxisOperations for the supported
+ // MEPs will be created; and it is that anonymous operation name which needs to
+ // be specified
+ QName operationName = null;
+ OperationDescription opDesc = requestMsgCtx.getOperationDescription();
+ if (opDesc != null && opDesc.getAxisOperation() != null)
+ operationName = opDesc.getName();
+ else
+ operationName = defaultOpName;
+ return operationName;
+ }
+
+ /**
+ * Executes the OperationClient
+ *
+ * @param opClient - Fully configured OperationClient
+ * @param block - Indicates if blocking or non-blocking execute
+ * @param msgContext - Axis2 MessageContext
+ * @throws AxisFault - All exceptions are returned as AxisFaults
+ */
+ private void execute(OperationClient opClient,
+ boolean block,
+ org.apache.axis2.context.MessageContext msgContext) throws AxisFault {
+ try {
+ // Pre-Execute logging and setup
+ preExecute(opClient, block, msgContext);
+ //check if Exception should be thrown on SOAPFault
+ if(log.isDebugEnabled()){
+ log.debug("Read throwExceptionIfSOAPFault property");
+ }
+ boolean exceptionToBeThrownOnSOAPFault= ClientUtils.getExceptionToBeThrownOnSOAPFault(msgContext);
+ if(log.isDebugEnabled()){
+ log.debug("throwExceptionIfSOAPFault property set on OperationClient.options "+ exceptionToBeThrownOnSOAPFault);
+ }
+ opClient.getOptions().setExceptionToBeThrownOnSOAPFault(exceptionToBeThrownOnSOAPFault);
+ // Invoke the OperationClient
+ opClient.execute(block);
+ } catch (Throwable e) {
+ // Catch all Throwable (including runtime exceptions and Errors) and
+ // throw as AxisFault.
+ // Since e could be a Throwable (or Error) instead of an Exception, we'll have to wrap it:
+ throw AxisFault.makeFault(ExceptionFactory.makeWebServiceException(e));
+ } finally {
+ // Post-Execute logging and setup
+ postExecute(opClient, block, msgContext);
+ }
+ }
+
+ /**
+ * Called by execute(OperationClient) to perform pre-execute tasks.
+ *
+ * @param opClient
+ * @param block - Indicates if blocking or non-blocking execute
+ * @param msgContext - Axis2 MessageContext
+ */
+ private void preExecute(OperationClient opClient,
+ boolean block,
+ org.apache.axis2.context.MessageContext msgContext) throws AxisFault {
+ // This assumes that we are on the ultimate execution thread
+
+ //This has to be here so the ThreadContextMigrator can pick it up.
+ msgContext.getOptions().setUseSeparateListener(opClient.getOptions().isUseSeparateListener());
+
+ ThreadContextMigratorUtil
+ .performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, msgContext);
+
+ //Enable the ThreadContextMigrator to override UseSeparateListener
+ opClient.getOptions().setUseSeparateListener(msgContext.getOptions().isUseSeparateListener());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Start OperationClient.execute(" + block + ")");
+ log.debug("UseSeparateListener: " + opClient.getOptions().isUseSeparateListener());
+ }
+ }
+
+ /**
+ * Called by execute(OperationClient) to perform post-execute tasks. Should be a mirror of
+ * preExecute
+ *
+ * @param opClient
+ * @param block - Indicates if blocking or non-blocking execute
+ * @param msgContext - Axis2 MessageContext
+ */
+ private void postExecute(OperationClient opClient,
+ boolean block,
+ org.apache.axis2.context.MessageContext msgContext) {
+ if (log.isDebugEnabled()) {
+ log.debug("End OperationClient.execute(" + block + ")");
+ }
+
+ /* TODO Currently this check causes SOAPMessageProviderTests to fail.
+ if (log.isDebugEnabled()) {
+ // Check for exploded OMSourcedElement
+ OMElement bodyElement = null;
+ if (msgContext.getEnvelope() != null &&
+ msgContext.getEnvelope().getBody() != null) {
+ bodyElement = msgContext.getEnvelope().getBody().getFirstElement();
+ }
+
+ boolean expanded = false;
+ if (bodyElement != null && bodyElement instanceof OMSourcedElementImpl) {
+ expanded = ((OMSourcedElementImpl)bodyElement).isExpanded();
+ }
+ // An exploded xml block may indicate a performance problem.
+ // In general an xml block should remain unexploded unless there is an
+ // outbound handler that touches the block.
+ if (expanded) {
+ log.debug("Developer Debug: Found an expanded xml block:" + bodyElement.getNamespace());
+ }
+ }
+ */
+ // Cleanup context
+ ThreadContextMigratorUtil
+ .performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, msgContext);
+ }
+
+ /**
+ * Answer if generation of SOAPFaultExceptions for local Exceptions should be disabled.. The default value
+ * is "false", meaning that if a local exception is encountered, a SOAPFaultException should be generated in
+ * the message AND the appropriate JAX-WS application handlers handleFault() methods should be called with
+ * that message.
+ *
+ * @param msgContext used to get the Axis2 Configuration Context to check for the property
+ * @return false if generating SOAPFaultExceptions for local exceptions should be be enabled (default)
+ * true if it should be disabled.
+ */
+ private static boolean isSOAPFaultForLocalExceptionDisabled(MessageContext msgContext) {
+ boolean soapFaultDisabled = false;
+
+ String flagValue = null;
+ org.apache.axis2.context.MessageContext axis2MC = msgContext.getAxisMessageContext();
+ if (axis2MC != null && axis2MC.getConfigurationContext() != null
+ && axis2MC.getConfigurationContext().getAxisConfiguration() != null ) {
+ AxisConfiguration axisConfig = axis2MC.getConfigurationContext().getAxisConfiguration();
+ Parameter parameter = axisConfig.getParameter(org.apache.axis2.jaxws.Constants.DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION);
+ if (parameter != null) {
+ flagValue = (String) parameter.getValue();
+ if (log.isDebugEnabled()) {
+ log.debug("Property set on configuration: " + org.apache.axis2.jaxws.Constants.DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION
+ + " with value " + flagValue);
+ }
+ }
+
+ // If the property was set, check the value.
+ if (flagValue != null) {
+ if ("false".equalsIgnoreCase(flagValue)) {
+ soapFaultDisabled = false;
+ } else if ("true".equalsIgnoreCase(flagValue)) {
+ soapFaultDisabled = true;
+ }
+ }
+ }
+ return soapFaultDisabled;
+ }
+
+}
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
------------------------------------------------------------------------------
svn:mime-type = text/plain