001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.soap.bindings.http.interceptors;
018    
019    import java.io.InputStream;
020    import java.util.List;
021    
022    import javax.xml.transform.Source;
023    import javax.xml.transform.dom.DOMSource;
024    
025    import org.apache.servicemix.soap.api.Fault;
026    import org.apache.servicemix.soap.api.Message;
027    import org.apache.servicemix.soap.api.model.Binding;
028    import org.apache.servicemix.soap.api.model.Operation;
029    import org.apache.servicemix.soap.api.model.wsdl2.Wsdl2Message.ContentModel;
030    import org.apache.servicemix.soap.bindings.http.HttpConstants;
031    import org.apache.servicemix.soap.bindings.http.interceptors.IriDecoderHelper.Param;
032    import org.apache.servicemix.soap.bindings.http.model.Wsdl2HttpBinding;
033    import org.apache.servicemix.soap.bindings.http.model.Wsdl2HttpMessage;
034    import org.apache.servicemix.soap.bindings.http.model.Wsdl2HttpOperation;
035    import org.apache.servicemix.soap.core.AbstractInterceptor;
036    import org.w3c.dom.Document;
037    
038    /**
039     * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
040     */
041    public class HttpDecoderInterceptor extends AbstractInterceptor {
042    
043        private final boolean server;
044        
045        public HttpDecoderInterceptor(boolean server) {
046            this.server = server;
047        }
048        
049        public void handleMessage(Message message) {
050            Operation<?> operation = message.get(Operation.class);
051            if (operation instanceof Wsdl2HttpOperation == false) {
052                return;
053            }
054            Wsdl2HttpBinding httpBinding = (Wsdl2HttpBinding) message.get(Binding.class);
055            Wsdl2HttpOperation httpOperation = (Wsdl2HttpOperation) operation;
056            Wsdl2HttpMessage httpMessage;
057            String serialization;
058            if (server) {
059                httpMessage = httpOperation.getInput();
060                serialization = httpOperation.getHttpInputSerialization();
061            } else {
062                httpMessage = httpOperation.getOutput();
063                serialization = httpOperation.getHttpOutputSerialization();
064            }
065            if (httpMessage.getContentModel() == ContentModel.ELEMENT ||
066                httpMessage.getContentModel() == ContentModel.ANY) {
067                // Serialization rules for XML
068                if (HttpConstants.SERIAL_APP_URLENCODED.equals(serialization)) {
069                    normalizeUrlEncoded(message, httpBinding, httpOperation, httpMessage);
070                } else if (HttpConstants.SERIAL_MULTIPART_FORMDATA.equals(serialization)) {
071                    normalizeFormData(message);
072                } else {
073                    normalizeXml(message);
074                }
075            } else if (httpMessage.getContentModel() == ContentModel.NONE) {
076                if (message.getContent(Source.class) != null) {
077                    throw new Fault("No content allowed");
078                }
079            } else {
080                throw new Fault("Unsupported content model: " + httpMessage.getContentModel());
081            }
082        }
083    
084        private void normalizeXml(Message message) {
085            // TODO Auto-generated method stub
086            
087        }
088    
089        private void normalizeFormData(Message message) {
090            // TODO Auto-generated method stub
091            
092        }
093    
094        private void normalizeUrlEncoded(Message message, Wsdl2HttpBinding binding, Wsdl2HttpOperation httpOperation, Wsdl2HttpMessage httpMessage) {
095            InputStream is = message.getContent(InputStream.class);
096            String uri = message.getTransportHeaders().get(HttpConstants.REQUEST_URI);
097            String loc = IriDecoderHelper.combine(binding.getLocation(), httpOperation.getHttpLocation());
098            List<Param> params = IriDecoderHelper.decode(uri, loc, is);
099            Document doc = IriDecoderHelper.buildDocument(httpMessage.getElementDeclaration(), params);
100            message.setContent(Source.class, new DOMSource(doc));
101        }
102    
103    }