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 
WsgenOptions()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
parseArguments(String[] args, int i)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
addFile(String arg)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 
validate()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      */
validateEndpointClass()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 
validateBinding()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 
validateArguments()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 
getBindingID(String protocol)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 
getClass(String className)288     private Class getClass(String className) {
289         try {
290             return getClassLoader().loadClass(className);
291         } catch (ClassNotFoundException e) {
292             return null;
293         }
294     }
295 
296 }
297