/****************************************************************************** | |
* Copyright (c) 2011, EBM WebSourcing | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License 2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/legal/epl-2.0/ | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* EBM WebSourcing - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.bpel.common.wsdl.parsers; | |
import java.util.Collection; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import org.eclipse.emf.common.util.URI; | |
import org.eclipse.emf.ecore.resource.Resource; | |
import org.eclipse.emf.ecore.resource.ResourceSet; | |
import org.eclipse.wst.wsdl.Definition; | |
import org.eclipse.wst.wsdl.Import; | |
import org.eclipse.wst.wsdl.WSDLPackage; | |
import org.eclipse.wst.wsdl.internal.util.WSDLResourceFactoryImpl; | |
/** | |
* A set of utilities to parse WSDL definitions and accounting for file imports. | |
* <p> | |
* This class aims at providing more features than the WSDL meta-model (from WTP) | |
* or than WSDL4j. The difference resides in the support of resource imports. | |
* </p> | |
* <p> | |
* The implementation is currently based on the EMF meta-model for WSDL. | |
* </p> | |
* | |
* @author Vincent Zurczak - EBM WebSourcing | |
*/ | |
public class WsdlParser { | |
/** | |
* Loads a WSDL definition. | |
* @param emfUri an EMF URI | |
* @param resourceSet a resource set | |
* @return an instance of {@link Definition} | |
* <p> | |
* This object does not support inclusions of WSDL files. | |
* It means imported WSDL definitions must be parsed separately. | |
* Note that XML schema inclusions are correctly supported. | |
* </p> | |
*/ | |
public static Definition loadWsdlDefinition( URI emfUri, ResourceSet resourceSet ) { | |
Resource resource = resourceSet.getResource( emfUri, true ); | |
return (Definition) resource.getContents().iterator().next(); | |
} | |
/** | |
* Loads a set of WSDL definition from one document. | |
* <p> | |
* The set includes the other definitions that come from the imports. | |
* </p> | |
* | |
* @see #findAllWsdlDefinitions(Definition) | |
* @param emfUri an EMF URI | |
* @param resourceSet a resource set | |
* @return an instance of {@link Definition} | |
* <p> | |
* This object supports inclusions of WSDL and XML Schema. | |
* XML schema inclusions are supported natively by the Definition object. | |
* WSDL inclusions are supported because every WSDL import results in a Definition instance. | |
* </p> | |
* <p> | |
* This method handles cyclic inclusions. | |
* </p> | |
*/ | |
public static Collection<Definition> loadAllWsdlDefinitions( URI emfUri, ResourceSet resourceSet ) { | |
Resource resource = resourceSet.getResource( emfUri, true ); | |
Definition def = (Definition) resource.getContents().iterator().next(); | |
return findAllWsdlDefinitions( def ); | |
} | |
/** | |
* Finds all the referenced WSDL definitions from one already loaded definition. | |
* <p> | |
* The set includes the other definitions that come from the imports. | |
* </p> | |
* | |
* @param alreadyLoadedDefinition a WSDL definition | |
* @return an instance of {@link Definition} | |
* <p> | |
* This object supports inclusions of WSDL and XML Schema. | |
* XML schema inclusions are supported natively by the Definition object. | |
* WSDL inclusions are supported because every WSDL import results in a Definition instance. | |
* </p> | |
* <p> | |
* This method handles cyclic inclusions. | |
* </p> | |
*/ | |
public static Collection<Definition> findAllWsdlDefinitions( Definition alreadyLoadedDefinition ) { | |
// Add the initial definition | |
Set<Definition> definitions = new HashSet<Definition> (); | |
definitions.add( alreadyLoadedDefinition ); | |
// Process the imports | |
processImports( alreadyLoadedDefinition.getImports(), definitions ); | |
return definitions; | |
} | |
/** | |
* Checks whether a definition seems valid or not. | |
* <p> | |
* The need for such a method results from the following discovery: when you load | |
* a WSDL 2.0 with the EMF meta-model, no error is thrown. Instead, a definition is | |
* created but it contains no information. | |
* </p> | |
* | |
* @param def a WSDL definition | |
* @return true if the definition seems valid, or false if it is definitely not a valid one | |
*/ | |
public static boolean seemsValidDefinition( Definition def ) { | |
return def.getBindings().size() != 0 | |
|| def.getPortTypes().size() != 0 | |
|| def.getServices().size() != 0 | |
|| def.getImports().size() != 0 | |
|| def.getTypes() != null; | |
} | |
/** | |
* Creates a resource set to parse WSDL definitions. | |
* <p> | |
* Note that WSDL extensions, such as partner link types, are not supported. | |
* Their support must be added in the resource set. | |
* </p> | |
* | |
* @return a resource set to parse WSDL | |
*/ | |
public static ResourceSet createBasicResourceSetForWsdl() { | |
ResourceSet resourceSet = XmlSchemaParser.createBasicResourceSetForXmlSchema(); | |
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put( "wsdl", new WSDLResourceFactoryImpl()); | |
resourceSet.getPackageRegistry().put( WSDLPackage.eNS_URI, WSDLPackage.eINSTANCE ); | |
return resourceSet; | |
} | |
/** | |
* Finds the definitions from imports and processes them recursively. | |
* @param imports a map of imports (see {@link Definition#getImports()}) | |
* @param definitions a list of definitions, found from import declarations | |
*/ | |
private static void processImports( Map<?,?> imports, Collection<Definition> definitions ) { | |
for( Object o : imports.values()) { | |
// Case "java.util.list" | |
if( o instanceof List<?> ) { | |
for( Object oo : ((List<?>) o)) { | |
Definition d = ((Import) oo).getEDefinition(); | |
if( d != null && ! definitions.contains( d )) { | |
definitions.add( d ); | |
processImports( d.getImports(), definitions ); | |
} | |
} | |
} | |
// Case "org.eclipse.wst.Definition" | |
else if( o instanceof Definition ) { | |
Definition d = (Definition) o;; | |
if( ! definitions.contains( d )) { | |
definitions.add( d ); | |
processImports( d.getImports(), definitions ); | |
} | |
} | |
} | |
} | |
} |