/******************************************************************************* * Copyright (c) 2013 INRIA. * 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: * Cau� Clasen - initial API and implementation *******************************************************************************/ package fr.inria.atlanmod.emfviews.core; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; 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.resource.Resource; import fr.inria.atlanmod.emfviews.elements.MergeElementImpl; import fr.inria.atlanmod.emfviews.elements.ReproduceElementImpl; public class MetamodelManager { private Resource compositionMetamodel; private List<EPackage> contributingMetamodels = new ArrayList<EPackage>(); private Map<String, EClass> mergeClassesByName = new HashMap<String, EClass>(); private Map<EStructuralFeature, EStructuralFeature> virtualToConcreteFeature = new HashMap<EStructuralFeature, EStructuralFeature>(); private Map<EStructuralFeature, EStructuralFeature> concreteToVirtualFeature = new HashMap<EStructuralFeature, EStructuralFeature>(); private Map<EStructuralFeature, EStructuralFeature> concreteToMergedFeature = new HashMap<EStructuralFeature, EStructuralFeature>(); private Map<String, List<EStructuralFeature>> virtualAssociations = new HashMap<String, List<EStructuralFeature>>(); private Map<EClass, EClass> concreteToVirtualClass = new HashMap<EClass, EClass>(); private View virtualModel; public MetamodelManager(Collection<Object> contributingMetamodels, Resource compositionMetamodel, View virtualModel) { this.virtualModel = virtualModel; this.compositionMetamodel = compositionMetamodel; this.contributingMetamodels = new ArrayList<>(); for (Object object : contributingMetamodels) { if (object instanceof EPackage) { EPackage tp = (EPackage) object; this.contributingMetamodels.add(tp); } } this.buildMaps(); } private Map<String, List<EClass>> produceCompositionClasses() { Map<String, List<EClass>> compositionClassesByName = new HashMap<String, List<EClass>>(); if (virtualModel != null && virtualModel.getResourceSet() != null && virtualModel.getResourceSet().getPackageRegistry() != null && virtualModel.getResourceSet().getPackageRegistry().values() != null && virtualModel.getResourceSet().getPackageRegistry().values() .size() > 0) { Collection<Object> listOfVirtualMMPackages = virtualModel .getResourceSet().getPackageRegistry().values(); ArrayList<EPackage> packs = new ArrayList<>(); for (Object object : listOfVirtualMMPackages) { if (object instanceof EPackage) { EPackage tempPack = (EPackage) object; if (tempPack.getName().compareToIgnoreCase("ecore") != 0) { packs.add(tempPack); } } } ArrayList<EClassifier> classifiers = new ArrayList(); for (EPackage tempPack : packs) { classifiers.addAll(tempPack.getEClassifiers()); } for (EClassifier obj : classifiers) { if (obj instanceof EClass) { if (((EClass) obj).getEPackage().getName() .equals("MergePackage")) { mergeClassesByName.put(((EClass) obj).getName(), (EClass) obj); } else { if (compositionClassesByName.get(((EClass) obj) .getName()) == null) { List<EClass> ecs = new ArrayList<EClass>(); ecs.add((EClass) obj); compositionClassesByName.put( ((EClass) obj).getName(), ecs); } else { compositionClassesByName.get( ((EClass) obj).getName()).add((EClass) obj); } } } } } else { for (Iterator<EObject> i = compositionMetamodel.getAllContents(); i .hasNext();) { EObject obj = i.next(); if (obj instanceof EClass) { if (((EClass) obj).getEPackage().getName() .equals("MergePackage")) { mergeClassesByName.put(((EClass) obj).getName(), (EClass) obj); } else { if (compositionClassesByName.get(((EClass) obj) .getName()) == null) { List<EClass> ecs = new ArrayList<EClass>(); ecs.add((EClass) obj); compositionClassesByName.put( ((EClass) obj).getName(), ecs); } else { compositionClassesByName.get( ((EClass) obj).getName()).add((EClass) obj); } } } } } return compositionClassesByName; } private void buildMaps() { Map<String, List<EClass>> contributingClassesByName = new HashMap<String, List<EClass>>(); Map<String, List<EClass>> compositionClassesByName = null; compositionClassesByName = produceCompositionClasses(); for (EPackage metamodel : contributingMetamodels) { for (EClassifier obj : metamodel.getEClassifiers()) { if (obj instanceof EClass) { if (contributingClassesByName.get(((EClass) obj).getName()) == null) { List<EClass> ecs = new ArrayList<EClass>(); ecs.add((EClass) obj); contributingClassesByName.put(((EClass) obj).getName(), ecs); } else { contributingClassesByName.get(((EClass) obj).getName()) .add((EClass) obj); } } } } for (List<EClass> lcec : contributingClassesByName.values()) { if (lcec.size() > 1) { for (EClass cec : lcec) { List<EClass> lvec = compositionClassesByName.get(cec .getName()); for (EClass vec : lvec) { if (vec.getEPackage().getNsURI() .equals(cec.getEPackage().getNsURI())) { this.concreteToVirtualClass.put(cec, vec); mapFeatures(cec, vec); } } } } else { EClass cec = lcec.get(0); EClass vec = compositionClassesByName.get(cec.getName()).get(0); this.concreteToVirtualClass.put(cec, vec); mapFeatures(cec, vec); } } for (List<EClass> lec : compositionClassesByName.values()) { for (EClass ec : lec) { if (ec.getName().equalsIgnoreCase("laneset")) { } for (EStructuralFeature sf : ec.getEStructuralFeatures()) { if (virtualToConcreteFeature.get(sf) == null) if (virtualAssociations.get(sf.getName()) == null) { List<EStructuralFeature> sfs = new ArrayList<EStructuralFeature>(); sfs.add(sf); virtualAssociations.put(sf.getName(), sfs); } else { virtualAssociations.get(sf.getName()).add(sf); } } } } } private void mapFeatures(EClass concEC, EClass virtuEC) { for (EStructuralFeature feature : concEC.getEStructuralFeatures()) { EStructuralFeature vf = virtuEC.getEStructuralFeature(feature .getName()); if (vf != null) { this.virtualToConcreteFeature.put(vf, feature); this.concreteToVirtualFeature.put(feature, vf); } } } public EStructuralFeature translateToVirtualFeature(EObject object, EStructuralFeature feature) { if (object instanceof ReproduceElementImpl) return this.concreteToVirtualFeature.get(feature); else if (object instanceof MergeElementImpl) { if (this.concreteToMergedFeature.get(feature) == null) { return this.concreteToVirtualFeature.get(feature); } else { return this.concreteToMergedFeature.get(feature); } } return null; } public EStructuralFeature translateFromVirtualFeature(EObject object, EStructuralFeature feature) { if (object instanceof ReproduceElementImpl) return this.virtualToConcreteFeature.get(feature); else if (object instanceof MergeElementImpl) throw new ViewOperationException( "could not translate feature for merged element"); return null; } public EClass translateToVirtualEClass(EClass eClass) { return this.concreteToVirtualClass.get(eClass); } public EStructuralFeature getVirtualAssociation(EObject object, String name) { List<EStructuralFeature> sfs = virtualAssociations.get(name); for (EStructuralFeature sf : sfs) { if (object.eClass().getEAllStructuralFeatures().contains(sf)) { return sf; } } throw new ViewOperationException("could not find virtual association"); } public boolean isVirtualAssociation(EStructuralFeature feature) { List<EStructuralFeature> sfs = virtualAssociations.get(feature .getName()); if (sfs == null) return false; else return sfs.contains(feature); } }