package com.sap.ap.cts.monet.deepcopy;
import java.util.Collection;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import com.sap.ide.cts.editor.deepcopy.DeepCopyHelper;
import com.sap.ide.cts.editor.deepcopy.GenericModelCopyStrategy;
import com.sap.ide.cts.editor.junitcreate.DocumentHistory;
import data.classes.AssociationEndSignatureImplementation;
import data.classes.SapClass;
/**
* A Runlet / NGPM metamodel specific policy handler. Used for deep copying in
* {@link DocumentHistory} and by ModelClipboard when performing drag&drop and
* copy&paste operations.
*
* @author D049157
*/
public class RunletModelCopyStrategy extends GenericModelCopyStrategy {
private static final String COPY_POSTFIX = "Cpy0";
private Boolean hasAssocEndConnectedToAssocEndSignImpl(EObject sourceElement, DeepCopyMap copyMap) {
ResourceSet co = sourceElement.get___Connection();
if (sourceElement instanceof data.classes.AssociationEnd) {
Collection<EObject> linkedElements = DeepCopyHelper.getAllLinkedElements(co, sourceElement);
for (EObject linkedElement : linkedElements) {
if (linkedElement instanceof AssociationEndSignatureImplementation
&& copyMap.containsKey(linkedElement)
&& copyMap.get(linkedElement).getModifiedPolicy().getDeepCopyPolicyOption() == DeepCopyPolicyOption.FULL_COPY) {
return true;
}
}
}
return false;
}
private Boolean hasAssocConnectedToAssocEnd(EObject sourceElement, DeepCopyMap copyMap) {
ResourceSet co = sourceElement.get___Connection();
if (sourceElement instanceof data.classes.Association) {
Collection<EObject> childElements = DeepCopyHelper.getCompositeChildrenImmediate(co, sourceElement);
for (EObject childElement : childElements) {
if (childElement instanceof data.classes.AssociationEnd
&& copyMap.containsKey(childElement)
&& copyMap.get(childElement).getModifiedPolicy().getDeepCopyPolicyOption() == DeepCopyPolicyOption.FULL_COPY) {
return true;
}
}
}
return false;
}
private Boolean hasAssocConnectedToClassTypeDef(EObject sourceElement, DeepCopyMap copyMap) {
ResourceSet co = sourceElement.get___Connection();
if (sourceElement instanceof data.classes.Association) {
Collection<EObject> childElements = DeepCopyHelper.getCompositeChildrenImmediate(co, sourceElement);
for (EObject childElement : childElements) {
if (childElement instanceof data.classes.ClassTypeDefinition
&& copyMap.containsKey(childElement)
&& copyMap.get(childElement).getModifiedPolicy().getDeepCopyPolicyOption() == DeepCopyPolicyOption.FULL_COPY) {
}
}
}
return false;
}
@Override
protected DeepCopyPolicy getMetaModelSpecificMapping(EObject sourceElement, DeepCopyMap copyMap) {
if (hasAssocEndConnectedToAssocEndSignImpl(sourceElement, copyMap)) {
// System.out.println("altering to FULL for: AssocEnd via AssocEndSignImpl");
return new DeepCopyPolicy(DeepCopyPolicyOption.FULL_COPY, null);
}
if (hasAssocConnectedToClassTypeDef(sourceElement, copyMap)) {
// System.out.println("altering to FULL for: Assoc via ClassTypeDef");
return new DeepCopyPolicy(DeepCopyPolicyOption.FULL_COPY, null);
}
if (hasAssocConnectedToAssocEnd(sourceElement, copyMap)) {
// System.out.println("altering to FULL for: Assoc via EndAssoc");
return new DeepCopyPolicy(DeepCopyPolicyOption.FULL_COPY, null);
}
return null;
}
@Override
public Boolean prepareLinkingToCompositeParent(String identifier, RefBaseObject source, RefBaseObject copy) {
// Create a new, unique name with the same length as the original
// class name. Otherwise all indices of logged activities would
// need to be adapted.
if (copy instanceof SapClass) {
SapClass clazz = (SapClass) copy;
ResourceSet co = clazz.get___Connection();
String classname = clazz.getName();
if (COPY_POSTFIX.length() <= classname.length()) {
classname = replaceStringEndWith(classname, COPY_POSTFIX);
}
Integer counter = 0;
while(classExists(co, classname)) {
counter += 1;
int substr_size = counter.toString().length();
if (substr_size > classname.length()) {
throw new RuntimeException("Failed to generate unique name for copy " + clazz + " of " + source);
}
classname = replaceStringEndWith(classname, counter.toString());
}
assert classname.length() == clazz.getName().length();
clazz.setName(classname);
}
return true;
}
private String replaceStringEndWith(String string, String replaceEnd) {
String strBegin = string.substring(0, string.length() - replaceEnd.length());
return strBegin + replaceEnd;
}
private Boolean classExists(ResourceSet co, String classname) {
MQLProcessor mql = co.getMQLProcessor();
MQLResultSet queryResult = mql.execute(
"select c from data::classes::SapClass as c where for c(name='" + classname + "')",
mql.getQueryScopeProvider(/* scopeInclusive */false, /* partitionScope */ null, (String[]) null));
return queryResult.getRefObjects("c").length > 0;
}
}