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.http.interceptor;
019:
020: import java.io.InputStream;
021: import java.util.Collection;
022: import java.util.Collections;
023: import java.util.List;
024: import java.util.ResourceBundle;
025: import java.util.logging.Logger;
026:
027: import javax.xml.stream.XMLInputFactory;
028: import javax.xml.stream.XMLStreamException;
029: import javax.xml.stream.XMLStreamReader;
030: import javax.xml.transform.dom.DOMSource;
031:
032: import org.w3c.dom.Document;
033:
034: import org.apache.cxf.binding.http.IriDecoderHelper;
035: import org.apache.cxf.binding.http.IriDecoderHelper.Param;
036: import org.apache.cxf.binding.http.URIMapper;
037: import org.apache.cxf.binding.xml.interceptor.XMLMessageInInterceptor;
038: import org.apache.cxf.common.i18n.BundleUtils;
039: import org.apache.cxf.interceptor.DocLiteralInInterceptor;
040: import org.apache.cxf.interceptor.Fault;
041: import org.apache.cxf.interceptor.StaxInInterceptor;
042: import org.apache.cxf.message.Message;
043: import org.apache.cxf.phase.AbstractPhaseInterceptor;
044: import org.apache.cxf.phase.Phase;
045: import org.apache.cxf.service.Service;
046: import org.apache.cxf.service.model.BindingOperationInfo;
047: import org.apache.cxf.service.model.MessagePartInfo;
048: import org.apache.cxf.service.model.SchemaInfo;
049: import org.apache.cxf.staxutils.StaxUtils;
050:
051: public class URIParameterInInterceptor extends
052: AbstractPhaseInterceptor<Message> {
053:
054: private static final Logger LOG = Logger
055: .getLogger(URIParameterInInterceptor.class.getName());
056: private static final ResourceBundle BUNDLE = BundleUtils
057: .getBundle(URIParameterInInterceptor.class);
058:
059: public URIParameterInInterceptor() {
060: super (Phase.UNMARSHAL);
061: addBefore(XMLMessageInInterceptor.class.getName());
062: }
063:
064: public void handleMessage(Message message) {
065: String path = (String) message
066: .get(DispatchInterceptor.RELATIVE_PATH);
067: String method = (String) message
068: .get(Message.HTTP_REQUEST_METHOD);
069: String contentType = (String) message.get(Message.CONTENT_TYPE);
070:
071: LOG.info("URIParameterInterceptor handle message on path ["
072: + path + "] with content-type [" + contentType + "]");
073:
074: BindingOperationInfo op = message.getExchange().get(
075: BindingOperationInfo.class);
076:
077: URIMapper mapper = (URIMapper) message.getExchange().get(
078: Service.class).get(URIMapper.class.getName());
079: String location = mapper.getLocation(op);
080:
081: List<MessagePartInfo> parts = op.getOperationInfo().getInput()
082: .getMessageParts();
083:
084: if (parts.size() == 0) {
085: message.setContent(Object.class, Collections.EMPTY_LIST);
086: return;
087: }
088:
089: if (parts.size() > 1) {
090: throw new Fault(new org.apache.cxf.common.i18n.Message(
091: "SINGLE_PART_REQUIRED", BUNDLE));
092: }
093:
094: message.getInterceptorChain()
095: .add(new XMLMessageInInterceptor());
096: message.getInterceptorChain()
097: .add(new DocLiteralInInterceptor());
098:
099: MessagePartInfo part = parts.get(0);
100:
101: List<Param> params = null;
102: if ("application/x-www-form-urlencoded.".equals(contentType)) {
103: params = IriDecoderHelper.decode(path, location, message
104: .getContent(InputStream.class));
105: } else if ("application/xml".equals(contentType)) {
106: params = IriDecoderHelper.decodeIri(path, location);
107: } else if ("text/xml".equals(contentType)) {
108: params = IriDecoderHelper.decodeIri(path, location);
109: } else if ("multipart/form-data".equals(contentType)) {
110: // TODO
111: } else {
112: params = IriDecoderHelper.decodeIri(path, location);
113: }
114:
115: mergeParams(message, path, method, part, params);
116: }
117:
118: private void mergeParams(Message message, String path,
119: String method, MessagePartInfo part, List<Param> params) {
120: // TODO: If its a POST/PUT operation we probably need to merge the
121: // incoming doc
122: Document doc;
123: Collection<SchemaInfo> schemas = part.getMessageInfo()
124: .getOperation().getInterface().getService()
125: .getSchemas();
126: if ("POST".equals(method) || "PUT".equals(method)) {
127: XMLInputFactory inputFactory = StaxInInterceptor
128: .getXMLInputFactory(message);
129: try {
130: XMLStreamReader reader = inputFactory
131: .createXMLStreamReader(message
132: .getContent(InputStream.class));
133: doc = StaxUtils.read(reader);
134: } catch (XMLStreamException e) {
135: throw new Fault(e);
136: }
137: doc = IriDecoderHelper.interopolateParams(doc, part
138: .getXmlSchema(), schemas, params);
139: } else {
140: doc = IriDecoderHelper.buildDocument(part.getXmlSchema(),
141: schemas, params);
142: }
143:
144: XMLStreamReader reader = StaxUtils
145: .createXMLStreamReader(new DOMSource(doc));
146: try {
147: reader.next();
148: } catch (XMLStreamException e) {
149: throw new Fault(e);
150: }
151: message.setContent(XMLStreamReader.class, reader);
152: }
153: }
|