blob: 2ef86d2a4ef4f5c1538eeacb18938406a6ec0065 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 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.wst.xsd.contentmodel.internal;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAnyElement;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMContent;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocumentation;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMGroup;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamespace;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList;
import org.eclipse.wst.xml.core.internal.contentmodel.annotation.AnnotationMap;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMAttributeDeclarationImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMDataTypeImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMDocumentImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMEntityDeclarationImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMGroupImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNodeListImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDescriptionBuilder;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xsd.contentmodel.internal.util.XSDSchemaLocatorAdapterFactory;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDAttributeUseCategory;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDConstraint;
import org.eclipse.xsd.XSDContentTypeCategory;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDEnumerationFacet;
import org.eclipse.xsd.XSDForm;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDParticleContent;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaContent;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDWildcard;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.eclipse.xsd.util.XSDSwitch;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/**
* Utility class to build cmnodes from XML Schema nodes. The XML Schema model is
* found in the org.eclipse.xsd plugin.
*
* TODO: getNamespaceURI()currently always returns '##any'.
*/
public class XSDImpl
{
/*
* properties common to all cmnodes the following properties defined in
* CMNodeImpl class: PROPERTY_DOCUMENTATION PROPERTY_DOCUMENTATION_SOURCE
* PROPERTY_DOCUMENTATION_LANGUAGE PROPERTY_MOF_NOTIFIER
* PROPERTY_DEFINITION_INFO PROPERTY_DEFINITION
*
* the following properties defined in this class, XSDImpl:
* PROPERTY_CMDOCUMENT PROPERTY_USES_LOCAL_ELEMENT_DECLARATIONS
* PROPERTY_IS_NAME_SPACE_AWARE PROPERTY_NS_PREFIX_QUALIFICATION
* PROPERTY_NILLABLE PROPERTY_SPEC
*/
public static final String PROPERTY_CMDOCUMENT = "CMDocument";
public static final String PROPERTY_USES_LOCAL_ELEMENT_DECLARATIONS = "http://org.eclipse.wst/cm/properties/usesLocalElementDeclarations";
public static final String PROPERTY_IS_NAME_SPACE_AWARE = "http://org.eclipse.wst/cm/properties/isNameSpaceAware";
public static final String PROPERTY_NS_PREFIX_QUALIFICATION = "http://org.eclipse.wst/cm/properties/nsPrefixQualification";
public static final String PROPERTY_NILLABLE = "http://org.eclipse.wst/cm/properties/nillable";
public static final String PROPERTY_SPEC = "spec";
/*
* properties common to all CMDocument nodes: PROPERTY_TARGET_NAMESPACE_URI
* PROPERTY_IMPORTED_NAMESPACE_INFO PROPERTY_NAMESPACE_INFO
* PROPERTY_ELEMENT_FORM_DEFAULT PROPERTY_ANNOTATION_MAP
* PROPERTY_ENCODING_INFO
*/
public static final String PROPERTY_TARGET_NAMESPACE_URI = "http://org.eclipse.wst/cm/properties/targetNamespaceURI";
public static final String PROPERTY_IMPORTED_NAMESPACE_INFO = "http://org.eclipse.wst/cm/properties/importedNamespaceInfo";
public static final String PROPERTY_NAMESPACE_INFO = "http://org.eclipse.wst/cm/properties/namespaceInfo";
public static final String PROPERTY_ELEMENT_FORM_DEFAULT = "http://org.eclipse.wst/cm/properties/elementFormDefault";
public static final String PROPERTY_ANNOTATION_MAP = "annotationMap";
public static final String PROPERTY_ENCODING_INFO = "encodingInfo";
/*
* properties common to all CMElementDeclaration nodes: PROPERTY_XSITYPES
* PROPERTY_DERIVED_ELEMENT_DECLARATION PROPERTY_SUBSTITUTION_GROUP
* PROPERTY_ABSTRACT
*/
public static final String PROPERTY_XSITYPES = "XSITypes";
public static final String PROPERTY_DERIVED_ELEMENT_DECLARATION = "DerivedElementDeclaration";
public static final String PROPERTY_SUBSTITUTION_GROUP = "SubstitutionGroup";
public static final String PROPERTY_ABSTRACT = "Abstract";
/**
* Definition info for element declarations.
*/
public static final String DEFINITION_INFO_GLOBAL = "global";
public static final String DEFINITION_INFO_LOCAL = "local";
public static final String XML_LANG_ATTRIBUTE = "xml:lang";
public static final String PLATFORM_PROTOCOL = "platform:";
protected static XSDAdapterFactoryImpl xsdAdapterFactoryImpl = new XSDAdapterFactoryImpl();
protected static XSIDocument xsiDocument = new XSIDocument();
/**
* Given uri for an XML Schema document, parse the document and build
* corresponding CMDocument node.
*
* @param uri -
* the uri for an XML Schema document
* @param grammarErrorChecking -
* grammar error checking flag
* @param errorList -
* the resulting error list
* @return the corresponding CMDocument node.
* @deprecated -- use buildCMDocument(String uri)
*/
public static CMDocument buildCMDocument(String uri, int grammarErrorChecking, List errorList)
{
return buildCMDocument(uri);
}
/**
* Given uri for an XML Schema document, parse the document and build
* corresponding CMDocument node.
*
* @param uri -
* the uri for an XML Schema document
* @return the corresponding CMDocument node.
*/
public static CMDocument buildCMDocument(String uri)
{
CMDocument cmDocument = null;
XSDSchema xsdSchema = buildXSDModel(uri);
if (xsdSchema != null)
{
cmDocument = (CMDocument) getAdapter(xsdSchema);
CMDocumentEncodingHelper.setEncodingInfo(cmDocument, uri);
}
return cmDocument;
}
/**
* Given uri for an XML Schema document, parse the document and build
* corresponding CMDocument node.
*
* @param uri -
* the uri for an XML Schema document
* @return the corresponding CMDocument node.
*/
public static XSDSchema buildXSDModel(String uriString)
{
XSDSchema xsdSchema = null;
try
{
// if XML Schema for Schema is requested, get it through schema model
if (uriString.endsWith("2001/XMLSchema.xsd"))
{
xsdSchema = XSDSchemaImpl.getSchemaForSchema(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001);
}
else
{
ResourceSet resourceSet = new ResourceSetImpl();
//resourceSet.getAdapterFactories().add(new XSDSchemaLocationResolverAdapterFactory());
resourceSet.getAdapterFactories().add(new XSDSchemaLocatorAdapterFactory());
URI uri = createURI(uriString);
XSDResourceImpl resource = (XSDResourceImpl)resourceSet.createResource(URI.createURI("*.xsd"));
resource.setURI(uri);
resource.load(null);
xsdSchema = resource.getSchema();
}
}
catch (Exception e)
{
}
return xsdSchema;
}
// TODO ... looks like we can remove this class?
//
static class InternalURIConverter extends URIConverterImpl
{
protected InputStream createURLInputStream(URI uri) throws IOException
{
if ("http".equals(uri.scheme()))
{
String theURI = uri.toString();
String mapped = URIResolverPlugin.createResolver().resolve(theURI, theURI, theURI);
if (mapped != null)
{
uri = createURI(mapped);
}
}
return super.createURLInputStream(uri);
}
}
/**
* Returns an appropriate URI based on a uri string.
*
* @param uriString -
* a uri string.
* @return an appropriate URI based on a uri string.
*/
public static URI createURI(String uriString)
{
if (hasProtocol(uriString))
return URI.createURI(uriString);
else
return URI.createFileURI(uriString);
}
private static boolean hasProtocol(String uri)
{
boolean result = false;
if (uri != null)
{
int index = uri.indexOf(":");
if (index != -1 && index > 2) // assume protocol with be length 3 so that
// the'C' in 'C:/' is not interpreted as a
// protocol
{
result = true;
}
}
return result;
}
/**
* Returns true if string begins with platform protocol.
*
* @param uriString -
* a uri string.
* @return true if string begins with platform protocol.
*/
public static boolean withPlatformProtocol(String uriString)
{
return uriString.startsWith(PLATFORM_PROTOCOL);
}
/**
* Returns the value of the 'Min Occurs' attribute. The default value is "1".
*
* @param component -
* a concrete component.
* @return the value of the 'Min Occurs' attribute.
*/
public static int getMinOccurs(XSDConcreteComponent component)
{
int minOccur = 1;
if (component != null)
{
Object o = component.getContainer();
if (o instanceof XSDParticle)
{
if (((XSDParticle) o).isSetMinOccurs())
{
try
{
minOccur = ((XSDParticle) o).getMinOccurs();
}
catch (Exception e)
{
minOccur = 1;
}
}
}
}
return minOccur;
}
/**
* Returns the value of the 'Max Occurs' attribute. The default value is "1".
*
* @param component -
* a concrete component.
* @return the value of the 'Max Occurs' attribute.
*/
public static int getMaxOccurs(XSDConcreteComponent component)
{
int maxOccur = 1;
if (component != null)
{
Object o = component.getContainer();
if (o instanceof XSDParticle)
{
if (((XSDParticle) o).isSetMaxOccurs())
{
try
{
maxOccur = ((XSDParticle) o).getMaxOccurs();
}
catch (Exception e)
{
maxOccur = 1;
}
}
}
}
return maxOccur;
}
/**
* Returns the enumerated values for the given type.
*
* @param type -
* a type definition.
* @return the enumerated values for the given type.
*/
public static String[] getEnumeratedValuesForType(XSDTypeDefinition type)
{
List result = new ArrayList();
if (type instanceof XSDSimpleTypeDefinition)
{
List enumerationFacets = ((XSDSimpleTypeDefinition) type).getEnumerationFacets();
for (Iterator i = enumerationFacets.iterator(); i.hasNext();)
{
XSDEnumerationFacet enumFacet = (XSDEnumerationFacet) i.next();
List values = enumFacet.getValue();
for (Iterator j = values.iterator(); j.hasNext();)
{
Object o = j.next();
if (o != null)
{
result.add(o.toString());
}
}
}
}
String[] array = new String[result.size()];
result.toArray(array);
return array;
}
/**
* Return a list of documentation elements from the given annotation. Working
* with documentation elements requires dropping down into the DOM model.
*
* @param annotation -
* an XSDAnnotation node.
* @return a list of documentation elements.
*/
public static CMNodeList getDocumentations(XSDAnnotation annotation)
{
CMNodeListImpl documentations = new CMNodeListImpl();
if (annotation != null)
{
List documentationsElements = annotation.getUserInformation();
for (Iterator i = documentationsElements.iterator(); i.hasNext();)
{
documentations.getList().add(new DocumentationImpl((Element) i.next()));
}
}
return documentations;
}
/**
* Adapted from public static List findTypesDerivedFrom(XSDSchema schema,
* String namespace, String localName) in class XSDSchemaQueryTools found in
* org.eclipse.xsd plugin.
*
* Find typeDefinitions that derive from a given type.
*
* @param type
* the type derived from
* @return List of any XSDTypeDefinitions found
*/
public static List findTypesDerivedFrom(XSDTypeDefinition type)
{
ArrayList typesDerivedFrom = new ArrayList();
if (type != null)
{
XSDSchema schema = type.getSchema();
String localName = type.getName();
if ((null != schema) && (null != localName))
{
String namespace = schema.getTargetNamespace();
// A handy convenience method quickly gets all
// typeDefinitions within our schema; note that
// whether or not this returns types in included,
// imported, or redefined schemas is subject to change
List typedefs = schema.getTypeDefinitions();
for (Iterator iter = typedefs.iterator(); iter.hasNext();)
{
XSDTypeDefinition typedef = (XSDTypeDefinition) iter.next();
if (typedef instanceof XSDComplexTypeDefinition)
{
// Walk the baseTypes from this typedef seeing if any
// of them match the requested one
if (isTypeDerivedFrom(typedef, namespace, localName))
{
// We found it, return the original one and continue
typesDerivedFrom.add(typedef);
continue;
}
}
}
}
}
return typesDerivedFrom;
}
/**
* Adapted from protected static boolean isTypeDerivedFrom(XSDTypeDefinition
* typedef, String namespace, String localName) in class XSDSchemaQueryTools
* found in org.eclipse.xsd plugin.
*
* Recursive worker method to find typeDefinitions that derive from a named
* type.
*
* @see #findTypesDerivedFrom(XSDSchema, String, String)
* @param typeDef
* to see if it's derived from
* @param namespace
* for the type derived from
* @param localName
* for the type derived from
* @return true if it is; false otherwise
*/
protected static boolean isTypeDerivedFrom(XSDTypeDefinition typedef, String namespace, String localName)
{
// Walk the baseTypes from this typedef seeing if any
// of them match the requested one
XSDTypeDefinition baseType = typedef.getBaseType();
// As this convenience method if our parameters match
if (baseType.hasNameAndTargetNamespace(localName, namespace))
{
return true;
}
XSDTypeDefinition rootType = typedef.getRootType();
if (rootType == baseType)
{
// If we've hit the root, we aren't derived from it
return false;
}
else
{
// Otherwise continue to traverse upwards
return isTypeDerivedFrom(baseType, namespace, localName);
}
}
/**
* Returns the corresponding cmnode of the specified XML Schema node.
*
* @param target -
* an XML Schema node
* @return the corresponding cmnode.
*/
public static CMNode getAdapter(Notifier o)
{
return (CMNode) xsdAdapterFactoryImpl.adapt(o);
}
/**
* Adapted from public String getPrefix(String ns, boolean withColon) in class
* TypesHelper found in org.eclipse.wst.xsd.editor plugin.
*
* @param schema -
* the relevant schema
* @param ns -
* the relevant namespace
*/
public static String getPrefix(XSDSchema schema, String ns)
{
String key = "";
if ((schema != null) && (ns != null))
{
Map map = schema.getQNamePrefixToNamespaceMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext())
{
Object keyObj = iter.next();
Object value = map.get(keyObj);
if (value != null && value.toString().equals(ns))
{
if (keyObj != null)
{
key = keyObj.toString();
}
else
{
key = "";
}
break;
}
}
}
return key;
}
/**
* The Factory for the XSD adapter model. It provides a create method for each
* non-abstract class of the model.
*/
public static class XSDAdapterFactoryImpl extends AdapterFactoryImpl
{
public Adapter createAdapter(Notifier target)
{
XSDSwitch xsdSwitch = new XSDSwitch()
{
public Object caseXSDWildcard(XSDWildcard object)
{
return new XSDWildcardAdapter(object);
}
public Object caseXSDModelGroupDefinition(XSDModelGroupDefinition object)
{
return new XSDModelGroupDefinitionAdapter(object);
}
public Object caseXSDAttributeUse(XSDAttributeUse object)
{
return new XSDAttributeUseAdapter(object);
}
public Object caseXSDElementDeclaration(XSDElementDeclaration object)
{
return new XSDElementDeclarationAdapter(object);
}
public Object caseXSDModelGroup(XSDModelGroup object)
{
return new XSDModelGroupAdapter(object);
}
public Object caseXSDSchema(XSDSchema object)
{
return new XSDSchemaAdapter(object);
}
};
Object o = xsdSwitch.doSwitch((EObject) target);
Adapter result = null;
if (o instanceof Adapter)
{
result = (Adapter) o;
}
else
{
Thread.dumpStack();
}
return result;
}
public Adapter adapt(Notifier target)
{
return adapt(target, this);
}
}
/**
* XSDBaseAdapter -- an abstract base node in the model. All other model nodes
* are derived from it.
*/
public static abstract class XSDBaseAdapter extends CMNodeImpl
{
protected CMNodeListImpl documentation = new CMNodeListImpl();
/**
* Returns the name of the node. The default value is an empty string value.
* All derived classes must override this method if they do not want the
* default value.
*
* @return the name of the node.
*/
public String getNodeName()
{
return "";
}
/**
* Returns true of the given factory is the factory for this XSD adapter
* model.
*
* @param type -
* a factory
* @return true if the type is the adapter factory for this model.
*/
public boolean isAdapterForType(Object type)
{
return type == xsdAdapterFactoryImpl;
}
/**
* Returns true if the property is supported for this class.
*
* @param propertyName -
* name of a property
* @return true if the property is supported.
*/
public boolean supports(String propertyName)
{
return propertyName.equals(PROPERTY_NS_PREFIX_QUALIFICATION) || propertyName.equals(PROPERTY_NILLABLE) || propertyName.equals(PROPERTY_USES_LOCAL_ELEMENT_DECLARATIONS)
|| propertyName.equals(PROPERTY_DOCUMENTATION) || propertyName.equals(PROPERTY_DOCUMENTATION_SOURCE) || propertyName.equals(PROPERTY_DOCUMENTATION_LANGUAGE)
|| propertyName.equals(PROPERTY_MOF_NOTIFIER) || propertyName.equals(PROPERTY_DEFINITION_INFO) || propertyName.equals(PROPERTY_DEFINITION) || propertyName.equals(PROPERTY_CMDOCUMENT)
|| propertyName.equals(PROPERTY_IS_NAME_SPACE_AWARE) || propertyName.equals(PROPERTY_SPEC) || super.supports(propertyName);
}
/**
* Returns the value of the 'Nillable' attribute. This represents the
* nillable infoset property. The default value is false. All derived
* classes must override this method if they do not want the default value.
*
* @return the value of the 'Nillable' attribute.
*/
public boolean isNillable()
{
return false;
}
/**
* Returns the cmdocument that is the owner of this cmnode. The default
* value is null; All derived classes must override this method if they do
* not want the default value.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return null;
}
/**
* Return a list of documentation elements. The default value is an empty
* CMNodeList; All derived classes must override this method if they do not
* want the default value.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
return documentation;
}
/**
* Returns the property value for the property name. Returns null if the
* property is not supported.
*
* @param propertyName -
* name of a property
* @return the property value for the property name.
*/
public Object getProperty(String propertyName)
{
Object result = null;
if (propertyName.equals(PROPERTY_CMDOCUMENT))
{
result = getCMDocument();
}
else if (propertyName.equals(PROPERTY_DOCUMENTATION))
{
result = getDocumentation();
}
else if (propertyName.equals(PROPERTY_USES_LOCAL_ELEMENT_DECLARATIONS))
{
result = Boolean.TRUE;
}
else if (propertyName.equals(PROPERTY_IS_NAME_SPACE_AWARE))
{
result = Boolean.TRUE;
}
else if (propertyName.equals(PROPERTY_NS_PREFIX_QUALIFICATION))
{
result = getNSPrefixQualification();
}
else if (propertyName.equals(PROPERTY_NILLABLE))
{
result = isNillable() ? xsiDocument.nilAttribute : null;
}
else if (propertyName.equals(PROPERTY_MOF_NOTIFIER))
{
result = getKey();
}
else if (propertyName.equals(PROPERTY_SPEC))
{
result = getSpec();
}
else
{
result = super.getProperty(propertyName);
{
CMDocument cmDocument = getCMDocument();
if (cmDocument instanceof XSDSchemaAdapter)
{
AnnotationMap map = ((XSDSchemaAdapter) cmDocument).annotationMap;
if (map != null)
{
String spec = getSpec();
if (spec != null)
{
result = map.getProperty(getSpec(), propertyName);
}
}
}
}
}
return result;
}
/*
* Returns the value of the form [attribute] which affects the target
* namespace of locally scoped features. The default value is null. All
* derived classes must override this method if they do not want the default
* value. @return the value of the form [attribute].
*/
public Object getNSPrefixQualification()
{
return null;
}
/**
* Returns a general XPath expression for the node.
*
* @return a general XPath expression for the node.
*/
public String getSpec()
{
return "//" + getNodeName();
}
}
/**
* XSDSchemaAdapter implements CMDocument. A representation of the model
* object 'Schema'.
*/
public static class XSDSchemaAdapter extends XSDBaseAdapter implements CMDocument
{
protected XSDSchema xsdSchema;
protected CMNamedNodeMapImpl namedNodeMap;
protected CMNamedNodeMapImpl entityNodeMap;
protected String[] encodingInfo = new String[2];
protected AnnotationMap annotationMap = new AnnotationMap();
protected Hashtable substitutionGroupTable;
/**
* Constructor.
*
* @param xsdSchema -
* the schema node.
*/
public XSDSchemaAdapter(XSDSchema xsdSchema)
{
this.xsdSchema = xsdSchema;
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdSchema;
}
/**
* Returns the filename.
*
* @return the filename.
*/
public String getNodeName()
{
// See buildCMDocument() above.
return xsdSchema.getSchemaLocation();
}
/**
* Returns true if the property is supported for this class.
*
* @param propertyName -
* name of a property
* @return true if the property is supported.
*/
public boolean supports(String propertyName)
{
return propertyName.equals(PROPERTY_TARGET_NAMESPACE_URI) || propertyName.equals(PROPERTY_IMPORTED_NAMESPACE_INFO) || propertyName.equals(PROPERTY_NAMESPACE_INFO)
|| propertyName.equals(PROPERTY_ELEMENT_FORM_DEFAULT) || propertyName.equals(PROPERTY_ANNOTATION_MAP) || propertyName.equals(PROPERTY_ENCODING_INFO) || super.supports(propertyName);
}
/**
* Returns true if a prefix is globally required for elements.
*
* @param xsdSchema -
* the corresponding schema node.
* @return true if a prefix is globally required for elements.
*/
protected boolean isPrefixRequired(XSDSchema xsdSchema)
{
boolean result = true;
if (xsdSchema.isSetElementFormDefault())
result = !(xsdSchema.getElementFormDefault().getValue() == XSDForm.QUALIFIED);
return result;
}
/**
* Returns the property value for the property name. Returns null if the
* property is not supported.
*
* @param propertyName -
* name of a property
* @return the property value for the property name.
*/
public Object getProperty(String propertyName)
{
Object result = null;
if (propertyName.equals(PROPERTY_TARGET_NAMESPACE_URI))
{
result = xsdSchema.getTargetNamespace();
}
else if (propertyName.equals(PROPERTY_IMPORTED_NAMESPACE_INFO))
{
List list = new Vector();
getImportedNamespaceInfo(xsdSchema, list);
result = list;
}
else if (propertyName.equals(PROPERTY_NAMESPACE_INFO))
{
List list = new Vector();
NamespaceInfo info = new NamespaceInfo();
info.uri = xsdSchema.getTargetNamespace();
info.prefix = getPrefix(xsdSchema, info.uri);
info.locationHint = null; // note that this locationHint info is null
// for the root xsd file
info.isPrefixRequired = isPrefixRequired(xsdSchema);
list.add(info);
getImportedNamespaceInfo(xsdSchema, list);
result = list;
}
else if (propertyName.equals(PROPERTY_ELEMENT_FORM_DEFAULT))
{
result = xsdSchema.getElementFormDefault().getName();
}
else if (propertyName.equals(PROPERTY_ANNOTATION_MAP))
{
result = annotationMap;
}
else if (propertyName.equals(PROPERTY_ENCODING_INFO))
{
result = encodingInfo;
}
else if (propertyName.equals("allElements"))
{
result = getAllElements();
}
else if (propertyName.startsWith("getElementForType#"))
{
int index = propertyName.indexOf("#");
String typeName = propertyName.substring(index + 1, propertyName.length());
//
//
XSDTypeDefinition td = xsdSchema.resolveTypeDefinition(typeName);
if (td != null)
{
LocalElementVisitor localElementVisitor = new LocalElementVisitor();
localElementVisitor.visitTypeDefinition(td);
result = localElementVisitor.getCMNamedNodeMap();
}
}
else
{
result = super.getProperty(propertyName);
}
return result;
}
/**
* Gather information on namespaces used in external references.
*
* @param theXSDSchema -
* the corresponding schema node
* @param list -
* the list of imported namespaces.
*/
public void getImportedNamespaceInfo(XSDSchema theXSDSchema, List list)
{
for (Iterator iterator = theXSDSchema.getContents().iterator(); iterator.hasNext();)
{
XSDSchemaContent content = (XSDSchemaContent) iterator.next();
if (content instanceof XSDImport)
{
XSDImport xImport = (XSDImport) content;
XSDSchema importedXSDSchema = xImport.getResolvedSchema();
NamespaceInfo info = new NamespaceInfo();
info.uri = xImport.getNamespace();
info.prefix = getPrefix(importedXSDSchema, info.uri);
info.locationHint = xImport.getSchemaLocation();
if (importedXSDSchema != null)
{
info.isPrefixRequired = isPrefixRequired(importedXSDSchema);
}
list.add(info);
}
}
}
/**
* Returns set of named (top-level) element declarations for this schema
* node.
*
* @return a set of named (top-level) element declarations.
*/
public CMNamedNodeMap getElements()
{
if (namedNodeMap == null)
{
namedNodeMap = new CMNamedNodeMapImpl();
// Note that if we call xsdSchema.getElementDeclarations()
// we get 'more' elements than we really want since we also
// get 'imported' elements. Below we test to ensure the elements
// actually have the same target namespace as the schema.
String targetNamespace = xsdSchema.getTargetNamespace();
for (Iterator i = xsdSchema.getElementDeclarations().iterator(); i.hasNext();)
{
XSDElementDeclaration ed = (XSDElementDeclaration) i.next();
if (targetNamespace != null ? targetNamespace.equals(ed.getTargetNamespace()) : ed.getTargetNamespace() == null)
{
XSDElementDeclarationAdapter adapter = (XSDElementDeclarationAdapter) getAdapter(ed);
namedNodeMap.getHashtable().put(adapter.getNodeName(), adapter);
}
}
}
return namedNodeMap;
}
/**
* Returns the built-in entity declarations.
*
* @return the built-in entity declarations.
*/
public CMNamedNodeMap getEntities()
{
if (entityNodeMap == null)
{
entityNodeMap = new CMNamedNodeMapImpl();
// add the built in entity declarations
entityNodeMap.getHashtable().put("amp", new CMEntityDeclarationImpl("amp", "&"));
entityNodeMap.getHashtable().put("lt", new CMEntityDeclarationImpl("lt", "<"));
entityNodeMap.getHashtable().put("gt", new CMEntityDeclarationImpl("gt", ">"));
entityNodeMap.getHashtable().put("quot", new CMEntityDeclarationImpl("quot", "\""));
entityNodeMap.getHashtable().put("apos", new CMEntityDeclarationImpl("apos", "'"));
}
return entityNodeMap;
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return DOCUMENT;
}
/*
* Returns null. !!! Why are we not implementing this???? @return null.
*/
public CMNamespace getNamespace()
{
return null;
}
/**
* Returns this.
*
* @return this.
*/
public CMDocument getCMDocument()
{
return this;
}
public CMNamedNodeMap getAllElements()
{
CMNamedNodeMapImpl map = new CMNamedNodeMapImpl();
for (Iterator i = getElements().iterator(); i.hasNext(); )
{
CMElementDeclaration ed = (CMElementDeclaration)i.next();
map.put(ed);
addLocalElementDefinitions(map, ed);
}
return map;
}
protected void addLocalElementDefinitions(CMNamedNodeMapImpl map, CMElementDeclaration parentElementDeclaration)
{
CMNamedNodeMap localElementMap = parentElementDeclaration.getLocalElements();
for (Iterator i = localElementMap.iterator(); i.hasNext(); )
{
CMElementDeclaration ed = (CMElementDeclaration)i.next();
if (map.getNamedItem(ed.getNodeName()) == null)
{
map.put(ed);
addLocalElementDefinitions(map, ed);
}
}
}
}
/**
* XSDAttributeUseAdapter implements CMAttributeDeclaration. A representation
* of the model object 'Attribute Use'.
*/
public static class XSDAttributeUseAdapter extends XSDBaseAdapter implements CMAttributeDeclaration
{
// provides access to the XML Schema node
protected XSDAttributeUse xsdAttributeUse;
// provides access to the type of the attribute
protected CMDataType dataType = new DataTypeImpl();
/**
* Constructor.
*
* @param xsdAttributeUse -
* the XML Schema node.
*/
public XSDAttributeUseAdapter(XSDAttributeUse xsdAttributeUse)
{
this.xsdAttributeUse = xsdAttributeUse;
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdAttributeUse;
}
/**
* Returns a general XPath expression for the node.
*
* @return a general XPath expression for the node.
*/
public String getSpec()
{
return "//@" + getAttrName();
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return ATTRIBUTE_DECLARATION;
}
/**
* Returns the name of the node. Similar to getAttrName().
*
* @return the name of the node.
*/
public String getNodeName()
{
return getAttrName();
}
/**
* getEnumAttr method
*
* @return java.util.Enumeration
* @deprecated -- to be replaced in future with additional CMDataType
* methods (currently found on CMDataTypeHelper)
*/
public Enumeration getEnumAttr()
{
return Collections.enumeration(Collections.EMPTY_LIST);
}
/**
* Returns the name of this attribute. Similar to getNodeName().
*
* @return the name of this attribute.
*/
public String getAttrName()
{
return xsdAttributeUse.getAttributeDeclaration().getName();
}
/**
* Returns the type of the attribute.
*
* @return the type of the attribute.
*/
public CMDataType getAttrType()
{
return dataType;
}
/**
* Returns the value of the default or fixed constraint.
*
* @return the value of the default or fixed constraint.
*/
public String getDefaultValue()
{
return dataType.getImpliedValue();
}
/**
* Returns the usage constraint for this attribute. The usages are defined
* in CMAttributeDeclaration class (OPTIONAL, REQUIRED, FIXED or
* PROHIBITED).
*
* @return the usage constraint for this attribute.
*/
public int getUsage()
{
int useKind = OPTIONAL;
switch (xsdAttributeUse.getUse().getValue())
{
case XSDAttributeUseCategory.OPTIONAL : {
useKind = OPTIONAL;
break;
}
case XSDAttributeUseCategory.PROHIBITED : {
useKind = PROHIBITED;
break;
}
case XSDAttributeUseCategory.REQUIRED : {
useKind = REQUIRED;
break;
}
}
return useKind;
}
/*
* Returns the value of the form [attribute] which affects the target
* namespace of locally scoped features. If the form is not set on this
* attribute, then see if there is a globally defined default. @return the
* value of the form [attribute].
*/
public Object getNSPrefixQualification()
{
String form = null;
if (xsdAttributeUse.getContent() != xsdAttributeUse.getAttributeDeclaration())
{
form = "qualified";
}
else if (xsdAttributeUse.getContent().isSetForm())
{
form = xsdAttributeUse.getContent().getForm().getName();
}
else
{
XSDSchema schema = xsdAttributeUse.getSchema();
if (schema != null)
form = schema.getAttributeFormDefault().getName();
}
return form;
}
/**
* Return a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
XSDAnnotation annotation = xsdAttributeUse.getAttributeDeclaration().getAnnotation();
return getDocumentations(annotation);
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(xsdAttributeUse.getSchema());
}
/**
* XSDAttributeUseAdapter.DataTypeImpl An inner class to hold type
* information for this attribute.
*/
public class DataTypeImpl implements CMDataType
{
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return CMNode.DATA_TYPE;
}
/**
* Returns the name of the attribute type. Same as getDataTypeName().
*
* @return the name of the attribute type.
*/
public String getNodeName()
{
return getDataTypeName();
}
/**
* Returns false. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return false.
*/
public boolean supports(String propertyName)
{
return false;
}
/**
* Returns null. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return null.
*/
public Object getProperty(String propertyName)
{
return null;
}
/**
* Returns the name of the attribute type. Same as getNodeName().
*
* @return the name of the attribute type.
*/
public String getDataTypeName()
{
XSDSimpleTypeDefinition sc = xsdAttributeUse.getAttributeDeclaration().getTypeDefinition();
String typeName = sc.getName();
return typeName != null ? typeName : "string";
}
/**
* Returns the kind of constraint: none, default or fixed. The kinds are
* defined in CMDataType class (IMPLIED_VALUE_NONE, IMPLIED_VALUE_FIXED or
* IMPLIED_VALUE_DEFAULT).
*
* @return the kind of constraint: none, default or fixed.
*/
public int getImpliedValueKind()
{
int result = IMPLIED_VALUE_NONE;
if (xsdAttributeUse.isSetConstraint())
{
if (xsdAttributeUse.getConstraint().getValue() == XSDConstraint.DEFAULT)
result = IMPLIED_VALUE_DEFAULT;
else if (xsdAttributeUse.getConstraint().getValue() == XSDConstraint.FIXED)
result = IMPLIED_VALUE_FIXED;
}
return result;
}
/**
* Returns the value of the default or fixed constraint.
*
* @return the value of the default or fixed constraint.
*/
public String getImpliedValue()
{
String result = null;
if (xsdAttributeUse.isSetConstraint())
{
result = xsdAttributeUse.getLexicalValue();
}
return result;
}
/**
* Returns the enumerated values for the attribute type.
*
* @return the enumerated values for the attribute type.
*/
public String[] getEnumeratedValues()
{
return getEnumeratedValuesForType(getXSDType());
}
/**
* Generate a valid value for the attribute based on its type.
*
* @return a valid value for the attribute based on its type.
*/
public String generateInstanceValue()
{
XSDAttributeDeclaration attr = xsdAttributeUse.getAttributeDeclaration();
return XSDTypeUtil.getInstanceValue(attr.getResolvedAttributeDeclaration().getTypeDefinition());
}
/**
* Returns the corresponding XML Schema type definition.
*
* @return the corresponding XML Schema type definition.
*/
protected XSDTypeDefinition getXSDType()
{
XSDAttributeDeclaration attr = xsdAttributeUse.getAttributeDeclaration();
return attr.getResolvedAttributeDeclaration().getTypeDefinition();
}
}
}
/**
* ElementDeclarationBaseImpl implements CMElementDeclaration. This is the
* base class for XSDElementDeclaration and DerivedElementDeclarationImpl.
*
* Abstract methods in this class are: public abstract Object getKey(); public
* abstract Object getNSPrefixQualification(); public abstract
* XSDElementDeclaration getXSDElementDeclaration(); public abstract
* XSDTypeDefinition getXSDType(); public abstract List getXSITypes(); public
* abstract CMElementDeclaration getDerivedElementDeclaration(String
* uriQualifiedTypeName); public abstract CMNode getDefinition(); public
* abstract String getDefinitionInfo(); public abstract CMNodeListImpl
* getSubstitutionGroup();
*/
public static abstract class ElementDeclarationBaseImpl extends XSDBaseAdapter implements CMElementDeclaration
{
protected CMDataType dataType = new DataTypeImpl();
protected CMNamedNodeMap namedNodeMap;
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected abstract XSDElementDeclaration getXSDElementDeclaration();
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected abstract XSDElementDeclaration getResolvedXSDElementDeclaration();
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return ELEMENT_DECLARATION;
}
/**
* Returns the name of the node. The same as getElementName().
*
* @return the name of the node.
*/
public String getNodeName()
{
return getElementName();
}
/**
* Returns the name of this element. The same as getNodeName().
*
* @return the name of this element.
*/
public String getElementName()
{
String result = getResolvedXSDElementDeclaration().getName();
return result != null ? result : "";
}
/**
* Returns true if the property is supported for this class.
*
* @param propertyName -
* name of a property
* @return true if the property is supported.
*/
public boolean supports(String propertyName)
{
return propertyName.equals(PROPERTY_XSITYPES) || propertyName.equals(PROPERTY_DERIVED_ELEMENT_DECLARATION) || propertyName.equals(PROPERTY_SUBSTITUTION_GROUP)
|| propertyName.equals(PROPERTY_ABSTRACT) || super.supports(propertyName);
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public abstract Object getKey();
/**
* Returns the set of attributes defined for this element.
*
* @return the set of attributes defined for this element.
*/
public CMNamedNodeMap getAttributes()
{
CMNamedNodeMapImpl map = new CMNamedNodeMapImpl();
XSDTypeDefinition td = getXSDType();
getAttributes(map, td);
addXSITypeAttribute(map);
return map;
}
/**
* Gather the set of attributes defined for this element.
*
* @param map -
* used for returning the set of attributes.
* @param xsdTypeDefinition -
* the type definition for this element.
*/
public void getAttributes(CMNamedNodeMapImpl map, XSDTypeDefinition xsdTypeDefinition)
{
if (xsdTypeDefinition instanceof XSDComplexTypeDefinition)
{
XSDComplexTypeDefinition ctd = (XSDComplexTypeDefinition) xsdTypeDefinition;
for (Iterator i = ctd.getAttributeUses().iterator(); i.hasNext();)
{
XSDAttributeUse xsdAttributeUse = (XSDAttributeUse) i.next();
XSDAttributeUseAdapter adapter = (XSDAttributeUseAdapter) getAdapter(xsdAttributeUse);
if (adapter != null && adapter.getNodeName() != null)
{
map.getHashtable().put(adapter.getNodeName(), adapter);
}
}
}
}
/**
* Returns the content for this element.
*
* @return the content for this element.
*/
public CMContent getContent()
{
CMContent result = null;
XSDTypeDefinition td = getXSDType();
if (td instanceof XSDComplexTypeDefinition)
{
DerivedChildVisitor dcv = new DerivedChildVisitor(td);
dcv.visitTypeDefinition(td);
CMNodeList nodeList = dcv.getChildNodeList();
if (nodeList.getLength() > 1)
{
result = new CMGroupImpl(nodeList, CMGroup.SEQUENCE);
}
else if (nodeList.getLength() > 0)
{
result = (CMContent) nodeList.item(0);
}
}
return result;
}
/**
* Returns the content type of this element. The content type is defined in
* CMElementDeclaration (ANY, EMPTY, ELEMENT, MIXED, PCDATA or CDATA).
*
* @return the content type of this element.
*/
public int getContentType()
{
int contentType = EMPTY;
XSDTypeDefinition td = getXSDType();
if (td instanceof XSDSimpleTypeDefinition)
{
String typeName = td.getName();
if (typeName != null && typeName.equals("anyType"))
{
contentType = ANY;
}
else
{
contentType = PCDATA;
}
}
else if (td instanceof XSDComplexTypeDefinition)
{
XSDContentTypeCategory category = ((XSDComplexTypeDefinition) td).getContentTypeCategory();
if (category != null)
{
switch (category.getValue())
{
case XSDContentTypeCategory.ELEMENT_ONLY :
contentType = ELEMENT;
break;
case XSDContentTypeCategory.EMPTY :
contentType = EMPTY;
break;
case XSDContentTypeCategory.MIXED :
contentType = MIXED;
break;
case XSDContentTypeCategory.SIMPLE :
contentType = PCDATA;
break;
}
}
}
return contentType;
}
/**
* Returns the name of the element type.
*
* @return the name of the element type.
*/
public CMDataType getDataType()
{
CMDataType result = null;
int contentType = getContentType();
boolean hasDataType = contentType == PCDATA || contentType == MIXED;
if (hasDataType)
{
result = dataType;
}
return result;
}
/**
* Returns the value of 'Min Occurs' attribute. The default value is "1".
*
* @return the value of the 'Min Occurs' attribute.
*/
public int getMinOccur()
{
return getMinOccurs(getXSDElementDeclaration());
}
/**
* Returns the value of the 'Max Occurs' attribute. The default value is
* "1".
*
* @return the value of the 'Max Occurs' attribute.
*/
public int getMaxOccur()
{
return getMaxOccurs(getXSDElementDeclaration());
}
/**
* Returns the referenced element declaration if this is an element
* reference. Otherwise it returns itself.
*
* @return an element declaration.
*/
protected abstract CMNode getDefinition();
/**
* Returns a string indicating whether the element declaration is global or
* local. Returns null if this is an element reference.
*
* @return a string indicating whether the element declaration is global or
* local.
*/
protected abstract String getDefinitionInfo();
/**
* Returns the elements local to this element declaration.
*
* @return the elements local to this element declaration.
*/
public CMNamedNodeMap getLocalElements()
{
if (namedNodeMap == null)
{
LocalElementVisitor localElementVisitor = new LocalElementVisitor();
localElementVisitor.visitTypeDefinition(getXSDType());
namedNodeMap = localElementVisitor.getCMNamedNodeMap();
}
return namedNodeMap;
}
/**
* Returns the property value for the property name. Returns null if the
* property is not supported.
*
* @param propertyName -
* name of a property
* @return the property value for the property name.
*/
public Object getProperty(String propertyName)
{
Object result = null;
if (propertyName.equals(PROPERTY_DEFINITION_INFO))
{
result = getDefinitionInfo();
}
else if (propertyName.equals(PROPERTY_DEFINITION))
{
result = getDefinition();
}
else if (propertyName.equals(PROPERTY_XSITYPES))
{
result = getXSITypes();
}
else if (propertyName.startsWith(PROPERTY_DERIVED_ELEMENT_DECLARATION))
{
int index = propertyName.indexOf("=");
if (index != -1)
{
String uriQualifiedTypeName = propertyName.substring(index + 1);
result = getDerivedElementDeclaration(uriQualifiedTypeName);
}
}
else if (propertyName.equals(PROPERTY_SUBSTITUTION_GROUP))
{
return getSubstitutionGroup();
}
else if (propertyName.equals(PROPERTY_ABSTRACT))
{
return getAbstract();
}
else
{
result = super.getProperty(propertyName);
}
return result;
}
/**
* Returns the value of the 'Nillable' attribute. This represents the
* nillable infoset property. The default value is false.
*
* @return the value of the 'Nillable' attribute.
*/
public boolean isNillable()
{
if (getXSDElementDeclaration().isSetNillable())
return getXSDElementDeclaration().isNillable();
else
return false;
}
/**
* Returns whether the element is 'Abstract'.
*
* @return true if the element is 'Abstract'.
*/
public Boolean getAbstract()
{
boolean result = getResolvedXSDElementDeclaration().isAbstract();
// TODO... how do we handle elements with abstract type's ?
return result ? Boolean.TRUE : Boolean.FALSE;
}
/**
* Returns a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
XSDAnnotation annotation = getXSDElementDeclaration().getAnnotation();
return getDocumentations(annotation);
}
/**
* Returns the corresponding XML Schema type definition.
*
* @return the corresponding XML Schema type definition.
*/
protected abstract XSDTypeDefinition getXSDType();
/**
* Returns a list of type names.
*
* @return a list of type names.
*/
protected abstract List getXSITypes();
/**
* Return the element declaration corresponding to the given uri qualified
* type name.
*
* @param uriQualifiedTypeName -
* a uri qualified type name
* @return corresponding element declaration.
*/
protected abstract CMElementDeclaration getDerivedElementDeclaration(String uriQualifiedTypeName);
/**
* Returns a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected void addXSITypeAttribute(CMNamedNodeMapImpl map)
{
List list = getXSITypes();
int listSize = list.size();
if (listSize > 1)
{
CMDataType dataType = new CMDataTypeImpl("typeNames", (String) null);
CMAttributeDeclarationImpl attribute = new CMAttributeDeclarationImpl("type", CMAttributeDeclaration.OPTIONAL, dataType);
attribute.setCMDocument(xsiDocument);
attribute.setPrefixQualification(true);
attribute.setXSITypes(list);
map.getHashtable().put(attribute.getNodeName(), attribute);
}
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(getResolvedXSDElementDeclaration().getSchema());
}
/**
* Returns the substitution group for this element. The group consists of:
* 1. the element declaration itself 2. and any element declaration that has
* a {substitution group affiliation} in the group
*
* @return the substitution group for this element.
*/
protected abstract CMNodeListImpl getSubstitutionGroup();
/*
* XSDElementDeclarationAdapter.DataTypeImpl An inner class to hold type
* information for this element.
*/
public class DataTypeImpl implements CMDataType
{
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return CMNode.DATA_TYPE;
}
/**
* Returns the name of the element type. Same as getDataTypeName().
*
* @return the name of the element type.
*/
public String getNodeName()
{
return getDataTypeName();
}
/**
* Returns false. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return false.
*/
public boolean supports(String propertyName)
{
return false;
}
/**
* Returns null. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return null.
*/
public Object getProperty(String propertyName)
{
return null;
}
/**
* Returns the name of the element type. Same as getNodeName().
*
* @return the name of the element type.
*/
public String getDataTypeName()
{
String typeName = null;
XSDSimpleTypeDefinition std = getXSDType().getSimpleType();
if (std != null)
typeName = std.getName();
return typeName != null ? typeName : "string";
}
/**
* Returns the kind of constraint: none, default or fixed. The kinds are
* defined in CMDataType class (IMPLIED_VALUE_NONE, IMPLIED_VALUE_FIXED or
* IMPLIED_VALUE_DEFAULT).
*
* @return the kind of constraint: none, default or fixed.
*/
public int getImpliedValueKind()
{
int result = IMPLIED_VALUE_NONE;
if (getXSDElementDeclaration().isSetConstraint())
{
if (getXSDElementDeclaration().getConstraint().getValue() == XSDConstraint.DEFAULT)
result = IMPLIED_VALUE_DEFAULT;
else if (getXSDElementDeclaration().getConstraint().getValue() == XSDConstraint.FIXED)
result = IMPLIED_VALUE_FIXED;
}
return result;
}
/**
* Returns the value of the default or fixed constraint.
*
* @return the value of the default or fixed constraint.
*/
public String getImpliedValue()
{
String result = null;
if (getXSDElementDeclaration().isSetConstraint())
{
result = getXSDElementDeclaration().getLexicalValue();
}
return result;
}
/**
* Returns the enumerated values for the attribute type.
*
* @return the enumerated values for the attribute type.
*/
public String[] getEnumeratedValues()
{
return getEnumeratedValuesForType(getXSDType());
}
public String generateInstanceValue()
{
return XSDTypeUtil.getInstanceValue(getXSDType());
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(getXSDElementDeclaration().getSchema());
}
}
}
/**
* XSDElementDeclarationAdapter implements CMElementDeclaration. A
* representation of the model object 'Element Declaration'.
*/
public static class XSDElementDeclarationAdapter extends ElementDeclarationBaseImpl
{
protected List derivedElementDeclarations = null;
protected List xsiTypes = null;
protected XSDElementDeclaration xsdElementDeclaration;
protected CMNodeListImpl substitutionGroup;
/**
* Constructor.
*
* @param xsdElementDeclaration -
* the XML Schema node.
*/
public XSDElementDeclarationAdapter(XSDElementDeclaration xsdElementDeclaration)
{
this.xsdElementDeclaration = xsdElementDeclaration;
}
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected XSDElementDeclaration getXSDElementDeclaration()
{
return xsdElementDeclaration;
}
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected XSDElementDeclaration getResolvedXSDElementDeclaration()
{
return xsdElementDeclaration.getResolvedElementDeclaration();
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdElementDeclaration;
}
/**
* Returns the referenced element declaration if this is an element
* reference. Otherwise it returns itself.
*
* @return an element declaration.
*/
public CMNode getDefinition()
{
return getAdapter(xsdElementDeclaration.getResolvedElementDeclaration());
}
/**
* Returns a string indicating whether the element declaration is global or
* local. Returns null if this is an element reference.
*
* @return a string indicating whether the element declaration is global or
* local.
*/
protected String getDefinitionInfo()
{
if (xsdElementDeclaration.isElementDeclarationReference())
return null;
else if (xsdElementDeclaration.isGlobal())
return DEFINITION_INFO_GLOBAL;
else
return DEFINITION_INFO_LOCAL;
}
public Object getNSPrefixQualification()
{
String form = null;
if (xsdElementDeclaration.isElementDeclarationReference())
{
form = "qualified";
}
else
{
if (xsdElementDeclaration.isSetForm())
{
form = xsdElementDeclaration.getForm().getName();
}
else
{
XSDSchema schema = xsdElementDeclaration.getSchema();
if (schema != null)
form = schema.getElementFormDefault().getName();
}
}
return form;
}
/**
* Returns the corresponding XML Schema type definition.
*
* @return the corresponding XML Schema type definition.
*/
protected XSDTypeDefinition getXSDType()
{
return xsdElementDeclaration.getResolvedElementDeclaration().getTypeDefinition();
}
/**
* Returns a list of type names.
*
* @return a list of type names.
*/
protected List getXSITypes()
{
if (xsiTypes == null)
{
computeDerivedTypeInfo();
}
return xsiTypes;
}
protected void computeDerivedTypeInfo()
{
xsiTypes = new Vector();
derivedElementDeclarations = new Vector();
computeDerivedTypeInfoHelper(getXSDType(), xsiTypes, derivedElementDeclarations);
}
protected void computeDerivedTypeInfoHelper(XSDTypeDefinition type, List typeNameList, List edList)
{
if (type instanceof XSDComplexTypeDefinition)
{
List derivedTypes = findTypesDerivedFrom(type);
ArrayList inclusiveDerivedTypes = new ArrayList();
inclusiveDerivedTypes.add(type);
if ((derivedTypes != null) && (derivedTypes.size() > 0))
{
inclusiveDerivedTypes.addAll(derivedTypes);
}
for (Iterator i = inclusiveDerivedTypes.iterator(); i.hasNext();)
{
XSDTypeDefinition derivedType = (XSDTypeDefinition) i.next();
XSDSchema schema = derivedType.getSchema();
if (schema != null)
{
String uri = schema.getTargetNamespace();
String name = derivedType.getName();
if (name != null)
{
name = uri != null ? ("[" + uri + "]" + name) : name;
typeNameList.add(name);
DerivedElementDeclarationImpl ed = new DerivedElementDeclarationImpl(this, derivedType, name);
edList.add(ed);
}
}
}
}
}
/**
* Return the element declaration corresponding to the given uri qualified
* type name.
*
* @param uriQualifiedTypeName -
* a uri qualified type name
* @return corresponding element declaration.
*/
protected CMElementDeclaration getDerivedElementDeclaration(String uriQualifiedTypeName)
{
CMElementDeclaration result = null;
if (derivedElementDeclarations == null)
{
computeDerivedTypeInfo();
}
for (Iterator i = derivedElementDeclarations.iterator(); i.hasNext();)
{
DerivedElementDeclarationImpl ed = (DerivedElementDeclarationImpl) i.next();
if ((ed != null) && (ed.uriQualifiedTypeName != null))
{
if (ed.uriQualifiedTypeName.equals(uriQualifiedTypeName))
{
result = ed;
break;
}
}
}
return result;
}
/**
* Returns the substitution group for this element. The group consists of:
* 1. the element declaration itself 2. and any element declaration that has
* a {substitution group affiliation} in the group
*
* @return the substitution group for this element.
*/
protected CMNodeListImpl getSubstitutionGroup()
{
if (substitutionGroup == null)
{
substitutionGroup = new CMNodeListImpl();
List sgroup = getResolvedXSDElementDeclaration().getSubstitutionGroup();
for (Iterator i = sgroup.iterator(); i.hasNext();)
{
XSDElementDeclaration ed = (XSDElementDeclaration) i.next();
substitutionGroup.add(getAdapter(ed));
}
}
return substitutionGroup;
}
}
/**
* DerivedElementDeclarationImpl extends ElementDeclarationBaseImpl
*
*/
public static class DerivedElementDeclarationImpl extends ElementDeclarationBaseImpl
{
protected XSDElementDeclarationAdapter owner;
protected XSDTypeDefinition xsdType;
public String uriQualifiedTypeName;
/**
* Constructor.
*
* @param owner -
* @param xsdType -
* @param uriQualifiedTypeName -
*/
public DerivedElementDeclarationImpl(XSDElementDeclarationAdapter owner, XSDTypeDefinition xsdType, String uriQualifiedTypeName)
{
this.owner = owner;
this.xsdType = xsdType;
this.uriQualifiedTypeName = uriQualifiedTypeName;
}
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected XSDElementDeclaration getXSDElementDeclaration()
{
return (XSDElementDeclaration) owner.getKey();
}
/**
* Returns corresponding XML Schema element declaration.
*
* @return corresponding XML Schema element declaration.
*/
protected XSDElementDeclaration getResolvedXSDElementDeclaration()
{
return ((XSDElementDeclaration) owner.getKey()).getResolvedElementDeclaration();
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return owner.getKey();
}
/**
* Returns the corresponding XML Schema type definition.
*
* @return the corresponding XML Schema type definition.
*/
protected XSDTypeDefinition getXSDType()
{
return xsdType;
}
/**
* Returns a list of type names.
*
* @return a list of type names.
*/
protected List getXSITypes()
{
return owner.getXSITypes();
}
/**
* Return the element declaration corresponding to the given uri qualified
* type name.
*
* @param uriQualifiedTypeName -
* a uri qualified type name
* @return corresponding element declaration.
*/
protected CMElementDeclaration getDerivedElementDeclaration(String uriQualifiedTypeName)
{
return owner.getDerivedElementDeclaration(uriQualifiedTypeName);
}
/**
* Returns the referenced element declaration if this is an element
* reference. Otherwise it returns itself.
*
* @return an element declaration.
*/
protected CMNode getDefinition()
{
return this;
}
/**
* Returns a string indicating whether the element declaration is global or
* local. Returns null if this is an element reference.
*
* @return a string indicating whether the element declaration is global or
* local.
*/
protected String getDefinitionInfo()
{
return owner.getDefinitionInfo();
}
/*
* Returns the value of the form [attribute] which affects the target
* namespace of locally scoped features. @return the value of the form
* [attribute].
*/
public Object getNSPrefixQualification()
{
return owner.getNSPrefixQualification();
}
/**
* Returns the substitution group for this element. The group consists of:
* 1. the element declaration itself 2. and any element declaration that has
* a {substitution group affiliation} in the group
*
* @return the substitution group for this element.
*/
protected CMNodeListImpl getSubstitutionGroup()
{
return owner.getSubstitutionGroup();
}
}
/**
* XSDWildcardAdapter
*/
public static class XSDWildcardAdapter extends XSDBaseAdapter implements CMAnyElement
{
protected XSDWildcard xsdWildcard;
public XSDWildcardAdapter(XSDWildcard xsdWildcard)
{
this.xsdWildcard = xsdWildcard;
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdWildcard;
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return ANY_ELEMENT;
}
/**
* Returns the name of the node. The default value is an empty string value.
* All derived classes must override this method if they do not want the
* default value.
*
* @return the name of the node.
*/
public String getNodeName()
{
return "any";
}
public String getNamespaceURI()
{
String uri = xsdWildcard.getElement().getAttribute("namespace");
return (uri != null || uri.length() == 0) ? uri : "##any";
}
/**
* Returns the value of 'Min Occurs' attribute. The default value is "1".
*
* @return the value of the 'Min Occurs' attribute.
*/
public int getMinOccur()
{
return getMinOccurs(xsdWildcard);
}
/**
* Returns the value of the 'Max Occurs' attribute. The default value is
* "1".
*
* @return the value of the 'Max Occurs' attribute.
*/
public int getMaxOccur()
{
return getMaxOccurs(xsdWildcard);
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(xsdWildcard.getSchema());
}
/**
* Returns a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
XSDAnnotation annotation = xsdWildcard.getAnnotation();
return getDocumentations(annotation);
}
}
/**
* XSDModelGroupAdapter
*/
public static class XSDModelGroupAdapter extends XSDBaseAdapter implements CMGroup
{
protected XSDModelGroup xsdModelGroup;
public XSDModelGroupAdapter()
{
}
public XSDModelGroupAdapter(XSDModelGroup xsdModelGroup)
{
this.xsdModelGroup = xsdModelGroup;
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return GROUP;
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdModelGroup;
}
/**
* Returns a list of the children of this group.
*
* @return a list of the children of this group.
*/
public CMNodeList getChildNodes()
{
CMNodeListImpl nodeList = new CMNodeListImpl();
if (xsdModelGroup != null)
{
for (Iterator i = xsdModelGroup.getParticles().iterator(); i.hasNext();)
{
XSDParticle particle = (XSDParticle) i.next();
XSDParticleContent content = particle.getContent();
CMNode adapter = getAdapter(content);
if (adapter != null)
{
nodeList.getList().add(adapter);
}
}
}
return nodeList;
}
/**
* Returns the name of the node. The default value is an empty string value.
* All derived classes must override this method if they do not want the
* default value.
*
* @return the name of the node.
*/
public String getNodeName()
{
CMDescriptionBuilder descriptionBuilder = new CMDescriptionBuilder();
return descriptionBuilder.buildDescription(this);
}
/**
* Returns the value of 'Min Occurs' attribute. The default value is "1".
*
* @return the value of the 'Min Occurs' attribute.
*/
public int getMinOccur()
{
return getMinOccurs(xsdModelGroup);
}
/**
* Returns the value of the 'Max Occurs' attribute. The default value is
* "1".
*
* @return the value of the 'Max Occurs' attribute.
*/
public int getMaxOccur()
{
return getMaxOccurs(xsdModelGroup);
}
/**
* Return operator of this group -- CHOICE, SEQUENCE or ALL value.
*
* @return the operator of this group.
*/
public int getOperator()
{
int result = 0;
//todo... handle ALONE case by checkig if child count == 1
if (xsdModelGroup != null)
{
switch (xsdModelGroup.getCompositor().getValue())
{
case XSDCompositor.CHOICE : {
result = CHOICE;
break;
}
case XSDCompositor.SEQUENCE : {
result = SEQUENCE;
break;
}
case XSDCompositor.ALL : {
result = ALL;
break;
}
}
}
return result;
}
/**
* Returns a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
XSDAnnotation annotation = xsdModelGroup.getAnnotation();
return getDocumentations(annotation);
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(xsdModelGroup.getSchema());
}
}
/**
* XSDModelGroupDefinitionAdapter
*/
public static class XSDModelGroupDefinitionAdapter extends XSDBaseAdapter implements CMGroup
{
protected XSDModelGroupDefinition xsdModelGroupDefinition;
public XSDModelGroupDefinitionAdapter(XSDModelGroupDefinition xsdModelGroupDefinition)
{
this.xsdModelGroupDefinition = xsdModelGroupDefinition;
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return GROUP;
}
/**
* Returns the key for this cmnode which is the corresponding XML Schema
* node.
*
* @return the key for this cmnode.
*/
public Object getKey()
{
return xsdModelGroupDefinition;
}
/**
* Returns a list of the children of this group.
*
* @return a list of the children of this group.
*/
public CMNodeList getChildNodes()
{
CMNodeListImpl nodeList = new CMNodeListImpl();
XSDModelGroup modelGroup = xsdModelGroupDefinition.getResolvedModelGroupDefinition().getModelGroup();
if (modelGroup != null)
{
CMNode adapter = getAdapter(modelGroup);
nodeList.add(adapter);
}
return nodeList;
}
/**
* Returns the name of the node. The default value is an empty string value.
* All derived classes must override this method if they do not want the
* default value.
*
* @return the name of the node.
*/
public String getNodeName()
{
CMDescriptionBuilder descriptionBuilder = new CMDescriptionBuilder();
return descriptionBuilder.buildDescription(this);
}
/**
* Returns the value of 'Min Occurs' attribute. The default value is "1".
*
* @return the value of the 'Min Occurs' attribute.
*/
public int getMinOccur()
{
return getMinOccurs(xsdModelGroupDefinition);
}
/**
* Returns the value of the 'Max Occurs' attribute. The default value is
* "1".
*
* @return the value of the 'Max Occurs' attribute.
*/
public int getMaxOccur()
{
return getMaxOccurs(xsdModelGroupDefinition);
}
/**
* Return operator of this group -- CHOICE, SEQUENCE or ALL value.
*
* @return the operator of this group.
*/
public int getOperator()
{
return XSDCompositor.SEQUENCE;
}
/**
* Returns a list of documentation elements.
*
* @return a list of documentation elements.
*/
protected CMNodeList getDocumentation()
{
XSDAnnotation annotation = xsdModelGroupDefinition.getAnnotation();
return getDocumentations(annotation);
}
/**
* Returns the cmdocument that is the owner of this cmnode.
*
* @return the cmdocument corresponding to this cmnode.
*/
public CMDocument getCMDocument()
{
return (CMDocument) getAdapter(xsdModelGroupDefinition.getSchema());
}
}
/**
* DocumentationImpl implements CMDocumentation. A representation of the
* documentation element part of the 'User Information' feature. Working with
* the documentation element requires dropping down into the DOM model.
*/
public static class DocumentationImpl implements CMDocumentation
{
protected Element documentation;
/**
* Constructor.
*
* @param documentation -
* a documentation element.
*/
public DocumentationImpl(Element documentation)
{
this.documentation = documentation;
}
/**
* Returns the type of the node. The types are defined in CMNode class
* (ANY_ELEMENT, ATTRIBUTE_DECLARATION, DATA_TYPE, DOCUMENT,
* ELEMENT_DECLARATION, ENTITY_DECLARATION, GROUP, NAME_SPACE or
* DOCUMENTATION).
*
* @return the type of this node.
*/
public int getNodeType()
{
return DOCUMENTATION;
}
/**
* Returns an empty string value.
*
* @return an empty string value.
*/
public String getNodeName()
{
return "";
}
/**
* Returns false. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return false.
*/
public boolean supports(String propertyName)
{
return false;
}
/**
* Returns null. This class does not support any properties.
*
* @param propertyName -
* name of a property
* @return null.
*/
public Object getProperty(String propertyName)
{
return null;
}
/**
* Returns the content of the documentation element.
*
* @return the content of the documentation element.
*/
public String getValue()
{
String content = "";
boolean contentFound = false;
NodeList nodes = documentation.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++)
{
Node node = nodes.item(i);
if (node instanceof Text)
{
contentFound = true;
content += node.getNodeValue();
}
}
return contentFound ? content : null;
}
/**
* Returns the xml:lang attribute value of the documentation element.
*
* @return the xml:lang attribute value of the documentation element.
*/
public String getLanguage()
{
return documentation.hasAttributeNS(XSDConstants.XML_NAMESPACE_URI_1998, XML_LANG_ATTRIBUTE) ? documentation.getAttributeNS(XSDConstants.XML_NAMESPACE_URI_1998, XML_LANG_ATTRIBUTE) : null;
}
/**
* Returns the source attribute value of the documentation element.
*
* @return the source attribute value of the documentation element.
*/
public String getSource()
{
return documentation.hasAttributeNS(null, XSDConstants.SOURCE_ATTRIBUTE) ? documentation.getAttributeNS(null, XSDConstants.SOURCE_ATTRIBUTE) : null;
}
}
/**
* XSIDocument extends CMDocumentImpl. This class is used to hold those
* attributes that are for direct use in any XML documents. These attributes
* are in a different namespace, which has the namespace name
* http://www.w3.org/2001/XMLSchema-instance. Attributes in this namespace
* include: xsi:type xsi:nil xsi:schemaLocation xsi:noNamespaceSchemaLocation
*/
public static class XSIDocument extends CMDocumentImpl
{
public CMAttributeDeclarationImpl nilAttribute;
/**
* Constructor. Creates the 'xsi:nil'
*/
public XSIDocument()
{
super(XSDConstants.SCHEMA_INSTANCE_URI_2001);
// create the 'nill' attribute
String[] values = {"false", "true"};
nilAttribute = new CMAttributeDeclarationImpl("nil", CMAttributeDeclaration.REQUIRED, new CMDataTypeImpl("boolean", values));
nilAttribute.setPrefixQualification(true);
nilAttribute.setCMDocument(this);
}
}
/**
* Note this XSD model visitor differs from the XSD model visitor in
* org.eclipse.wst.xsd.editor plugin. In visitModelGroup method we call
* getParticles() instead of getContents(). This gathers all of the content of
* a derived type.
*/
public static class XSDCMVisitor extends XSDVisitor
{
public void visitSimpleTypeDefinition(XSDSimpleTypeDefinition type)
{
XSDParticle ctd = type.getComplexType();
if (ctd != null)
visitParticle(ctd);
}
public void visitModelGroup(XSDModelGroup modelGroup)
{
if (modelGroup.getParticles() != null)
{
for (Iterator iterator = modelGroup.getParticles().iterator(); iterator.hasNext();)
{
XSDParticle particle = (XSDParticle) iterator.next();
visitParticle(particle);
}
}
}
public void visitModelGroupDefinition(XSDModelGroupDefinition modelGroupDef)
{
XSDModelGroup modelGroup = modelGroupDef.getResolvedModelGroupDefinition().getModelGroup();
if (modelGroup != null)
{
visitModelGroup(modelGroup);
}
}
}
/**
* A visitor class that walks the xsd model and computes the list of children
* that belong to the initially visited element type.
*/
public static class DerivedChildVisitor extends XSDCMVisitor
{
protected CMNodeListImpl childNodeList = new CMNodeListImpl();
protected List baseTypeList = new Vector();
Object root;
DerivedChildVisitor(Object root)
{
this.root = root;
}
public CMNodeListImpl getChildNodeList()
{
return childNodeList;
}
public void visitWildcard(XSDWildcard wildcard)
{
childNodeList.getList().add(getAdapter(wildcard));
}
public void visitElementDeclaration(XSDElementDeclaration element)
{
childNodeList.getList().add(getAdapter(element));
}
public void visitModelGroup(XSDModelGroup modelGroup)
{
childNodeList.getList().add(getAdapter(modelGroup));
}
public void visitModelGroupDefinition(XSDModelGroupDefinition modelGroupDefinition)
{
childNodeList.getList().add(getAdapter(modelGroupDefinition));
}
}
/**
* A visitor class that gathers all of the elements within a type definition.
*/
public static class LocalElementVisitor extends XSDCMVisitor
{
protected CMNamedNodeMapImpl namedNodeMap = new CMNamedNodeMapImpl();
protected List baseTypeList = new Vector();
public void visitElementDeclaration(XSDElementDeclaration element)
{
XSDElementDeclarationAdapter adapter = (XSDElementDeclarationAdapter) getAdapter(element);
namedNodeMap.getHashtable().put(adapter.getNodeName(), adapter);
}
public CMNamedNodeMap getCMNamedNodeMap()
{
return namedNodeMap;
}
}
}