| /******************************************************************************* |
| * Copyright (c) 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.ui.util; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.xsd.XSDAnnotation; |
| import org.eclipse.xsd.XSDAttributeDeclaration; |
| import org.eclipse.xsd.XSDAttributeGroupDefinition; |
| import org.eclipse.xsd.XSDAttributeUse; |
| import org.eclipse.xsd.XSDAttributeUseCategory; |
| import org.eclipse.xsd.XSDComplexTypeContent; |
| import org.eclipse.xsd.XSDComplexTypeDefinition; |
| import org.eclipse.xsd.XSDConcreteComponent; |
| import org.eclipse.xsd.XSDConstraint; |
| import org.eclipse.xsd.XSDElementDeclaration; |
| import org.eclipse.xsd.XSDFacet; |
| import org.eclipse.xsd.XSDFactory; |
| import org.eclipse.xsd.XSDFeature; |
| import org.eclipse.xsd.XSDIdentityConstraintDefinition; |
| import org.eclipse.xsd.XSDImport; |
| import org.eclipse.xsd.XSDInclude; |
| import org.eclipse.xsd.XSDModelGroup; |
| import org.eclipse.xsd.XSDModelGroupDefinition; |
| import org.eclipse.xsd.XSDNamedComponent; |
| import org.eclipse.xsd.XSDNotationDeclaration; |
| import org.eclipse.xsd.XSDParticle; |
| import org.eclipse.xsd.XSDSchema; |
| import org.eclipse.xsd.XSDSchemaCompositor; |
| import org.eclipse.xsd.XSDSchemaContent; |
| import org.eclipse.xsd.XSDSimpleTypeDefinition; |
| import org.eclipse.xsd.XSDTypeDefinition; |
| import org.eclipse.xsd.XSDWildcard; |
| import org.eclipse.xsd.XSDXPathDefinition; |
| import org.eclipse.xsd.util.XSDConstants; |
| import org.eclipse.xsd.util.XSDUtil; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.Text; |
| |
| /** |
| * Collection of utility methods for dealing with navigation of the XSD model |
| */ |
| public class XSDUtils { |
| |
| // singleton lists of XSD simple type definitions for supported primitives (see getPrimitives()) and |
| // all xsd primitives (see getAdvancedPrimitives()) respectively |
| private static List<XSDSimpleTypeDefinition> primitives; |
| private static List<XSDTypeDefinition> advancedPrimitives; |
| |
| // XSD short list -- these are the types presented to the user by default, rather than inundating them with |
| // all the available types |
| private static List<String> xsdShortList = new ArrayList<String>(); |
| static |
| { |
| xsdShortList.add("string"); //$NON-NLS-1$ |
| xsdShortList.add("int"); //$NON-NLS-1$ |
| xsdShortList.add("double"); //$NON-NLS-1$ |
| xsdShortList.add("date"); //$NON-NLS-1$ |
| xsdShortList.add("time"); //$NON-NLS-1$ |
| xsdShortList.add("dateTime"); //$NON-NLS-1$ |
| xsdShortList.add("boolean"); //$NON-NLS-1$ |
| xsdShortList.add("hexBinary"); //$NON-NLS-1$ |
| xsdShortList.add("float"); //$NON-NLS-1$ |
| } |
| |
| |
| // A list of all supported XSD types. Usually the user will not be presented with the full list, but |
| // rather with the xsd short list |
| private static List<String> supportedPrimitives = new ArrayList<String>(); |
| static { |
| supportedPrimitives.add("anyType"); //$NON-NLS-1$ |
| supportedPrimitives.add("anyURI"); //$NON-NLS-1$ |
| supportedPrimitives.add("base64Binary"); //$NON-NLS-1$ |
| supportedPrimitives.add("boolean"); //$NON-NLS-1$ |
| supportedPrimitives.add("byte"); //$NON-NLS-1$ |
| supportedPrimitives.add("date"); //$NON-NLS-1$ |
| supportedPrimitives.add("dateTime"); //$NON-NLS-1$ |
| supportedPrimitives.add("decimal"); //$NON-NLS-1$ |
| supportedPrimitives.add("double"); //$NON-NLS-1$ |
| supportedPrimitives.add("duration"); //$NON-NLS-1$ |
| supportedPrimitives.add("ENTITIES"); //$NON-NLS-1$ |
| supportedPrimitives.add("ENTITY"); //$NON-NLS-1$ |
| supportedPrimitives.add("float"); //$NON-NLS-1$ |
| supportedPrimitives.add("gDay"); //$NON-NLS-1$ |
| supportedPrimitives.add("gMonth"); //$NON-NLS-1$ |
| supportedPrimitives.add("gMonthDay"); //$NON-NLS-1$ |
| supportedPrimitives.add("gYear"); //$NON-NLS-1$ |
| supportedPrimitives.add("gYearMonth"); //$NON-NLS-1$ |
| supportedPrimitives.add("hexBinary"); //$NON-NLS-1$ |
| supportedPrimitives.add("ID"); //$NON-NLS-1$ |
| supportedPrimitives.add("IDREF"); //$NON-NLS-1$ |
| supportedPrimitives.add("IDREFS"); //$NON-NLS-1$ |
| supportedPrimitives.add("int"); //$NON-NLS-1$ |
| supportedPrimitives.add("integer"); //$NON-NLS-1$ |
| supportedPrimitives.add("language"); //$NON-NLS-1$ |
| supportedPrimitives.add("long"); //$NON-NLS-1$ |
| supportedPrimitives.add("Name"); //$NON-NLS-1$ |
| supportedPrimitives.add("NCName"); //$NON-NLS-1$ |
| supportedPrimitives.add("negativeInteger"); //$NON-NLS-1$ |
| supportedPrimitives.add("NMTOKEN"); //$NON-NLS-1$ |
| supportedPrimitives.add("NMTOKENS"); //$NON-NLS-1$, "NMTOKENS"); |
| supportedPrimitives.add("nonNegativeInteger"); //$NON-NLS-1$ |
| supportedPrimitives.add("nonPositiveInteger"); //$NON-NLS-1$ |
| supportedPrimitives.add("normalizedString"); //$NON-NLS-1$ |
| supportedPrimitives.add("NOTATION"); //$NON-NLS-1$ |
| supportedPrimitives.add("positiveInteger"); //$NON-NLS-1$ |
| supportedPrimitives.add("QName"); //$NON-NLS-1$ |
| supportedPrimitives.add("short"); //$NON-NLS-1$ |
| supportedPrimitives.add("string"); //$NON-NLS-1$ |
| supportedPrimitives.add("time"); //$NON-NLS-1$ |
| supportedPrimitives.add("token"); //$NON-NLS-1$ |
| supportedPrimitives.add("unsignedByte"); //$NON-NLS-1$ |
| supportedPrimitives.add("unsignedInt"); //$NON-NLS-1$ |
| supportedPrimitives.add("unsignedLong"); //$NON-NLS-1$ |
| supportedPrimitives.add("unsignedShort"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Add a local annotation with userInfo to the given item. |
| * |
| * <p> |
| * Note: We take an XSDConcreteComponent, however we must then cast it to |
| * one of the types that has a setAnnotation call defined, since it doesn't |
| * have a clear 'parent' interface for annotations. |
| * </p> |
| * |
| * <p> |
| * Also note that UserInformation and ApplicationInformation objects can |
| * only be added <b>after </b> the parent of the annotation has been added |
| * to an XSDSchema object. This is because these objects are modeled in the |
| * concrete DOM layer only, and otherwise will throw a DOMException. |
| * <p> |
| * |
| * @param component |
| * to add annotation to; may be any kind of XSDConcreteComponent |
| * object including an XSDSchema |
| * @param text |
| * text to add as the userInformation (xsd:documentation) node to |
| * the annotation |
| * @return the XSDAnnotation object created, after having been added to the |
| * component; null if any error occoured |
| */ |
| public static XSDAnnotation addDocumentation(XSDConcreteComponent component, String text) { |
| if (null == component) { |
| throw new IllegalArgumentException("addDocumentation called with null component"); //$NON-NLS-1$ |
| } |
| try { |
| |
| // First get the factory from the component: this is |
| // roundabout, but saves the user from having to |
| // pass it in |
| XSDFactory xsdFactory = XSDFactory.eINSTANCE; |
| |
| // Create an XSDAnnotation object to hold everything |
| XSDAnnotation xsdAnnotation = xsdFactory.createXSDAnnotation(); |
| |
| // Depending on the XSDConcreteComponent type, cast to |
| // the appropriate type and add the annotation or, if component |
| // already has an annotation, use that one instead. |
| if (component instanceof XSDAttributeDeclaration) { |
| if(((XSDAttributeDeclaration) component).getAnnotation() == null) |
| ((XSDAttributeDeclaration) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDAttributeDeclaration) component).getAnnotation(); |
| } else if (component instanceof XSDAttributeGroupDefinition) { |
| if(((XSDAttributeGroupDefinition) component).getAnnotation() == null) |
| ((XSDAttributeGroupDefinition) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDAttributeGroupDefinition) component).getAnnotation(); |
| } else if (component instanceof XSDElementDeclaration) { |
| if(((XSDElementDeclaration) component).getAnnotation() == null) |
| ((XSDElementDeclaration) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDElementDeclaration) component).getAnnotation(); |
| } else if (component instanceof XSDFacet) { |
| if(((XSDFacet) component).getAnnotation() == null) |
| ((XSDFacet) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDFacet) component).getAnnotation(); |
| } else if (component instanceof XSDIdentityConstraintDefinition) { |
| if(((XSDIdentityConstraintDefinition) component).getAnnotation() == null) |
| ((XSDIdentityConstraintDefinition) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDIdentityConstraintDefinition) component).getAnnotation(); |
| } else if (component instanceof XSDImport) { |
| if(((XSDImport) component).getAnnotation() == null) |
| ((XSDImport) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDImport) component).getAnnotation(); |
| } else if (component instanceof XSDInclude) { |
| if(((XSDInclude) component).getAnnotation() == null) |
| ((XSDInclude) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDInclude) component).getAnnotation(); |
| } else if (component instanceof XSDModelGroup) { |
| if(((XSDModelGroup) component).getAnnotation() == null) |
| ((XSDModelGroup) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDModelGroup) component).getAnnotation(); |
| } else if (component instanceof XSDModelGroupDefinition) { |
| if(((XSDModelGroupDefinition) component).getAnnotation() == null) |
| ((XSDModelGroupDefinition) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDModelGroupDefinition) component).getAnnotation(); |
| } else if (component instanceof XSDNotationDeclaration) { |
| if(((XSDNotationDeclaration) component).getAnnotation() == null) |
| ((XSDNotationDeclaration) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDNotationDeclaration) component).getAnnotation(); |
| } else if (component instanceof XSDTypeDefinition) { |
| if(((XSDTypeDefinition) component).getAnnotation() == null) |
| ((XSDTypeDefinition) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDTypeDefinition) component).getAnnotation(); |
| } else if (component instanceof XSDWildcard) { |
| if(((XSDWildcard) component).getAnnotation() == null) |
| ((XSDWildcard) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDWildcard) component).getAnnotation(); |
| } else if (component instanceof XSDXPathDefinition) { |
| if(((XSDXPathDefinition) component).getAnnotation() == null) |
| ((XSDXPathDefinition) component).setAnnotation(xsdAnnotation); |
| else |
| xsdAnnotation = ((XSDXPathDefinition) component).getAnnotation(); |
| } else if (component instanceof XSDSchema) { |
| // Note that this adds a global annotation to the |
| // schema itself, not to any subcomponent |
| ((XSDSchema) component).getContents().add(xsdAnnotation); |
| } else { |
| // Whoops, asked us to annotate an unannotateable item |
| throw new IllegalArgumentException("Unable to addDocumentation onto type: " + component); //$NON-NLS-1$ |
| } |
| |
| // Remove any old documentation elements |
| for(int i = 0; i < xsdAnnotation.getElement().getChildNodes().getLength(); i++) { |
| Node node = xsdAnnotation.getElement().getChildNodes().item(i); |
| if(node.getNodeName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG)) |
| xsdAnnotation.getElement().removeChild(node); |
| } |
| xsdAnnotation.getUserInformation().clear(); |
| |
| if (text!=null) |
| { |
| // Now that the xsdAnnotation is added to a parent |
| // XSDConcreteComponent, go ahead and create the |
| // UserInformation node (xsd:documentation) and |
| // add a DOM textNode to it containing the information |
| Element userInfo = xsdAnnotation.createUserInformation(null); |
| userInfo.appendChild(userInfo.getOwnerDocument().createTextNode(text)); |
| |
| // Add the finished userInfo object to the concrete |
| // element of the xsdAnnotation |
| xsdAnnotation.getElement().appendChild(userInfo); |
| |
| // Add the finished userInfo object to the user information |
| // list |
| xsdAnnotation.getUserInformation().add(userInfo); |
| } |
| |
| return xsdAnnotation; |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| /** |
| * Adds the text to the component as a Documentation element (just like addDocumentation) and then adds the |
| * Documentation attributes to the Documentation element if they exist. |
| * If text is null then no documentation is set. |
| * If attributes is null then no attributes are added to the documentation element. |
| * @param component |
| * @param text |
| * @param attributes |
| * @return |
| */ |
| public static XSDAnnotation addDocumentationAndAttributes(XSDConcreteComponent component, String text, Map attributes) |
| { |
| if (null == component) |
| { |
| throw new IllegalArgumentException("addDocumentationAndAttributes called with null component"); //$NON-NLS-1$ |
| } |
| |
| // nothing to add |
| if (text==null && attributes==null) |
| return null; |
| |
| // add documentation |
| XSDAnnotation annotation = addDocumentation(component, text); |
| |
| if (annotation==null) |
| return null; |
| |
| // no attributes so return |
| if (attributes==null || attributes.isEmpty()) |
| return annotation; |
| |
| // get annotation dom element, create if necessary |
| Element userInfo = null; |
| if (annotation.getUserInformation().isEmpty()) |
| { |
| userInfo = annotation.createUserInformation(null); |
| annotation.getElement().appendChild(userInfo); |
| } |
| else |
| { |
| for (Iterator<Element> i = annotation.getUserInformation().iterator(); i.hasNext();) |
| { |
| userInfo = i.next(); |
| if (userInfo.getTagName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG)) |
| { |
| break; |
| } |
| } |
| } |
| |
| if (userInfo==null) |
| return null; |
| |
| // add attributes |
| String key = null; |
| for (Iterator<String> iter = attributes.keySet().iterator(); iter.hasNext();) |
| { |
| key = iter.next(); |
| userInfo.setAttribute(key, (String)attributes.get(key)); |
| } |
| |
| return annotation; |
| } |
| |
| |
| /** |
| * Returns a string which is not used by any element in 'elements'. The name |
| * is generated by appending numerical suffixes on to 'prefix' until a |
| * unique one is found. PRECONDITION: 'elements' is a list of |
| * XSDNamedComponent instances |
| * |
| * @param prefix |
| * @param elements |
| * @return |
| */ |
| public static String createUniqueElementName(String prefix, List elements) { |
| ArrayList<String> usedNames = new ArrayList<String>(); |
| for(Iterator i = elements.iterator(); i.hasNext(); ) { |
| usedNames.add( getDisplayName((XSDNamedComponent) i.next())); |
| } |
| |
| int i = 1; |
| String testName = prefix + i++; |
| while(usedNames.contains(testName)) { |
| testName = prefix + i++; |
| } |
| return testName; |
| } |
| |
| /** |
| * Like getPrimitives(), this returns a list of XSDTypeDefinitions. However where getPrimitives() |
| * returns the basic set supported by the editor, getAdvancedPrimitives returns every known XSD |
| * primitive type. |
| * @return |
| */ |
| public static List<XSDTypeDefinition> getAdvancedPrimitives() { |
| advancedPrimitives = null; |
| if(advancedPrimitives == null) { |
| advancedPrimitives = new ArrayList<XSDTypeDefinition>(); |
| |
| // Get the schema for schemas instance to use when resolving primitives |
| XSDSchema schemaForSchemas = XSDUtil.getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001); |
| |
| // Start adding the simple types using the supportedPrimitives list |
| for (String typeName : supportedPrimitives) { |
| XSDTypeDefinition type = schemaForSchemas.resolveSimpleTypeDefinition(typeName); |
| advancedPrimitives.add(type); |
| } |
| |
| // Return primitives in alpha order |
| Collections.sort(advancedPrimitives, new Comparator() { |
| |
| public int compare(Object o1, Object o2) { |
| if(o1 == null || o2 == null || ((XSDTypeDefinition) o1).getName() == null) |
| return 0; |
| return ((XSDTypeDefinition) o1).getName().compareToIgnoreCase(((XSDTypeDefinition) o2).getName()); |
| } |
| }); |
| } |
| return advancedPrimitives; |
| } |
| |
| /** |
| * Retrieves all the root Data types defined in the schema including complex types, user-defined simple types and anonymous |
| * complex types. If there's an anonymous complex type definition (from a root element declaration) then we return |
| * the element declaration's anonymous type. |
| * @param schema |
| * @return |
| */ |
| public static List<XSDTypeDefinition> getAllDataTypes(XSDSchema schema) |
| { |
| if (schema==null) |
| return Collections.emptyList(); |
| |
| List<XSDTypeDefinition> bos = new ArrayList<XSDTypeDefinition>(); |
| |
| EList<XSDSchemaContent> contents = schema.getContents(); |
| // First try the easy approach -- if this XSD contains a type definition, that's our BO, |
| // return it. This is the recommended path, and the way our tooling does things. |
| for (XSDSchemaContent item : contents) { |
| if (item instanceof XSDTypeDefinition) |
| bos.add((XSDTypeDefinition)item); |
| } |
| |
| // If we failed, we try a second pass, this time looking for an element |
| // with an anonymous complex |
| // type defined in line |
| for (XSDSchemaContent item : contents) { |
| if (item instanceof XSDElementDeclaration) |
| { |
| XSDElementDeclaration element = (XSDElementDeclaration) item; |
| if (element.getAnonymousTypeDefinition() instanceof XSDComplexTypeDefinition) |
| { |
| bos.add(element.getAnonymousTypeDefinition()); |
| } |
| } |
| } |
| return bos; |
| } |
| |
| /** |
| * Given a BO (XSD Complex Type), return a list of the attributes |
| * within the complexType. |
| * @param bo |
| * @return List of XSDAttributeDeclaration |
| */ |
| public static List<XSDAttributeDeclaration> getChildAttributes(XSDComplexTypeDefinition bo) |
| { |
| EList attrContents = bo.getAttributeContents(); |
| List<XSDAttributeDeclaration> attrs = new ArrayList<XSDAttributeDeclaration>(); |
| for (int i=0; i< attrContents.size(); i++) |
| { |
| Object next = attrContents.get(i); |
| |
| // Attribute contents may include actual attribute delcarations (wrapped in XSDAttributeUses) or |
| // attribute group definitions, containing bundles of attributes |
| if(next instanceof XSDAttributeUse) { |
| attrs.add( ((XSDAttributeUse) next).getContent().getResolvedAttributeDeclaration() ); |
| |
| } else if (next instanceof XSDAttributeGroupDefinition) { |
| |
| // Add these attributes to the end of attrContents to be processed in turn |
| XSDAttributeGroupDefinition attrGroup = (XSDAttributeGroupDefinition) next; |
| if(attrGroup.getResolvedAttributeGroupDefinition() != null) |
| attrContents.addAll(attrGroup.getResolvedAttributeGroupDefinition().getAttributeUses()); |
| |
| } |
| } |
| return attrs; |
| } |
| |
| /** |
| * Given a BO (XSD Complex Type), return a list of the XSDFeatures |
| * within the complexType's modelgroup (sequence, choice, etc.) |
| * @param bo |
| * @return |
| */ |
| public static List<XSDFeature> getChildElements(XSDComplexTypeDefinition bo) |
| { |
| return XSDUtils.getChildElements( getModelGroup(bo) ); |
| } |
| |
| /** |
| * Given an XSDFeature, return a list of the XSDFeatures |
| * within the complexType's modelgroup (sequence, choice, etc.) |
| * @param bo |
| * @return |
| */ |
| public static List<XSDFeature> getChildElements(XSDFeature elem) |
| { |
| XSDComplexTypeDefinition cType = getResolvedComplexType(elem); |
| return (cType != null) ? XSDUtils.getChildElements(cType) : Collections.EMPTY_LIST; |
| } |
| |
| |
| /** |
| * Given a Model group, return a list of the XSDFeatures |
| * declared within. |
| * @param group |
| * @return |
| */ |
| public static List<XSDFeature> getChildElements(XSDModelGroup group) |
| { |
| if(group == null) |
| return new ArrayList<XSDFeature>(); |
| |
| List<XSDFeature> children = new ArrayList<XSDFeature>(); |
| for(Iterator<XSDParticle> i = group.getContents().iterator(); i.hasNext();) |
| { |
| XSDParticle next = i.next(); |
| if(next.getContent() instanceof XSDFeature) |
| children.add((XSDFeature) next.getContent()); |
| else if (next.getTerm() instanceof XSDModelGroup) |
| children.addAll(getChildElements((XSDModelGroup) next.getTerm())); |
| } |
| return children; |
| } |
| |
| /** |
| * Return the contents of the documentation element in type's annotation, if it has one. |
| * Otherwise return null |
| * @param type |
| * @return |
| */ |
| public static String getDocumentation(XSDFeature element) { |
| XSDAnnotation annotation = null; |
| |
| if (element instanceof XSDAttributeDeclaration) |
| annotation = ((XSDAttributeDeclaration)element).getAnnotation(); |
| else if (element instanceof XSDElementDeclaration) |
| annotation = ((XSDElementDeclaration)element).getAnnotation(); |
| |
| if(annotation != null) { |
| for(Iterator i = annotation.getUserInformation().iterator(); i.hasNext(); ) { |
| Element domElement = (Element) i.next(); |
| if(domElement.getTagName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG) && |
| domElement.getFirstChild() instanceof Text) { |
| return ((Text) domElement.getFirstChild()).getData(); |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the attributes on the documentation element if they exist. I.e. returns source and xml:lang |
| * Returns an empty map if none. |
| * @param type |
| * @return |
| */ |
| public static Map<String, String> getDocumentationAttributes(XSDTypeDefinition type) |
| { |
| Map<String, String> attributes = new HashMap<String, String>(); |
| |
| if (type.getAnnotation() != null) |
| { |
| XSDAnnotation annotation = type.getAnnotation(); |
| for (Iterator i = annotation.getUserInformation().iterator(); i |
| .hasNext();) |
| { |
| Element element = (Element) i.next(); |
| if (element.getTagName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG)) |
| { |
| String source = element.getAttribute("source"); //$NON-NLS-1$ |
| String lang = element.getAttribute("xml:lang"); //$NON-NLS-1$ |
| if (lang==null || lang.length()<1) |
| lang = element.getAttribute("lang"); //$NON-NLS-1$ |
| |
| if (source!=null && source.length()>0) |
| attributes.put("source", source); //$NON-NLS-1$ |
| |
| if (lang!=null && lang.length()>0) |
| attributes.put("xml:lang", lang); //$NON-NLS-1$ |
| |
| return attributes; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the attributes on the documentation element if they exist. I.e. returns source and xml:lang |
| * Returns an empty map if none. |
| * @param element |
| * @return |
| */ |
| public static Map<String, String> getDocumentationAttributes(XSDFeature element) |
| { |
| XSDAnnotation annotation = null; |
| Map<String, String> attributes = new HashMap<String, String>(); |
| |
| if (element instanceof XSDAttributeDeclaration) |
| annotation = ((XSDAttributeDeclaration)element).getAnnotation(); |
| else if (element instanceof XSDElementDeclaration) |
| annotation = ((XSDElementDeclaration)element).getAnnotation(); |
| |
| if (annotation != null) |
| { |
| for (Iterator i = annotation.getUserInformation().iterator(); i |
| .hasNext();) |
| { |
| Element domElement = (Element) i.next(); |
| if (domElement.getTagName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG)) |
| { |
| String source = domElement.getAttribute("source"); //$NON-NLS-1$ |
| String lang = domElement.getAttribute("xml:lang"); //$NON-NLS-1$ |
| if (lang==null || lang.length()<1) |
| lang = domElement.getAttribute("lang"); //$NON-NLS-1$ |
| |
| if (source!=null && source.length()>0) |
| attributes.put("source", source); //$NON-NLS-1$ |
| |
| if (lang!=null && lang.length()>0) |
| attributes.put("xml:lang", lang); //$NON-NLS-1$ |
| |
| return attributes; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return the contents of the documentation element in type's annotation, if it has one. |
| * Otherwise return null |
| * @param type |
| * @return |
| */ |
| public static String getDocumentation(XSDTypeDefinition type) { |
| if(type.getAnnotation() != null) { |
| XSDAnnotation annotation = type.getAnnotation(); |
| for(Iterator i = annotation.getUserInformation().iterator(); i.hasNext(); ) { |
| Element element = (Element) i.next(); |
| if(element.getTagName().endsWith(XSDConstants.DOCUMENTATION_ELEMENT_TAG) && |
| element.getFirstChild() instanceof Text) { |
| return ((Text) element.getFirstChild()).getData(); |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Given an XSD Complex Type Definition, return the model group containing |
| * its child elements. |
| * @param element |
| * @return |
| */ |
| public static XSDModelGroup getModelGroup(XSDComplexTypeDefinition cType) |
| { |
| XSDParticle particle = cType.getComplexType(); |
| |
| // In cases where cType doesn't have a model group AND cType has a parent with a modelgroup, the |
| // call above will rather unexpectedly give us cType's PARENT's model group, rather than the null we |
| // might expect. We don't want that here, if the model group returned is null or belongs to someone |
| // other than us, return null |
| if (particle==null || particle.eContainer() != cType) { |
| return null; |
| } |
| |
| // get the model group |
| Object particleContent = particle.getContent(); |
| XSDModelGroup group = null; |
| |
| if (particleContent instanceof XSDModelGroupDefinition) { |
| group = ((XSDModelGroupDefinition)particleContent).getResolvedModelGroupDefinition().getModelGroup(); |
| } else if (particleContent instanceof XSDModelGroup) { |
| group = (XSDModelGroup)particleContent; |
| } |
| |
| if (group == null) { |
| return null; |
| } |
| |
| // if the content of the complex type is empty then the content |
| // must be in the complexContent, ie. we're extending another BO. |
| // if the group and the type are not in the same resource then |
| // we are extending another BO and we don't want to show inherited |
| // attributes. |
| if ( group.getContents().isEmpty() || group.eResource() != cType.eResource()) |
| { |
| // if we are extending another BO then get the elements |
| // we are adding |
| if (cType.getBaseType()!=null) |
| { |
| XSDComplexTypeContent content = cType.getContent(); |
| |
| if (content instanceof XSDParticle) { |
| particleContent = ((XSDParticle)content).getContent(); |
| if (particleContent instanceof XSDModelGroupDefinition) { |
| group = ((XSDModelGroupDefinition)particleContent).getResolvedModelGroupDefinition().getModelGroup(); |
| } else if (particleContent instanceof XSDModelGroup) { |
| group = (XSDModelGroup)particleContent; |
| } |
| } |
| |
| } |
| } |
| |
| return group; |
| } |
| |
| /** |
| * General utility method for finding a name for an xsd component. This method will handle |
| * mapping of xsd primitive names to their human readable counterparts, as well as resolving |
| * element references for attributes and walking up object hierarchies for anonymous types. |
| * Basically this method should be used whenever a name is needed to minimize the risk of |
| * having a name of 'null' -- though this method WILL return null if no name can be found. |
| * @param component |
| * @return |
| */ |
| public static String getDisplayName(XSDNamedComponent component) { |
| |
| if(component == null) |
| return null; |
| |
| if(component instanceof XSDTypeDefinition) |
| return getDisplayNameFromXSDType((XSDTypeDefinition) component); |
| |
| if (component instanceof XSDFeature) { |
| XSDFeature feature = (XSDFeature) component; |
| if(feature.getName() != null) |
| return feature.getName(); |
| else if (feature.getResolvedFeature() != null && feature.getResolvedFeature().getName() != null) |
| return feature.getResolvedFeature().getName(); |
| } |
| |
| return component.getName(); |
| |
| } |
| |
| /** |
| * Try a variety of methods to get a human readable name for type. In order, this method will |
| * - check whether type is null, and if so return null |
| * - check whether type is a restriction of a primitive type, if so return its parent's name |
| * - check whether type is a complex anonymous (un-named) inner type of a named element, and if so, return the element's name |
| * - check whether type is a primitive type, and if so return a human-readable version of that type |
| * - check whether type is a named, non-primitive type, and if so, return its name |
| * @param xsdType |
| * @return |
| */ |
| public static String getDisplayNameFromXSDType(XSDTypeDefinition type) { |
| return getDisplayNameFromXSDType(type, true); |
| } |
| |
| /** |
| * Try a variety of methods to get a human readable name for type. In order, this method will |
| * - check whether type is null, and if so return null |
| * - check whether type is a complex anonymous (un-named) inner type of a named element, and if so, return the element's name |
| * - check whether type is a primitive type, and if so return a human-readable version of that type |
| * - check whether type is a named, non-primitive type, and if so, return its name |
| * - if returnPrimitiveParents is true, check whether type is a restriction of a primitive type, |
| * if so return its parent's name |
| * @param xsdType |
| * @param returnPrimitiveParents if true, and if type is an anonymous restriction of an xsd primitive |
| * type, this method will return the name of the parent primitive type. If false, restrictions of |
| * primitive types will not be treated differently from other types, and their container hierarchy will |
| * be walked, instead of their inheritance hierarchy. |
| * @return |
| */ |
| public static String getDisplayNameFromXSDType(XSDTypeDefinition type, boolean returnPrimitiveParents) { |
| if(type == null) |
| return null; |
| |
| |
| |
| // Does type have a name? If not, walk up the container tree to try and find one |
| if(type.getName() == null || type.getName().length() == 0) { |
| |
| // In the special case where type is a restriction on a primitive type, just return the parent's |
| // name (which will either be a primitive itself, or a named simple type) |
| if(returnPrimitiveParents && isRestrictedPrimitiveType(type)) { |
| return getDisplayNameFromXSDType(type.getBaseType()); |
| } |
| |
| EObject container = type.eContainer(); |
| |
| while(container != null) { |
| if(container instanceof XSDNamedComponent && ((XSDNamedComponent) container).getName() != null) { |
| return ((XSDNamedComponent) container).getName(); |
| } |
| container = container.eContainer(); |
| } |
| // Type doesn't have a name, or a container with a name, nothing useful |
| return null; |
| } else |
| return type.getName(); |
| } |
| |
| /** |
| * Return the type definition for the primitive with name xsdName (note, this is not the human-readable |
| * name, but the actual XSD type name.) Return null if a type with this name is not in the list of |
| * all primitives |
| * @param xsdName |
| * @return |
| */ |
| public static XSDSimpleTypeDefinition getPrimitive(String xsdName) { |
| for(Iterator<XSDTypeDefinition> i = getAdvancedPrimitives().iterator(); i.hasNext();) { |
| XSDSimpleTypeDefinition next = (XSDSimpleTypeDefinition) i.next(); |
| if(next.getName().equals(xsdName)) { |
| return next; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * |
| * @return Returns a list of XSDSimpleTypeDefinitions representing each of the supported primitives. |
| * These will have their XSD spec names (e.g. xsd:dateTime) so they will likely need to be fed to |
| * getDisplayName() if they are going to be presented to humans |
| */ |
| public static List<XSDSimpleTypeDefinition> getPrimitives() { |
| if(primitives == null) { |
| primitives = new ArrayList<XSDSimpleTypeDefinition>(); |
| |
| // Get the schema for schemas instance to use when resolving primitives |
| XSDSchema schemaForSchemas = XSDUtil.getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001); |
| |
| // Start adding the simple types from the XSD short list |
| for(Iterator<String> i = xsdShortList.iterator(); i.hasNext(); ) { |
| String typeName = i.next(); |
| |
| XSDSimpleTypeDefinition type = schemaForSchemas.resolveSimpleTypeDefinition(typeName); |
| primitives.add(type); |
| } |
| |
| // Return primitives in alpha order |
| Collections.sort(primitives, new Comparator() { |
| |
| public int compare(Object o1, Object o2) { |
| if(o1 == null || o2 == null || getDisplayNameFromXSDType((XSDTypeDefinition) o1) == null) |
| return 0; |
| return getDisplayNameFromXSDType((XSDTypeDefinition) o1).compareTo(getDisplayNameFromXSDType((XSDTypeDefinition) o2)); |
| } |
| }); |
| } |
| return primitives; |
| } |
| |
| /** |
| * Return a collection of all types referenced by the attributes (XSDFeatures) of source. This |
| * method is non-recursive (i.e. the list only contains direct references, not references-of-references) |
| * Will not return null, but may return an empty set. This will not return a BO reference if the file |
| * has been deleted (or just doesn't exist). |
| * @param source The complex type to examine for references |
| * @return a Collection of XSDComplexTypeDefinition instances -- no duplicates |
| */ |
| public static Collection<XSDComplexTypeDefinition> getReferencedTypes(XSDComplexTypeDefinition source) { |
| if(source == null) |
| return Collections.emptySet(); |
| |
| List<XSDComplexTypeDefinition> results = new ArrayList<XSDComplexTypeDefinition>(); |
| for(Iterator<XSDFeature> i = getChildElements(source).iterator(); i.hasNext(); ) { |
| XSDFeature element = i.next(); |
| XSDComplexTypeDefinition elementType = getResolvedComplexType(element); |
| if(elementType != null && !results.contains(elementType) && !XSDConstants.isSchemaForSchemaNamespace(elementType.getTargetNamespace())) |
| results.add(elementType); |
| } |
| return results; |
| } |
| |
| /** |
| * Return a collection of all types referenced by the attributes (XSDFeatures) of source. This |
| * method is non-recursive (i.e. the list only contains direct references, not references-of-references) |
| * Will not return null, but may return an empty set. This will return a BO reference if the file |
| * has been deleted (or just doesn't exist). |
| * @param source The complex type to examine for references |
| * @return a Collection of XSDTypeDefinition (could be complex or simple type) instances -- no duplicates |
| */ |
| public static Collection<XSDTypeDefinition> getAllReferencedTypes(XSDComplexTypeDefinition source) |
| { |
| return getAllReferencedTypes(source, false); |
| } |
| |
| /** |
| * Return a collection of all types referenced by the attributes (XSDFeatures) of source. This |
| * method is non-recursive (i.e. the list only contains direct references, not references-of-references) |
| * Will not return null, but may return an empty set. This will return a BO reference if the file |
| * has been deleted (or just doesn't exist). |
| * @param source The complex type to examine for references |
| * @param includeAnonymous if true, the returned list will include anonymous inlined types as well. These |
| * are not technically "referenced", however it allows this method to be used as a way to get all non-primitive |
| * types used in any way by source |
| * @return a Collection of XSDTypeDefinition (could be complex or simple type) instances -- no duplicates |
| */ |
| public static Collection<XSDTypeDefinition> getAllReferencedTypes(XSDComplexTypeDefinition source, boolean includeAnonymous) |
| { |
| if (source == null) |
| return Collections.emptySet(); |
| |
| List<XSDTypeDefinition> results = new ArrayList<XSDTypeDefinition>(); |
| XSDTypeDefinition elementType = null; |
| for (Iterator<XSDFeature> i = getChildElements(source).iterator(); i.hasNext();) |
| { |
| XSDFeature next = i.next(); |
| elementType = getResolvedType(next); |
| |
| // Only add non-null, non-duplicate, non-primitive types. If includeAnonymous is false, |
| // anonymous types should be filtered out as well |
| if( elementType != null && |
| !results.contains(elementType) && |
| !XSDConstants.isSchemaForSchemaNamespace(elementType.getTargetNamespace()) && |
| (includeAnonymous || elementType.eContainer() != next) ) |
| results.add(elementType); |
| } |
| return results; |
| } |
| |
| /** |
| * Given an element, return its complex type, or null if it does not have a complex type. This is |
| * slightly more complicated than just calling getType() since an element may not have a type at all, it |
| * may reference another element. |
| * @param element |
| * @return |
| */ |
| public static XSDComplexTypeDefinition getResolvedComplexType(XSDFeature feature) { |
| // The contents of this method have been adapted to the more general getResolvedType, |
| // but this method is maintained for compatibility and convenience |
| XSDTypeDefinition resolvedType = getResolvedType(feature); |
| if(resolvedType instanceof XSDComplexTypeDefinition) |
| return (XSDComplexTypeDefinition) resolvedType; |
| return null; |
| } |
| |
| /** |
| * Given an element, return its type, or null if it does not have a type. This is |
| * slightly more complicated than just calling getType() since an element may not have |
| * a type at all, it may reference another element. |
| * @param element |
| * @return |
| */ |
| public static XSDTypeDefinition getResolvedType(XSDFeature feature) { |
| |
| // Special case of elements referencing stale XSD complex types |
| if (feature instanceof XSDElementDeclaration && ((XSDElementDeclaration) feature).getTypeDefinition() instanceof XSDComplexTypeDefinition) { |
| |
| XSDElementDeclaration element = (XSDElementDeclaration) feature; |
| |
| // We have a type, but types can be proxies, and proxies can become |
| // stale if the referenced |
| // type changes, so before we return it, re-resolve the proxy and |
| // then return it |
| XSDComplexTypeDefinition oldType = (XSDComplexTypeDefinition) element.getTypeDefinition(); |
| EObject newType = EcoreUtil.resolve(element.getTypeDefinition(), element); |
| if (oldType != newType) { |
| // We only return the resolved type if the name and the namespace has not changed. Changing the name |
| // and namespace is essentially an unresolved BO. |
| String oldName = oldType.getName(); |
| String newName = ((XSDTypeDefinition)newType).getName(); |
| String oldTNS = oldType.getTargetNamespace(); |
| String newTNS = ((XSDTypeDefinition)newType).getTargetNamespace(); |
| |
| if ( ((oldName==newName) || (oldName!=null && oldName.equals(newName))) && |
| ((oldTNS==newTNS) || (oldTNS!=null && oldTNS.equals(newTNS))) ) |
| element.setTypeDefinition((XSDTypeDefinition) newType); |
| } |
| return element.getTypeDefinition(); |
| |
| } else if (feature.getType() != null) { |
| return feature.getType(); |
| } else if (feature.getResolvedFeature() != null && feature.getResolvedFeature().getType() != null) { |
| // We reference another element |
| return feature.getResolvedFeature().getType(); |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Return the base type from which this type inherits - that is, all xsd types are |
| * either xsd:anyType or xsd:anySimpleType at the topmost level of inheritance, so return the second |
| * topmost level of type's inheritance. The first specific type from which type inherits. |
| * @param type |
| * @return |
| */ |
| public static XSDTypeDefinition getRootType(XSDTypeDefinition type) { |
| if(type == null) |
| return null; |
| |
| XSDTypeDefinition baseType = type.getBaseType(); |
| while(baseType != null && !XSDConstants.isAnySimpleType(baseType) && !XSDConstants.isAnyType(baseType)) { |
| // walk one more step up the hierarchy |
| type = baseType; |
| baseType = type.getBaseType(); |
| } |
| |
| // Since baseType, type's immediate parent, broke the while condition, we know that type is now |
| // as high up the tree as we want to be |
| return type; |
| |
| |
| |
| } |
| |
| /** |
| * Given a schema, return the list of XSDSimpleTypeDefinitions found within it. Will not return null, |
| * but may return an empty list |
| * @param schema |
| * @return |
| */ |
| public static List<XSDSimpleTypeDefinition> getUserDefinedSimpleTypes(XSDSchema schema) { |
| if(schema == null) |
| return Collections.emptyList(); |
| |
| List<XSDSimpleTypeDefinition> result = new ArrayList<XSDSimpleTypeDefinition>(); |
| for (XSDSchemaContent next : schema.getContents()) { |
| if(next instanceof XSDSimpleTypeDefinition) |
| result.add((XSDSimpleTypeDefinition)next); |
| } |
| return result; |
| } |
| |
| /** |
| * Given a display name for a BO attribute type, return the XSD type name. |
| * If the given input is not a display name, the input is returned. |
| * @param displayName |
| * @return |
| */ |
| public static String getXSDTypeFromDisplayName(String displayName) |
| { |
| // Now a no-op since we no longer translate XSD type names to "human readable" ones |
| return displayName; |
| } |
| |
| /** |
| * Return true iff type is a descendant of a primitive xsd type. Will not return true for primitives |
| * themselves. |
| * @param type |
| * @return |
| */ |
| public static boolean isRestrictedPrimitiveType(XSDTypeDefinition type) { |
| if(type instanceof XSDComplexTypeDefinition) |
| return false; |
| |
| XSDTypeDefinition baseType = getRootType(type); |
| return getAdvancedPrimitives().contains(baseType); |
| } |
| |
| /** |
| * Gets the "minOccurs" attribute value for the given XSDFeature, if |
| * there is none then it returns the default 1. |
| * @param xsdElem |
| * @return |
| */ |
| public static int getMinOccurs(XSDFeature xsdElem) |
| { |
| if (xsdElem.eContainer() instanceof XSDAttributeUse) |
| { |
| return (((XSDAttributeUse)xsdElem.eContainer()).getUse()==XSDAttributeUseCategory.REQUIRED_LITERAL?1:0); |
| } |
| |
| XSDParticle particle = (XSDParticle)xsdElem.eContainer(); |
| int min = 1; |
| if (particle.isSetMinOccurs()) |
| min = particle.getMinOccurs(); |
| |
| return min; |
| } |
| |
| /** |
| * Gets the "maxOccurs" attribute value for the given XSDFeature, if |
| * there is none then it returns the default 1. |
| * @param xsdElem |
| * @return |
| */ |
| public static int getMaxOccurs(XSDFeature xsdElem) |
| { |
| int max = 1; |
| |
| // not a particle means an attribute use. attributes are maxed at 1. |
| if ( !(xsdElem.eContainer() instanceof XSDParticle) ) |
| return max; |
| |
| XSDParticle particle = (XSDParticle)xsdElem.eContainer(); |
| if (particle.isSetMaxOccurs()) |
| max = particle.getMaxOccurs(); |
| |
| return max; |
| } |
| |
| /** |
| * Return the Data Type from the given schema with the given name. |
| * @param schema - The schema containing the type. |
| * @param boName - The local name of the type to retrieve -- if null method returns first type found. |
| * @return The XSDTypeDefinition if one exists, null otherwise |
| */ |
| public static XSDTypeDefinition getDataType(XSDSchema schema, String typeName) { |
| if(schema == null) |
| return null; |
| |
| boolean pickFirstFound = (typeName==null || typeName.length()<1); |
| |
| EList<XSDSchemaContent> contents = schema.getContents(); |
| |
| // First try the easy approach -- if this XSD contains a type definition with the right name, that's |
| // our type, return it. This is the recommended path, and the way our tooling does things. |
| for(Iterator<XSDSchemaContent> i = contents.iterator(); i.hasNext(); ) { |
| Object item = i.next(); |
| if(item instanceof XSDTypeDefinition) |
| if (pickFirstFound) |
| return (XSDTypeDefinition) item; |
| else if ( typeName.equals(getDisplayName((XSDTypeDefinition)item))) |
| return (XSDTypeDefinition) item; |
| } |
| |
| // If we failed, we try a second pass, this time looking for an element with an anonymous |
| // type defined in line |
| for(Iterator<XSDSchemaContent> i = contents.iterator(); i.hasNext(); ) { |
| Object item = i.next(); |
| if(item instanceof XSDFeature) { |
| XSDFeature element = (XSDFeature) item; |
| XSDTypeDefinition resolvedType = getResolvedType(element); |
| if(resolvedType != null && resolvedType.getSchema() == schema) { |
| if (pickFirstFound) |
| return resolvedType; |
| else if (typeName.equals(getDisplayName(element))) |
| return resolvedType; |
| } |
| } |
| } |
| return null; |
| |
| } |
| |
| /** |
| * Gets the "default" attribute value for the given XSDFeature, if there |
| * is none then it returns an empty string. |
| * @param xsdElem |
| * @return |
| */ |
| public static String getDefaultValue(XSDFeature xsdElem) |
| { |
| XSDConstraint constraint = null; |
| if (xsdElem instanceof XSDAttributeDeclaration) |
| { |
| // attribute declarations store their default values in |
| // their containers (attribute uses) |
| XSDAttributeUse use = (XSDAttributeUse)xsdElem.getContainer(); |
| if (use.isSetConstraint()) |
| constraint = use.getConstraint(); |
| |
| if (constraint!=null && constraint.equals(XSDConstraint.DEFAULT_LITERAL)) |
| if (use.getLexicalValue()!=null) |
| return use.getLexicalValue(); |
| else |
| return ""; //$NON-NLS-1$ |
| } |
| else if (xsdElem instanceof XSDElementDeclaration) |
| { |
| if (xsdElem.isSetConstraint()) |
| constraint = xsdElem.getConstraint(); |
| |
| if (constraint!=null && constraint.equals(XSDConstraint.DEFAULT_LITERAL)) |
| if (xsdElem.getLexicalValue()!=null) |
| return xsdElem.getLexicalValue(); |
| else |
| return ""; //$NON-NLS-1$ |
| |
| } |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Return the enclosing Complex Type definition. |
| * @param component |
| * @return |
| */ |
| public static XSDComplexTypeDefinition getEnclosingTypeDefinition(EObject component) |
| { |
| if (component == null) |
| return null; |
| |
| if (component instanceof XSDComplexTypeDefinition) |
| return (XSDComplexTypeDefinition)component; |
| |
| return getEnclosingTypeDefinition(component.eContainer()); |
| } |
| |
| /** |
| * Given an XSD schema with a new target namespace set, this method will cycle through the XSD schema directives |
| * (i.e. imports/includes/redefines) and remove as appropriate. |
| * |
| * I.e. this method will remove all includes/redefines if the new TNS is different than the old TNS and it will remove |
| * all imports that have the same namespace as the new TNS (since these should now be includes). |
| * |
| * @param schema - has the new target namespace set |
| * @param oldTNS |
| */ |
| public static void removeImportsAndIncludes(XSDSchema schema, String oldTNS) |
| { |
| if (schema==null) |
| return; |
| |
| String newTNS = schema.getTargetNamespace(); |
| |
| // namespace hasn't changed |
| if (newTNS==null && oldTNS==null) |
| return; |
| |
| // namespace hasn't changed |
| if (newTNS!=null && newTNS.equals(oldTNS)) |
| return; |
| |
| // namespace has changed so remove all includes and remove any imports to the new namespace |
| ArrayList schemaContents = new ArrayList(schema.getContents()); |
| for (Iterator i = schemaContents.iterator(); i.hasNext();) |
| { |
| Object next = i.next(); |
| if (next instanceof XSDImport) |
| { |
| XSDImport nextImport = (XSDImport) next; |
| if (nextImport.getNamespace()==null && newTNS==null) |
| schema.getContents().remove(nextImport); |
| else if (nextImport.getNamespace()!=null && nextImport.getNamespace().equals(newTNS)) |
| schema.getContents().remove(nextImport); |
| } |
| else if (next instanceof XSDSchemaCompositor) |
| { |
| schema.getContents().remove(next); |
| } |
| } |
| |
| } |
| |
| /** |
| * Given an XSD complex type, return a list of the XSDFeatures (element |
| * and attribute declarations) within the complex type. |
| */ |
| public static List<XSDFeature> getXSDElementsAndAttributes(XSDComplexTypeDefinition complexType) |
| { |
| List<XSDFeature> result = getChildElements(complexType); |
| result.addAll( getChildAttributes(complexType)); |
| |
| return result; |
| } |
| } |