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.util.Collection;
021: import java.util.Iterator;
022: import java.util.ResourceBundle;
023:
024: import javax.xml.namespace.QName;
025: import javax.xml.stream.XMLStreamReader;
026: import javax.xml.validation.Schema;
027:
028: import org.w3c.dom.Node;
029:
030: import org.apache.cxf.common.i18n.BundleUtils;
031: import org.apache.cxf.databinding.DataReader;
032: import org.apache.cxf.endpoint.Endpoint;
033: import org.apache.cxf.message.Exchange;
034: import org.apache.cxf.message.Message;
035: import org.apache.cxf.phase.AbstractPhaseInterceptor;
036: import org.apache.cxf.service.Service;
037: import org.apache.cxf.service.model.BindingMessageInfo;
038: import org.apache.cxf.service.model.BindingOperationInfo;
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.ServiceModelUtil;
043: import org.apache.cxf.staxutils.DepthXMLStreamReader;
044: import org.apache.cxf.wsdl.EndpointReferenceUtils;
045:
046: public abstract class AbstractInDatabindingInterceptor extends
047: AbstractPhaseInterceptor<Message> {
048:
049: private static final QName XSD_ANY = new QName(
050: "http://www.w3.org/2001/XMLSchema", "anyType", "xsd");
051:
052: private static final ResourceBundle BUNDLE = BundleUtils
053: .getBundle(AbstractInDatabindingInterceptor.class);
054:
055: public AbstractInDatabindingInterceptor(String phase) {
056: super (phase);
057: }
058:
059: public AbstractInDatabindingInterceptor(String i, String phase) {
060: super (i, phase);
061: }
062:
063: protected boolean isRequestor(Message message) {
064: return Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE));
065: }
066:
067: protected <T> DataReader<T> getDataReader(Message message,
068: Class<T> input) {
069: Service service = ServiceModelUtil.getService(message
070: .getExchange());
071: DataReader<T> dataReader = service.getDataBinding()
072: .createReader(input);
073: if (dataReader == null) {
074: throw new Fault(new org.apache.cxf.common.i18n.Message(
075: "NO_DATAREADER", BUNDLE, service.getName()));
076: }
077: dataReader.setAttachments(message.getAttachments());
078: setSchemaInMessage(service, message, dataReader);
079:
080: return dataReader;
081: }
082:
083: protected DataReader<XMLStreamReader> getDataReader(Message message) {
084: return getDataReader(message, XMLStreamReader.class);
085: }
086:
087: protected DataReader<Node> getNodeDataReader(Message message) {
088: return getDataReader(message, Node.class);
089: }
090:
091: private void setSchemaInMessage(Service service, Message message,
092: DataReader<?> reader) {
093: Object en = message
094: .getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
095: if (Boolean.TRUE.equals(en) || "true".equals(en)) {
096: //all serviceInfos have the same schemas
097: Schema schema = EndpointReferenceUtils.getSchema(service
098: .getServiceInfos().get(0));
099: reader.setSchema(schema);
100: }
101: }
102:
103: protected DepthXMLStreamReader getXMLStreamReader(Message message) {
104: XMLStreamReader xr = message.getContent(XMLStreamReader.class);
105: if (xr instanceof DepthXMLStreamReader) {
106: return (DepthXMLStreamReader) xr;
107: }
108: DepthXMLStreamReader dr = new DepthXMLStreamReader(xr);
109: message.setContent(XMLStreamReader.class, dr);
110: return dr;
111: }
112:
113: /**
114: * Find the next possible message part in the message. If an operation in
115: * the list of operations is no longer a viable match, it will be removed
116: * from the Collection.
117: *
118: * @param exchange
119: * @param operations
120: * @param name
121: * @param client
122: * @param index
123: * @return
124: */
125: protected MessagePartInfo findMessagePart(Exchange exchange,
126: Collection<OperationInfo> operations, QName name,
127: boolean client, int index) {
128: Endpoint ep = exchange.get(Endpoint.class);
129: MessagePartInfo lastChoice = null;
130: for (Iterator<OperationInfo> itr = operations.iterator(); itr
131: .hasNext();) {
132: OperationInfo op = itr.next();
133:
134: BindingOperationInfo boi = ep.getEndpointInfo()
135: .getBinding().getOperation(op);
136: if (boi == null) {
137: continue;
138: }
139: BindingMessageInfo msgInfo = null;
140: if (client) {
141: msgInfo = boi.getOutput();
142: } else {
143: msgInfo = boi.getInput();
144: }
145:
146: if (msgInfo == null) {
147: itr.remove();
148: continue;
149: }
150:
151: Collection bodyParts = msgInfo.getMessageParts();
152: if (bodyParts.size() == 0 || bodyParts.size() <= index) {
153: itr.remove();
154: continue;
155: }
156:
157: MessagePartInfo p = (MessagePartInfo) msgInfo
158: .getMessageParts().get(index);
159: if (name.getNamespaceURI() == null
160: || name.getNamespaceURI().length() == 0) {
161: // message part has same namespace with the message
162: name = new QName(p.getMessageInfo().getName()
163: .getNamespaceURI(), name.getLocalPart());
164: }
165: if (name.equals(p.getConcreteName())) {
166: exchange.put(BindingOperationInfo.class, boi);
167: exchange.put(OperationInfo.class, boi
168: .getOperationInfo());
169: exchange.setOneWay(op.isOneWay());
170: return p;
171: }
172:
173: if (XSD_ANY.equals(p.getTypeQName())) {
174: lastChoice = p;
175: } else {
176: itr.remove();
177: }
178: }
179: return lastChoice;
180: }
181:
182: /**
183: * Returns a BindingOperationInfo if the operation is indentified as
184: * a wrapped method, return null if it is not a wrapped method
185: * (i.e., it is a bare method)
186: *
187: * @param exchange
188: * @param name
189: * @param client
190: * @return
191: */
192: protected BindingOperationInfo getBindingOperationInfo(
193: Exchange exchange, QName name, boolean client) {
194: String local = name.getLocalPart();
195: if (client && local.endsWith("Response")) {
196: local = local.substring(0, local.length() - 8);
197: }
198:
199: // TODO: Allow overridden methods.
200: BindingOperationInfo bop = ServiceModelUtil.getOperation(
201: exchange, local);
202:
203: if (bop != null) {
204: exchange.put(BindingOperationInfo.class, bop);
205: exchange.put(OperationInfo.class, bop.getOperationInfo());
206: }
207: return bop;
208: }
209:
210: protected MessageInfo getMessageInfo(Message message,
211: BindingOperationInfo operation) {
212: return getMessageInfo(message, operation, isRequestor(message));
213: }
214:
215: protected MessageInfo getMessageInfo(Message message,
216: BindingOperationInfo operation, boolean requestor) {
217: MessageInfo msgInfo;
218: OperationInfo intfOp = operation.getOperationInfo();
219: if (requestor) {
220: msgInfo = intfOp.getOutput();
221: message.put(MessageInfo.class, intfOp.getOutput());
222: } else {
223: msgInfo = intfOp.getInput();
224: message.put(MessageInfo.class, intfOp.getInput());
225: }
226: return msgInfo;
227: }
228: }
|