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.interceptor;
019:
020: import java.lang.reflect.InvocationTargetException;
021: import java.lang.reflect.Method;
022: import java.util.ResourceBundle;
023:
024: import javax.xml.stream.XMLStreamWriter;
025:
026: import org.w3c.dom.Node;
027:
028: import org.apache.cxf.common.i18n.BundleUtils;
029: import org.apache.cxf.databinding.DataBinding;
030: import org.apache.cxf.databinding.DataWriter;
031: import org.apache.cxf.frontend.FaultInfoException;
032: import org.apache.cxf.message.Message;
033: import org.apache.cxf.phase.AbstractPhaseInterceptor;
034: import org.apache.cxf.phase.Phase;
035: import org.apache.cxf.service.Service;
036: import org.apache.cxf.service.model.BindingFaultInfo;
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.staxutils.W3CDOMStreamWriter;
041:
042: public class FaultOutInterceptor extends
043: AbstractPhaseInterceptor<Message> {
044: private static final ResourceBundle BUNDLE = BundleUtils
045: .getBundle(FaultOutInterceptor.class);
046:
047: public FaultOutInterceptor() {
048: super (Phase.PRE_PROTOCOL);
049: }
050:
051: public void handleMessage(Message message) throws Fault {
052: Fault f = (Fault) message.getContent(Exception.class);
053:
054: Throwable cause = f.getCause();
055: if (cause == null) {
056: return;
057: }
058:
059: BindingOperationInfo bop = message.getExchange().get(
060: BindingOperationInfo.class);
061: FaultInfo fi = getFaultForClass(bop, cause.getClass());
062:
063: if (cause instanceof Exception && fi != null) {
064: Exception ex = (Exception) cause;
065: Object bean = getFaultBean(cause, fi, message);
066: Service service = message.getExchange().get(Service.class);
067:
068: MessagePartInfo part = fi.getMessageParts().iterator()
069: .next();
070: DataBinding db = service.getDataBinding();
071:
072: if (isDOMSupported(db)) {
073: DataWriter<Node> writer = db.createWriter(Node.class);
074:
075: writer.write(bean, part, f.getOrCreateDetail());
076: } else {
077: XMLStreamWriter xsw = new W3CDOMStreamWriter(f
078: .getOrCreateDetail());
079:
080: DataWriter<XMLStreamWriter> writer = db
081: .createWriter(XMLStreamWriter.class);
082:
083: writer.write(bean, part, xsw);
084: }
085:
086: f.setMessage(ex.getMessage());
087: }
088: }
089:
090: private boolean isDOMSupported(DataBinding db) {
091: boolean supportsDOM = false;
092: for (Class c : db.getSupportedWriterFormats()) {
093: if (c.equals(Node.class)) {
094: supportsDOM = true;
095: }
096: }
097: return supportsDOM;
098: }
099:
100: protected Object getFaultBean(Throwable cause, FaultInfo faultPart,
101: Message message) {
102: if (FaultInfoException.class.isAssignableFrom(cause.getClass())) {
103: try {
104: Method method = cause.getClass().getMethod(
105: "getFaultInfo", new Class[0]);
106: return method.invoke(cause, new Object[0]);
107: } catch (InvocationTargetException e) {
108: throw new Fault(new org.apache.cxf.common.i18n.Message(
109: "INVOKE_FAULT_INFO", BUNDLE), e);
110: } catch (NoSuchMethodException e) {
111: throw new Fault(new org.apache.cxf.common.i18n.Message(
112: "NO_FAULT_INFO_METHOD", BUNDLE), e);
113: } catch (Exception e) {
114: throw new Fault(new org.apache.cxf.common.i18n.Message(
115: "NO_ACCCESS_FAULT_INFO", BUNDLE), e);
116: }
117: }
118: return cause;
119: }
120:
121: /**
122: * Find the correct Fault part for a particular exception.
123: *
124: * @param op
125: * @param class1
126: * @return
127: */
128: public FaultInfo getFaultForClass(BindingOperationInfo op,
129: Class class1) {
130: for (BindingFaultInfo bfi : op.getFaults()) {
131:
132: FaultInfo faultInfo = bfi.getFaultInfo();
133: Class<?> c = (Class) faultInfo.getProperty(Class.class
134: .getName());
135: if (c.isAssignableFrom(class1)) {
136: return faultInfo;
137: }
138: }
139:
140: return null;
141: }
142: }
|