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.server; 27 28 import com.sun.istack.internal.NotNull; 29 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer; 30 import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult; 31 import com.sun.xml.internal.ws.api.server.SDDocument; 32 import com.sun.xml.internal.ws.api.server.SDDocumentSource; 33 34 import javax.xml.namespace.QName; 35 import javax.xml.transform.Result; 36 import javax.xml.ws.Holder; 37 import javax.xml.ws.WebServiceException; 38 import java.net.URL; 39 import java.net.MalformedURLException; 40 import java.util.ArrayList; 41 import java.util.HashMap; 42 import java.util.List; 43 import java.util.Map; 44 45 /** 46 * WSDLGenerator uses WSDLResolver while creating WSDL artifacts. WSDLResolver 47 * is used to control the file names and which artifact to be generated or not. 48 * 49 * @author Jitendra Kotamraju 50 */ 51 final class WSDLGenResolver implements com.oracle.webservices.internal.api.databinding.WSDLResolver { 52 53 private final List<SDDocumentImpl> docs; 54 private final List<SDDocumentSource> newDocs = new ArrayList<SDDocumentSource>(); 55 private SDDocumentSource concreteWsdlSource; 56 57 private SDDocumentImpl abstractWsdl; 58 private SDDocumentImpl concreteWsdl; 59 60 /** 61 * targetNS -> schema documents. 62 */ 63 private final Map<String, List<SDDocumentImpl>> nsMapping = new HashMap<String,List<SDDocumentImpl>>(); 64 65 private final QName serviceName; 66 private final QName portTypeName; 67 68 public WSDLGenResolver(@NotNull List<SDDocumentImpl> docs,QName serviceName,QName portTypeName) { 69 this.docs = docs; 70 this.serviceName = serviceName; 71 this.portTypeName = portTypeName; 72 73 for (SDDocumentImpl doc : docs) { 74 if(doc.isWSDL()) { 75 SDDocument.WSDL wsdl = (SDDocument.WSDL) doc; 76 if(wsdl.hasPortType()) 77 abstractWsdl = doc; 78 } 79 if(doc.isSchema()) { 80 SDDocument.Schema schema = (SDDocument.Schema) doc; 81 List<SDDocumentImpl> sysIds = nsMapping.get(schema.getTargetNamespace()); 82 if (sysIds == null) { 83 sysIds = new ArrayList<SDDocumentImpl>(); 84 nsMapping.put(schema.getTargetNamespace(), sysIds); 85 } 86 sysIds.add(doc); 87 } 88 } 89 } 90 91 /** 92 * Generates the concrete WSDL that contains service element. 93 * 94 * @return Result the generated concrete WSDL 95 */ 96 public Result getWSDL(String filename) { 97 URL url = createURL(filename); 98 MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); 99 xsb.setSystemId(url.toExternalForm()); 100 concreteWsdlSource = SDDocumentSource.create(url,xsb); 101 newDocs.add(concreteWsdlSource); 102 XMLStreamBufferResult r = new XMLStreamBufferResult(xsb); 103 r.setSystemId(filename); 104 return r; 105 } 106 107 /** 108 * At present, it returns file URL scheme eventhough there is no resource 109 * in the filesystem. 110 * 111 * @return URL of the generated document 112 * 113 */ 114 private URL createURL(String filename) { 115 try { 116 return new URL("file:///"+filename); 117 } catch (MalformedURLException e) { 118 // TODO: I really don't think this is the right way to handle this error, 119 // WSDLResolver needs to be documented carefully. 120 throw new WebServiceException(e); 121 } 122 } 123 124 /** 125 * Updates filename if the suggested filename need to be changed in 126 * wsdl:import. If the metadata already contains abstract wsdl(i.e. a WSDL 127 * which has the porttype), then the abstract wsdl shouldn't be generated 128 * 129 * return null if abstract WSDL need not be generated 130 * Result the abstract WSDL 131 */ 132 public Result getAbstractWSDL(Holder<String> filename) { 133 if (abstractWsdl != null) { 134 filename.value = abstractWsdl.getURL().toString(); 135 return null; // Don't generate abstract WSDL 136 } 137 URL url = createURL(filename.value); 138 MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); 139 xsb.setSystemId(url.toExternalForm()); 140 SDDocumentSource abstractWsdlSource = SDDocumentSource.create(url,xsb); 141 newDocs.add(abstractWsdlSource); 142 XMLStreamBufferResult r = new XMLStreamBufferResult(xsb); 143 r.setSystemId(filename.value); 144 return r; 145 } 146 147 /** 148 * Updates filename if the suggested filename need to be changed in 149 * xsd:import. If there is already a schema document for the namespace 150 * in the metadata, then it is not generated. 151 * 152 * return null if schema need not be generated 153 * Result the generated schema document 154 */ 155 public Result getSchemaOutput(String namespace, Holder<String> filename) { 156 List<SDDocumentImpl> schemas = nsMapping.get(namespace); 157 if (schemas != null) { 158 if (schemas.size() > 1) { 159 throw new ServerRtException("server.rt.err", 160 "More than one schema for the target namespace "+namespace); 161 } 162 filename.value = schemas.get(0).getURL().toExternalForm(); 163 return null; // Don't generate schema 164 } 165 166 URL url = createURL(filename.value); 167 MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer(); 168 xsb.setSystemId(url.toExternalForm()); 169 SDDocumentSource sd = SDDocumentSource.create(url,xsb); 170 newDocs.add(sd); 171 172 XMLStreamBufferResult r = new XMLStreamBufferResult(xsb); 173 r.setSystemId(filename.value); 174 return r; 175 } 176 177 /** 178 * Converts SDDocumentSource to SDDocumentImpl and updates original docs. It 179 * categories the generated documents into WSDL, Schema types. 180 * 181 * @return the primary WSDL 182 * null if it is not there in the generated documents 183 * 184 */ 185 public SDDocumentImpl updateDocs() { 186 for (SDDocumentSource doc : newDocs) { 187 SDDocumentImpl docImpl = SDDocumentImpl.create(doc,serviceName,portTypeName); 188 if (doc == concreteWsdlSource) { 189 concreteWsdl = docImpl; 190 } 191 docs.add(docImpl); 192 } 193 return concreteWsdl; 194 } 195 196 }