1 /* 2 * Copyright (c) 1997, 2012, 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.tools.internal.ws.wscompile; 27 28 import com.sun.tools.internal.ws.api.WsgenExtension; 29 import com.sun.tools.internal.ws.api.WsgenProtocol; 30 import com.sun.tools.internal.ws.resources.WscompileMessages; 31 import com.sun.xml.internal.ws.api.BindingID; 32 import com.sun.xml.internal.ws.binding.SOAPBindingImpl; 33 import com.sun.xml.internal.ws.util.ServiceFinder; 34 35 import javax.jws.WebService; 36 import javax.xml.namespace.QName; 37 import java.io.File; 38 import java.util.ArrayList; 39 import java.util.LinkedHashMap; 40 import java.util.LinkedHashSet; 41 import java.util.List; 42 import java.util.Map; 43 import java.util.Set; 44 45 /** 46 * @author Vivek Pandey 47 */ 48 public class WsgenOptions extends Options { 49 /** 50 * -servicename 51 */ 52 public QName serviceName; 53 54 /** 55 * -portname 56 */ 57 public QName portName; 58 59 /** 60 * -r 61 */ 62 public File nonclassDestDir; 63 64 65 /** 66 * -wsdl 67 */ 68 public boolean genWsdl; 69 70 /** 71 * -inlineSchemas 72 */ 73 public boolean inlineSchemas; 74 75 /** 76 * protocol value 77 */ 78 public String protocol = "soap1.1"; 79 80 public Set<String> protocols = new LinkedHashSet<String>(); 81 public Map<String, String> nonstdProtocols = new LinkedHashMap<String, String>(); 82 83 /** 84 * -XwsgenReport 85 */ 86 public File wsgenReport; 87 88 /** 89 * -Xdonotoverwrite 90 */ 91 public boolean doNotOverWrite; 92 93 /** 94 * Tells if user specified a specific protocol 95 */ 96 public boolean protocolSet = false; 97 98 /** 99 * <code>-x file1 -x file2 ...<code/><br /> 100 * Files to be parsed to get classes' metadata in addition/instead of using annotations and reflection API 101 */ 102 public List<String> externalMetadataFiles = new ArrayList<String>(); 103 104 private static final String SERVICENAME_OPTION = "-servicename"; 105 private static final String PORTNAME_OPTION = "-portname"; 106 private static final String HTTP = "http"; 107 private static final String SOAP11 = "soap1.1"; 108 public static final String X_SOAP12 = "Xsoap1.2"; 109 110 public WsgenOptions() { 111 protocols.add(SOAP11); 112 protocols.add(X_SOAP12); 113 nonstdProtocols.put(X_SOAP12, SOAPBindingImpl.X_SOAP12HTTP_BINDING); 114 ServiceFinder<WsgenExtension> extn = ServiceFinder.find(WsgenExtension.class); 115 for(WsgenExtension ext : extn) { 116 Class clazz = ext.getClass(); 117 WsgenProtocol pro = (WsgenProtocol)clazz.getAnnotation(WsgenProtocol.class); 118 protocols.add(pro.token()); 119 nonstdProtocols.put(pro.token(), pro.lexical()); 120 } 121 } 122 123 @Override 124 protected int parseArguments(String[] args, int i) throws BadCommandLineException { 125 126 int j = super.parseArguments(args, i); 127 if (args[i].equals(SERVICENAME_OPTION)) { 128 serviceName = QName.valueOf(requireArgument(SERVICENAME_OPTION, args, ++i)); 129 if (serviceName.getNamespaceURI() == null || serviceName.getNamespaceURI().length() == 0) { 130 throw new BadCommandLineException(WscompileMessages.WSGEN_SERVICENAME_MISSING_NAMESPACE(args[i])); 131 } 132 if (serviceName.getLocalPart() == null || serviceName.getLocalPart().length() == 0) { 133 throw new BadCommandLineException(WscompileMessages.WSGEN_SERVICENAME_MISSING_LOCALNAME(args[i])); 134 } 135 return 2; 136 } else if (args[i].equals(PORTNAME_OPTION)) { 137 portName = QName.valueOf(requireArgument(PORTNAME_OPTION, args, ++i)); 138 if (portName.getNamespaceURI() == null || portName.getNamespaceURI().length() == 0) { 139 throw new BadCommandLineException(WscompileMessages.WSGEN_PORTNAME_MISSING_NAMESPACE(args[i])); 140 } 141 if (portName.getLocalPart() == null || portName.getLocalPart().length() == 0) { 142 throw new BadCommandLineException(WscompileMessages.WSGEN_PORTNAME_MISSING_LOCALNAME(args[i])); 143 } 144 return 2; 145 } else if (args[i].equals("-r")) { 146 nonclassDestDir = new File(requireArgument("-r", args, ++i)); 147 if (!nonclassDestDir.exists()) { 148 throw new BadCommandLineException(WscompileMessages.WSCOMPILE_NO_SUCH_DIRECTORY(nonclassDestDir.getPath())); 149 } 150 return 2; 151 } else if (args[i].startsWith("-wsdl")) { 152 genWsdl = true; 153 //String value = requireArgument("-wsdl", args, ++i).substring(5); 154 String value = args[i].substring(5); 155 int index = value.indexOf(':'); 156 if (index == 0) { 157 value = value.substring(1); 158 index = value.indexOf('/'); 159 if (index == -1) { 160 protocol = value; 161 } else { 162 protocol = value.substring(0, index); 163 } 164 protocolSet = true; 165 } 166 return 1; 167 } else if (args[i].equals("-XwsgenReport")) { 168 // undocumented switch for the test harness 169 wsgenReport = new File(requireArgument("-XwsgenReport", args, ++i)); 170 return 2; 171 } else if (args[i].equals("-Xdonotoverwrite")) { 172 doNotOverWrite = true; 173 return 1; 174 } else if (args[i].equals("-inlineSchemas")) { 175 inlineSchemas = true; 176 return 1; 177 } else if ("-x".equals(args[i])) { 178 externalMetadataFiles.add(requireArgument("-x", args, ++i)); 179 return 1; 180 } 181 182 return j; 183 } 184 185 186 @Override 187 protected void addFile(String arg) { 188 endpoints.add(arg); 189 } 190 191 List<String> endpoints = new ArrayList<String>(); 192 193 public Class endpoint; 194 195 196 private boolean isImplClass; 197 198 public void validate() throws BadCommandLineException { 199 if(nonclassDestDir == null) 200 nonclassDestDir = destDir; 201 202 if (!protocols.contains(protocol)) { 203 throw new BadCommandLineException(WscompileMessages.WSGEN_INVALID_PROTOCOL(protocol, protocols)); 204 } 205 206 if (endpoints.isEmpty()) { 207 throw new BadCommandLineException(WscompileMessages.WSGEN_MISSING_FILE()); 208 } 209 if (protocol == null || protocol.equalsIgnoreCase(X_SOAP12) && !isExtensionMode()) { 210 throw new BadCommandLineException(WscompileMessages.WSGEN_SOAP_12_WITHOUT_EXTENSION()); 211 } 212 213 if (nonstdProtocols.containsKey(protocol) && !isExtensionMode()) { 214 throw new BadCommandLineException(WscompileMessages.WSGEN_PROTOCOL_WITHOUT_EXTENSION(protocol)); 215 } 216 if (inlineSchemas && !genWsdl) { 217 throw new BadCommandLineException(WscompileMessages.WSGEN_INLINE_SCHEMAS_ONLY_WITH_WSDL()); 218 } 219 220 validateEndpointClass(); 221 validateArguments(); 222 } 223 /** 224 * Get an implementation class annotated with @WebService annotation. 225 */ 226 private void validateEndpointClass() throws BadCommandLineException { 227 Class clazz = null; 228 for(String cls : endpoints){ 229 clazz = getClass(cls); 230 if (clazz == null) 231 continue; 232 233 if (clazz.isEnum() || clazz.isInterface() || 234 clazz.isPrimitive()) { 235 continue; 236 } 237 isImplClass = true; 238 WebService webService = (WebService) clazz.getAnnotation(WebService.class); 239 if(webService == null) 240 continue; 241 break; 242 } 243 if(clazz == null){ 244 throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoints.get(0))); 245 } 246 if(!isImplClass){ 247 throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_MUST_BE_IMPLEMENTATION_CLASS(clazz.getName())); 248 } 249 endpoint = clazz; 250 validateBinding(); 251 } 252 253 private void validateBinding() throws BadCommandLineException { 254 if (genWsdl) { 255 BindingID binding = BindingID.parse(endpoint); 256 if ((binding.equals(BindingID.SOAP12_HTTP) || 257 binding.equals(BindingID.SOAP12_HTTP_MTOM)) && 258 !(protocol.equals(X_SOAP12) && isExtensionMode())) { 259 throw new BadCommandLineException(WscompileMessages.WSGEN_CANNOT_GEN_WSDL_FOR_SOAP_12_BINDING(binding.toString(), endpoint.getName())); 260 } 261 if (binding.equals(BindingID.XML_HTTP)) { 262 throw new BadCommandLineException(WscompileMessages.WSGEN_CANNOT_GEN_WSDL_FOR_NON_SOAP_BINDING(binding.toString(), endpoint.getName())); 263 } 264 } 265 } 266 267 private void validateArguments() throws BadCommandLineException { 268 if (!genWsdl) { 269 if (serviceName != null) { 270 throw new BadCommandLineException(WscompileMessages.WSGEN_WSDL_ARG_NO_GENWSDL(SERVICENAME_OPTION)); 271 } 272 if (portName != null) { 273 throw new BadCommandLineException(WscompileMessages.WSGEN_WSDL_ARG_NO_GENWSDL(PORTNAME_OPTION)); 274 } 275 } 276 } 277 278 BindingID getBindingID(String protocol) { 279 if (protocol.equals(SOAP11)) 280 return BindingID.SOAP11_HTTP; 281 if (protocol.equals(X_SOAP12)) 282 return BindingID.SOAP12_HTTP; 283 String lexical = nonstdProtocols.get(protocol); 284 return (lexical != null) ? BindingID.parse(lexical) : null; 285 } 286 287 288 private Class getClass(String className) { 289 try { 290 return getClassLoader().loadClass(className); 291 } catch (ClassNotFoundException e) { 292 return null; 293 } 294 } 295 296 }