/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.resource; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; 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.util.EcoreUtil; import org.eclipse.xsd.XSDComponent; import org.eclipse.xsd.XSDSchema; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.eclipse.xsd.util.XSDConstants; import org.eclipse.xsd.util.XSDResourceImpl; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.types.DatatypeConstants; import org.teiid.designer.core.util.ModelObjectCollector; /** * @since 8.0 */ public class BuiltInTypesHrefConverter implements EObjectHrefConverter { /** Delimiter used to separate the URI string from the URI fragment */ protected static final String URI_REFERENCE_DELIMITER = "#"; //$NON-NLS-1$ protected static final String SCHEMA_FOR_SCHEMA_URI_2001_SUFFIX = "www.w3.org/2001/XMLSchema.xsd"; //$NON-NLS-1$ protected static final String SCHEMA_INSTANCE_URI_2001_SUFFIX = "www.w3.org/2001/XMLSchema-instance.xsd"; //$NON-NLS-1$ protected static final String MAGIC_SCHEMA_URI_2001_SUFFIX = "www.w3.org/2001/MagicXMLSchema.xsd"; //$NON-NLS-1$ protected static final URI SCHEMA_FOR_SCHEMA_URI = URI.createURI(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001); protected static final URI SCHEMA_INSTANCE_URI = URI.createURI(XSDConstants.SCHEMA_INSTANCE_URI_2001); protected static final URI XML_MAGIC_SCHEMA_URI = URI.createURI("http://www.w3.org/2001/MagicXMLSchema"); //$NON-NLS-1$ protected static final URI XML_SCHEMA_URI = URI.createURI("http://www.w3.org/2001/xml.xsd"); //$NON-NLS-1$ protected static final URI BUILTIN_DATATYPES_URI = URI.createURI(DatatypeConstants.BUILTIN_DATATYPES_URI); private static final boolean DEBUG = false; private Map logicalUriMap = null; private Map physicalUriMap = null; private ResourceSet eResourceSet = null; // ================================================================================== // C O N S T R U C T O R S // ================================================================================== /** * @since 5.0 */ public BuiltInTypesHrefConverter( final ResourceSet theResourceSet ) { CoreArgCheck.isNotNull(theResourceSet); this.eResourceSet = theResourceSet; this.logicalUriMap = new HashMap(); this.physicalUriMap = new HashMap(); doInit(); } // ================================================================================== // I N T E R F A C E M E T H O D S // ================================================================================== /** * @see org.teiid.designer.core.resource.EObjectHrefConverter#getLogicalURI(org.eclipse.emf.ecore.EObject) * @since 5.0 */ @Override public URI getLogicalURI( final EObject eObject ) { CoreArgCheck.isNotNull(eObject); URI physicalURI = createPhysicalURI(eObject); return (URI)this.logicalUriMap.get(physicalURI); } /** * @see org.teiid.designer.core.resource.EObjectHrefConverter#getLogicalURI(org.eclipse.emf.common.util.URI) * @since 5.0 */ @Override public URI getLogicalURI( final URI physicalURI ) { CoreArgCheck.isNotNull(physicalURI); return (URI)this.logicalUriMap.get(physicalURI); } /** * @see org.teiid.designer.core.resource.EObjectHrefConverter#getPhysicalURI(org.eclipse.emf.ecore.EObject) * @since 5.0 */ @Override public URI getPhysicalURI( final EObject eObject ) { CoreArgCheck.isNotNull(eObject); URI logicalURI = createLogicalURI(eObject); return (URI)this.physicalUriMap.get(logicalURI); } /** * @see org.teiid.designer.core.resource.EObjectHrefConverter#getPhysicalURI(org.eclipse.emf.common.util.URI) * @since 5.0 */ @Override public URI getPhysicalURI( final URI logicalURI ) { CoreArgCheck.isNotNull(logicalURI); return (URI)this.physicalUriMap.get(logicalURI); } // ================================================================================== // P R O T E C T E D M E T H O D S // ================================================================================== /** * Populate the URI map with the logical to physical URI EObject mappings for all built-in datatypes along with the inverse * mappings of physical to logical URI. */ protected synchronized void doInit() { // Create URI mappings for the Teiid Designer built-in datatypes resource // "http://www.metamatrix.com/metamodels/SimpleDatatypes-instance" XSDResourceImpl xsdResource = getBuiltInTypesResource(BUILTIN_DATATYPES_URI); if (xsdResource != null) { XSDSchema schema = xsdResource.getSchema(); CoreArgCheck.isNotNull(schema); addMappings(getXsdComponents(schema)); } else { String msg = ModelerCore.Util.getString("BuiltInTypesHrefConverter.BuiltInTypes_resource_not_loaded", BUILTIN_DATATYPES_URI); //$NON-NLS-1$ ModelerCore.Util.log(msg); } // Create URI mappings for the XML schema for schema resource // "http://www.w3.org/2001/XMLSchema" xsdResource = getBuiltInTypesResource(SCHEMA_FOR_SCHEMA_URI); if (xsdResource != null) { XSDSchema schema = xsdResource.getSchema(); CoreArgCheck.isNotNull(schema); addMappings(getXsdComponents(schema)); } else { String msg = ModelerCore.Util.getString("BuiltInTypesHrefConverter.BuiltInTypes_resource_not_loaded", SCHEMA_FOR_SCHEMA_URI); //$NON-NLS-1$ ModelerCore.Util.log(msg); } // Create URI mappings for the XML schema instance resource // "http://www.w3.org/2001/XMLSchema-instance" xsdResource = getBuiltInTypesResource(SCHEMA_INSTANCE_URI); if (xsdResource != null) { XSDSchema schema = xsdResource.getSchema(); CoreArgCheck.isNotNull(schema); addMappings(getXsdComponents(schema)); } else { String msg = ModelerCore.Util.getString("BuiltInTypesHrefConverter.BuiltInTypes_resource_not_loaded", SCHEMA_INSTANCE_URI); //$NON-NLS-1$ ModelerCore.Util.log(msg); } // Create URI mappings for the xml.xsd resource // "http://www.w3.org/2001/xml.xsd" xsdResource = getBuiltInTypesResource(XML_SCHEMA_URI); if (xsdResource != null) { XSDSchema schema = xsdResource.getSchema(); CoreArgCheck.isNotNull(schema); addMappings(getXsdComponents(schema)); } else { String msg = ModelerCore.Util.getString("BuiltInTypesHrefConverter.BuiltInTypes_resource_not_loaded", XML_SCHEMA_URI); //$NON-NLS-1$ ModelerCore.Util.log(msg); } // Create URI mappings for the XML magic schema resource (contains xs:anyType, xs:anySimpleType) // "http://www.w3.org/2001/MagicXMLSchema" xsdResource = getBuiltInTypesResource(XML_MAGIC_SCHEMA_URI); if (xsdResource != null) { XSDSchema schema = xsdResource.getSchema(); CoreArgCheck.isNotNull(schema); addMappings(getXsdComponents(schema)); } else { String msg = ModelerCore.Util.getString("BuiltInTypesHrefConverter.BuiltInTypes_resource_not_loaded", XML_MAGIC_SCHEMA_URI); //$NON-NLS-1$ ModelerCore.Util.log(msg); } if (DEBUG) { ModelerCore.Util.log("BuiltInTypesHrefConverter.doInit(): uriMap.size() = " + this.logicalUriMap.size()); //$NON-NLS-1$ } } /** * Return the built-in type resource specified by the URI * * @param logicalUri * @return * @since 5.0 */ protected XSDResourceImpl getBuiltInTypesResource( final URI logicalUri ) { CoreArgCheck.isNotNull(logicalUri); XSDResourceImpl r = (XSDResourceImpl)eResourceSet.getResource(logicalUri, false); if (r != null && !r.isLoaded()) { try { r.load(eResourceSet.getLoadOptions()); } catch (Throwable e) { ModelerCore.Util.log(e); } } return r; } /** * Create URI mappings for the apecified array of XSDComponent instances * * @param components * @since 5.0 */ protected void addMappings( final XSDComponent[] components ) { CoreArgCheck.isNotNull(components); for (int i = 0; i != components.length; ++i) { final URI logicalURI = createLogicalURI(components[i]); final URI physicalURI = createPhysicalURI(components[i]); this.physicalUriMap.put(logicalURI, physicalURI); this.logicalUriMap.put(physicalURI, logicalURI); if (DEBUG) { ModelerCore.Util.log("BuiltInTypesHrefConverter.addMappings(): " + logicalURI + " -> " + physicalURI); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * Return an array of all XSDComponent instances found in the specified schema * * @param schema * @return * @since 5.0 */ protected XSDComponent[] getXsdComponents( final XSDSchema schema ) { CoreArgCheck.isNotNull(schema); // Collect all the EObject instances in this resource using the // ModelObjectCollector class to avoid a ConcurrentModificationException // that may occur when using the TreeIterator (i.e. super.getAllContents()) CoreArgCheck.isNotNull(schema.eResource()); final ModelObjectCollector moc = new ModelObjectCollector(schema.eResource()); final List result = moc.getEObjects(); for (final Iterator i = result.iterator(); i.hasNext();) { final EObject eObject = (EObject)i.next(); if (!(eObject instanceof XSDComponent)) { i.remove(); } } return (XSDComponent[])result.toArray(new XSDComponent[result.size()]); } /** * Return the logical URI for the specified XSD component. The URIs are derived in a manner that is consistent with the * EResourceXmiSaveImpl method of writing href values representing references to these XSD components * * @param component * @return * @since 5.0 */ protected URI createLogicalURI( final EObject eObject ) { URI logicalURI = null; if (eObject instanceof XSDSimpleTypeDefinition) { logicalURI = URI.createURI(((XSDSimpleTypeDefinition)eObject).getURI()); } else { // Get the URI for the object (this works if it's a proxy) ... final URI uri = EcoreUtil.getURI(eObject); final String uriString = uri.trimFragment().toString(); // MagicXMLSchema.xsd suffix on the resource URI if (uriString.endsWith(MAGIC_SCHEMA_URI_2001_SUFFIX)) { logicalURI = XML_MAGIC_SCHEMA_URI.appendFragment(uri.fragment()); } // XMLSchema.xsd suffix on the resource URI else if (uriString.endsWith(SCHEMA_FOR_SCHEMA_URI_2001_SUFFIX)) { logicalURI = SCHEMA_FOR_SCHEMA_URI.appendFragment(uri.fragment()); } // XMLSchema-instance.xsd suffix on the resource URI else if (uriString.endsWith(SCHEMA_INSTANCE_URI_2001_SUFFIX)) { logicalURI = SCHEMA_INSTANCE_URI.appendFragment(uri.fragment()); } } return logicalURI; } /** * Return the physical URI for the specified EObject. * * @param eObject * @return * @since 5.0 */ protected URI createPhysicalURI( final EObject eObject ) { return EcoreUtil.getURI(eObject); } }