All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis2.jaxws.ExceptionFactory Maven / Gradle / Ivy

/*
 * 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.
 * 

* Example Usage: // Example usage *

* 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. *

* 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); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy