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.model.wsdl; 27 28import com.sun.istack.internal.NotNull; 29import com.sun.xml.internal.ws.api.model.ParameterBinding; 30import com.sun.xml.internal.ws.api.model.wsdl.WSDLMessage; 31import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel; 32import com.sun.xml.internal.ws.api.model.wsdl.WSDLOperation; 33import com.sun.xml.internal.ws.api.model.wsdl.WSDLPortType; 34import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundOperation; 35import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLBoundPortType; 36import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLMessage; 37import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLModel; 38import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPart; 39import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPort; 40import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLPortType; 41import com.sun.xml.internal.ws.api.model.wsdl.editable.EditableWSDLService; 42import com.sun.xml.internal.ws.policy.PolicyMap; 43 44import javax.jws.WebParam.Mode; 45import javax.xml.namespace.QName; 46 47import java.util.Collections; 48import java.util.HashMap; 49import java.util.LinkedHashMap; 50import java.util.Map; 51 52/** 53 * Implementation of {@link WSDLModel} 54 * 55 * @author Vivek Pandey 56 */ 57public 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 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 */ 75 public WSDLModelImpl() { 76 super(null,-1); 77 } 78 79 public void addMessage(EditableWSDLMessage msg){ 80 messages.put(msg.getName(), msg); 81 } 82 83 public EditableWSDLMessage getMessage(QName name){ 84 return messages.get(name); 85 } 86 87 public void addPortType(EditableWSDLPortType pt){ 88 portTypes.put(pt.getName(), pt); 89 } 90 91 public EditableWSDLPortType getPortType(QName name){ 92 return portTypes.get(name); 93 } 94 95 public void addBinding(EditableWSDLBoundPortType boundPortType){ 96 assert !bindings.containsValue(boundPortType); 97 bindings.put(boundPortType.getName(), boundPortType); 98 } 99 100 public EditableWSDLBoundPortType getBinding(QName name){ 101 return bindings.get(name); 102 } 103 104 public void addService(EditableWSDLService svc){ 105 services.put(svc.getName(), svc); 106 } 107 108 public EditableWSDLService getService(QName name){ 109 return services.get(name); 110 } 111 112 public Map<QName, EditableWSDLMessage> getMessages() { 113 return messages; 114 } 115 116 public @NotNull Map<QName, EditableWSDLPortType> getPortTypes() { 117 return portTypes; 118 } 119 120 public @NotNull Map<QName, ? extends EditableWSDLBoundPortType> getBindings() { 121 return unmBindings; 122 } 123 124 public @NotNull Map<QName, EditableWSDLService> getServices(){ 125 return services; 126 } 127 128 /** 129 * Returns the first service QName from insertion order 130 */ 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 */ 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 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 */ 206 public PolicyMap getPolicyMap() { 207 return policyMap; 208 } 209 210 /** 211 * Set PolicyMap for the WSDLModel. 212 * @param policyMap 213 */ 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 */ 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