/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.cxf.tools.corba.processors.idl; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.wsdl.Binding; import javax.wsdl.Definition; import javax.wsdl.Import; import javax.wsdl.Message; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.Types; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import antlr.ASTVisitor; import antlr.collections.AST; import org.apache.cxf.binding.corba.wsdl.CorbaConstants; import org.apache.cxf.binding.corba.wsdl.TypeMappingType; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.tools.common.ToolException; import org.apache.cxf.tools.corba.common.ToolCorbaConstants; import org.apache.cxf.tools.corba.common.WSDLUtils; import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaCollection; import org.apache.ws.commons.schema.XmlSchemaForm; import org.apache.ws.commons.schema.XmlSchemaType; import org.apache.ws.commons.schema.constants.Constants; public final class WSDLASTVisitor implements ASTVisitor { Definition definition; XmlSchema schema; XmlSchemaCollection schemas; TypeMappingType typeMap; ScopeNameCollection scopedNames; ScopeNameCollection recursionList; DeferredActionCollection deferredActions; String targetNamespace; private boolean declaredWSAImport; private boolean supportPolymorphicFactories; private XmlSchemaType sequenceOctetType; private boolean boundedStringOverride; private String idlFile; private String outputDir; private String importSchemaFilename; private boolean schemaGenerated; private ModuleToNSMapper moduleToNSMapper; private WSDLSchemaManager manager; private Map<Scope, List<Scope>> inheritScopeMap; private String pragmaPrefix; public WSDLASTVisitor(String tns, String schemans, String corbatypemaptns, String pragmaPrefix) throws WSDLException, JAXBException { manager = new WSDLSchemaManager(); definition = manager.createWSDLDefinition(tns); inheritScopeMap = new TreeMap<Scope, List<Scope>>(); targetNamespace = tns; schemas = new XmlSchemaCollection(); scopedNames = new ScopeNameCollection(); deferredActions = new DeferredActionCollection(); if (schemans == null) { schemans = tns; } schema = manager.createXmlSchemaForDefinition(definition, schemans, schemas); declaredWSAImport = false; typeMap = manager.createCorbaTypeMap(definition, corbatypemaptns); // idl:sequence<octet> maps to xsd:base64Binary by default sequenceOctetType = schemas.getTypeByQName(Constants.XSD_BASE64); // treat bounded corba:string/corba:wstring as unbounded if set to true setBoundedStringOverride(false); moduleToNSMapper = new ModuleToNSMapper(); this.setPragmaPrefix(pragmaPrefix); } public WSDLASTVisitor(String tns, String schemans, String corbatypemaptns) throws WSDLException, JAXBException { this(tns, schemans, corbatypemaptns, null); } public void visit(AST node) { // <specification> ::= <definition>+ while (node != null) { Scope rootScope = new Scope(); DefinitionVisitor definitionVisitor = new DefinitionVisitor(rootScope, definition, schema, this); definitionVisitor.visit(node); node = node.getNextSibling(); } try { manager.attachSchemaToWSDL(definition, schema, isSchemaGenerated()); } catch (Exception ex) { throw new RuntimeException(ex); } } public void setSchemaGenerated(boolean value) { schemaGenerated = value; } public boolean isSchemaGenerated() { return schemaGenerated; } public void updateSchemaNamespace(String name) throws Exception { schema.setTargetNamespace(name); } public void setQualified(boolean qualified) throws Exception { if (qualified) { XmlSchemaForm form = XmlSchemaForm.QUALIFIED; schema.setAttributeFormDefault(form); schema.setElementFormDefault(form); } } public void setSupportPolymorphicFactories(boolean support) throws Exception { supportPolymorphicFactories = support; } public boolean getSupportPolymorphicFactories() { return supportPolymorphicFactories; } public void setIdlFile(String idl) { idlFile = idl; } public String getIdlFile() { return idlFile; } public Map<Scope, List<Scope>> getInheritedScopeMap() { return inheritScopeMap; } public void setOutputDir(String outDir) { outputDir = outDir; } public String getOutputDir() { return outputDir; } public Definition getDefinition() { return definition; } public WSDLSchemaManager getManager() { return manager; } public XmlSchema getSchema() { return schema; } public XmlSchemaCollection getSchemas() { return schemas; } public ScopeNameCollection getScopedNames() { return scopedNames; } public ScopeNameCollection getRecursionList() { return recursionList; } public DeferredActionCollection getDeferredActions() { return deferredActions; } public TypeMappingType getTypeMap() { return typeMap; } public XmlSchemaType getSequenceOctetType() { return sequenceOctetType; } public void setImportSchema(String filename) { importSchemaFilename = filename; } public String getImportSchemaFilename() { return importSchemaFilename; } public void setSequenceOctetType(String type) throws Exception { XmlSchemaType stype = null; if (type.equals(ToolCorbaConstants.CFG_SEQUENCE_OCTET_TYPE_BASE64BINARY)) { stype = schemas.getTypeByQName(Constants.XSD_BASE64); } else if (type.equals(ToolCorbaConstants.CFG_SEQUENCE_OCTET_TYPE_HEXBINARY)) { stype = schemas.getTypeByQName(Constants.XSD_HEXBIN); } else { throw new ToolException("WSDLASTVisitor: Invalid XmlSchemaType specified " + "for idl:sequence<octet> mapping."); } sequenceOctetType = stype; } public boolean getBoundedStringOverride() { return boundedStringOverride; } public void setBoundedStringOverride(boolean value) { boundedStringOverride = value; } public Binding[] getCorbaBindings() { List<Binding> result = new ArrayList<>(); Map<QName, Binding> bindings = CastUtils.cast(definition.getBindings()); for (Binding binding : bindings.values()) { List<ExtensibilityElement> extElements = CastUtils.cast(binding.getExtensibilityElements()); for (int i = 0; i < extElements.size(); i++) { ExtensibilityElement el = extElements.get(i); if (el.getElementType().equals(CorbaConstants.NE_CORBA_BINDING)) { result.add(binding); break; } } } return result.toArray(new Binding[result.size()]); } public boolean writeDefinition(Writer writer) throws Exception { writeDefinition(definition, writer); return true; } public boolean writeDefinition(Definition def, Writer writer) throws Exception { WSDLUtils.writeWSDL(def, writer); return true; } public boolean writeSchemaDefinition(Definition definit, Writer writer) throws Exception { Definition def = manager.createWSDLDefinition(targetNamespace + "-types"); def.createTypes(); def.setTypes(definit.getTypes()); WSDLUtils.writeSchema(def, writer); return true; } public boolean writeSchema(XmlSchema schemaRef, Writer writer) throws Exception { //REVISIT, it should be easier to write out the schema directly, but currently, //the XmlSchemaSerializer throws a NullPointerException, when setting up namespaces!!! //schemaRef.write(writer); Definition defn = manager.createWSDLDefinition(schemaRef.getTargetNamespace()); manager.attachSchemaToWSDL(defn, schemaRef, true); writeSchemaDefinition(defn, writer); return true; } // REVISIT - When CXF corrects the wsdlValidator - will switch back on the // validation of the generated wsdls. public boolean writeDefinitions(Writer writer, Writer schemaWriter, Writer logicalWriter, Writer physicalWriter, String schemaFilename, String logicalFile, String physicalFile) throws Exception { Definition logicalDef = getLogicalDefinition(schemaFilename, schemaWriter); Definition physicalDef = null; // schema only if ((schemaFilename != null || importSchemaFilename != null) && (logicalFile == null && physicalFile == null)) { physicalDef = getPhysicalDefinition(logicalDef, true); } else { physicalDef = getPhysicalDefinition(logicalDef, false); } // write out logical file -L and physical in default if (logicalFile != null && physicalFile == null) { writeDefinition(logicalDef, logicalWriter); manager.addWSDLDefinitionImport(physicalDef, logicalDef, "logicaltns", logicalFile); writeDefinition(physicalDef, writer); } else if (logicalFile != null && physicalFile != null) { // write both logical -L and physical files -P writeDefinition(logicalDef, logicalWriter); manager.addWSDLDefinitionImport(physicalDef, logicalDef, "logicaltns", logicalFile); writeDefinition(physicalDef, physicalWriter); } else if (logicalFile == null && physicalFile != null) { // write pyhsical file -P and logical in default writeDefinition(logicalDef, writer); manager.addWSDLDefinitionImport(physicalDef, logicalDef, "logicaltns", getIdlFile()); writeDefinition(physicalDef, physicalWriter); } else if ((logicalFile == null && physicalFile == null) && (schemaFilename != null || importSchemaFilename != null)) { // write out the schema file -T and default of logical // and physical together. writeDefinition(physicalDef, writer); } else if (logicalFile == null && physicalFile == null && schemaFilename == null) { writeDefinition(definition, writer); } return true; } // Gets the logical definition for a file - an import will be added for the // schema types if -T is used and a separate schema file generated. // if -n is used an import will be added for the schema types and no types generated. private Definition getLogicalDefinition(String schemaFilename, Writer schemaWriter) throws WSDLException, JAXBException, Exception { Definition def = manager.createWSDLDefinition(targetNamespace); // checks for -T option. if (schemaFilename != null) { writeSchemaDefinition(definition, schemaWriter); manager.addWSDLSchemaImport(def, schema.getTargetNamespace(), schemaFilename); } else { // checks for -n option if (importSchemaFilename == null) { Types types = definition.getTypes(); def.setTypes(types); } else { manager.addWSDLSchemaImport(def, schema.getTargetNamespace(), importSchemaFilename); } } Collection<PortType> portTypes = CastUtils.cast(definition.getAllPortTypes().values()); for (PortType port : portTypes) { def.addPortType(port); } Collection<Message> messages = CastUtils.cast(definition.getMessages().values()); for (Message msg : messages) { def.addMessage(msg); } Collection<String> namespaces = CastUtils.cast(definition.getNamespaces().values()); for (String namespace : namespaces) { String prefix = definition.getPrefix(namespace); if (!"corba".equals(prefix)) { def.addNamespace(prefix, namespace); } else { def.removeNamespace(prefix); } } Collection<Import> imports = CastUtils.cast(definition.getImports().values()); for (Import importType : imports) { def.addImport(importType); } def.setDocumentationElement(definition.getDocumentationElement()); def.setDocumentBaseURI(definition.getDocumentBaseURI()); return def; } // Write the physical definitions to a file. private Definition getPhysicalDefinition(Definition logicalDef, boolean schemaOnly) throws WSDLException, JAXBException { Definition def = null; if (schemaOnly) { def = logicalDef; } else { def = manager.createWSDLDefinition(targetNamespace); } Collection<String> namespaces = CastUtils.cast(definition.getNamespaces().values()); for (String namespace : namespaces) { String prefix = definition.getPrefix(namespace); def.addNamespace(prefix, namespace); } Collection<Binding> bindings = CastUtils.cast(definition.getAllBindings().values()); for (Binding binding : bindings) { def.addBinding(binding); } Collection<Service> services = CastUtils.cast(definition.getAllServices().values()); for (Service service : services) { def.addService(service); } Collection<ExtensibilityElement> extns = CastUtils.cast(definition.getExtensibilityElements()); for (ExtensibilityElement ext : extns) { def.addExtensibilityElement(ext); } def.setExtensionRegistry(definition.getExtensionRegistry()); return def; } public boolean getDeclaredWSAImport() { return declaredWSAImport; } public void setDeclaredWSAImport(boolean declaredImport) { declaredWSAImport = declaredImport; } public void setModuleToNSMapping(Map<String, String> map) { moduleToNSMapper.setDefaultMapping(false); moduleToNSMapper.setUserMapping(map); } public ModuleToNSMapper getModuleToNSMapper() { return moduleToNSMapper; } public void setExcludedModules(Map<String, List<String>> modules) { moduleToNSMapper.setExcludedModuleMap(modules); } public void setPragmaPrefix(String pragmaPrefix) { this.pragmaPrefix = pragmaPrefix; } public String getPragmaPrefix() { return pragmaPrefix; } }