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.net.URI;
021: import java.net.URISyntaxException;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.ResourceBundle;
025: import java.util.logging.Logger;
026:
027: import javax.xml.namespace.QName;
028: import javax.xml.stream.XMLStreamConstants;
029: import javax.xml.stream.XMLStreamReader;
030:
031: import org.apache.cxf.common.i18n.BundleUtils;
032: import org.apache.cxf.databinding.DataReader;
033: import org.apache.cxf.endpoint.Endpoint;
034: import org.apache.cxf.message.Message;
035: import org.apache.cxf.message.MessageContentsList;
036: import org.apache.cxf.phase.Phase;
037: import org.apache.cxf.service.model.BindingOperationInfo;
038: import org.apache.cxf.service.model.EndpointInfo;
039: import org.apache.cxf.service.model.MessageInfo;
040: import org.apache.cxf.service.model.MessagePartInfo;
041: import org.apache.cxf.service.model.OperationInfo;
042: import org.apache.cxf.service.model.ServiceInfo;
043: import org.apache.cxf.service.model.ServiceModelUtil;
044: import org.apache.cxf.staxutils.DepthXMLStreamReader;
045: import org.apache.cxf.staxutils.StaxUtils;
046:
047: public class WrappedInInterceptor extends
048: AbstractInDatabindingInterceptor {
049: private static final Logger LOG = Logger
050: .getLogger(WrappedInInterceptor.class.getName());
051: private static final ResourceBundle BUNDLE = BundleUtils
052: .getBundle(WrappedInInterceptor.class);
053:
054: public WrappedInInterceptor() {
055: super (Phase.UNMARSHAL);
056: addAfter(URIMappingInterceptor.class.getName());
057: }
058:
059: public void handleMessage(Message message) {
060: if (isGET(message) && message.getContent(List.class) != null) {
061: LOG.info("WrappedInInterceptor skipped in HTTP GET method");
062: return;
063: }
064:
065: DepthXMLStreamReader xmlReader = getXMLStreamReader(message);
066:
067: // Trying to find the operation name from the XML.
068: if (!StaxUtils.toNextElement(xmlReader)) {
069: // body may be empty for partial response to decoupled request
070: return;
071: }
072:
073: BindingOperationInfo operation = message.getExchange().get(
074: BindingOperationInfo.class);
075: boolean requestor = isRequestor(message);
076:
077: if (operation == null) {
078: String local = xmlReader.getLocalName();
079: if (requestor && local.endsWith("Response")) {
080: local = local.substring(0, local.length() - 8);
081: }
082:
083: // TODO: Allow overridden methods.
084: operation = ServiceModelUtil.getOperation(message
085: .getExchange(), local);
086: if (operation == null) {
087: throw new Fault(new org.apache.cxf.common.i18n.Message(
088: "NO_OPERATION", BUNDLE, local),
089: Fault.FAULT_CODE_CLIENT);
090: }
091:
092: }
093:
094: ServiceInfo si = operation.getBinding().getService();
095:
096: DataReader<XMLStreamReader> dr = getDataReader(message);
097: MessageContentsList objects = new MessageContentsList();
098:
099: MessageInfo msgInfo = setMessage(message, operation, requestor,
100: si);
101:
102: // Determine if there is a wrapper class
103: if (operation.isUnwrappedCapable()
104: && msgInfo.getMessageParts().get(0).getTypeClass() != null) {
105: Object wrappedObject = dr.read(msgInfo.getMessageParts()
106: .get(0), xmlReader);
107: objects
108: .put(msgInfo.getMessageParts().get(0),
109: wrappedObject);
110:
111: } else {
112: // Unwrap each part individually if we don't have a wrapper
113:
114: if (operation.isUnwrappedCapable()) {
115: operation = operation.getUnwrappedOperation();
116: }
117:
118: msgInfo = setMessage(message, operation, requestor, si);
119: List<MessagePartInfo> messageParts = msgInfo
120: .getMessageParts();
121: Iterator<MessagePartInfo> itr = messageParts.iterator();
122:
123: // advance just past the wrapped element so we don't get stuck
124: if (xmlReader.getEventType() == XMLStreamConstants.START_ELEMENT) {
125: StaxUtils.nextEvent(xmlReader);
126: }
127:
128: // loop through each child element
129: while (StaxUtils.toNextElement(xmlReader)) {
130: MessagePartInfo part = itr.next();
131: objects.put(part, dr.read(part, xmlReader));
132: }
133: }
134:
135: message.setContent(List.class, objects);
136: }
137:
138: private MessageInfo setMessage(Message message,
139: BindingOperationInfo operation, boolean requestor,
140: ServiceInfo si) {
141: MessageInfo msgInfo = getMessageInfo(message, operation,
142: requestor);
143: message.put(MessageInfo.class, msgInfo);
144:
145: message.getExchange()
146: .put(BindingOperationInfo.class, operation);
147: message.getExchange().put(OperationInfo.class,
148: operation.getOperationInfo());
149: message.getExchange().setOneWay(
150: operation.getOperationInfo().isOneWay());
151:
152: //Set standard MessageContext properties required by JAX_WS, but not specific to JAX_WS.
153: message.put(Message.WSDL_OPERATION, operation.getName());
154:
155: QName serviceQName = si.getName();
156: message.put(Message.WSDL_SERVICE, serviceQName);
157:
158: QName interfaceQName = si.getInterface().getName();
159: message.put(Message.WSDL_INTERFACE, interfaceQName);
160:
161: EndpointInfo endpointInfo = message.getExchange().get(
162: Endpoint.class).getEndpointInfo();
163: QName portQName = endpointInfo.getName();
164: message.put(Message.WSDL_PORT, portQName);
165:
166: String address = endpointInfo.getAddress();
167: URI wsdlDescription = null;
168: try {
169: wsdlDescription = new URI(address + "?wsdl");
170: } catch (URISyntaxException e) {
171: //do nothing
172: }
173: message.put(Message.WSDL_DESCRIPTION, wsdlDescription);
174:
175: return msgInfo;
176: }
177: }
|