blob: 1c4f8afebe98871589891c934fa90dc98a7d4f84 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2018 Borland Software Corporation 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:
* Borland Software Corporation - initial API and implementation
* Christopher Gerking - bugs 428620, 537041
* Ed Willink - bug 533564
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.emf.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
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.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.osgi.util.NLS;
/**
* @author pkobiakov
*/
public class EmfUtil {
private EmfUtil() {}
public static final String PATH_SEPARATOR = "::"; //$NON-NLS-1$
public static ModelContent loadModel(URI uri) {
return loadModel(uri, getDefaultLoadOptions(), null);
}
public static ModelContent loadModel(URI uri, ResourceSet rs) {
return loadModel(uri, getDefaultLoadOptions(), rs);
}
private static ModelContent loadModel(URI uri, Map<Object, Object> options, ResourceSet rs) {
if(uri == null) {
return null;
}
ResourceSet resourceSet = (rs != null) ? rs : createResourceSet(options);
Map<URI, URI> uriMap = resourceSet.getURIConverter().getURIMap();
Map<URI, URI> platformURIMap = EcorePlugin.computePlatformURIMap(true);
uriMap.putAll(platformURIMap);
String fragment = uri.fragment();
if (fragment != null && fragment.length() > 0) {
EObject eObject = resourceSet.getEObject(uri, true);
if (eObject == null) {
return null;
}
return new ModelContent(Collections.singletonList(eObject));
}
Resource resource = resourceSet.getResource(uri.trimFragment(), true);
if (resource == null) {
return null;
}
return new ModelContent(resource.getContents());
}
public static ModelContent safeLoadModel(URI uri, ResourceSet rs) {
return safeLoadModel(uri, getDefaultLoadOptions(), rs);
}
private static ModelContent safeLoadModel(URI uri, Map<Object, Object> options, ResourceSet rs) {
try {
return loadModel(uri, options, rs);
}
catch(Exception e){
return null;
}
}
public static Resource loadResource(URI uri) {
return createResourceSet(getDefaultLoadOptions()).getResource(uri, true);
}
private static ResourceSet createResourceSet(Map<Object, Object> options) {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getLoadOptions().putAll(options);
return resourceSet;
}
public static EObject resolveSource(EObject in, EObject inputType) {
if (inputType == null || inputType.eResource() == null) {
return in;
}
return resolveSource(in, inputType.eResource().getResourceSet());
}
public static EObject resolveSource(EObject in, ResourceSet rs) {
if (rs != null && EmfUtil.isDynamic(in)) {
ResourceSet inRS = in.eResource() != null ? in.eResource().getResourceSet() : null;
if (rs != inRS) {
URI uri = EcoreUtil.getURI(in);
if (uri != null && !"#//".equals(uri.toString())) { //$NON-NLS-1$
return rs.getEObject(uri, true);
}
}
}
return in;
}
public static Set<EObject> getResolvedContent(Collection<EObject> content, EObject metamodel) {
ResourceSet rs = (metamodel != null && metamodel.eResource() != null ? metamodel.eResource().getResourceSet() : null);
return getResolvedContent(content, rs);
}
public static Set<EObject> getResolvedContent(Collection<EObject> content, ResourceSet rs) {
Set<EObject> resolvedObjs = new LinkedHashSet<EObject>(content.size());
for (EObject obj : content) {
EObject resolved = null;
try {
resolved = resolveSource(obj, rs);
}
catch (Exception ex) {
}
resolvedObjs.add(resolved != null ? resolved : obj);
}
return resolvedObjs;
}
public static boolean isUriExistsAsEObject(URI uri, ResourceSet rs, boolean validateNonEmpty) {
ModelContent loadModel = null;
try {
loadModel = loadModel(uri, rs);
}
catch (Exception e) {
}
if (loadModel == null) {
return false;
}
return validateNonEmpty ? !loadModel.getContent().isEmpty() : true;
}
public static boolean isDynamic(EObject eObject) {
return eObject instanceof EStructuralFeature.Internal.DynamicValueHolder;
}
public static void saveModel(EObject eObject, URI uri, Map<Object, Object> opts) throws EmfException {
ResourceSet resourceSet = getOutputResourceSet();
Resource resource = resourceSet.createResource(uri);
resource.getContents().add(eObject);
Map<Object, Object> options = new HashMap<Object, Object>(opts);
options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
if(isDynamic(eObject)) {
options.put("SCHEMA_LOCATION", Boolean.TRUE); //$NON-NLS-1$
}
try {
resource.save(options);
} catch (Exception e) {
throw new EmfException(NLS.bind(Messages.EmfUtil_1, uri), e);
}
}
public static void saveModel(Resource modelExtent, Map<Object, Object> opts) throws EmfException {
Map<Object, Object> options = new HashMap<Object, Object>(opts);
options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
options.put(XMIResource.OPTION_PROCESS_DANGLING_HREF, XMIResource.OPTION_PROCESS_DANGLING_HREF_DISCARD);
for (EObject eObject : modelExtent.getContents()) {
if(isDynamic(eObject)) {
options.put("SCHEMA_LOCATION", Boolean.TRUE); //$NON-NLS-1$
break;
}
}
try {
modelExtent.save(options);
} catch (Exception e) {
throw new EmfException(NLS.bind(Messages.EmfUtil_1, modelExtent.getURI()), e);
}
}
public static ResourceSet getOutputResourceSet() {
return new ResourceSetImpl();
}
public static EPackage getRootPackage(EPackage pack) {
EPackage parent = pack.getESuperPackage();
if(parent == null) {
return pack;
}
else {
return getRootPackage(parent);
}
}
public static String getFullName(EClassifier cls) {
return getFullName(cls, PATH_SEPARATOR);
}
private static String getFullName(EClassifier cls, String delim) {
if(cls.getEPackage() == null) {
return cls.getName();
}
return getFullName(cls.getEPackage(), delim) + delim + cls.getName();
}
public static String getFullName(EPackage pack) {
return getFullName(pack, PATH_SEPARATOR);
}
private static String getFullName(EPackage pack, String delim) {
if(pack.getESuperPackage() != null) {
return getFullName(pack.getESuperPackage(), delim) + delim + pack.getName();
} else {
return pack.getName();
}
}
/**
* Get the given package full name relative to the specified owning package
*
* @param ePackage
* the package of which to retrieve the full name
* @param baseOwningPackage
* the package representing the root context for relative name
* resolution.
* <p>
* This package and its possible super-packages will be excluded
* from the full-name. If it is the immediate owning package of
* the <code>ePackage</code>, the local name of <code>ePackage</code> is
* returned.
*/
public static String getFullNameRelativeToPackage(EPackage ePackage, EPackage baseQwningPackage) {
if(ePackage.getESuperPackage() != null && ePackage.getESuperPackage() != baseQwningPackage) {
StringBuilder buf = new StringBuilder();
EPackage nextPackage = ePackage;
for(int i = 0; nextPackage != null && nextPackage != baseQwningPackage ; i++) {
if(i > 0) {
buf.insert(0, PATH_SEPARATOR);
}
buf.insert(0, nextPackage.getName());
nextPackage = nextPackage.getESuperPackage();
}
return getFullNameRelativeToPackage(ePackage.getESuperPackage(), baseQwningPackage) + PATH_SEPARATOR + ePackage.getName();
} else {
return ePackage.getName();
}
}
/**
* Get the given classifier's full name relative to the specified owning package
*
* @param eClassifier
* the classifier of which to retrieve name
* @param baseOwningPackage
* the package representing the root context for relative name
* resolution.
* <p>
* This package and its possible super-packages will be excluded
* from the full-name. If it is the immediate owning package of
* the given classifier, the local name of the classifier is
* returned.
*/
public static String getFullNameRelativeToPackage(EClassifier eClassifier, EPackage baseOwningPackage) {
EPackage immediateOwner = eClassifier.getEPackage();
if(baseOwningPackage != null && immediateOwner != null && baseOwningPackage != immediateOwner) {
String parentName = EmfUtil.getFullNameRelativeToPackage(immediateOwner, baseOwningPackage);
return parentName + PATH_SEPARATOR + eClassifier.getName();
}
return eClassifier.getName();
}
public static EClass getEClass(EPackage root, String[] fullName) throws EmfException {
EClassifier classifier = getEClassifier(root, fullName);
if(classifier instanceof EClass == false) {
throw new EmfException(NLS.bind(Messages.EmfUtil_6, fullName[fullName.length-1]));
}
return (EClass)classifier;
}
private static EClassifier getEClassifier(EPackage root, String[] fullName) throws EmfException {
if(fullName.length < 2) {
throw new EmfException(NLS.bind(Messages.EmfUtil_2, Arrays.asList(fullName)));
}
String rootPackName = fullName[0];
if(!rootPackName.equals(root.getName())) {
throw new EmfException(NLS.bind(Messages.EmfUtil_3, rootPackName, root.getName()));
}
MAIN:
for(int i = 1; i < fullName.length-1; i++) {
for (EPackage pack : root.getESubpackages()) {
if(fullName[i].equals(pack.getName())) {
root = pack;
continue MAIN;
}
}
throw new EmfException(NLS.bind(Messages.EmfUtil_5, fullName[i]));
}
EClassifier classifier = root.getEClassifier(fullName[fullName.length-1]);
return classifier;
}
public static URI makeUri(String uriString) {
if(uriString == null || uriString.length() == 0) {
return null;
}
URI uri = null;
try {
uri = URI.createURI(uriString);
}
catch (Exception e) {
return null;
}
return uri;
}
public static String getRootPackageUri(EClassifier cls) {
String uri = cls == null ? null : getRootPackage(cls.getEPackage()).getNsURI();
return uri;
}
public static boolean isAssignableFrom(EClassifier type, EClassifier from) {
if (type == from) {
return true;
}
if (false == from instanceof EClass) {
return false;
}
return ((EClass) from).getEAllSuperTypes().contains(type);
}
public static Map<Object, Object> getDefaultLoadOptions() {
Map<Object, Object> options = new HashMap<Object, Object>();
// create new session to avoid problems with parallel filling of containments lists (#31662, etc.)
return options;
}
public static Resource createResource(URI uri, ResourceSet outResourceSet) {
Resource resource = outResourceSet.createResource(uri);
if(resource != null) {
return resource;
}
Object possibleFactory = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().get(uri.fileExtension());
Resource.Factory factory = null;
if (possibleFactory instanceof Resource.Factory) {
factory = (Resource.Factory) possibleFactory;
}
if (possibleFactory instanceof Resource.Factory.Descriptor) {
factory = ((Resource.Factory.Descriptor) possibleFactory).createFactory();
}
if(factory == null) {
factory = new XMIResourceFactoryImpl();
}
return factory.createResource(uri);
}
public static boolean isUriMapped(ResourceSet resourceSet, URI uri) {
if (uri != null) {
URIConverter converter = resourceSet.getURIConverter();
if (converter != null) {
Map<URI, URI> uriMap = converter.getURIMap();
if (uriMap != null) {
return uriMap.containsKey(uri);
}
}
}
return false;
}
public static void cleanupResourceSet(ResourceSet rs) {
URI uri = URI.createURI(""); //$NON-NLS-1$
List<Resource> resCopy = new ArrayList<Resource>(rs.getResources());
for (Resource res : resCopy) {
if (res.eAdapters().contains(RESOURCE_PERSISTED_ADAPTER)) {
continue;
}
// for (TreeIterator<EObject> it = res.getAllContents(); it.hasNext();) {
// EObject eObject = it.next();
// eObject.eAdapters().clear();
// }
// res.getContents().clear();
// res.eAdapters().clear();
if (res.isLoaded()) {
for (TreeIterator<EObject> it = res.getAllContents(); it.hasNext();) {
EObject eObject = it.next();
((InternalEObject) eObject).eSetProxyURI(uri);
}
res.unload();
}
}
rs.getResources().clear();
rs.eAdapters().clear();
}
public static boolean isUriExists(URI uri, ResourceSet rs, boolean validateNonEmpty) {
URIConverter uriConverter = (rs != null ? rs.getURIConverter() : URIConverter.INSTANCE);
if (uriConverter.exists(uri, Collections.emptyMap())) {
return true;
}
return isUriExistsAsEObject(uri, rs, validateNonEmpty);
}
public static EPackage getFirstEPackageContent(Resource resource) {
for (EObject content : resource.getContents()) {
if (content instanceof EPackage) {
return (EPackage) content;
}
}
return null;
}
public static final Adapter RESOURCE_PERSISTED_ADAPTER = new AdapterImpl();
public static final Map<Object, Object> DEFAULT_SAVE_OPTIONS = new HashMap<Object, Object>();
static {
DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
}
}