/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed 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
*******************************************************************************/
package org.ebayopensource.turmeric.eclipse.typelibrary.ui.wst;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.xml.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.common.config.LibraryType;
import org.ebayopensource.turmeric.common.config.ReferredType;
import org.ebayopensource.turmeric.common.config.ReferredTypeLibraryType;
import org.ebayopensource.turmeric.common.config.TypeDependencyType;
import org.ebayopensource.turmeric.common.config.TypeLibraryDependencyType;
import org.ebayopensource.turmeric.eclipse.buildsystem.TypeDepMarshaller;
import org.ebayopensource.turmeric.eclipse.core.TurmericCoreActivator;
import org.ebayopensource.turmeric.eclipse.exception.core.SOABadParameterException;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem;
import org.ebayopensource.turmeric.eclipse.typelibrary.resources.SOAMessages;
import org.ebayopensource.turmeric.eclipse.typelibrary.utils.TypeLibraryUtil;
import org.ebayopensource.turmeric.eclipse.ui.monitor.typelib.SOAGlobalRegistryAdapter;
import org.ebayopensource.turmeric.eclipse.ui.views.registry.SOATypeLibraryConstants;
import org.ebayopensource.turmeric.eclipse.utils.core.VersionUtil;
import org.ebayopensource.turmeric.eclipse.utils.lang.StringUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.EclipseMessageUtils;
import org.ebayopensource.turmeric.tools.library.SOATypeRegistry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.ui.internal.commands.AddTypesCommand;
import org.eclipse.wst.wsdl.ui.internal.commands.AddXSDSchemaCommand;
import org.eclipse.wst.xsd.ui.internal.adt.editor.CommonMultiPageEditor;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDInclude;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaDirective;
import org.eclipse.xsd.XSDTypeDefinition;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* WTP Type Library Utility contains the WTP related utility functions. The WSDL
* is manipulated using the wtp emf model. Here in SOA it is used for both
* reading and writing the wsdl and xsd. There are some discouraged classes
* being used but will be removed in future. Most of them are getters and are
* being used in the templating and import use cases.
*
* @author smathew
*
*/
public class WTPTypeLibUtil {
/**
* Scans the schema and returns all the type imports pertaining to SOA
* protocol. Remember this will not return the normal XSD imports.ie the
* imports without the typelib: protocol. The registry is being queried for
* the type name before adding it to the returned map.
*
* @param xsdSchema
* @return
* @throws Exception
*/
public static Map<LibraryType, XSDSchemaDirective> getAllTypeLibImports(
XSDSchema xsdSchema) throws Exception {
Map<LibraryType, XSDSchemaDirective> typeImportsList = new ConcurrentHashMap<LibraryType, XSDSchemaDirective>();
for (Object xsdContent : xsdSchema.getContents()) {
if (xsdContent instanceof XSDSchemaDirective) {
XSDSchemaDirective xsdSchemaDirective = (XSDSchemaDirective) xsdContent;
String xsdSchemaLocation = xsdSchemaDirective
.getSchemaLocation();
String typeName = TypeLibraryUtil
.getTypeNameFromProtocolString(xsdSchemaLocation);
String importedTypeNameSpace = "";
if (xsdSchemaDirective instanceof XSDInclude) {
if (xsdSchemaDirective.getResolvedSchema() != null) {
importedTypeNameSpace = ((XSDInclude)xsdSchemaDirective).getResolvedSchema().getTargetNamespace();
} else {
importedTypeNameSpace = xsdSchema.getTargetNamespace();
}
} else if (xsdSchemaDirective instanceof XSDImport) {
importedTypeNameSpace = ((XSDImport) xsdSchemaDirective)
.getNamespace();
}
if (!StringUtils.isEmpty(typeName)) {
SOATypeRegistry typeRegistry = SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry();
LibraryType libType = typeRegistry.getType(new QName(importedTypeNameSpace,
typeName));
if (libType != null) {
typeImportsList.put(libType,
xsdSchemaDirective);
}
}
}
}
return typeImportsList;
}
/**
* Returns the types defined in the given WSDL definition that are part of
* the global registry. Basically the API scan the WSDL and finds all the
* types and then query the Global registry with the type name and will add
* it to the returned map only if the registry has the type. In short it
* returns all the type library types in the WSDL definition.
*
* @param definition
* @return
* @throws Exception
*/
public static Map<LibraryType, XSDTypeDefinition> getTypeLibraryTypes(
Definition definition) throws Exception {
Map<LibraryType, XSDTypeDefinition> allSchemas = new ConcurrentHashMap<LibraryType, XSDTypeDefinition>();
Types types = ((Types) definition.getTypes());
// Do we have a schema already?
for (Object objSchema : types.getSchemas()) {
XSDSchema xsdSchema = (XSDSchema) objSchema;
for (Object xsdSchemaContent : xsdSchema.getContents()) {
if (xsdSchemaContent instanceof XSDTypeDefinition) {
XSDTypeDefinition xsdTypeDefinition = (XSDTypeDefinition) xsdSchemaContent;
// Annotations will take precedence over the XSD target
// namespace
String nameSpace = getNameSpace(xsdTypeDefinition);
SOATypeRegistry typeRegistry = SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry();
LibraryType libraryType = typeRegistry.getType(
new QName(nameSpace, xsdTypeDefinition
.getName()));
if (libraryType != null) {
allSchemas.put(libraryType, xsdTypeDefinition);
}
}
}
}
return allSchemas;
}
public static String getNameSpace(XSDTypeDefinition xsdTypeDefinition)
throws SOABadParameterException {
for (XSDAnnotation annotation : xsdTypeDefinition.getAnnotations()) {
for (Element element : annotation.getApplicationInformation()) {
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
if (node instanceof Element) {
Element childElement = (Element) node;
if (StringUtils.equals(childElement.getNodeName(),
SOATypeLibraryConstants.TAG_TYPE_LIB)) {
if (StringUtils
.isEmpty(childElement
.getAttribute(SOATypeLibraryConstants.ATTR_NMSPC))) {
throw new SOABadParameterException(
StringUtil.formatString(
SOAMessages.ERR_NMSPC,
xsdTypeDefinition.getName()));
}
return childElement
.getAttribute(SOATypeLibraryConstants.ATTR_NMSPC);
}
}
}
}
}
return xsdTypeDefinition.getTargetNamespace();
}
/**
* Scan the given map of schemas and returns a new map containing only the
* types which has a version in the type dependency XML lower than the one
* in the the registry. Basically if Type A has version 1.0.0 in type
* dependency XML and the type information XML file inside the type library
* that holds Type A has version greater than 1.0.0.
*
* @param allSchemas the all schemas
* @param project the project
* @return the updated schemas
* @throws Exception the exception
*/
public static Map<LibraryType, XSDTypeDefinition> getUpdatedSchemas(
Map<LibraryType, XSDTypeDefinition> allSchemas, IProject project)
throws Exception {
Map<LibraryType, XSDTypeDefinition> newSchemas = new ConcurrentHashMap<LibraryType, XSDTypeDefinition>();
IFile typeDepFile = TurmericCoreActivator.getDependencyFile(project);
if (typeDepFile.exists() == false) {
return newSchemas;
}
SOATypeRegistry typeRegistry = SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry();
TypeLibraryDependencyType typeLibraryDependencyType = TypeDepMarshaller
.unmarshallIt(typeDepFile);
// compare type library by type library, because of ENF = false, type
// name could be duplicated.
for (TypeDependencyType type : typeLibraryDependencyType.getType()) {
for (ReferredTypeLibraryType referredTypeLibraryType : type
.getReferredTypeLibrary()) {
// get the type library be referred type library name. No
// duplicated types in type library.
String refTLName = referredTypeLibraryType.getName();
List<LibraryType> typesInTL = typeRegistry
.getTypesOfLibrary(refTLName);
for (LibraryType typeInTL : typesInTL) {
for (ReferredType refType : referredTypeLibraryType
.getReferredType()) {
if (StringUtils.equals(typeInTL.getName(), refType
.getName()) == false) {
continue;
}
if (VersionUtil.compare(typeInTL.getVersion(), refType
.getVersion()) <= 0) {
continue;
}
newSchemas.put(typeInTL, allSchemas.get(typeInTL));
}
}
}
}
// Set<ReferredType> referredTypes = TypeDepMarshaller
// .getALLReferredTypes(typeLibraryDependencyType);
// // Add all other dependent libraries this type is referring to
// for (LibraryType libraryType : allSchemas.keySet()) {
// for (ReferredType refType : referredTypes) {
// if (StringUtils
// .equals(libraryType.getName(), refType.getName()) == false) {
// continue;
// }
// if (VersionUtil.compare(libraryType.getVersion(), refType
// .getVersion()) <= 0) {
// continue;
// }
// newSchemas.put(libraryType, allSchemas.get(libraryType));
// }
// }
return newSchemas;
}
/**
* Making sure that this is a WTP editor and is a candidate for SOA to add
* their context menus.
*
* @param editorPart the editor part
* @return true, if successful
*/
public static boolean validateEditorForContextMenus(Object editorPart) {
return (editorPart != null && (editorPart instanceof StructuredTextEditor || editorPart instanceof CommonMultiPageEditor));
}
/**
* Removes the type from the model. Remember this is an IO operation. This
* just modifies the WTP EMF model. Returns true if the type was found in
* the definition and was successfully removed, Otherwise returns false.
* Editor will be dirty after successful execution of this operation.
*
* @param definition the definition
* @param qname the qname
* @return true, if successful
*/
public static boolean removeType(Definition definition, QName qname) {
if (hasSchema(definition, qname.getNamespaceURI())) {
XSDTypeDefinition xsdTypeDefinition = getType(definition, qname);
if (xsdTypeDefinition != null) {
return xsdTypeDefinition.getSchema().getContents().remove(
xsdTypeDefinition);
}
}
return false;
}
private static XSDTypeDefinition getType(Definition definition, QName qname) {
XSDTypeDefinition typeDefinition = null;
for (XSDSchema schema : getXSDSchema(definition, qname
.getNamespaceURI())) {
typeDefinition = getXSDTypeDefinition(schema, qname);
break;
}
return typeDefinition;
}
/**
* This code is copy pasted from inlineType function because today is the
* release and we want to minimize the impact. We have to refactor it out
* after the release. Basically this API delays the imports till the end of
* the execution
*
* @param impTypeSet the imp type set
* @param addditionalImpTypeSet the addditional imp type set
* @param definition the definition
* @param typeFolding the type folding
* @throws Exception the exception
*/
public static void wrapImport(Set<LibraryType> impTypeSet,
Set<LibraryType> addditionalImpTypeSet, Definition definition,
boolean typeFolding) throws Exception {
Map<XSDSchema, List<LibraryType>> srcTypes = new ConcurrentHashMap<XSDSchema, List<LibraryType>>();
for (LibraryType libraryType : impTypeSet) {
removeType(definition, TypeLibraryUtil.toQName(libraryType));
if (isTypeAlreadyInlined(libraryType.getName(), definition,
libraryType.getLibraryInfo().getLibraryNamespace(),
typeFolding)) {
return;
} else {
XSDSchema dstSchema = null;
XSDSchema srcSchema = TypeLibraryUtil
.parseSchema(TypeLibraryUtil.getXSD(libraryType));
String typeNamespace = libraryType.getLibraryInfo()
.getLibraryNamespace();
if (typeFolding)
typeNamespace = definition.getTargetNamespace();
// If its a new schema section we want to have the element form
// default values copied from the source.
if (!hasSchema(definition, typeNamespace)) {
dstSchema = getXSDSchema(definition, typeNamespace).get(0);
dstSchema.setElementFormDefault(srcSchema
.getElementFormDefault());
} else {
dstSchema = getXSDSchema(definition, typeNamespace).get(0);
}
if (srcTypes.get(dstSchema) == null) {
srcTypes.put(dstSchema, new ArrayList<LibraryType>());
}
srcTypes.get(dstSchema).add(libraryType);
for (Object objXsdSchemaContent : srcSchema.getContents()) {
if (objXsdSchemaContent != null
&& objXsdSchemaContent instanceof XSDImport) {
XSDImport xsdSchemaImport = (XSDImport) objXsdSchemaContent;
XSDImport xsdSchemaDirective = XSDFactory.eINSTANCE
.createXSDImport();
xsdSchemaDirective.setNamespace(xsdSchemaImport
.getNamespace());
if (!importExists(dstSchema, xsdSchemaImport
.getNamespace()))
dstSchema.getContents().add(0, xsdSchemaDirective);
}
}
}
}
// adding the imports for request and response and the elements inside
// it.
if (!typeFolding) {
XSDSchema mainSchema = getXSDSchema(definition,
definition.getTargetNamespace()).get(0);
for (LibraryType libraryType : addditionalImpTypeSet) {
addImportDirective(mainSchema, libraryType.getNamespace());
}
addImportDirective(mainSchema, GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getConfigurationRegistry()
.getBaseServiceResponseNameSpace());
addImportDirective(mainSchema, GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getConfigurationRegistry()
.getBaseServiceRequestNameSpace());
}
for (Entry<XSDSchema, List<LibraryType>> entry : srcTypes.entrySet()) {
XSDSchema destSchema = entry.getKey();
List<LibraryType> libTypes = entry.getValue();
for (LibraryType libType : libTypes) {
WTPCopyUtil.copy(destSchema, libType, typeFolding);
}
}
}
private static void addImportDirective(XSDSchema schema,
String libElementNamespace) {
if (!StringUtil.broadEquals(schema.getTargetNamespace(),
libElementNamespace)
&& !importExists(schema, libElementNamespace)) {
XSDImport xsdSchemaDirective = XSDFactory.eINSTANCE
.createXSDImport();
xsdSchemaDirective.setNamespace(libElementNamespace);
schema.getContents().add(0, xsdSchemaDirective);
}
}
private static boolean importExists(XSDSchema schema,
String libElementNamespace) {
for (Iterator i = schema.getContents().iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof XSDImport) {
if (StringUtil.broadEquals(((XSDImport) o).getNamespace(),
libElementNamespace)) {
return true;
}
}
}
return false;
}
// /**
// * Wrapper over the method.
// *
// * @see {@link WTPTypeLibUtil#inlineType(LibraryType, Definition,
// boolean)}
// * @param libraryType
// * @param definition
// * @throws MalformedURLException
// * @throws IOException
// * @throws Exception
// */
// public static void inlineType(LibraryType libraryType,
// Definition definition)
// throws MalformedURLException, IOException, Exception {
// inlineType(libraryType, definition, true, typeFolding);
// }
/**
* In-lines the given WTP WSDL definition objects with the given library
* type object(converted to an XSD model object after parsing). If the check
* for duplicate boolean is true the operation will become a no operation if
* the type is already in-lined. Uses internally the
* AddXSDTypeDefinitionCommand from WTP.
*
* @param libraryType the library type
* @param definition the definition
* @param checkForDuplicates -
* If true, this function will execute a duplicate check and will
* return silently without doing anything if the type already
* exists in the definition passed.
* @param typeFolding the type folding
* @return the i status
* @throws MalformedURLException the malformed url exception
* @throws IOException Signals that an I/O exception has occurred.
* @throws Exception the exception
*/
public static IStatus inlineType(LibraryType libraryType,
Definition definition, boolean checkForDuplicates,
boolean typeFolding) throws MalformedURLException, IOException,
Exception {
if (checkForDuplicates
&& isTypeAlreadyInlined(libraryType.getName(), definition,
libraryType.getLibraryInfo().getLibraryNamespace(),
typeFolding)) {
return EclipseMessageUtils.createStatus(
StringUtil.formatString(SOAMessages.ERR_SELECTED_TYPE_ALREADY_IMPORT,
libraryType.getName()), IStatus.WARNING);
} else {
XSDSchema dstSchema = null;
XSDSchema srcSchema = TypeLibraryUtil.parseSchema(TypeLibraryUtil
.getXSD(libraryType));
String typeNamespace = libraryType.getLibraryInfo()
.getLibraryNamespace();
if (typeFolding)
typeNamespace = definition.getTargetNamespace();
// If its a new schema section we want to have the element form
// default values copied from the source.
if (!hasSchema(definition, typeNamespace)) {
dstSchema = getXSDSchema(definition, typeNamespace).get(0);
dstSchema.setElementFormDefault(srcSchema
.getElementFormDefault());
} else {
dstSchema = getXSDSchema(definition, typeNamespace).get(0);
}
WTPCopyUtil.copy(dstSchema, libraryType, typeFolding);
// find all importted namespace in current schema
Set<String> importedNamespaces = new HashSet<String>();
for(Object dstXSDContentObj : dstSchema.getContents()){
if (dstXSDContentObj instanceof XSDImport) {
XSDImport importNode = (XSDImport)dstXSDContentObj;
importedNamespaces.add(importNode.getNamespace());
}
}
for (Object objXsdSchemaContent : srcSchema.getContents()) {
if (objXsdSchemaContent != null
&& objXsdSchemaContent instanceof XSDImport) {
XSDImport xsdSchemaImport = (XSDImport) objXsdSchemaContent;
if(importedNamespaces.contains(xsdSchemaImport.getNamespace()) == true){
// this import is already included, skip it.
continue;
}
XSDImport xsdSchemaDirective = XSDFactory.eINSTANCE
.createXSDImport();
xsdSchemaDirective.setNamespace(xsdSchemaImport
.getNamespace());
dstSchema.getContents().add(0, xsdSchemaDirective);
}
}
}
return Status.OK_STATUS;
}
private static XSDTypeDefinition getXSDTypeDefinition(XSDSchema schema,
QName typeQName) {
for (Object objTypeDefinition : schema.getTypeDefinitions()) {
if (objTypeDefinition instanceof XSDTypeDefinition) {
XSDTypeDefinition typeDefinition = (XSDTypeDefinition) objTypeDefinition;
if (StringUtils.equals(typeQName.getLocalPart(), typeDefinition
.getName())
&& StringUtils.equals(typeQName.getNamespaceURI(),
typeDefinition.getTargetNamespace())) {
return typeDefinition;
}
}
}
return null;
}
public static List<XSDSchema> getXSDSchema(Definition definition,
String targetNamespace) {
List<XSDSchema> schemaList = getTypes(definition).getSchemas(
targetNamespace);
if (schemaList == null || schemaList.isEmpty()) {
schemaList = new ArrayList<XSDSchema>();
AddXSDSchemaCommand command = new AddXSDSchemaCommand(definition,
targetNamespace);
command.run();
schemaList.add(((XSDSchemaExtensibilityElement) command
.getWSDLElement()).getSchema());
}
return schemaList;
}
private static boolean hasSchema(Definition definition,
String targetNamespace) {
List<XSDSchema> schemaList = getTypes(definition).getSchemas(
targetNamespace);
return schemaList != null && !schemaList.isEmpty();
}
/**
* Return the types.
*
* @param definition the definition
* @return the types
*/
public static Types getTypes(Definition definition) {
Types types = (Types) definition.getTypes();
if (types != null)
return types;
else {
AddTypesCommand command = new AddTypesCommand(definition);
command.run();
return (Types) command.getWSDLElement();
}
}
/**
* @param typeName
* @param definition
* @param nameSpace
* @return
*/
private static boolean isTypeAlreadyInlined(String typeName,
Definition definition, String nameSpace, boolean typeFolding) {
if (definition != null) {
if (definition.getTypes() != null) {
Types types = (Types) definition.getTypes();
List objSchemas = null;
// if type is folded then there is only one name space ideally
// and essentially does not match the types namespace. We might
// have to scan the annotation to find out the name space of the
// the type.
if (typeFolding)
objSchemas = types.getSchemas();
else
objSchemas = types.getSchemas(nameSpace);
for (Object schemaObj : objSchemas) {
if (schemaObj instanceof XSDSchema) {
XSDSchema xsdSchema = (XSDSchema) schemaObj;
for (Object objXsdTypeDefinition : xsdSchema
.getTypeDefinitions()) {
if (objXsdTypeDefinition != null
&& (objXsdTypeDefinition instanceof XSDTypeDefinition)
&& StringUtils
.equals(
((XSDTypeDefinition) objXsdTypeDefinition)
.getName(),
typeName)) {
// name check is enough for single name space
// WSDL.
if (typeFolding) {
return true;
}
// Both name space and names have to be equal
// for multiple name space WSDL.
else if (StringUtils
.equals(
((XSDTypeDefinition) objXsdTypeDefinition)
.getTargetNamespace(),
nameSpace)) {
return true;
}
}
}
}
}
}
}
return false;
}
/**
* Removes the inline type from wsdl definition.
*
* @param definition the definition
* @param selectedType the selected type
* @param importedTypesMap the imported types map
*/
public static void removeInlineTypeFromWSDLDefinition(Definition definition,
LibraryType selectedType,
Map<LibraryType, XSDTypeDefinition> importedTypesMap) {
Types types = ((Types) definition.getTypes());
XSDTypeDefinition deletedXsdTypeDefinition = importedTypesMap
.get(selectedType);
if (deletedXsdTypeDefinition == null) {
return;
}
XSDSchema deletedSchemasParent = null;
// Do we have a schema already?
Iterator<?> iterator = types.getSchemas().iterator();
while (iterator.hasNext()) {
XSDSchema xsdSchema = (XSDSchema) iterator.next();
for (Object xsdSchemaContent : xsdSchema.getContents()) {
if (xsdSchemaContent == deletedXsdTypeDefinition) {
deletedSchemasParent = xsdSchema;
break;
}
}
}
if (deletedSchemasParent == null) {
return;
}
// remove xsd type from definition
deletedSchemasParent.getContents().remove(deletedXsdTypeDefinition);
int typeCount = 0;
List<XSDImport> importNodes = new ArrayList<XSDImport>();
Set<String> importedNamespaces = new HashSet<String>();
// get all imported namespaces in current schema content and get xsd
// type definition count
for (Object xsdSchemaContent : deletedSchemasParent.getContents()) {
if (xsdSchemaContent instanceof XSDTypeDefinition) {
// found one xsd type in current schema
typeCount++;
XSDTypeDefinition type = (XSDTypeDefinition) xsdSchemaContent;
// find all import node in the xsd type via library type
LibraryType libraryType = null;
try {
QName qname = new QName(type.getTargetNamespace(), type
.getName());
libraryType = SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry()
.getType(qname);
} catch (Exception e) {
continue;
}
if (libraryType == null) {
continue;
}
try {
XSDSchema typeSchema = TypeLibraryUtil
.parseSchema(TypeLibraryUtil.getXSD(libraryType));
for (Object objXsdSchemaContent : typeSchema.getContents()) {
if (objXsdSchemaContent instanceof XSDImport) {
XSDImport importNode = (XSDImport) objXsdSchemaContent;
// add import namespace into a set
importedNamespaces.add(importNode.getNamespace());
}
}
} catch (IOException e) {
continue;
} catch (Exception e) {
continue;
}
} else if (xsdSchemaContent instanceof XSDImport) {
// found all import node in current schema and add it to a set
importNodes.add((XSDImport) xsdSchemaContent);
}
}
// remove unused import nodes
List<XSDImport> removeImportNodes = new ArrayList<XSDImport>();
for (XSDImport importNode : importNodes) {
String namespace = importNode.getNamespace();
// if a import in current schema is not used by any of xsd types in
// current schema
if (importedNamespaces.contains(namespace) == false) {
// plan to remove it
removeImportNodes.add(importNode);
}
}
// do remove
deletedSchemasParent.getContents().removeAll(removeImportNodes);
}
}