001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.tools.wsdlto;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.net.URI;
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Properties;
031: import java.util.Set;
032: import java.util.logging.Level;
033: import java.util.logging.Logger;
034: import javax.wsdl.Definition;
035: import javax.xml.namespace.QName;
036:
037: import org.w3c.dom.Element;
038:
039: import org.apache.cxf.Bus;
040: import org.apache.cxf.BusFactory;
041: import org.apache.cxf.catalog.OASISCatalogManager;
042: import org.apache.cxf.common.i18n.Message;
043: import org.apache.cxf.common.logging.LogUtils;
044: import org.apache.cxf.common.util.PropertiesLoaderUtils;
045: import org.apache.cxf.common.util.StringUtils;
046: import org.apache.cxf.service.model.InterfaceInfo;
047: import org.apache.cxf.service.model.ServiceInfo;
048: import org.apache.cxf.tools.common.AbstractCXFToolContainer;
049: import org.apache.cxf.tools.common.ClassNameProcessor;
050: import org.apache.cxf.tools.common.ClassUtils;
051: import org.apache.cxf.tools.common.FrontEndGenerator;
052: import org.apache.cxf.tools.common.Processor;
053: import org.apache.cxf.tools.common.ToolConstants;
054: import org.apache.cxf.tools.common.ToolContext;
055: import org.apache.cxf.tools.common.ToolException;
056: import org.apache.cxf.tools.common.toolspec.ToolSpec;
057: import org.apache.cxf.tools.common.toolspec.parser.BadUsageException;
058: import org.apache.cxf.tools.common.toolspec.parser.CommandDocument;
059: import org.apache.cxf.tools.common.toolspec.parser.ErrorVisitor;
060: import org.apache.cxf.tools.util.ClassCollector;
061: import org.apache.cxf.tools.util.URIParserUtil;
062: import org.apache.cxf.tools.validator.ServiceValidator;
063: import org.apache.cxf.tools.wsdlto.core.AbstractWSDLBuilder;
064: import org.apache.cxf.tools.wsdlto.core.DataBindingProfile;
065: import org.apache.cxf.tools.wsdlto.core.FrontEndProfile;
066: import org.apache.cxf.wsdl.WSDLConstants;
067: import org.apache.cxf.wsdl11.WSDLServiceBuilder;
068:
069: public class WSDLToJavaContainer extends AbstractCXFToolContainer {
070:
071: protected static final Logger LOG = LogUtils
072: .getL7dLogger(WSDLToJavaContainer.class);
073: private static final String DEFAULT_NS2PACKAGE = "http://www.w3.org/2005/08/addressing";
074: private static final String SERVICE_VALIDATOR = "META-INF/service.validator.xml";
075: String toolName;
076:
077: public WSDLToJavaContainer(String name, ToolSpec toolspec)
078: throws Exception {
079: super (name, toolspec);
080: this .toolName = name;
081: }
082:
083: public Set<String> getArrayKeys() {
084: Set<String> set = new HashSet<String>();
085: set.add(ToolConstants.CFG_PACKAGENAME);
086: set.add(ToolConstants.CFG_NEXCLUDE);
087: return set;
088: }
089:
090: public WSDLConstants.WSDLVersion getWSDLVersion() {
091: String version = (String) context
092: .get(ToolConstants.CFG_WSDL_VERSION);
093: return WSDLConstants.getVersion(version);
094: }
095:
096: public Bus getBus() {
097: Bus bus = BusFactory.getDefaultBus();
098:
099: OASISCatalogManager catalogManager = bus
100: .getExtension(OASISCatalogManager.class);
101:
102: String catalogLocation = getCatalogURL();
103: if (!StringUtils.isEmpty(catalogLocation)) {
104: try {
105: catalogManager.loadCatalog(new URI(catalogLocation)
106: .toURL());
107: } catch (Exception e) {
108: e.printStackTrace();
109: throw new ToolException(new Message(
110: "FOUND_NO_FRONTEND", LOG, catalogLocation));
111: }
112: }
113:
114: return bus;
115: }
116:
117: protected String getCatalogURL() {
118: String catalogLocation = (String) context
119: .get(ToolConstants.CFG_CATALOG);
120: return URIParserUtil.getAbsoluteURI(catalogLocation);
121: }
122:
123: @SuppressWarnings("unchecked")
124: public void execute() throws ToolException {
125: if (!hasInfoOption()) {
126: buildToolContext();
127: validate(context);
128:
129: FrontEndProfile frontend = context
130: .get(FrontEndProfile.class);
131:
132: if (frontend == null) {
133: Message msg = new Message("FOUND_NO_FRONTEND", LOG);
134: throw new ToolException(msg);
135: }
136:
137: WSDLConstants.WSDLVersion version = getWSDLVersion();
138:
139: String wsdlURL = (String) context
140: .get(ToolConstants.CFG_WSDLURL);
141: List<ServiceInfo> serviceList = new ArrayList<ServiceInfo>();
142:
143: // Build the ServiceModel from the WSDLModel
144: if (version == WSDLConstants.WSDLVersion.WSDL11) {
145: AbstractWSDLBuilder<Definition> builder = (AbstractWSDLBuilder<Definition>) frontend
146: .getWSDLBuilder();
147: builder.setContext(context);
148: builder.setBus(getBus());
149:
150: builder.build(URIParserUtil.getAbsoluteURI(wsdlURL));
151: builder.customize();
152: Definition definition = builder.getWSDLModel();
153:
154: context.put(Definition.class, definition);
155: if (context.optionSet(ToolConstants.CFG_VALIDATE_WSDL)) {
156: builder.validate(definition);
157: }
158:
159: WSDLServiceBuilder serviceBuilder = new WSDLServiceBuilder(
160: getBus());
161:
162: String serviceName = (String) context
163: .get(ToolConstants.CFG_SERVICENAME);
164:
165: if (serviceName != null) {
166: List<ServiceInfo> services = serviceBuilder
167: .buildServices(definition,
168: getServiceQName(definition));
169: serviceList.addAll(services);
170: } else if (definition.getServices().size() > 0) {
171: serviceList = serviceBuilder
172: .buildServices(definition);
173: } else {
174: serviceList = serviceBuilder
175: .buildMockServices(definition);
176: }
177: context.put(ClassCollector.class, new ClassCollector());
178: } else {
179: // TODO: wsdl2.0 support
180: }
181: Map<String, InterfaceInfo> interfaces = new HashMap<String, InterfaceInfo>();
182:
183: Map<String, Element> schemas = (Map<String, Element>) serviceList
184: .get(0)
185: .getProperty(
186: WSDLServiceBuilder.WSDL_SCHEMA_ELEMENT_LIST);
187: context.put(ToolConstants.SCHEMA_MAP, schemas);
188: context.put(ToolConstants.PORTTYPE_MAP, interfaces);
189: Processor processor = frontend.getProcessor();
190: if (processor instanceof ClassNameProcessor) {
191: processor.setEnvironment(context);
192: for (ServiceInfo service : serviceList) {
193:
194: context.put(ServiceInfo.class, service);
195:
196: ((ClassNameProcessor) processor)
197: .processClassNames();
198:
199: context.put(ServiceInfo.class, null);
200: }
201: }
202: generateTypes();
203:
204: for (ServiceInfo service : serviceList) {
205:
206: context.put(ServiceInfo.class, service);
207: if (context.optionSet(ToolConstants.CFG_VALIDATE_WSDL)) {
208: validate(service);
209: }
210:
211: // Build the JavaModel from the ServiceModel
212: processor.setEnvironment(context);
213: processor.process();
214:
215: if (!isSuppressCodeGen()) {
216: // Generate artifacts
217: for (FrontEndGenerator generator : frontend
218: .getGenerators()) {
219: generator.generate(context);
220: }
221: }
222: }
223:
224: // Build projects: compile classes and copy resources etc.
225: if (context.optionSet(ToolConstants.CFG_COMPILE)) {
226: new ClassUtils().compile(context);
227: }
228:
229: if (context.isExcludeNamespaceEnabled()) {
230: try {
231: removeExcludeFiles();
232: } catch (IOException e) {
233: throw new ToolException(e);
234: }
235: }
236: }
237:
238: }
239:
240: private boolean isSuppressCodeGen() {
241: return context.optionSet(ToolConstants.CFG_SUPPRESS_GEN);
242: }
243:
244: public void execute(boolean exitOnFinish) throws ToolException {
245: try {
246: if (getArgument() != null) {
247: super .execute(exitOnFinish);
248: }
249: execute();
250:
251: } catch (ToolException ex) {
252: if (ex.getCause() instanceof BadUsageException) {
253: printUsageException(toolName, (BadUsageException) ex
254: .getCause());
255: }
256: throw ex;
257: } catch (Exception ex) {
258: throw new ToolException(ex);
259: }
260: }
261:
262: @SuppressWarnings("unchecked")
263: public QName getServiceQName(Definition def) {
264: List<Definition> defs = new ArrayList<Definition>();
265: defs.add(def);
266: Iterator ite1 = def.getImports().values().iterator();
267: while (ite1.hasNext()) {
268: List defList = (List) ite1.next();
269: Iterator ite2 = defList.iterator();
270: while (ite2.hasNext()) {
271: javax.wsdl.Import importDef = (javax.wsdl.Import) ite2
272: .next();
273: defs.add(importDef.getDefinition());
274: }
275: }
276: String serviceName = (String) context
277: .get(ToolConstants.CFG_SERVICENAME);
278: QName qname = null;
279: for (Definition definition : defs) {
280: if (serviceName != null) {
281: for (Iterator<QName> ite = definition.getServices()
282: .keySet().iterator(); ite.hasNext();) {
283: QName qn = ite.next();
284: if (qn.getLocalPart().equalsIgnoreCase(
285: serviceName.toLowerCase())) {
286: return qn;
287: }
288: }
289: }
290: }
291:
292: if (qname == null) {
293: Message msg = new Message("SERVICE_NOT_FOUND", LOG,
294: new Object[] { serviceName });
295: throw new ToolException(msg);
296: }
297:
298: return qname;
299: }
300:
301: public void loadDefaultNSPackageMapping(ToolContext env) {
302: if (!env.hasExcludeNamespace(DEFAULT_NS2PACKAGE)
303: && env.getBooleanValue(ToolConstants.CFG_DEFAULT_NS,
304: "true")) {
305: env
306: .loadDefaultNS2Pck(getResourceAsStream("namespace2package.cfg"));
307: }
308: if (env.getBooleanValue(ToolConstants.CFG_DEFAULT_EX, "true")) {
309: env
310: .loadDefaultExcludes(getResourceAsStream("wsdltojavaexclude.cfg"));
311: }
312: }
313:
314: public void setExcludePackageAndNamespaces(ToolContext env) {
315: if (env.get(ToolConstants.CFG_NEXCLUDE) != null) {
316: String[] pns = null;
317: try {
318: pns = (String[]) env.get(ToolConstants.CFG_NEXCLUDE);
319: } catch (ClassCastException e) {
320: pns = new String[1];
321: pns[0] = (String) env.get(ToolConstants.CFG_NEXCLUDE);
322: }
323:
324: for (int j = 0; j < pns.length; j++) {
325: int pos = pns[j].indexOf("=");
326: String excludePackagename = pns[j];
327: if (pos != -1) {
328: String ns = pns[j].substring(0, pos);
329: excludePackagename = pns[j].substring(pos + 1);
330: env.addExcludeNamespacePackageMap(ns,
331: excludePackagename);
332: env.addNamespacePackageMap(ns, excludePackagename);
333: } else {
334: env.addExcludeNamespacePackageMap(pns[j], env
335: .mapPackageName(pns[j]));
336: }
337: }
338: }
339: }
340:
341: public void setPackageAndNamespaces(ToolContext env) {
342: if (env.get(ToolConstants.CFG_PACKAGENAME) != null) {
343: String[] pns = null;
344: try {
345: pns = (String[]) env.get(ToolConstants.CFG_PACKAGENAME);
346: } catch (ClassCastException e) {
347: pns = new String[1];
348: pns[0] = (String) env
349: .get(ToolConstants.CFG_PACKAGENAME);
350: }
351: for (int j = 0; j < pns.length; j++) {
352: int pos = pns[j].indexOf("=");
353: String packagename = pns[j];
354: if (pos != -1) {
355: String ns = pns[j].substring(0, pos);
356: packagename = pns[j].substring(pos + 1);
357: env.addNamespacePackageMap(ns, packagename);
358: } else {
359: env.setPackageName(packagename);
360: }
361: }
362: }
363: }
364:
365: public void validate(ToolContext env) throws ToolException {
366: String outdir = (String) env.get(ToolConstants.CFG_OUTPUTDIR);
367: if (outdir != null) {
368: File dir = new File(outdir);
369: if (!dir.exists()) {
370: Message msg = new Message("DIRECTORY_NOT_EXIST", LOG,
371: outdir);
372: throw new ToolException(msg);
373: }
374: if (!dir.isDirectory()) {
375: Message msg = new Message("NOT_A_DIRECTORY", LOG,
376: outdir);
377: throw new ToolException(msg);
378: }
379: }
380:
381: if (env.optionSet(ToolConstants.CFG_COMPILE)) {
382: String clsdir = (String) env
383: .get(ToolConstants.CFG_CLASSDIR);
384: if (clsdir != null) {
385: File dir = new File(clsdir);
386: if (!dir.exists()) {
387: Message msg = new Message("DIRECTORY_NOT_EXIST",
388: LOG, clsdir);
389: throw new ToolException(msg);
390: }
391: }
392: }
393:
394: String wsdl = (String) env.get(ToolConstants.CFG_WSDLURL);
395: if (StringUtils.isEmpty(wsdl)) {
396: Message msg = new Message("NO_WSDL_URL", LOG);
397: throw new ToolException(msg);
398: }
399:
400: env.put(ToolConstants.CFG_WSDLURL, URIParserUtil
401: .normalize(wsdl));
402:
403: String[] bindingFiles;
404: try {
405: bindingFiles = (String[]) env
406: .get(ToolConstants.CFG_BINDING);
407: if (bindingFiles == null) {
408: return;
409: }
410: } catch (ClassCastException e) {
411: bindingFiles = new String[1];
412: bindingFiles[0] = (String) env
413: .get(ToolConstants.CFG_BINDING);
414: }
415:
416: for (int i = 0; i < bindingFiles.length; i++) {
417: bindingFiles[i] = URIParserUtil
418: .getAbsoluteURI(bindingFiles[i]);
419: }
420:
421: env.put(ToolConstants.CFG_BINDING, bindingFiles);
422: }
423:
424: public void setAntProperties(ToolContext env) {
425: String installDir = System.getProperty("install.dir");
426: if (installDir != null) {
427: env.put(ToolConstants.CFG_INSTALL_DIR, installDir);
428: } else {
429: env.put(ToolConstants.CFG_INSTALL_DIR, ".");
430: }
431: }
432:
433: protected void setLibraryReferences(ToolContext env) {
434: Properties props = loadProperties(getResourceAsStream("wsdltojavalib.properties"));
435: if (props != null) {
436: for (Iterator keys = props.keySet().iterator(); keys
437: .hasNext();) {
438: String key = (String) keys.next();
439: env.put(key, props.get(key));
440: }
441: }
442: env.put(ToolConstants.CFG_ANT_PROP, props);
443: }
444:
445: public void buildToolContext() {
446: context = getContext();
447: context.addParameters(getParametersMap(getArrayKeys()));
448:
449: if (context.get(ToolConstants.CFG_OUTPUTDIR) == null) {
450: context.put(ToolConstants.CFG_OUTPUTDIR, ".");
451: }
452:
453: if (context.containsKey(ToolConstants.CFG_ANT)) {
454: setAntProperties(context);
455: setLibraryReferences(context);
456: }
457:
458: if (!context.containsKey(ToolConstants.CFG_WSDL_VERSION)) {
459: context.put(ToolConstants.CFG_WSDL_VERSION,
460: WSDLConstants.WSDL11);
461: }
462:
463: loadDefaultNSPackageMapping(context);
464: setPackageAndNamespaces(context);
465: setExcludePackageAndNamespaces(context);
466: }
467:
468: protected static InputStream getResourceAsStream(String file) {
469: return WSDLToJavaContainer.class.getResourceAsStream(file);
470: }
471:
472: public void checkParams(ErrorVisitor errors) throws ToolException {
473: CommandDocument doc = super .getCommandDocument();
474:
475: if (!doc.hasParameter("wsdlurl")) {
476: errors.add(new ErrorVisitor.UserError(
477: "WSDL/SCHEMA URL has to be specified"));
478: }
479: if (errors.getErrors().size() > 0) {
480: Message msg = new Message("PARAMETER_MISSING", LOG);
481: throw new ToolException(msg, new BadUsageException(
482: getUsage(), errors));
483: }
484: }
485:
486: public void removeExcludeFiles() throws IOException {
487: List<String> excludeGenFiles = context.getExcludeFileList();
488: if (excludeGenFiles == null) {
489: return;
490: }
491: String outPutDir = (String) context
492: .get(ToolConstants.CFG_OUTPUTDIR);
493: for (int i = 0; i < excludeGenFiles.size(); i++) {
494: String excludeFile = excludeGenFiles.get(i);
495: File file = new File(outPutDir, excludeFile);
496: file.delete();
497: File tmpFile = file.getParentFile();
498: while (tmpFile != null
499: && !tmpFile.getCanonicalPath().equalsIgnoreCase(
500: outPutDir)) {
501: if (tmpFile.isDirectory() && tmpFile.list().length == 0) {
502: tmpFile.delete();
503: }
504: tmpFile = tmpFile.getParentFile();
505: }
506:
507: if (context.get(ToolConstants.CFG_COMPILE) != null) {
508: String classDir = context
509: .get(ToolConstants.CFG_CLASSDIR) == null ? outPutDir
510: : (String) context
511: .get(ToolConstants.CFG_CLASSDIR);
512: File classFile = new File(classDir, excludeFile
513: .substring(0, excludeFile.indexOf(".java"))
514: + ".class");
515: classFile.delete();
516: File tmpClzFile = classFile.getParentFile();
517: while (tmpClzFile != null
518: && !tmpClzFile.getCanonicalPath()
519: .equalsIgnoreCase(outPutDir)) {
520: if (tmpClzFile.isDirectory()
521: && tmpClzFile.list().length == 0) {
522: tmpClzFile.delete();
523: }
524: tmpClzFile = tmpClzFile.getParentFile();
525: }
526: }
527: }
528: }
529:
530: public boolean passthrough() {
531: if (context.optionSet(ToolConstants.CFG_GEN_TYPES)
532: || context.optionSet(ToolConstants.CFG_ALL)) {
533: return false;
534: }
535: if (context.optionSet(ToolConstants.CFG_GEN_ANT)
536: || context.optionSet(ToolConstants.CFG_GEN_CLIENT)
537: || context.optionSet(ToolConstants.CFG_GEN_IMPL)
538: || context.optionSet(ToolConstants.CFG_GEN_SEI)
539: || context.optionSet(ToolConstants.CFG_GEN_SERVER)
540: || context.optionSet(ToolConstants.CFG_GEN_SERVICE)
541: || context.optionSet(ToolConstants.CFG_GEN_FAULT)) {
542: return true;
543: }
544: return false;
545: }
546:
547: public void generateTypes() throws ToolException {
548: DataBindingProfile dataBindingProfile = context
549: .get(DataBindingProfile.class);
550: if (dataBindingProfile == null) {
551: Message msg = new Message("FOUND_NO_DATABINDING", LOG);
552: throw new ToolException(msg);
553: }
554: dataBindingProfile.initialize(context);
555: if (passthrough()) {
556: return;
557: }
558: dataBindingProfile.generate(context);
559: }
560:
561: public void validate(final ServiceInfo service)
562: throws ToolException {
563: for (ServiceValidator validator : getServiceValidators()) {
564: validator.setService(service);
565: if (!validator.isValid()) {
566: throw new ToolException(validator.getErrorMessage());
567: }
568: }
569: }
570:
571: public List<ServiceValidator> getServiceValidators() {
572: List<ServiceValidator> validators = new ArrayList<ServiceValidator>();
573:
574: Properties initialExtensions = null;
575: try {
576: initialExtensions = PropertiesLoaderUtils
577: .loadAllProperties(SERVICE_VALIDATOR, Thread
578: .currentThread().getContextClassLoader());
579: } catch (IOException ex) {
580: throw new RuntimeException(ex);
581: }
582:
583: for (Iterator it = initialExtensions.values().iterator(); it
584: .hasNext();) {
585: String validatorClass = (String) it.next();
586: try {
587: if (LOG.isLoggable(Level.FINE)) {
588: LOG.fine("Found service validator : "
589: + validatorClass);
590: }
591: ServiceValidator validator = (ServiceValidator) Class
592: .forName(validatorClass).newInstance();
593: validators.add(validator);
594: } catch (Exception ex) {
595: LOG.log(Level.WARNING, "EXTENSION_ADD_FAILED_MSG", ex);
596: }
597: }
598: return validators;
599: }
600: }
|