package de.uniAugsburg.MAF.dfa.jwt.adapter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import org.eclipse.jwt.meta.model.core.Model;
import de.uniAugsburg.MAF.core.adapter.model.ResourceModelAdapter;
import de.uniAugsburg.MAF.core.util.model.EMFDynamicUtils;
import de.uniAugsburg.MAF.core.util.model.TargetMetamodelCopier;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.JWTConstants;
/**
* This adapter load JWT models and replaces linked activities
* (ActivityLinkNode) through embedded activities.
*/
public class JWTModelAdapter extends ResourceModelAdapter {
/**
* The constructor.
*
* @param modelSources
* @param modelID
* @param metamodelID
*/
public JWTModelAdapter(Map<URI, Object> modelSources, String modelID,
String metamodelID) {
super(modelSources, modelID, metamodelID);
}
/*
* (non-Javadoc)
*
* @see de.uniAugsburg.MAF.core.adapter.emfresource.ResourceModelAdapter#
* loadIntoEMFResource(java.util.Map,
* org.eclipse.emf.ecore.resource.Resource, java.util.Map, java.lang.Object)
*/
@Override
protected void loadIntoEMFResource(Map<Integer, EClass> metaModelClassMap,
Resource targetResource, Map<EObject, Object> targetTraceMap,
Object source) throws Exception {
// ignore all model resources except workflows files
if (!(((Resource) source).getContents().get(0) instanceof Model))
return;
// find SAN eclass
EClass classSAN = null;
for (EClass eclass : metaModelClassMap.values())
if (eclass.getName().equals(JWTConstants.EC_SAN)) {
classSAN = eclass;
break;
}
// copy model resource
Copier copier = new TargetMetamodelCopier(metaModelClassMap);
Collection<EObject> originalResourceContents = ((Resource) source)
.getContents();
Collection<EObject> copiedResourceContents = copier
.copyAll(originalResourceContents);
copier.copyReferences();
// trace elements and collect activities
Map<EObject, EObject> activityOrigToCopyMap = new HashMap<EObject, EObject>();
for (Entry<EObject, EObject> entry : copier.entrySet()) {
EObject originalEObject = entry.getKey();
EObject copiedEObject = entry.getValue();
if (copiedEObject.eClass().getName()
.equals(JWTConstants.EC_ACTIVITY))
activityOrigToCopyMap.put(originalEObject, copiedEObject);
targetTraceMap.put(copiedEObject, originalEObject);
}
// "flatten" activities by replacing ALN with SAN
for (Entry<EObject, EObject> activityEntry : activityOrigToCopyMap
.entrySet())
flattenScope(metaModelClassMap, targetTraceMap,
activityOrigToCopyMap, activityEntry.getValue(), classSAN);
// add the copy to the result resource
targetResource.getContents().addAll(copiedResourceContents);
}
/**
* Flatten scopes so they are completely available as embedded activities.
*
* @param metaModelClassMap
* @param targetTraceMap
* @param originalEObject
* @param copiedEObject
*/
private void flattenScope(Map<Integer, EClass> metaModelClassMap,
Map<EObject, Object> targetTraceMap,
Map<EObject, EObject> activityOrigToCopyMap, EObject copiedScope,
EClass classSAN) {
// 1. find all ALN in contents of copied activity and remove ALN from
// trace
Map<EObject, EObject> ALNsCopyToOrigMap = new HashMap<EObject, EObject>();
for (Iterator<EObject> iter = copiedScope.eAllContents(); iter
.hasNext();) {
EObject eObject = (EObject) iter.next();
if (eObject.eClass().getName().equals(JWTConstants.EC_ALN)) {
ALNsCopyToOrigMap.put(eObject,
(EObject) targetTraceMap.get(eObject));
targetTraceMap.remove(eObject);
}
}
// 2. substitute ALNs with SANs
Map<EObject, EObject> copySANreplacedOrigALNMap = new HashMap<EObject, EObject>();
for (Entry<EObject, EObject> ALNtoReplace : ALNsCopyToOrigMap
.entrySet()) {
EObject copyALNtoReplace = ALNtoReplace.getKey();
EObject origALNtoReplace = ALNtoReplace.getValue();
EObject copyScope = copyALNtoReplace.eContainer();
// remove ALN from its container scope
EMFDynamicUtils.getEReferenceValues(copyScope, "nodes").remove(
copyALNtoReplace);
// create and add SAN as replacement
EObject copyNewSAN = classSAN.getEPackage().getEFactoryInstance()
.create(classSAN);
((EObjectImpl) copyNewSAN).eSetClass(classSAN);
EMFDynamicUtils.getEReferenceValues(copyScope, "nodes").add(
copyNewSAN);
// set name
String copyNewSANName = EMFDynamicUtils.getEAttributeValue(
origALNtoReplace, "name") != null ? EMFDynamicUtils
.getEAttributeValue(origALNtoReplace, "name").toString()
: "";
EMFDynamicUtils.setEAttributeValue(copyNewSAN, "name", "[REPLACED]"
+ copyNewSANName);
// move input/output edges
EMFDynamicUtils.getEReferenceValues(copyNewSAN, "in")
.addAll(EMFDynamicUtils.getEReferenceValues(
copyALNtoReplace, "in"));
EMFDynamicUtils.getEReferenceValues(copyNewSAN, "out").addAll(
EMFDynamicUtils
.getEReferenceValues(copyALNtoReplace, "out"));
EMFDynamicUtils.getEReferenceValues(copyALNtoReplace, "in").clear();
EMFDynamicUtils.getEReferenceValues(copyALNtoReplace, "out")
.clear();
copySANreplacedOrigALNMap.put(copyNewSAN, origALNtoReplace);
}
// 3. store new SANs in tracemap with link to original ALNs
targetTraceMap.putAll(copySANreplacedOrigALNMap);
// 4. copy substructure of replaced ALNs
for (Entry<EObject, EObject> copySANreplacedOrigALN : copySANreplacedOrigALNMap
.entrySet()) {
EObject copyNewSAN = copySANreplacedOrigALN.getKey();
EObject origALN = copySANreplacedOrigALN.getValue();
// ignore if no linked activity
EObject linkedActivityOrig = EMFDynamicUtils.getEReferenceValue(
origALN, "linksto");
if (linkedActivityOrig == null) {
continue;
}
// create a copy of the copy of the linked activity (to make sure
// that its references are consistent with the elements in the copy)
EObject linkedActivityCopy = activityOrigToCopyMap
.get(linkedActivityOrig);
Copier copier = new TargetMetamodelCopier(metaModelClassMap);
EObject copyCopyActivity = copier.copy(linkedActivityCopy);
copier.copyReferences();
// move the contents into the new SAN in the copy
EMFDynamicUtils.getEReferenceValues(copyNewSAN, "nodes").addAll(
EMFDynamicUtils.getEReferenceValues(copyCopyActivity,
"nodes"));
EMFDynamicUtils.getEReferenceValues(copyNewSAN, "edges").addAll(
EMFDynamicUtils.getEReferenceValues(copyCopyActivity,
"edges"));
EMFDynamicUtils.getEReferenceValues(copyCopyActivity, "nodes")
.clear();
EMFDynamicUtils.getEReferenceValues(copyCopyActivity, "edges")
.clear();
// trace substructure
for (Entry<EObject, EObject> entry : copier.entrySet()) {
EObject copyObject = entry.getKey();
EObject copyCopyObject = entry.getValue();
if (copyCopyObject != copyCopyActivity) {
targetTraceMap.put(copyCopyObject,
targetTraceMap.get(copyObject));
}
}
}
// 5. recursively replace ALNs in newly created SANs
for (Entry<EObject, EObject> copySANreplacedOrigALN : copySANreplacedOrigALNMap
.entrySet()) {
EObject copyNewSAN = copySANreplacedOrigALN.getKey();
flattenScope(metaModelClassMap, targetTraceMap,
activityOrigToCopyMap, copyNewSAN, classSAN);
}
}
}
|