/* * 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.tuscany.sca.interfacedef.wsdl.impl; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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.WSDLElement; import javax.xml.namespace.QName; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLObject; import org.apache.tuscany.sca.xsd.XSDefinition; import org.apache.ws.commons.schema.XmlSchemaCollection; import org.apache.ws.commons.schema.XmlSchemaElement; import org.apache.ws.commons.schema.XmlSchemaType; /** * Represents a WSDL definition. * * @version $Rev$ $Date$ */ public class WSDLDefinitionImpl implements WSDLDefinition { private Definition definition; private String namespace; private URI location; private URI uri; private List<WSDLDefinition> imported = new ArrayList<WSDLDefinition>(); private List<XSDefinition> schemas = new ArrayList<XSDefinition>(); private boolean unresolved; private Binding binding; // WSDL in the same namespace can appear in multiple contributions // so we need to know which port type, binding and/or service we're looking for, // as well as which namespace, when we're resolving WSDL private QName nameOfPortTypeToResolve; private QName nameOfBindingToResolve; private QName nameOfServiceToResolve; private Map<String, String> wsdliLocations = new HashMap<String, String>(); protected WSDLDefinitionImpl() { } public Definition getDefinition() { return definition; } public void setDefinition(Definition definition) { this.definition = definition; } public boolean isUnresolved() { return unresolved; } public void setUnresolved(boolean undefined) { this.unresolved = undefined; } public String getNamespace() { if (isUnresolved()) { return namespace; } else if (definition != null) { return definition.getTargetNamespace(); } else { return namespace; } } public void setNamespace(String namespace) { if (!isUnresolved()) { throw new IllegalStateException(); } else { this.namespace = namespace; } } /* @Override public int hashCode() { return String.valueOf(getNamespace()).hashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj instanceof WSDLDefinition) { WSDLDefinition def = (WSDLDefinition)obj; if (getNamespace() != null) { return getNamespace().equals(def.getNamespace()); } else { return def.getNamespace() == null; } } else { return false; } } */ /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getXmlSchemas() */ public List<XSDefinition> getXmlSchemas() { return schemas; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getLocation() */ public URI getLocation() { return location; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#setLocation(java.net.URI) */ public void setLocation(URI url) { this.location = url; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getURI() */ public URI getURI() { return uri; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#setURI(java.net.URI) */ public void setURI(URI uri) { this.uri = uri; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getImportedDefinitions() */ public List<WSDLDefinition> getImportedDefinitions() { return imported; } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((location == null) ? 0 : location.hashCode()); result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); return result; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof WSDLDefinitionImpl)) return false; final WSDLDefinitionImpl other = (WSDLDefinitionImpl)obj; if (location == null) { if (other.location != null) return false; } else if (!location.equals(other.location)) return false; if (namespace == null) { if (other.namespace != null) return false; } else if (!namespace.equals(other.namespace)) return false; return true; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getXmlSchemaElement(javax.xml.namespace.QName) */ public XmlSchemaElement getXmlSchemaElement(QName name) { XmlSchemaCollection schemaCollection = null; for (XSDefinition xsd : schemas) { if (schemaCollection == null && xsd.getSchemaCollection() != null) { schemaCollection = xsd.getSchemaCollection(); } XmlSchemaElement element = xsd.getXmlSchemaElement(name); if (element != null) { return element; } } if (schemaCollection != null) { XmlSchemaElement element = schemaCollection.getElementByQName(name); if ( element != null) { return element; } } for ( WSDLDefinition d: imported ) { if ( d.getDefinition() == definition ) { XmlSchemaElement element = d.getXmlSchemaElement(name); if ( element != null ) return element; break; } } for ( WSDLDefinition d : imported ) { XmlSchemaElement element = d.getXmlSchemaElement(name); if ( element != null ) return element; } return null; } /** * @see org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition#getXmlSchemaType(javax.xml.namespace.QName) */ public XmlSchemaType getXmlSchemaType(QName name) { XmlSchemaCollection schemaCollection = null; for (XSDefinition xsd : schemas) { if (xsd.getSchemaCollection() != null) { schemaCollection = xsd.getSchemaCollection(); } XmlSchemaType type = xsd.getXmlSchemaType(name); if (type != null) { return type; } } if (schemaCollection != null) { XmlSchemaType type = schemaCollection.getTypeByQName(name); if ( type != null ) { return type; } } // If this is an aggregated facade WSDL, the definition that this is intended to represent // will be in the list of imports. We check for the type in this definition first before // proceeding to any imports. // TODO - This aggregated WSDL facade is a little strange and this isn't the most efficient // way to handle this. For now, this resolves an issue where inline types are being // returned from the wrong wsdl, but this could be improved. for ( WSDLDefinition d: imported ) { if ( d.getDefinition() == definition ) { XmlSchemaType type = d.getXmlSchemaType(name); if ( type != null ) return type; break; } } for ( WSDLDefinition d: imported ) { XmlSchemaType type = d.getXmlSchemaType(name); if ( type != null ) return type; break; } return null; } @SuppressWarnings("unchecked") private static <T extends WSDLElement> WSDLObject<T> getWSDLObject(Definition definition, Class<T> type, QName name) { if (definition == null) { return null; } Map<QName, WSDLElement> map = null; if (type == PortType.class) { map = definition.getPortTypes(); } else if (type == Service.class) { map = definition.getServices(); } else if (type == Binding.class) { map = definition.getBindings(); } else if (type == Message.class) { map = definition.getMessages(); } else { throw new IllegalArgumentException("Invalid type: " + type.getName()); } if (map.containsKey(name)) { return (WSDLObject<T>)new WSDLObjectImpl(definition, map.get(name)); } else { for (Object imports : definition.getImports().values()) { List<Import> importList = (List<Import>)imports; for (Import i : importList) { definition = i.getDefinition(); WSDLObject<T> element = getWSDLObject(definition, type, name); if (element != null) { return element; } } } } return null; } public <T extends WSDLElement> WSDLObject<T> getWSDLObject(Class<T> type, QName name) { return getWSDLObject(definition, type, name); } public Binding getBinding() { return binding; } public void setBinding(Binding binding) { this.binding = binding; } public QName getNameOfPortTypeToResolve() { return nameOfPortTypeToResolve; } public void setNameOfPortTypeToResolve(QName nameOfPortTypeToResolve) { this.nameOfPortTypeToResolve = nameOfPortTypeToResolve; } public QName getNameOfBindingToResolve() { return nameOfBindingToResolve; } public void setNameOfBindingToResolve(QName nameOfBindingToResolve) { this.nameOfBindingToResolve = nameOfBindingToResolve; } public QName getNameOfServiceToResolve() { return nameOfServiceToResolve; } public void setNameOfServiceToResolve(QName nameOfServiceToResolve) { this.nameOfServiceToResolve = nameOfServiceToResolve; } @Override public Map<String, String> getWsdliLocations() { return wsdliLocations ; } }