src/share/jaxws_classes/com/sun/xml/internal/ws/fault/ExceptionBean.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.fault;
    28 import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
    29 import com.sun.xml.internal.ws.developer.ServerSideException;
    30 import org.w3c.dom.Element;
    31 import org.w3c.dom.Node;
    33 import javax.xml.bind.JAXBContext;
    34 import javax.xml.bind.JAXBException;
    35 import javax.xml.bind.Marshaller;
    36 import javax.xml.bind.PropertyException;
    37 import javax.xml.bind.annotation.XmlAttribute;
    38 import javax.xml.bind.annotation.XmlElement;
    39 import javax.xml.bind.annotation.XmlElementWrapper;
    40 import javax.xml.bind.annotation.XmlRootElement;
    41 import java.util.ArrayList;
    42 import java.util.List;
    44 /**
    45  * JAXB-bound bean that captures the exception and its call stack.
    46  *
    47  * <p>
    48  * This is used to capture the stack trace of the server side error and
    49  * send that over to the client.
    50  *
    51  * @author Kohsuke Kawaguchi
    52  */
    53 @XmlRootElement(namespace=ExceptionBean.NS,name=ExceptionBean.LOCAL_NAME)
    54 final class ExceptionBean {
    55     /**
    56      * Converts the given {@link Throwable} into an XML representation
    57      * and put that as a DOM tree under the given node.
    58      */
    59     public static void marshal( Throwable t, Node parent ) throws JAXBException {
    60         Marshaller m = JAXB_CONTEXT.createMarshaller();
    61         try {
    62                 m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper",nsp);
    63         } catch (PropertyException pe) {}
    64         m.marshal(new ExceptionBean(t), parent );
    65     }
    67     /**
    68      * Does the reverse operation of {@link #marshal(Throwable, Node)}. Constructs an
    69      * {@link Exception} object from the XML.
    70      */
    71     public static ServerSideException unmarshal( Node xml ) throws JAXBException {
    72         ExceptionBean e = (ExceptionBean) JAXB_CONTEXT.createUnmarshaller().unmarshal(xml);
    73         return e.toException();
    74     }
    76     @XmlAttribute(name="class")
    77     public String className;
    78     @XmlElement
    79     public String message;
    80     @XmlElementWrapper(namespace=NS,name="stackTrace")
    81     @XmlElement(namespace=NS,name="frame")
    82     public List<StackFrame> stackTrace = new ArrayList<StackFrame>();
    83     @XmlElement(namespace=NS,name="cause")
    84     public ExceptionBean cause;
    86     // so that people noticed this fragment can turn it off
    87     @XmlAttribute
    88     public String note = "To disable this feature, set "+SOAPFaultBuilder.CAPTURE_STACK_TRACE_PROPERTY+" system property to false";
    90     ExceptionBean() {// for JAXB
    91     }
    93     /**
    94      * Creates an {@link ExceptionBean} tree that represents the given {@link Throwable}.
    95      */
    96     private ExceptionBean(Throwable t) {
    97         this.className = t.getClass().getName();
    98         this.message = t.getMessage();
   100         for (StackTraceElement f : t.getStackTrace()) {
   101             stackTrace.add(new StackFrame(f));
   102         }
   104         Throwable cause = t.getCause();
   105         if(t!=cause && cause!=null)
   106             this.cause = new ExceptionBean(cause);
   107     }
   109     private ServerSideException toException() {
   110         ServerSideException e = new ServerSideException(className,message);
   111         if(stackTrace!=null) {
   112             StackTraceElement[] ste = new StackTraceElement[stackTrace.size()];
   113             for( int i=0; i<stackTrace.size(); i++ )
   114                 ste[i] = stackTrace.get(i).toStackTraceElement();
   115             e.setStackTrace(ste);
   116         }
   117         if(cause!=null)
   118             e.initCause(cause.toException());
   119         return e;
   120     }
   122     /**
   123      * Captures one stack frame.
   124      */
   125     static final class StackFrame {
   126         @XmlAttribute(name="class")
   127         public String declaringClass;
   128         @XmlAttribute(name="method")
   129         public String methodName;
   130         @XmlAttribute(name="file")
   131         public String fileName;
   132         @XmlAttribute(name="line")
   133         public String lineNumber;
   135         StackFrame() {// for JAXB
   136         }
   138         public StackFrame(StackTraceElement ste) {
   139             this.declaringClass = ste.getClassName();
   140             this.methodName = ste.getMethodName();
   141             this.fileName = ste.getFileName();
   142             this.lineNumber = box(ste.getLineNumber());
   143         }
   145         private String box(int i) {
   146             if(i>=0) return String.valueOf(i);
   147             if(i==-2)   return "native";
   148             return "unknown";
   149         }
   151         private int unbox(String v) {
   152             try {
   153                 return Integer.parseInt(v);
   154             } catch (NumberFormatException e) {
   155                 if ("native".equals(v)) {
   156                     return -2;
   157                 }
   158                 return -1;
   159             }
   160         }
   162         private StackTraceElement toStackTraceElement() {
   163             return new StackTraceElement(declaringClass,methodName,fileName,unbox(lineNumber));
   164         }
   165     }
   167     /**
   168      * Checks if the given element is the XML representation of {@link ExceptionBean}.
   169      */
   170     public static boolean isStackTraceXml(Element n) {
   171         return LOCAL_NAME.equals(n.getLocalName()) && NS.equals(n.getNamespaceURI());
   172     }
   174     private static final JAXBContext JAXB_CONTEXT;
   176     /**
   177      * Namespace URI.
   178      */
   179     /*package*/ static final String NS = "http://jax-ws.dev.java.net/";
   181     /*package*/ static final String LOCAL_NAME = "exception";
   183     static {
   184         try {
   185             JAXB_CONTEXT = JAXBContext.newInstance(ExceptionBean.class);
   186         } catch (JAXBException e) {
   187             // this must be a bug in our code
   188             throw new Error(e);
   189         }
   190     }
   192     private static final NamespacePrefixMapper nsp = new NamespacePrefixMapper() {
   193         public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
   194             if (NS.equals(namespaceUri)) {
   195                 return "";
   196             }
   197             return suggestion;
   198         }
   199     };
   200 }

mercurial