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 
26 package com.sun.xml.internal.ws.model.wsdl;
27 
28 import com.sun.istack.internal.NotNull;
29 import com.sun.xml.internal.ws.api.model.ParameterBinding;
30 import com.sun.xml.internal.ws.api.model.wsdl.WSDLMessage;
31 import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel;
32 import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation;
33 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPortType;
34 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation;
35 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType;
36 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage;
37 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLModel;
38 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPart;
39 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPort;
40 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPortType;
41 import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLService;
42 import com.sun.xml.internal.ws.policy.PolicyMap;
43 
44 import javax.jws.WebParam.Mode;
45 import javax.xml.namespace.QName;
46 
47 import java.util.Collections;
48 import java.util.HashMap;
49 import java.util.LinkedHashMap;
50 import java.util.Map;
51 
52 /**
53  * Implementation of {@link WSDLModel}
54  *
55  * @author Vivek Pandey
56  */
57 public final class WSDLModelImpl extends AbstractExtensibleImpl implements EditableWSDLModel {
58     private final Map<QName, EditableWSDLMessage> messages = new HashMap<QName, EditableWSDLMessage>();
59     private final Map<QName, EditableWSDLPortType> portTypes = new HashMap<QName, EditableWSDLPortType>();
60     private final Map<QName, EditableWSDLBoundPortType> bindings = new HashMap<QName, EditableWSDLBoundPortType>();
61     private final Map<QName, EditableWSDLService> services = new LinkedHashMap<QName, EditableWSDLService>();
62 
63     private PolicyMap policyMap;
64     private final Map<QName, EditableWSDLBoundPortType> unmBindings
65         = Collections.<QName, EditableWSDLBoundPortType>unmodifiableMap(bindings);
66 
67 
WSDLModelImpl(@otNull String systemId)68     public WSDLModelImpl(@NotNull String systemId) {
69         super(systemId,-1);
70     }
71 
72     /**
73      * To create {@link WSDLModelImpl} from WSDL that doesn't have a system ID.
74      */
WSDLModelImpl()75     public WSDLModelImpl() {
76         super(null,-1);
77     }
78 
addMessage(EditableWSDLMessage msg)79     public void addMessage(EditableWSDLMessage msg){
80         messages.put(msg.getName(), msg);
81     }
82 
getMessage(QName name)83     public EditableWSDLMessage getMessage(QName name){
84         return messages.get(name);
85     }
86 
addPortType(EditableWSDLPortType pt)87     public void addPortType(EditableWSDLPortType pt){
88         portTypes.put(pt.getName(), pt);
89     }
90 
getPortType(QName name)91     public EditableWSDLPortType getPortType(QName name){
92         return portTypes.get(name);
93     }
94 
addBinding(EditableWSDLBoundPortType boundPortType)95     public void addBinding(EditableWSDLBoundPortType boundPortType){
96         assert !bindings.containsValue(boundPortType);
97         bindings.put(boundPortType.getName(), boundPortType);
98     }
99 
getBinding(QName name)100     public EditableWSDLBoundPortType getBinding(QName name){
101         return bindings.get(name);
102     }
103 
addService(EditableWSDLService svc)104     public void addService(EditableWSDLService svc){
105         services.put(svc.getName(), svc);
106     }
107 
getService(QName name)108     public EditableWSDLService getService(QName name){
109         return services.get(name);
110     }
111 
getMessages()112     public Map<QName, EditableWSDLMessage> getMessages() {
113         return messages;
114     }
115 
getPortTypes()116     public @NotNull Map<QName, EditableWSDLPortType> getPortTypes() {
117         return portTypes;
118     }
119 
getBindings()120     public @NotNull Map<QName, ? extends EditableWSDLBoundPortType> getBindings() {
121         return unmBindings;
122     }
123 
getServices()124     public @NotNull Map<QName, EditableWSDLService> getServices(){
125         return services;
126     }
127 
128     /**
129      * Returns the first service QName from insertion order
130      */
getFirstServiceName()131     public QName getFirstServiceName(){
132         if(services.isEmpty())
133             return null;
134         return services.values().iterator().next().getName();
135     }
136 
137     /**
138      *
139      * @param serviceName non-null service QName
140      * @param portName    non-null port QName
141      * @return
142      *          WSDLBoundOperation on success otherwise null. throws NPE if any of the parameters null
143      */
getBinding(QName serviceName, QName portName)144     public EditableWSDLBoundPortType getBinding(QName serviceName, QName portName){
145         EditableWSDLService service = services.get(serviceName);
146         if(service != null){
147             EditableWSDLPort port = service.get(portName);
148             if(port != null)
149                 return port.getBinding();
150         }
151         return null;
152     }
153 
finalizeRpcLitBinding(EditableWSDLBoundPortType boundPortType)154     public void finalizeRpcLitBinding(EditableWSDLBoundPortType boundPortType){
155         assert(boundPortType != null);
156         QName portTypeName = boundPortType.getPortTypeName();
157         if(portTypeName == null)
158             return;
159         WSDLPortType pt = portTypes.get(portTypeName);
160         if(pt == null)
161             return;
162         for (EditableWSDLBoundOperation bop : boundPortType.getBindingOperations()) {
163             WSDLOperation pto = pt.get(bop.getName().getLocalPart());
164             WSDLMessage inMsgName = pto.getInput().getMessage();
165             if(inMsgName == null)
166                 continue;
167             EditableWSDLMessage inMsg = messages.get(inMsgName.getName());
168             int bodyindex = 0;
169             if(inMsg != null){
170                 for(EditableWSDLPart part:inMsg.parts()){
171                     String name = part.getName();
172                     ParameterBinding pb = bop.getInputBinding(name);
173                     if(pb.isBody()){
174                         part.setIndex(bodyindex++);
175                         part.setBinding(pb);
176                         bop.addPart(part, Mode.IN);
177                     }
178                 }
179             }
180             bodyindex=0;
181             if(pto.isOneWay())
182                 continue;
183             WSDLMessage outMsgName = pto.getOutput().getMessage();
184             if(outMsgName == null)
185                 continue;
186             EditableWSDLMessage outMsg = messages.get(outMsgName.getName());
187             if(outMsg!= null){
188                 for(EditableWSDLPart part:outMsg.parts()){
189                     String name = part.getName();
190                     ParameterBinding pb = bop.getOutputBinding(name);
191                     if(pb.isBody()){
192                         part.setIndex(bodyindex++);
193                         part.setBinding(pb);
194                         bop.addPart(part, Mode.OUT);
195                     }
196                 }
197             }
198         }
199     }
200 
201     /**
202      * Gives the PolicyMap associated with the WSDLModel
203      *
204      * @return PolicyMap
205      */
getPolicyMap()206     public PolicyMap getPolicyMap() {
207         return policyMap;
208     }
209 
210     /**
211      * Set PolicyMap for the WSDLModel.
212      * @param policyMap
213      */
setPolicyMap(PolicyMap policyMap)214     public void setPolicyMap(PolicyMap policyMap) {
215         this.policyMap = policyMap;
216     }
217 
218     /**
219      * Invoked at the end of the model construction to fix up references, etc.
220      */
freeze()221     public void freeze() {
222         for (EditableWSDLService service : services.values()) {
223             service.freeze(this);
224         }
225         for (EditableWSDLBoundPortType bp : bindings.values()) {
226             bp.freeze();
227         }
228         // Enforce freeze all the portTypes referenced by this endpoints, see Bug8966673 for detail
229         for (EditableWSDLPortType pt : portTypes.values()) {
230             pt.freeze();
231         }
232     }
233 }
234