/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.mappingsmodel.schema;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
import javax.xml.XMLConstants;
import org.apache.xerces.impl.xs.XMLSchemaLoader;
import org.apache.xerces.impl.xs.opti.AttrImpl;
import org.apache.xerces.impl.xs.opti.ElementImpl;
import org.apache.xerces.impl.xs.opti.SchemaDOM;
import org.apache.xerces.impl.xs.opti.SchemaDOMParser;
import org.apache.xerces.impl.xs.opti.SchemaParsingConfig;
import org.apache.xerces.util.URI;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xs.StringList;
import org.apache.xerces.xs.XSException;
import org.apache.xerces.xs.XSModel;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaFileReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaURLReference;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWModel;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWNominative;
import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants;
import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.QName;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.xml.MWXmlProject;
import org.eclipse.persistence.tools.workbench.mappingsmodel.resource.ClasspathResourceSpecification;
import org.eclipse.persistence.tools.workbench.mappingsmodel.resource.FileResourceSpecification;
import org.eclipse.persistence.tools.workbench.mappingsmodel.resource.ResourceException;
import org.eclipse.persistence.tools.workbench.mappingsmodel.resource.ResourceSpecification;
import org.eclipse.persistence.tools.workbench.mappingsmodel.resource.UrlResourceSpecification;
import org.eclipse.persistence.tools.workbench.mappingsmodel.xml.SchemaChange;
import org.eclipse.persistence.tools.workbench.utility.CollectionTools;
import org.eclipse.persistence.tools.workbench.utility.HashBag;
import org.eclipse.persistence.tools.workbench.utility.iterators.CompositeIterator;
import org.eclipse.persistence.tools.workbench.utility.iterators.FilteringIterator;
import org.eclipse.persistence.tools.workbench.utility.iterators.TransformationIterator;
import org.eclipse.persistence.tools.workbench.utility.node.Node;
import org.eclipse.persistence.tools.workbench.utility.string.StringTools;
import org.w3c.dom.NamedNodeMap;
public final class MWXmlSchema extends MWModel
implements MWNominative
{
public static final int INFINITY = 2147483640;
private boolean shouldUseDefaultNamespace;
public static final String SHOULD_USE_DEFAULT_NAMESPACE = "shouldUseDefaultNamespace";
private String defaultNamespaceUrl;
public static final String DEFAULT_NAMESPACE_URL = "defaultNamespaceUrl";
// **************** MW-specific info **************************************
/** Used by user to uniquely identify a schema */
private volatile String name;
public static final String NAME_PROPERTY = "name";
/** Location of the schema file resource */
private volatile ResourceSpecification schemaSource;
public static final String SCHEMA_SOURCE_PROPERTY = "schemaSource";
// **************** XDK-imported info *************************************
/** The url of the target namespace */
private volatile String targetNamespaceUrl;
/**
* Contains the target Namespace object and all imported Namespace objects
* These are the namespaces directly declared by the schema
*/
private Collection declaredNamespaces;
public static final String NAMESPACES_COLLECTION = "namespaces";
/** Contains all built-in types - not persisted */
private List builtInNamespaces;
// **************** Static creators ***************************************
public static MWXmlSchema createFromFile(MWXmlSchemaRepository parent, String name, String filePath) {
MWXmlSchema schema = new MWXmlSchema(parent, name);
schema.setSchemaSource(new FileResourceSpecification(schema, filePath));
return schema;
}
public static MWXmlSchema createFromUrl(MWXmlSchemaRepository parent, String name, String url) {
MWXmlSchema schema = new MWXmlSchema(parent, name);
schema.setSchemaSource(new UrlResourceSpecification(schema, url));
return schema;
}
public static MWXmlSchema createFromClasspath(MWXmlSchemaRepository parent, String name, String resourceName) {
MWXmlSchema schema = new MWXmlSchema(parent, name);
schema.setSchemaSource(new ClasspathResourceSpecification(schema, resourceName));
return schema;
}
// **************** Constructors ******************************************
/** For TopLink only */
private MWXmlSchema() {
super();
}
private MWXmlSchema(MWModel parent) {
super(parent);
}
private MWXmlSchema(MWModel parent, String name) {
this(parent);
this.initialize(name);
}
// **************** Initialization ****************************************
protected void initialize() {
super.initialize();
this.initializeBuiltInNamespaces();
}
private void initializeBuiltInNamespaces() {
this.builtInNamespaces = new Vector();
this.builtInNamespaces.add(MWNamespace.xsdNamespace(this));
this.builtInNamespaces.add(MWNamespace.xsiNamespace(this));
}
protected void initialize(Node parent) {
super.initialize(parent);
this.targetNamespaceUrl = "";
this.defaultNamespaceUrl = "";
this.shouldUseDefaultNamespace = false;
this.declaredNamespaces = new HashBag();
}
private void initialize(String schemaName) {
this.name = schemaName;
}
protected void addChildrenTo(List children) {
super.addChildrenTo(children);
children.add(this.schemaSource);
synchronized (this.declaredNamespaces) { children.addAll(this.declaredNamespaces); }
synchronized (this.builtInNamespaces) { children.addAll(this.builtInNamespaces); }
}
// **************** Nominative implementation ***************************
public String getName() {
return this.name;
}
public void setName(String name) {
if (name == null) {
throw new NullPointerException();
}
String old = this.name;
this.name = name;
if (this.attributeValueHasChanged(old, name)) {
// synch up the repository before notifying everyone
try {
this.schemaRepository().schemaRenamed(old, name, this);
} catch (RuntimeException ex) {
this.name = old; // restore the name before re-throwing the exception
throw ex;
}
this.firePropertyChanged(NAME_PROPERTY, old, name);
this.getProject().nodeRenamed(this);
}
}
// **************** Load mechanism API ************************************
public ResourceSpecification getSchemaSource() {
return this.schemaSource;
}
private void setSchemaSource(ResourceSpecification newSchemaSource) {
ResourceSpecification oldSchemaLocation = this.schemaSource;
this.schemaSource = newSchemaSource;
this.firePropertyChanged(SCHEMA_SOURCE_PROPERTY, oldSchemaLocation, newSchemaSource);
}
public void setFileSchemaLocation(String filePath) {
this.setSchemaSource(new FileResourceSpecification(this, filePath));
}
public void setUrlSchemaLocation(String url) {
this.setSchemaSource(new UrlResourceSpecification(this, url));
}
public void setClasspathSchemaLocation(String resourceName) {
this.setSchemaSource(new ClasspathResourceSpecification(this, resourceName));
}
// **************** Namespaces ********************************************
public String targetNamespaceUrl() {
return this.targetNamespaceUrl;
}
public void setTargetNamespaceUrl(String newTargetNamespaceUrl) {
this.targetNamespaceUrl = newTargetNamespaceUrl;
if ("".equals(this.defaultNamespaceUrl)) {
this.defaultNamespaceUrl = this.targetNamespaceUrl;
}
}
/** Returns an Iterator of declared Namespace objects only */
public Iterator declaredNamespaces() {
return this.declaredNamespaces.iterator();
}
private MWNamespace declaredNamespace(String namespaceUrl) {
for (Iterator stream = this.declaredNamespaces(); stream.hasNext(); ) {
MWNamespace next = (MWNamespace) stream.next();
if (next.getNamespaceUrl().equals(namespaceUrl)) {
return next;
}
}
return null;
}
private MWNamespace addDeclaredNamespace(String namespaceUrl) {
MWNamespace namespace = new MWNamespace(this);
this.addDeclaredNamespace(namespace);
return namespace;
}
private void addDeclaredNamespace(MWNamespace namespace) {
this.declaredNamespaces.add(namespace);
this.fireItemAdded(NAMESPACES_COLLECTION, namespace);
}
private void removeDeclaredNamespace(MWNamespace namespace) {
this.declaredNamespaces.remove(namespace);
this.fireItemRemoved(NAMESPACES_COLLECTION, namespace);
this.getProject().nodeRemoved(namespace);
}
public MWNamespace targetNamespace() {
return this.declaredNamespace(this.targetNamespaceUrl());
}
public Iterator importedNamespaces() {
return new FilteringIterator(this.declaredNamespaces()) {
protected boolean accept(Object next) {
return ! ((MWNamespace) next).isTargetNamespace();
}
};
}
// **************** Built in namespaces ***********************************
public ListIterator builtInNamespaces() {
return this.builtInNamespaces.listIterator();
}
private MWNamespace builtInNamespace(String namespaceUrl) {
for (Iterator stream = this.builtInNamespaces(); stream.hasNext(); ) {
MWNamespace next = (MWNamespace) stream.next();
if (next.getNamespaceUrl().equals(namespaceUrl)) {
return next;
}
}
return null;
}
// **************** Convenience *******************************************
public MWXmlSchemaRepository schemaRepository() {
return (MWXmlSchemaRepository) this.getParent();
}
public void toString(StringBuffer sb) {
sb.append(this.name);
}
// **************** General namespace API *********************************
/** Return an iterator over all the contained namespaces (built-in last) */
private Iterator namespaces() {
return new CompositeIterator(this.declaredNamespaces(), this.builtInNamespaces());
}
/** Return the URL string of the first namespace for the given prefix, if it exists */
public String namespaceUrlForPrefix(String namespacePrefix) {
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
MWNamespace namespace = (MWNamespace) stream.next();
if (namespacePrefix.equals(namespace.getNamespacePrefix())) {
return namespace.getNamespaceUrl();
}
}
return "";
}
/** Return the prefix of the first namespace for the given URL string, if it exists */
public String namespacePrefixForUrl(String namespaceUrl) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
return "";
}
return this.namespaceForUrl(namespaceUrl).getNamespacePrefix();
}
/** Return the first namespace for the given URL string, if it exists */
public MWNamespace namespaceForUrl(String namespaceUrl) {
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
MWNamespace next = (MWNamespace) stream.next();
if (next.getNamespaceUrl().equals(namespaceUrl)) {
return next;
}
}
return null;
}
// **************** Querying **********************************************
public int attributeCount() {
int attributeCount = 0;
for (Iterator stream = this.declaredNamespaces(); stream.hasNext(); ) {
attributeCount += ((MWNamespace) stream.next()).attributeCount();
}
return attributeCount;
}
public MWAttributeDeclaration attribute(String attributeName) {
return this.attribute(this.targetNamespaceUrl, attributeName);
}
public MWAttributeDeclaration attribute(String namespaceUrl, String attributeName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.namespaceForUrl(namespaceUrl).attribute(attributeName);
}
public int elementCount() {
int elementCount = 0;
for (Iterator stream = this.declaredNamespaces(); stream.hasNext(); ) {
elementCount += ((MWNamespace) stream.next()).elementCount();
}
return elementCount;
}
public MWElementDeclaration element(String elementName) {
return this.element(this.targetNamespaceUrl, elementName);
}
public MWElementDeclaration element(String namespaceUrl, String elementName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.namespaceForUrl(namespaceUrl).element(elementName);
}
public int typeCount() {
int typeCount = 0;
for (Iterator stream = this.declaredNamespaces(); stream.hasNext(); ) {
typeCount += ((MWNamespace) stream.next()).typeCount();
}
return typeCount;
}
public MWComplexTypeDefinition complexType(String complexTypeName) {
return this.complexType(this.targetNamespaceUrl, complexTypeName);
}
public MWComplexTypeDefinition complexType(String namespaceUrl, String complexTypeName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.namespaceForUrl(namespaceUrl).complexType(complexTypeName);
}
public Iterator complexTypes() {
return new CompositeIterator(this.complexTypeIterators());
}
private Iterator complexTypeIterators() {
return new TransformationIterator(this.declaredNamespaces()) {
protected Object transform(Object next) {
return ((MWNamespace) next).complexTypes();
}
};
}
public MWSimpleTypeDefinition simpleType(String simpleTypeName) {
return this.simpleType(this.targetNamespaceUrl, simpleTypeName);
}
public MWSimpleTypeDefinition simpleType(String namespaceUrl, String simpleTypeName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.namespaceForUrl(namespaceUrl).simpleType(simpleTypeName);
}
public Iterator simpleTypes() {
return new CompositeIterator(this.simpleTypeIterators());
}
private Iterator simpleTypeIterators() {
return new TransformationIterator(this.declaredNamespaces()) {
protected Object transform(Object next) {
return ((MWNamespace) next).simpleTypes();
}
};
}
public int modelGroupDefinitionCount() {
int groupCount = 0;
for (Iterator stream = this.declaredNamespaces(); stream.hasNext(); ) {
groupCount += ((MWNamespace) stream.next()).modelGroupDefinitionsCount();
}
return groupCount;
}
public MWModelGroupDefinition modelGroupDefinition(String modelGroupDefName) {
return this.modelGroupDefinition(this.targetNamespaceUrl, modelGroupDefName);
}
public MWModelGroupDefinition modelGroupDefinition(String namespaceUrl, String modelGroupDefName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.namespaceForUrl(namespaceUrl).modelGroupDefinition(modelGroupDefName);
}
public MWModelGroup modelGroup(String modelGroupDefName) {
return this.modelGroup(this.targetNamespaceUrl, modelGroupDefName);
}
public MWModelGroup modelGroup(String namespaceUrl, String modelGroupDefName) {
if (namespaceUrl == null || "".equals(namespaceUrl)) {
namespaceUrl = targetNamespaceUrl();
}
return this.modelGroupDefinition(namespaceUrl, modelGroupDefName).getModelGroup();
}
public Iterator structuralComponents() {
return new CompositeIterator(this.structuralComponentIterators());
}
private Iterator structuralComponentIterators() {
return new TransformationIterator(this.declaredNamespaces()) {
protected Object transform(Object next) {
return ((MWNamespace) next).structuralComponents();
}
};
}
public Iterator contextComponents() {
return new CompositeIterator(this.contextComponentIterators());
}
private Iterator contextComponentIterators() {
return new TransformationIterator(this.declaredNamespaces()) {
protected Object transform(Object next) {
return ((MWNamespace) next).contextComponents();
}
};
}
public Iterator rootElements() {
return new CompositeIterator(this.rootElementIterators());
}
private Iterator rootElementIterators() {
return new TransformationIterator(this.declaredNamespaces()) {
protected Object transform(Object next) {
return ((MWNamespace) next).elements();
}
};
}
public MWNamedSchemaComponent component(QName qName) {
if (qName.getComponentType() == QName.ATTRIBUTE_TYPE) {
return this.attribute(qName.getNamespaceURI(), qName.getLocalName());
}
else if (qName.getComponentType() == QName.ELEMENT_TYPE) {
return this.element(qName.getNamespaceURI(), qName.getLocalName());
}
else if (qName.getComponentType() == QName.COMPLEX_TYPE_TYPE) {
return this.complexType(qName.getNamespaceURI(), qName.getLocalName());
}
else if (qName.getComponentType() == QName.GROUP_TYPE) {
return this.modelGroupDefinition(qName.getNamespaceURI(), qName.getLocalName());
}
else {
return null;
}
}
// **************** Refreshing ********************************************
public void reload()
throws ResourceException
{
URI uri = this.schemaSource.validResourceURI();
XMLSchemaLoader schemaLoader = new XMLSchemaLoader();
XSModel xmlSchemaModel = null;
XMLInputSource inputSource = new XMLInputSource(null, uri.toString(), null);
SchemaDOMParser parser = new SchemaDOMParser(new SchemaParsingConfig());
try {
xmlSchemaModel = schemaLoader.loadURI(uri.toString());
parser.parse(inputSource);
} catch (Throwable t) {
if (t instanceof XSException) {
throw (XSException) t;
}
throw new RuntimeException(t);
}
SchemaDOM schemaDOM = (SchemaDOM)parser.getDocument2();
this.reload(xmlSchemaModel, schemaDOM);
this.fireStateChanged();
((MWXmlProject) this.getProject()).schemaChanged(SchemaChange.schemaStructureChange(this));
this.reloadSchemaPrefixes(schemaDOM);
}
private void reload(XSModel xmlSchema, SchemaDOM schemaDOM) {
// Keep track of the namespaces that are no longer present.
Collection oldNamespaces = CollectionTools.collection(this.declaredNamespaces());
this.reloadTargetNamespace(xmlSchema, schemaDOM, oldNamespaces);
StringList allNamespaceUrls = xmlSchema.getNamespaces();
for (int i = 0; i < allNamespaceUrls.getLength(); i ++ ) {
String namespaceUrl = allNamespaceUrls.item(i);
if (namespaceUrl != null && ! namespaceUrl.equals(this.targetNamespaceUrl()) && ! namespaceUrl.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
this.reloadImportedNamespace(xmlSchema, schemaDOM, namespaceUrl, oldNamespaces);
}
}
for (Iterator stream = oldNamespaces.iterator(); stream.hasNext(); ) {
this.removeDeclaredNamespace((MWNamespace) stream.next());
}
this.resolveReferences();
}
private void reloadTargetNamespace(XSModel xmlSchema, SchemaDOM schemaDOM, Collection oldNamespaces) {
String url = "";
String uriString = schemaDOM.getDocumentElement().getAttribute("targetNamespace");
if (uriString != null && uriString != "") {
url = uriString;
}
MWNamespace targetNamespace = this.targetNamespace();
this.setTargetNamespaceUrl(url);
this.reloadNamespace(xmlSchema, schemaDOM, targetNamespace, url, oldNamespaces);
targetNamespace = this.targetNamespace();
if (targetNamespace.getNamespacePrefix().equals("")) {
targetNamespace.setDeclared(false);
}
}
private void reloadImportedNamespace(XSModel xmlSchema, SchemaDOM schemaDOM, String namespaceUrl, Collection oldNamespaces) {
MWNamespace namespace = this.declaredNamespace(namespaceUrl);
this.reloadNamespace(xmlSchema, schemaDOM, namespace, namespaceUrl, oldNamespaces);
}
private void reloadNamespace(XSModel xmlSchema, SchemaDOM schemaDOM, MWNamespace namespace, String namespaceUrl, Collection oldNamespaces) {
if (namespace == null) {
namespace = this.addDeclaredNamespace(namespaceUrl);
}
else {
oldNamespaces.remove(namespace);
}
namespace.reload(xmlSchema, schemaDOM, namespaceUrl);
}
private void reloadSchemaPrefixes(SchemaDOM schemaDOM) {
ElementImpl schemaElement = (ElementImpl)schemaDOM.getDocumentElement();
// parse <schema attributes ...>
NamedNodeMap map = schemaElement.getAttributes();
int nAttr = map.getLength();
AttrImpl attr;
String localName, value, ns;
for (int i = 0; i < nAttr; i++) {
attr = (AttrImpl)map.item(i);
localName = attr.getLocalName();
value = attr.getValue();
ns = attr.getNamespaceURI();
if (ns == XMLConstants.XMLNS_ATTRIBUTE_NS_URI && localName != XMLConstants.XMLNS_ATTRIBUTE) {
MWNamespace namespace = this.namespaceForUrl(value);
if (namespace != null) {
namespace.setNamespacePrefixFromSchemaDoc(localName);
}
}
}
}
public void resolveReferences() {
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
((MWNamespace) stream.next()).resolveReferences();
}
}
// **************** Problems **********************************************
protected void addProblemsTo(List currentProblems) {
super.addProblemsTo(currentProblems);
this.checkRequiredNamespacePrefix(currentProblems);
this.checkDuplicateNamespacePrefix(currentProblems);
this.checkSpacesinNamespacePrefix(currentProblems);
}
private void checkSpacesinNamespacePrefix(List currentProblems) {
for (Iterator stream = this.namespaces(); stream.hasNext();) {
MWNamespace namespace = (MWNamespace) stream.next();
if (! "".equals(namespace.getNamespaceUrl()) && StringTools.contains(namespace.getNamespacePrefix(), " ", '\0')) {
currentProblems.add(this.buildProblem(ProblemConstants.SCHEMA_NAMESPACE_PREFIX_CONTAINS_SPACE, namespace.getNamespaceUrlForDisplay()));
}
}
}
private void checkRequiredNamespacePrefix(List currentProblems) {
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
MWNamespace namespace = (MWNamespace) stream.next();
if (! "".equals(namespace.getNamespaceUrl()) && "".equals(namespace.getNamespacePrefix()) && !namespace.getNamespaceUrl().equals(this.defaultNamespaceUrl)) {
currentProblems.add(this.buildProblem(ProblemConstants.SCHEMA_NAMESPACE_PREFIX_NOT_SPECIFIED, namespace.getNamespaceUrlForDisplay()));
}
}
}
private void checkDuplicateNamespacePrefix(List currentProblems) {
HashBag usedPrefixes = new HashBag();
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
String prefix = ((MWNamespace) stream.next()).getNamespacePrefix();
if (! "".equals(prefix)) {
usedPrefixes.add(prefix);
}
}
for (Iterator stream = usedPrefixes.uniqueIterator(); stream.hasNext(); ) {
String prefix = (String) stream.next();
if (usedPrefixes.count(prefix) > 1) {
currentProblems.add(this.buildProblem(ProblemConstants.SCHEMA_NAMESPACE_PREFIX_DUPLICATED, prefix));
}
}
}
// **************** Runtime conversion ************************************
public XMLSchemaReference runtimeSchemaReference() {
if (this.schemaSource instanceof ClasspathResourceSpecification) {
return new XMLSchemaClassPathReference(this.schemaSource.getLocation());
}
else if (this.schemaSource instanceof FileResourceSpecification) {
return new XMLSchemaFileReference(this.schemaSource.getLocation());
}
else if (this.schemaSource instanceof UrlResourceSpecification) {
return new XMLSchemaURLReference(this.schemaSource.getLocation());
}
else {
return null;
}
}
public NamespaceResolver runtimeNamespaceResolver() {
NamespaceResolver namespaceResolver = new NamespaceResolver();
for (Iterator stream = this.namespaces(); stream.hasNext(); ) {
MWNamespace namespace = (MWNamespace) stream.next();
if (namespace.isDeclared() && ! "".equals(namespace.getNamespacePrefix())) {
namespaceResolver.put(namespace.getNamespacePrefix(), namespace.getNamespaceUrl());
}
}
if (this.shouldUseDefaultNamespace() && !"".equals(this.getDefaultNamespaceUrl())) {
namespaceResolver.setDefaultNamespaceURI(this.getDefaultNamespaceUrl());
}
return namespaceResolver;
}
// **************** Toplink use only *************************************
public static XMLDescriptor buildDescriptor() {
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(MWXmlSchema.class);
descriptor.setDefaultRootElement("xml-schema");
descriptor.addDirectMapping("name", "name/text()");
XMLDirectMapping targetNamespaceMapping = new XMLDirectMapping();
targetNamespaceMapping.setAttributeName("targetNamespaceUrl");
targetNamespaceMapping.setXPath("target-namespace-url/text()");
targetNamespaceMapping.setNullValue("");
descriptor.addMapping(targetNamespaceMapping);
XMLDirectMapping defaultNamespaceMapping = new XMLDirectMapping();
defaultNamespaceMapping.setAttributeName("defaultNamespaceUrl");
defaultNamespaceMapping.setXPath("default-namespace-url/text()");
defaultNamespaceMapping.setNullValue("");
descriptor.addMapping(defaultNamespaceMapping);
XMLDirectMapping shouldDefaultNamespaceMapping = new XMLDirectMapping();
shouldDefaultNamespaceMapping.setAttributeName("shouldUseDefaultNamespace");
shouldDefaultNamespaceMapping.setXPath("should-default-namespace-url/text()");
shouldDefaultNamespaceMapping.setNullValue(false);
descriptor.addMapping(shouldDefaultNamespaceMapping);
XMLCompositeObjectMapping schemaLocationMapping = new XMLCompositeObjectMapping();
schemaLocationMapping.setAttributeName("schemaSource");
schemaLocationMapping.setXPath("schema-source");
schemaLocationMapping.setReferenceClass(ResourceSpecification.class);
descriptor.addMapping(schemaLocationMapping);
XMLCompositeCollectionMapping builtInNamespacesMapping = new XMLCompositeCollectionMapping();
builtInNamespacesMapping.setAttributeName("builtInNamespaces");
builtInNamespacesMapping.setGetMethodName("getPersistedBuiltInNamespacesForTopLink");
builtInNamespacesMapping.setSetMethodName("setPersistedBuiltInNamespacesForTopLink");
builtInNamespacesMapping.setXPath("built-in-namespaces/namespace");
builtInNamespacesMapping.setReferenceClass(BuiltInNamespace.class);
descriptor.addMapping(builtInNamespacesMapping);
XMLCompositeCollectionMapping namespacesMapping = new XMLCompositeCollectionMapping();
namespacesMapping.setAttributeName("declaredNamespaces");
namespacesMapping.setGetMethodName("getDeclaredNamespacesForToplink");
namespacesMapping.setSetMethodName("setDeclaredNamespacesForToplink");
namespacesMapping.setXPath("declared-namespaces/namespace");
namespacesMapping.setReferenceClass(MWNamespace.class);
descriptor.addMapping(namespacesMapping);
return descriptor;
}
private Collection getPersistedBuiltInNamespacesForTopLink() {
Collection persistedBuiltInNamespaces = new Vector();
for (Iterator stream = this.builtInNamespaces(); stream.hasNext(); ) {
MWNamespace nonPersistedNamespace = (MWNamespace) stream.next();
BuiltInNamespace persistedNamespace = new BuiltInNamespace();
persistedNamespace.url = nonPersistedNamespace.getNamespaceUrl();
persistedNamespace.prefix = nonPersistedNamespace.getNamespacePrefix();
persistedNamespace.declared = Boolean.valueOf(nonPersistedNamespace.isDeclared());
persistedBuiltInNamespaces.add(persistedNamespace);
}
return persistedBuiltInNamespaces;
}
private void setPersistedBuiltInNamespacesForTopLink(Collection persistedBuiltInNamespaces) {
for (Iterator stream = persistedBuiltInNamespaces.iterator(); stream.hasNext(); ) {
BuiltInNamespace persistedNamespace = (BuiltInNamespace) stream.next();
String url = persistedNamespace.url;
String prefix = persistedNamespace.prefix;
boolean declared = persistedNamespace.declared.booleanValue();
MWNamespace nonpersistedNamespace = this.builtInNamespace(url);
nonpersistedNamespace.setNamespacePrefixFromSchemaDocForTopLink(prefix);
nonpersistedNamespace.setNamespaceIsDeclaredFromSchemaDocForTopLink(declared);
}
}
private Collection getDeclaredNamespacesForToplink() {
return CollectionTools.sortedSet(declaredNamespaces());
}
private void setDeclaredNamespacesForToplink(Collection newNamespaces) {
this.declaredNamespaces = newNamespaces;
}
// **************** Member classes ****************************************
/**
* Used only by TopLink.
* This class is used to persist built in namespace information.
*/
public static class BuiltInNamespace
{
public static XMLDescriptor buildDescriptor(){
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(BuiltInNamespace.class);
((AbstractDirectMapping) descriptor.addDirectMapping("url", "@url")).setNullValue("");
((AbstractDirectMapping) descriptor.addDirectMapping("prefix", "@prefix")).setNullValue("");
((AbstractDirectMapping) descriptor.addDirectMapping("declared", "@declared")).setNullValue(Boolean.FALSE);
return descriptor;
}
String url;
String prefix;
Boolean declared;
private BuiltInNamespace() {
super();
}
}
public String getDefaultNamespaceUrl() {
return defaultNamespaceUrl;
}
public void setDefaultNamespaceUrl(String newDefaultNamespaceUrl) {
String oldUrl = this.defaultNamespaceUrl;
this.defaultNamespaceUrl = newDefaultNamespaceUrl;
firePropertyChanged(DEFAULT_NAMESPACE_URL, oldUrl, newDefaultNamespaceUrl);
}
public boolean shouldUseDefaultNamespace() {
return shouldUseDefaultNamespace;
}
public void setShouldUseDefaultNamespace(boolean newValue) {
boolean oldValue = this.shouldUseDefaultNamespace;
this.shouldUseDefaultNamespace = newValue;
firePropertyChanged(SHOULD_USE_DEFAULT_NAMESPACE, oldValue, newValue);
}
}