| /******************************************************************************* |
| * 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$ |
| } |
| |
| } |