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.binding.xml.interceptor;
019:
020: import java.util.Collection;
021: import java.util.ResourceBundle;
022: import java.util.logging.Logger;
023:
024: import javax.xml.namespace.QName;
025: import javax.xml.stream.XMLStreamException;
026: import javax.xml.stream.XMLStreamReader;
027:
028: import org.apache.cxf.binding.xml.XMLFault;
029: import org.apache.cxf.bindings.xformat.XMLBindingMessageFormat;
030: import org.apache.cxf.common.i18n.BundleUtils;
031: import org.apache.cxf.endpoint.Endpoint;
032: import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor;
033: import org.apache.cxf.interceptor.DocLiteralInInterceptor;
034: import org.apache.cxf.interceptor.Fault;
035: import org.apache.cxf.message.Exchange;
036: import org.apache.cxf.message.Message;
037: import org.apache.cxf.phase.Phase;
038: import org.apache.cxf.service.model.BindingInfo;
039: import org.apache.cxf.service.model.BindingMessageInfo;
040: import org.apache.cxf.service.model.BindingOperationInfo;
041: import org.apache.cxf.service.model.MessagePartInfo;
042: import org.apache.cxf.service.model.OperationInfo;
043: import org.apache.cxf.staxutils.DepthXMLStreamReader;
044: import org.apache.cxf.staxutils.StaxUtils;
045:
046: public class XMLMessageInInterceptor extends
047: AbstractInDatabindingInterceptor {
048: private static final Logger LOG = Logger
049: .getLogger(XMLMessageInInterceptor.class.getName());
050: private static final ResourceBundle BUNDLE = BundleUtils
051: .getBundle(XMLMessageInInterceptor.class);
052:
053: public XMLMessageInInterceptor() {
054: this (Phase.UNMARSHAL);
055: }
056:
057: public XMLMessageInInterceptor(String phase) {
058: super (phase);
059: addBefore(DocLiteralInInterceptor.class.getName());
060: }
061:
062: public void handleMessage(Message message) throws Fault {
063: if (isGET(message)) {
064: LOG
065: .info("XMLMessageInInterceptor skipped in HTTP GET method");
066: return;
067: }
068: Endpoint ep = message.getExchange().get(Endpoint.class);
069:
070: XMLStreamReader xsr = message.getContent(XMLStreamReader.class);
071: DepthXMLStreamReader reader = new DepthXMLStreamReader(xsr);
072: if (!StaxUtils.toNextElement(reader)) {
073: throw new Fault(new org.apache.cxf.common.i18n.Message(
074: "NO_OPERATION_ELEMENT", BUNDLE));
075: }
076:
077: Exchange ex = message.getExchange();
078: QName startQName = reader.getName();
079: // handling xml fault message
080: if (startQName.getLocalPart().equals(XMLFault.XML_FAULT_ROOT)) {
081: message.getInterceptorChain().abort();
082:
083: if (ep.getInFaultObserver() != null) {
084: ep.getInFaultObserver().onMessage(message);
085: return;
086: }
087: }
088: // handling xml normal inbound message
089: BindingOperationInfo boi = ex.get(BindingOperationInfo.class);
090: boolean isRequestor = isRequestor(message);
091: if (boi == null) {
092: BindingInfo service = ep.getEndpointInfo().getBinding();
093: boi = getBindingOperationInfo(isRequestor, startQName,
094: service, xsr);
095: if (boi != null) {
096: ex.put(BindingOperationInfo.class, boi);
097: ex.put(OperationInfo.class, boi.getOperationInfo());
098: ex.setOneWay(boi.getOperationInfo().isOneWay());
099: }
100: } else {
101: BindingMessageInfo bmi = isRequestor ? boi.getOutput()
102: : boi.getInput();
103:
104: if (hasRootNode(bmi, startQName)) {
105: try {
106: xsr.nextTag();
107: } catch (XMLStreamException xse) {
108: throw new Fault(
109: new org.apache.cxf.common.i18n.Message(
110: "STAX_READ_EXC", BUNDLE));
111: }
112: }
113: }
114: }
115:
116: private BindingOperationInfo getBindingOperationInfo(
117: boolean isRequestor, QName startQName, BindingInfo bi,
118: XMLStreamReader xsr) {
119:
120: BindingOperationInfo match = null;
121: for (BindingOperationInfo boi : bi.getOperations()) {
122: BindingMessageInfo bmi;
123: if (!isRequestor) {
124: bmi = boi.getInput();
125: } else {
126: bmi = boi.getOutput();
127: }
128:
129: if (hasRootNode(bmi, startQName)) {
130: match = boi;
131: //Consume The rootNode tag
132: try {
133: xsr.nextTag();
134: } catch (XMLStreamException xse) {
135: throw new Fault(
136: new org.apache.cxf.common.i18n.Message(
137: "STAX_READ_EXC", BUNDLE));
138: }
139: } else {
140: Collection<MessagePartInfo> bodyParts = bmi
141: .getMessageParts();
142: if (bodyParts.size() == 1) {
143: MessagePartInfo p = bodyParts.iterator().next();
144: if (p.getConcreteName().equals(startQName)) {
145: match = boi;
146: }
147: }
148: }
149: }
150: return match;
151: }
152:
153: private boolean hasRootNode(BindingMessageInfo bmi, QName elName) {
154: XMLBindingMessageFormat xmf = bmi
155: .getExtensor(XMLBindingMessageFormat.class);
156: return xmf != null && xmf.getRootNode().equals(elName);
157: }
158: }
|