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

Fri, 14 Feb 2014 11:13:45 +0100

author
mkos
date
Fri, 14 Feb 2014 11:13:45 +0100
changeset 515
6cd506508147
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8026188: Enhance envelope factory
Summary: Avoiding caching data initialized via TCCL in static context; fix also reviewed by Alexander Fomin
Reviewed-by: ahgross, mgrebac, skoivu

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

mercurial