/**
* 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;
}
}