| /******************************************************************************* |
| * Copyright (c) 2007 Borland Software Corporation |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Borland Software Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.m2m.internal.qvt.oml.emf.util; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| 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.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EcorePackage; |
| 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.ResourceImpl; |
| 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.m2m.internal.qvt.oml.emf.util.mmregistry.IMetamodelDesc; |
| import org.eclipse.m2m.internal.qvt.oml.emf.util.mmregistry.MetamodelRegistry; |
| import org.eclipse.osgi.util.NLS; |
| |
| |
| /** |
| * @author pkobiakov |
| */ |
| @SuppressWarnings("unchecked") |
| public class EmfUtil { |
| private EmfUtil() {} |
| |
| public static ModelContent loadModel(URI uri) { |
| return loadModel(uri, getDefaultLoadOptions(), null); |
| } |
| |
| public static ModelContent loadModel(URI uri, ResourceSet rs) { |
| return loadModel(uri, getDefaultLoadOptions(), rs); |
| } |
| |
| public static ModelContent loadModel(URI uri, Map options, ResourceSet rs) { |
| if(uri == null) { |
| return null; |
| } |
| ResourceSet resourceSet = (rs != null) ? rs : createResourceSet(options); |
| 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 || resource.getContents().isEmpty()) { |
| return null; |
| } |
| return new ModelContent(resource.getContents()); |
| } |
| |
| public static ModelContent safeLoadModel(URI uri, ResourceSet rs) { |
| return safeLoadModel(uri, getDefaultLoadOptions(), rs); |
| } |
| |
| public static ModelContent safeLoadModel(URI uri, Map options, ResourceSet rs) { |
| try { |
| return loadModel(uri, options, rs); |
| } |
| catch(Exception e){ |
| return null; |
| } |
| } |
| |
| public static Resource loadResource(URI uri) { |
| return loadResource(uri, getDefaultLoadOptions()); |
| } |
| |
| public static Resource loadResource(URI uri, Map options) { |
| return createResourceSet(options).getResource(uri, true); |
| } |
| |
| private static ResourceSet createResourceSet(Map options) { |
| ResourceSet resourceSet = new ResourceSetImpl() { |
| |
| @Override |
| protected Resource delegatedGetResource(URI uri, boolean loadOnDemand) { |
| Resource resource = super.delegatedGetResource(uri, loadOnDemand); |
| if (resource == null) { |
| URI trimmedURI = uri.trimFragment(); |
| try { |
| IMetamodelDesc descriptor = MetamodelRegistry.getInstance().getMetamodelDesc(trimmedURI.toString()); |
| EPackage ePackage = descriptor.getModel(); |
| resource = ePackage.eResource(); |
| if (resource == null) { |
| resource = new ResourceImpl(trimmedURI); |
| resource.getContents().add(ePackage); |
| } |
| } catch (EmfException e) { |
| // ignore |
| } |
| } |
| return resource; |
| } |
| |
| }; |
| resourceSet.getLoadOptions().putAll(options); |
| return resourceSet; |
| } |
| |
| public static EObject resolveSource(EObject in, EObject inputType) { |
| if (inputType == null || inputType.eResource() == null) { |
| return in; |
| } |
| if (EmfUtil.isDynamic(in)) { |
| ResourceSet inRS = in.eResource() != null ? in.eResource().getResourceSet() : null; |
| if (inputType.eResource().getResourceSet() != inRS |
| && inputType.eResource().getResourceSet() != null) { |
| URI uri = EcoreUtil.getURI(in); |
| if (uri != null && !"#//".equals(uri.toString())) { //$NON-NLS-1$ |
| return inputType.eResource().getResourceSet().getEObject(uri, true); |
| } |
| } |
| } |
| return in; |
| } |
| |
| public static boolean isUriExisted(String textUri, ResourceSet rs) { |
| URI destUri = makeUri(textUri); |
| if (destUri != null) { |
| ModelContent loadModel = null; |
| try { |
| loadModel = loadModel(destUri, rs); |
| } |
| catch (Exception e) { |
| } |
| if (loadModel != null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private static boolean isDynamic(EObject eObject) { |
| return eObject instanceof EStructuralFeature.Internal.DynamicValueHolder; |
| } |
| |
| |
| public static void saveModel(EObject eObject, URI uri, Map opts) throws EmfException { |
| ResourceSet resourceSet = getOutputResourceSet(); |
| |
| Resource resource = resourceSet.createResource(uri); |
| resource.getContents().add(eObject); |
| |
| Map options = new HashMap(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, URI uri, Map opts) throws EmfException { |
| modelExtent.setURI(uri); |
| |
| Map options = new HashMap(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, uri), 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, "::"); //$NON-NLS-1$ |
| } |
| |
| public 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, "::"); //$NON-NLS-1$ |
| } |
| |
| public 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) { |
| String delim = "::"; //$NON-NLS-1$ |
| 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, delim); |
| } |
| buf.insert(0, nextPackage.getName()); |
| |
| nextPackage = nextPackage.getESuperPackage(); |
| } |
| |
| return getFullNameRelativeToPackage(ePackage.getESuperPackage(), baseQwningPackage) + delim + 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 + "::" + eClassifier.getName(); //$NON-NLS-1$ |
| } |
| return eClassifier.getName(); |
| } |
| |
| public static String getMetamodelName(EPackage pack) { |
| String name = pack.getName(); |
| String nsURI = pack.getNsURI(); |
| if (nsURI != null && nsURI.length() > 0) { |
| name += " (" + nsURI + ")"; //$NON-NLS-1$//$NON-NLS-2$ |
| } |
| return name; |
| } |
| |
| 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; |
| } |
| |
| public 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++) { |
| List subPackages = root.getESubpackages(); |
| for (Iterator it = subPackages.iterator(); it.hasNext();) { |
| EPackage pack = (EPackage) it.next(); |
| 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 getDefaultLoadOptions() { |
| Map options = new HashMap(); |
| // create new session to avoid problems with parallel filling of containments lists (#31662, etc.) |
| return options; |
| } |
| |
| public static String getFileNameForResult(String moduleName, EClass cls) { |
| return moduleName + "." + getExtensionForResult(cls); //$NON-NLS-1$ |
| } |
| |
| public static String getExtensionForResult(final EClassifier cls) { |
| if(cls == null) { |
| return XMIResource.XMI_NS; |
| } |
| |
| EPackage root = EmfUtil.getRootPackage(cls.getEPackage()); |
| return root.getName(); |
| } |
| |
| 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 isContainmentReference(EStructuralFeature feature) { |
| if (feature.eClass() == EcorePackage.eINSTANCE.getEReference()) { |
| EReference ref = (EReference) feature; |
| return ref.isContainment(); |
| } |
| |
| return false; |
| } |
| |
| public static final 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 final Map DEFAULT_SAVE_OPTIONS = new HashMap(); |
| static { |
| DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$ |
| } |
| } |