blob: 6b276f55d20ecb3ab52d6d56014b9481f2617735 [file] [log] [blame]
/*
* Copyright (c) 2012, 2018 CEA, Obeo, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Kenn Hussey (CEA) - initial API and implementation
* Kenn Hussey (CEA) - 389542, 399544, 425846, 418466, 429352
* Mikael Barbero (Obeo) - 414572
* Christian W. Damus (CEA) - 414572, 401682
* Kenn Hussey - 526217, 539580, 535301
*/
package org.eclipse.uml2.uml.resources.util;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.ContentHandler;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.xmi.impl.RootXMLContentHandlerImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLContentHandlerImpl;
import org.eclipse.uml2.types.TypesPackage;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.UMLPlugin;
import org.eclipse.uml2.uml.profile.standard.StandardPackage;
import org.eclipse.uml2.uml.resource.CMOF2UMLResource;
import org.eclipse.uml2.uml.resource.UML212UMLResource;
import org.eclipse.uml2.uml.resource.UML22UMLResource;
import org.eclipse.uml2.uml.resource.UML302UMLResource;
import org.eclipse.uml2.uml.resource.UML402UMLResource;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.resource.XMI2UMLResource;
import org.eclipse.uml2.uml.resources.ResourcesPlugin;
import org.eclipse.uml2.uml.util.UMLUtil;
/**
* @since 4.0
*/
public class UMLResourcesUtil
extends UMLUtil {
private static final ContentHandler XMI_CONTENT_HANDLER = new XMLContentHandlerImpl.XMI();
private static final ContentHandler UML2_1_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UML22UMLResource.UML2_CONTENT_TYPE_IDENTIFIER,
new String[]{UML22UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
UML22UMLResource.UML2_METAMODEL_NS_URI, null);
private static final ContentHandler UML2_2_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UMLResource.UML_2_0_0_CONTENT_TYPE_IDENTIFIER,
new String[]{UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND, UML2_UML_PACKAGE_2_0_NS_URI, null);
private static final ContentHandler UML2_2_1_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UMLResource.UML_2_1_0_CONTENT_TYPE_IDENTIFIER,
new String[]{UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
UML212UMLResource.UML_METAMODEL_NS_URI, null);
private static final ContentHandler UML2_3_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UMLResource.UML_3_0_0_CONTENT_TYPE_IDENTIFIER,
new String[]{UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
UML302UMLResource.UML_METAMODEL_NS_URI, null);
private static final ContentHandler UML2_4_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UMLResource.UML_4_0_0_CONTENT_TYPE_IDENTIFIER,
new String[]{UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
UML402UMLResource.UML_METAMODEL_NS_URI, null);
private static final ContentHandler UML2_5_0_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
UMLResource.UML_5_0_0_CONTENT_TYPE_IDENTIFIER,
new String[]{UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND, UMLPackage.eNS_URI, null);
private static final ContentHandler OMG_2_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_1_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_1_NS_URI, null);
private static final ContentHandler OMG_2_1_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_1_1_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_1_1_NS_URI, null);
private static final ContentHandler OMG_2_2_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_2_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_2_NS_URI, null);
private static final ContentHandler OMG_2_4_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_4_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_4_NS_URI, null);
private static final ContentHandler OMG_2_4_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_4_1_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_4_1_NS_URI, null);
private static final ContentHandler OMG_2_5_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
XMI2UMLResource.UML_2_5_CONTENT_TYPE_IDENTIFIER,
new String[]{XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
XMI2UMLResource.UML_METAMODEL_2_5_NS_URI, null);
private static final ContentHandler CMOF_2_0_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
CMOF2UMLResource.CMOF_2_0_CONTENT_TYPE_IDENTIFIER, new String[]{
CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
CMOF2UMLResource.CMOF_2_0_METAMODEL_NS_URI, null);
private static final ContentHandler CMOF_2_4_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
CMOF2UMLResource.CMOF_2_4_CONTENT_TYPE_IDENTIFIER, new String[]{
CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
CMOF2UMLResource.CMOF_2_4_METAMODEL_NS_URI, null);
private static final ContentHandler CMOF_2_4_1_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
CMOF2UMLResource.CMOF_2_4_1_CONTENT_TYPE_IDENTIFIER, new String[]{
CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
CMOF2UMLResource.CMOF_2_4_1_METAMODEL_NS_URI, null);
private static final ContentHandler CMOF_2_5_CONTENT_HANDLER = new RootXMLContentHandlerImpl(
CMOF2UMLResource.CMOF_2_5_CONTENT_TYPE_IDENTIFIER, new String[]{
CMOF2UMLResource.FILE_EXTENSION, XMI2UMLResource.FILE_EXTENSION},
RootXMLContentHandlerImpl.XMI_KIND,
CMOF2UMLResource.CMOF_2_5_METAMODEL_NS_URI, null);
/**
* Adds registrations to EMF's and UML2's global registries that enable
* working with UML models. To apply the same registrations only locally on
* a resource set (e.g., for isolation from other EMF-based code in the same
* class loader), use the {@link #initLocalRegistries(ResourceSet)} method,
* instead.
*
* @see #initLocalRegistries(ResourceSet)
*
* @since 5.0
*/
public static void initGlobalRegistries() {
initPackageRegistry(EPackage.Registry.INSTANCE);
initEPackageNsURIToProfileLocationMap(UMLPlugin
.getEPackageNsURIToProfileLocationMap());
initURIConverterURIMap(URIConverter.URI_MAP);
initContentHandlerRegistry(ContentHandler.Registry.INSTANCE);
initResourceFactoryRegistry(Resource.Factory.Registry.INSTANCE);
}
/**
* Adds registrations to a resource set's local registries that enable
* working with UML models in that resource set.
*
* @see #initPackageRegistry(org.eclipse.emf.ecore.EPackage.Registry)
* @see #initResourceFactoryRegistry(org.eclipse.emf.ecore.resource.Resource.Factory.Registry)
* @see #initContentHandlerRegistry(org.eclipse.emf.ecore.resource.ContentHandler.Registry)
* @see #initURIConverterURIMap(Map)
* @see #initEPackageNsURIToProfileLocationMap(Map)
*
* @since 5.0
*/
public static void initLocalRegistries(ResourceSet resourceSet) {
initPackageRegistry(resourceSet.getPackageRegistry());
// there is no local registry for this
initEPackageNsURIToProfileLocationMap(UMLPlugin
.getEPackageNsURIToProfileLocationMap());
initURIConverterURIMap(resourceSet.getURIConverter().getURIMap());
// there is no local registry for this
initContentHandlerRegistry(ContentHandler.Registry.INSTANCE);
initResourceFactoryRegistry(resourceSet.getResourceFactoryRegistry());
}
/**
* <p>
* Initializes the global registries and, if provided, the local registries
* for the specified resource set, with the registrations needed to work
* with UML2 resources in stand-alone mode (i.e., without Eclipse).
* </p>
* <p>
* <string>Note</string> that as of the 5.0 release, clients now have more
* fine-grained control over which registries (local or global) are
* initialized. Clients are encouraged to use these new APIs to ensure
* optimal behaviour and, where necessary, isolation from other code in the
* same class loader using the global registries.
* </p>
*
* @param resourceSet
* The resource set whose local registries to initialize, or
* <code>null</code> to perform only global registrations.
* @return The resource set (or <code>null</code>).
*
* @since 4.0
*
* @see #initLocalRegistries(ResourceSet)
* @see #initGlobalRegistries()
*/
public static ResourceSet init(ResourceSet resourceSet) {
initGlobalRegistries();
return UMLUtil.init(resourceSet);
}
/**
* Adds packages required for working with UML models to the specified
* registry.
*
* @param packageRegistry
* a package registry, perhaps local to a resource set or perhaps
* the global registry
*
* @return the same {@code packageRegistry}
*
* @since 5.0
*/
public static EPackage.Registry initPackageRegistry(
EPackage.Registry packageRegistry) {
packageRegistry.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
packageRegistry.put(UML2_TYPES_PACKAGE_4_0_NS_URI,
TypesPackage.eINSTANCE);
packageRegistry.put(TypesPackage.eNS_URI, TypesPackage.eINSTANCE);
packageRegistry.put(UML2_UML_PACKAGE_2_0_NS_URI, UMLPackage.eINSTANCE);
packageRegistry.put(UML212UMLResource.UML_METAMODEL_NS_URI,
UMLPackage.eINSTANCE);
packageRegistry.put(UML302UMLResource.UML_METAMODEL_NS_URI,
UMLPackage.eINSTANCE);
packageRegistry.put(UML402UMLResource.UML_METAMODEL_NS_URI,
UMLPackage.eINSTANCE);
packageRegistry.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
packageRegistry.put(UML212UMLResource.STANDARD_PROFILE_NS_URI,
StandardPackage.eINSTANCE);
packageRegistry.put(UML402UMLResource.STANDARD_L2_PROFILE_NS_URI,
StandardPackage.eINSTANCE);
packageRegistry.put(UML402UMLResource.STANDARD_L3_PROFILE_NS_URI,
StandardPackage.eINSTANCE);
packageRegistry.put(StandardPackage.eNS_URI, StandardPackage.eINSTANCE);
return packageRegistry;
}
/**
* Adds resource factories required for working with UML models to the
* specified registry.
*
* @param resourceFactoryRegistry
* a resource-factory registry, perhaps local to a resource set
* or perhaps the global registry
*
* @return the same {@code resourceFactoryRegistry}
*
* @since 5.0
*/
public static Resource.Factory.Registry initResourceFactoryRegistry(
Resource.Factory.Registry resourceFactoryRegistry) {
Map<String, Object> extensionToFactoryMap = resourceFactoryRegistry
.getExtensionToFactoryMap();
extensionToFactoryMap.put(UMLResource.FILE_EXTENSION,
UMLResource.Factory.INSTANCE);
Map<String, Object> contentTypeToFactoryMap = resourceFactoryRegistry
.getContentTypeToFactoryMap();
contentTypeToFactoryMap.put(UMLResource.UML_CONTENT_TYPE_IDENTIFIER,
UMLResource.Factory.INSTANCE);
return resourceFactoryRegistry;
}
/**
* Adds content-type handlers required for working with UML models to the
* specified registry.
*
* @param contentHandlerRegistry
* a content-type handler registry, perhaps local to a resource
* set or perhaps the global registry
*
* @return the same {@code contentHandlerRegistry}
*
* @since 5.0
*/
public static ContentHandler.Registry initContentHandlerRegistry(
ContentHandler.Registry contentHandlerRegistry) {
List<ContentHandler> contentHandlers = contentHandlerRegistry
.get(ContentHandler.Registry.LOW_PRIORITY);
if (contentHandlers == null
|| !contentHandlers.contains(XMI_CONTENT_HANDLER)) {
contentHandlerRegistry.put(ContentHandler.Registry.LOW_PRIORITY,
XMI_CONTENT_HANDLER);
}
contentHandlers = contentHandlerRegistry
.get(ContentHandler.Registry.NORMAL_PRIORITY);
if (contentHandlers == null) {
contentHandlerRegistry.put(ContentHandler.Registry.NORMAL_PRIORITY,
contentHandlers = new ArrayList<ContentHandler>());
}
if (!contentHandlers.contains(UML2_5_0_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_5_0_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(UML2_4_0_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_4_0_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(UML2_3_0_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_3_0_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(UML2_2_1_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_2_1_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(UML2_2_0_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_2_0_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(UML2_1_0_0_CONTENT_HANDLER)) {
contentHandlers.add(UML2_1_0_0_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_5_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_5_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_4_1_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_4_1_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_4_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_4_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_2_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_2_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_1_1_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_1_1_CONTENT_HANDLER);
}
if (!contentHandlers.contains(OMG_2_1_CONTENT_HANDLER)) {
contentHandlers.add(OMG_2_1_CONTENT_HANDLER);
}
if (!contentHandlers.contains(CMOF_2_5_CONTENT_HANDLER)) {
contentHandlers.add(CMOF_2_5_CONTENT_HANDLER);
}
if (!contentHandlers.contains(CMOF_2_4_1_CONTENT_HANDLER)) {
contentHandlers.add(CMOF_2_4_1_CONTENT_HANDLER);
}
if (!contentHandlers.contains(CMOF_2_4_CONTENT_HANDLER)) {
contentHandlers.add(CMOF_2_4_CONTENT_HANDLER);
}
if (!contentHandlers.contains(CMOF_2_0_CONTENT_HANDLER)) {
contentHandlers.add(CMOF_2_0_CONTENT_HANDLER);
}
return contentHandlerRegistry;
}
/**
* Adds resource URI mappings required for working with UML models to the
* specified map. These include at least mappings for the UML2-provided
* model libraries, metamodels, and profiles.
*
* @param uriMap
* a URI map, perhaps local to a resource set or perhaps the
* global URI map
*
* @return the same {@code uriMap}
*
* @since 5.0
*/
public static Map<URI, URI> initURIConverterURIMap(Map<URI, URI> uriMap) {
URI umlURI = getBaseUMLURI();
mapURIs(uriMap, "platform:/plugin/org.eclipse.uml2.uml/model/", //$NON-NLS-1$
umlURI.appendSegment("model"), "org.eclipse.uml2.uml"); //$NON-NLS-1$ //$NON-NLS-2$
URI umlResourcesURI = getBaseUMLResourcesURI();
mapURIs(uriMap, UMLResource.METAMODELS_PATHMAP,
umlResourcesURI.appendSegment("metamodels"), //$NON-NLS-1$
ResourcesPlugin.PLUGIN_ID);
mapURIs(uriMap, UMLResource.PROFILES_PATHMAP,
umlResourcesURI.appendSegment("profiles"), //$NON-NLS-1$
ResourcesPlugin.PLUGIN_ID);
mapURIs(uriMap, UMLResource.LIBRARIES_PATHMAP,
umlResourcesURI.appendSegment("libraries"), //$NON-NLS-1$
ResourcesPlugin.PLUGIN_ID);
return uriMap;
}
/**
* Adds profile namespace URI mappings required for working with UML models
* to the specified map. These include at least mappings for the
* UML2-provided profiles.
*
* @param ePackageNsURIToProfileLocationMap
* a profile location map, perhaps local to a resource set or
* perhaps the global location map
*
* @return the same {@code ePackageNsURIToProfileLocationMap}
*
* @since 5.0
*/
public static Map<String, URI> initEPackageNsURIToProfileLocationMap(
Map<String, URI> ePackageNsURIToProfileLocationMap) {
ePackageNsURIToProfileLocationMap.put(StandardPackage.eNS_URI,
URI.createURI("pathmap://UML_PROFILES/Standard.profile.uml#_0")); //$NON-NLS-1$
ePackageNsURIToProfileLocationMap.put(UMLResource.ECORE_PROFILE_NS_URI,
URI.createURI("pathmap://UML_PROFILES/Ecore.profile.uml#_0")); //$NON-NLS-1$
ePackageNsURIToProfileLocationMap.put(UMLResource.UML2_PROFILE_NS_URI,
URI.createURI("pathmap://UML_PROFILES/UML2.profile.uml#_0")); //$NON-NLS-1$
return ePackageNsURIToProfileLocationMap;
}
private static URI getBaseUMLURI() {
URL resultURL = UMLUtil.class.getClassLoader()
.getResource(String.format("model/%s", "UML.ecore")); //$NON-NLS-1$ //$NON-NLS-2$
URI result;
if (resultURL != null) {
// remove the /model/UML.ecore segments of the resource
// we found
result = URI.createURI(resultURL.toExternalForm(), true)
.trimSegments(2);
} else {
// probably, we're not running with JARs, so assume the source
// project folder layout
resultURL = UMLUtil.class.getResource("UMLUtil.class"); //$NON-NLS-1$
String baseURL = resultURL.toExternalForm();
int index = baseURL.lastIndexOf("/bin/"); //$NON-NLS-1$
if (index != -1) {
baseURL = baseURL.substring(0, index);
}
result = URI.createURI(baseURL, true);
}
return result;
}
private static URI getBaseUMLResourcesURI() {
URI umlMetamodel = URI.createURI(UMLResource.UML_METAMODEL_URI);
URL resultURL = UMLResourcesUtil.class.getClassLoader().getResource(
String.format("metamodels/%s", umlMetamodel.lastSegment())); //$NON-NLS-1$
URI result;
if (resultURL != null) {
// remove the /metamodel/UML.metamodel.uml segments of the resource
// we found
result = URI.createURI(resultURL.toExternalForm(), true)
.trimSegments(2);
} else {
// probably, we're not running with JARs, so assume the source
// project folder layout
resultURL = UMLResourcesUtil.class
.getResource("UMLResourcesUtil.class"); //$NON-NLS-1$
String baseURL = resultURL.toExternalForm();
int index = baseURL.lastIndexOf("/bin/"); //$NON-NLS-1$
if (index != -1) {
baseURL = baseURL.substring(0, index);
}
result = URI.createURI(baseURL, true);
}
return result;
}
private static void mapURIs(Map<URI, URI> uriMap, String uri, URI location,
String pluginID) {
URI prefix = URI.createURI(uri);
// ensure trailing separator (make it a "URI prefix")
if (!prefix.hasTrailingPathSeparator()) {
prefix = prefix.appendSegment(""); //$NON-NLS-1$
}
// same with the location
if (!location.hasTrailingPathSeparator()) {
location = location.appendSegment(""); //$NON-NLS-1$
}
uriMap.put(prefix, location);
// and platform URIs, too
String folder = location.segment(location.segmentCount() - 2);
String platformURI = String.format("%s/%s/", //$NON-NLS-1$
pluginID, folder);
uriMap.put(URI.createPlatformPluginURI(platformURI, true), location);
uriMap.put(URI.createPlatformResourceURI(platformURI, true), location);
}
}