1/*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.xml.internal.ws.server.provider;
27
28import com.sun.istack.internal.Nullable;
29import com.sun.xml.internal.ws.api.SOAPVersion;
30import com.sun.xml.internal.ws.api.WSBinding;
31import com.sun.xml.internal.ws.api.message.Message;
32import com.sun.xml.internal.ws.api.message.Messages;
33import com.sun.xml.internal.ws.api.message.Packet;
34import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
35import com.sun.xml.internal.ws.fault.SOAPFaultBuilder;
36import com.sun.xml.internal.ws.resources.ServerMessages;
37
38import javax.xml.soap.MimeHeader;
39import javax.xml.soap.MimeHeaders;
40import javax.xml.soap.SOAPException;
41import javax.xml.soap.SOAPMessage;
42import javax.xml.transform.Source;
43import javax.xml.ws.Service;
44import javax.xml.ws.WebServiceException;
45import java.util.ArrayList;
46import java.util.HashMap;
47import java.util.Iterator;
48import java.util.List;
49import java.util.Map;
50
51/**
52 * @author Jitendra Kotamraju
53 */
54abstract class SOAPProviderArgumentBuilder<T> extends ProviderArgumentsBuilder<T> {
55    protected final SOAPVersion soapVersion;
56
57    private SOAPProviderArgumentBuilder(SOAPVersion soapVersion) {
58        this.soapVersion = soapVersion;
59    }
60
61    static ProviderArgumentsBuilder create(ProviderEndpointModel model, SOAPVersion soapVersion) {
62        if (model.mode == Service.Mode.PAYLOAD) {
63            return new PayloadSource(soapVersion);
64        } else {
65            if(model.datatype==Source.class)
66                return new MessageSource(soapVersion);
67            if(model.datatype==SOAPMessage.class)
68                return new SOAPMessageParameter(soapVersion);
69            if(model.datatype==Message.class)
70                return new MessageProviderArgumentBuilder(soapVersion);
71            throw new WebServiceException(ServerMessages.PROVIDER_INVALID_PARAMETER_TYPE(model.implClass,model.datatype));
72        }
73    }
74
75    private static final class PayloadSource extends SOAPProviderArgumentBuilder<Source> {
76        PayloadSource(SOAPVersion soapVersion) {
77            super(soapVersion);
78        }
79
80        /*protected*/ public Source getParameter(Packet packet) {
81            return packet.getMessage().readPayloadAsSource();
82        }
83
84        protected Message getResponseMessage(Source source) {
85            return Messages.createUsingPayload(source, soapVersion);
86        }
87
88        protected Message getResponseMessage(Exception e) {
89            return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
90        }
91
92    }
93
94    private static final class MessageSource extends SOAPProviderArgumentBuilder<Source> {
95        MessageSource(SOAPVersion soapVersion) {
96            super(soapVersion);
97        }
98
99        /*protected*/ public Source getParameter(Packet packet) {
100            return packet.getMessage().readEnvelopeAsSource();
101        }
102
103        protected Message getResponseMessage(Source source) {
104            return Messages.create(source, soapVersion);
105        }
106
107        protected Message getResponseMessage(Exception e) {
108            return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
109        }
110    }
111
112    private static final class SOAPMessageParameter extends SOAPProviderArgumentBuilder<SOAPMessage> {
113        SOAPMessageParameter(SOAPVersion soapVersion) {
114            super(soapVersion);
115        }
116
117        /*protected*/ public SOAPMessage getParameter(Packet packet) {
118            try {
119                return packet.getMessage().readAsSOAPMessage(packet, true);
120            } catch (SOAPException se) {
121                throw new WebServiceException(se);
122            }
123        }
124
125        protected Message getResponseMessage(SOAPMessage soapMsg) {
126            return Messages.create(soapMsg);
127        }
128
129        protected Message getResponseMessage(Exception e) {
130            return SOAPFaultBuilder.createSOAPFaultMessage(soapVersion, null, e);
131        }
132
133        @Override
134        protected Packet getResponse(Packet request, @Nullable SOAPMessage returnValue, WSDLPort port, WSBinding binding) {
135            Packet response = super.getResponse(request, returnValue, port, binding);
136            // Populate SOAPMessage's transport headers
137            if (returnValue != null && response.supports(Packet.OUTBOUND_TRANSPORT_HEADERS)) {
138                MimeHeaders hdrs = returnValue.getMimeHeaders();
139                Map<String, List<String>> headers = new HashMap<String, List<String>>();
140                Iterator i = hdrs.getAllHeaders();
141                while(i.hasNext()) {
142                    MimeHeader header = (MimeHeader)i.next();
143                    if(header.getName().equalsIgnoreCase("SOAPAction"))
144                        // SAAJ sets this header automatically, but it interferes with the correct operation of JAX-WS.
145                        // so ignore this header.
146                        continue;
147
148                    List<String> list = headers.get(header.getName());
149                    if (list == null) {
150                        list = new ArrayList<String>();
151                        headers.put(header.getName(), list);
152                    }
153                    list.add(header.getValue());
154                }
155                response.put(Packet.OUTBOUND_TRANSPORT_HEADERS, headers);
156            }
157            return response;
158        }
159
160    }
161
162}
163