001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.jaxws.interceptors;
019:
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.util.ResourceBundle;
023:
024: import javax.xml.namespace.QName;
025: import javax.xml.ws.WebFault;
026:
027: import org.w3c.dom.Node;
028:
029: import org.apache.cxf.common.i18n.BundleUtils;
030: import org.apache.cxf.databinding.DataWriter;
031: import org.apache.cxf.interceptor.Fault;
032: import org.apache.cxf.jaxws.support.JaxWsServiceConfiguration;
033: import org.apache.cxf.message.Message;
034: import org.apache.cxf.phase.AbstractPhaseInterceptor;
035: import org.apache.cxf.phase.Phase;
036: import org.apache.cxf.service.Service;
037: import org.apache.cxf.service.model.BindingOperationInfo;
038: import org.apache.cxf.service.model.FaultInfo;
039: import org.apache.cxf.service.model.MessagePartInfo;
040: import org.apache.cxf.service.model.OperationInfo;
041:
042: public class WebFaultOutInterceptor extends
043: AbstractPhaseInterceptor<Message> {
044: private static final ResourceBundle BUNDLE = BundleUtils
045: .getBundle(JaxWsServiceConfiguration.class);
046:
047: public WebFaultOutInterceptor() {
048: super (Phase.PRE_PROTOCOL);
049: }
050:
051: private QName getFaultName(WebFault wf) {
052: return new QName(wf.targetNamespace(), wf.name());
053: }
054:
055: private WebFault getWebFaultAnnotation(Class<?> t) {
056: WebFault fault = t.getAnnotation(WebFault.class);
057: if (fault == null && t.getSuperclass() != null
058: && Throwable.class.isAssignableFrom(t.getSuperclass())) {
059: fault = getWebFaultAnnotation(t.getSuperclass());
060: }
061: return fault;
062: }
063:
064: public void handleMessage(Message message) throws Fault {
065: Fault f = (Fault) message.getContent(Exception.class);
066:
067: Throwable cause = f.getCause();
068: WebFault fault = null;
069: if (cause != null) {
070: fault = getWebFaultAnnotation(cause.getClass());
071: }
072: if (cause instanceof Exception && fault != null) {
073: Exception ex = (Exception) cause;
074: try {
075: Method method = cause.getClass().getMethod(
076: "getFaultInfo", new Class[0]);
077: Object faultInfo = method.invoke(cause, new Object[0]);
078:
079: Service service = message.getExchange().get(
080: Service.class);
081:
082: DataWriter<Node> writer = service.getDataBinding()
083: .createWriter(Node.class);
084:
085: OperationInfo op = message.getExchange().get(
086: BindingOperationInfo.class).getOperationInfo();
087: QName faultName = getFaultName(fault);
088: MessagePartInfo part = getFaultMessagePart(faultName,
089: op);
090: writer.write(faultInfo, part, f.getOrCreateDetail());
091:
092: f.setMessage(ex.getMessage());
093: } catch (InvocationTargetException e) {
094: throw new Fault(new org.apache.cxf.common.i18n.Message(
095: "INVOCATION_TARGET_EXC", BUNDLE), e);
096: } catch (NoSuchMethodException e) {
097: throw new Fault(new org.apache.cxf.common.i18n.Message(
098: "NO_GETFAULTINFO_METHOD", BUNDLE), e);
099: } catch (IllegalArgumentException e) {
100: throw new Fault(new org.apache.cxf.common.i18n.Message(
101: "COULD_NOT_INVOKE", BUNDLE), e);
102: } catch (IllegalAccessException e) {
103: throw new Fault(new org.apache.cxf.common.i18n.Message(
104: "COULD_NOT_INVOKE", BUNDLE), e);
105: }
106: }
107: }
108:
109: private MessagePartInfo getFaultMessagePart(QName qname,
110: OperationInfo op) {
111: for (FaultInfo faultInfo : op.getFaults()) {
112: for (MessagePartInfo mpi : faultInfo.getMessageParts()) {
113: String ns = null;
114: if (mpi.isElement()) {
115: ns = mpi.getElementQName().getNamespaceURI();
116: } else {
117: ns = mpi.getTypeQName().getNamespaceURI();
118: }
119: if (qname.getLocalPart().equals(
120: mpi.getConcreteName().getLocalPart())
121: && qname.getNamespaceURI().equals(ns)) {
122: return mpi;
123: }
124: }
125:
126: }
127: return null;
128: }
129:
130: }
|