Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 365515

Summary: Two global URI Maps.
Product: [Modeling] EMF Reporter: Ed Willink <ed>
Component: CoreAssignee: Ed Merks <Ed.Merks>
Status: RESOLVED WORKSFORME QA Contact:
Severity: normal    
Priority: P3    
Version: 2.7.0   
Target Milestone: ---   
Hardware: PC   
OS: Windows Vista   
Whiteboard:

Description Ed Willink CLA 2011-12-04 01:45:12 EST
I've been finding that global URI mappings do not always work.

The problem appears to be that there are two global URI Maps, only one of which is used by delegation. The following test fails:

	assert URIConverter.URI_MAP == URIConverter.INSTANCE.getURIMap();

Presumably URIConverter.INSTANCE should use a private constructor that passes the static URIConverter.URI_MAP for use as its own URI map.
Comment 1 Ed Merks CLA 2011-12-04 06:17:18 EST
ExtensibleURIConveterImpl has

  protected URIMap getInternalURIMap()
  {
    if (uriMap == null)
    {
      URIMappingRegistryImpl mappingRegistryImpl =
        new URIMappingRegistryImpl()
        {
          private static final long serialVersionUID = 1L;

          @Override
          protected URI delegatedGetURI(URI uri)
          {
            return URIMappingRegistryImpl.INSTANCE.getURI(uri);
          }
        };

      uriMap = (URIMap)mappingRegistryImpl.map();
    }

    return uriMap;
  }

So it always delegates to the global URI_MAP

  Map<URI, URI> URI_MAP = org.eclipse.emf.ecore.resource.impl.URIMappingRegistryImpl.INSTANCE.map();

which gets populated in URIMappingRegistryReader.

I know global mapping registrations work and I do expect the assertion to fail, because each URI converter has its own URI map, but I don't see how this leads to "global URI mappings do not always work."
Comment 2 Ed Willink CLA 2011-12-04 06:56:10 EST
Yes. a URIConverter delegates to URI_Map., but that is not what the Bugzilla is about.

URIConverter.INSTANCE is documented as

   * The global static URI converter instance.
   * It's generally not a good idea to modify any aspect of this instance.
   * Instead, use a resource set's {@link ResourceSet#getURIConverter() local} instance.

and URIConverter.INSTANCE.getURIMap() is availble and consequently ciuld be understood to be a global URIMap, so the Javadoc provides two distinct candaidates for the global URIMap which is confusing and has caufght me out when trying to write 'polymorphic' global/local code and so translated the 'null' URIConverter to URIConverter.INSTANCE.

The "It's generally not a good idea to modify any aspect of this instance" is a partial warning not to tough, but this is undermined by ... local, whuicgh isn't applicable globally.

It would herlp to at least have a stronger comment about what the global instnace is useful for and a strong warning that URIConverter.URI_MAP is distinct from URIConverter.INSTANCE.getURIMap().
Comment 3 Ed Merks CLA 2011-12-04 11:58:21 EST
It would seems clear though when you read the documentation for URIConverter.getURIMap() that this map is different from the global URI map and will delegate to the global URI map.  Nothing anywhere implies that any URI converter will even delegate to any other URI converter's URI map, including not delegating to the global instance.