Hi all,
I try to load a base PatternModel (*.eiq file) which is based on our latest discussions here in the forum. Then I want to generate one additional paatern which should be added top the loaded PatternModel. This PatternModel then should be serialised but I get some strange errors. Attached to this mail you'll find first the generator test case. Second, you'll find the pattern which should be added to the PatternModel. Third, the pattern model which will be loaded initially. Can anybody help me with that?
best regards,
Jan
############## generator test case (IncQueryGenerationTest.java) ###############
package org.emftext.refactoring.matching.incquery;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
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.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.viatra2.patternlanguage.EMFPatternLanguageRuntimeModule;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.ParameterRef;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.Pattern;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.PatternBody;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.PatternCall;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.PatternCompositionConstraint;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.PatternLanguageFactory;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.Type;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.Variable;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.VariableReference;
import org.eclipse.viatra2.patternlanguage.core.patternLanguage.VariableValue;
import org.eclipse.viatra2.patternlanguage.eMFPatternLanguage.EMFPatternLanguagePackage;
import org.eclipse.viatra2.patternlanguage.eMFPatternLanguage.PatternModel;
import org.eclipse.xtext.resource.IResourceFactory;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class IncQueryGenerationTest {
private static final String[] NAMES = new String[]{"OrigContainer","ContainerContainer", "Extract", "NewContainer", "MovedReference"};
private static final String[] relations = new String[]{
"extracts:OrigContainer:Extract"
,"source:ContainerContainer:OrigContainer"
, "target:ContainerContainer:NewContainer"
, "referer:OrigContainer:MovedReference"
, "moved:NewContainer:Extract"
, "containerRef:MovedReference:NewContainer->"};
private static final String TEMPLATE_FILE = "base.eiq";
private static final String OUTPUT_FOLDER = ".";
private static final String CONTAINMENT_PATTERN_NAME = "containment";
private static final String REFERENCE_PATTERN_NAME = "reference";
private static Resource patternResource;
// a template will be loaded first which then can be extended
private static PatternModel patternModel;
// patterns to be referenced in generated pattern
private static Pattern containmentPattern;
private static Pattern referencePattern;
@BeforeClass
public static void init(){
initLanguages();
initModels();
initReferencedPatterns();
}
@Test
public void generatePatternTest(){
PatternLanguageFactory factory = PatternLanguageFactory.eINSTANCE;
Pattern pattern = factory.createPattern();
pattern.setName("ExtractXWithRefClass");
PatternBody patternBody = factory.createPatternBody();
pattern.getBodies().add(patternBody);
Map<String, Variable> variableNameMap = new HashMap<>();
for (String name : NAMES) {
Variable variable = factory.createVariable();
variable.setName(name);
Type type = factory.createType();
type.setTypename(EClass.class.getSimpleName());
variable.setType(type);
variableNameMap.put(variable.getName(), variable);
pattern.getParameters().add(variable);
}
for (String coll : relations) {
String[] parts = coll.split(":");
String name = parts[0];
String source = parts[1];
String target = parts[2];
boolean isReference = target.endsWith("->");
if(isReference){
target = target.substring(0, target.length() - 2);
}
Variable variable = factory.createVariable();
variable.setName(name);
Type type = factory.createType();
type.setTypename(EReference.class.getSimpleName());
variable.setType(type);
pattern.getParameters().add(variable);
PatternCall patternCall = factory.createPatternCall();
Pattern calledPattern = null;
if(isReference){
calledPattern = referencePattern;
} else {
calledPattern = containmentPattern;
}
assertNotNull("calledPattern mustn't be null", calledPattern);
patternCall.setPatternRef(calledPattern);
VariableValue sourceValue = factory.createVariableValue();
VariableValue targetValue = factory.createVariableValue();
VariableReference sourceVariableReference = factory.createVariableReference();
VariableReference targetVariableReference = factory.createVariableReference();
ParameterRef sourceParameterRef = factory.createParameterRef();
sourceParameterRef.setReferredParam(variableNameMap.get(source));
sourceVariableReference.setVariable(sourceParameterRef);
ParameterRef targetParameterRef = factory.createParameterRef();
targetParameterRef.setReferredParam(variableNameMap.get(target));
targetVariableReference.setVariable(targetParameterRef);
sourceVariableReference.setVar(sourceParameterRef.getReferredParam().getName());
targetVariableReference.setVar(targetParameterRef.getReferredParam().getName());
sourceValue.setValue(sourceVariableReference);
targetValue.setValue(targetVariableReference);
patternCall.getParameters().add(sourceValue);
if(isReference){
VariableValue referenceValue = factory.createVariableValue();
VariableReference referenceVariableReference = factory.createVariableReference();
sourceVariableReference.setVariable(variable);
referenceVariableReference.setVar(variable.getName());
referenceValue.setValue(referenceVariableReference);
patternCall.getParameters().add(referenceValue);
}
patternCall.getParameters().add(targetValue);
PatternCompositionConstraint constraint = factory.createPatternCompositionConstraint();
constraint.setCall(patternCall);
patternBody.getConstraints().add(constraint);
}
patternModel.getPatterns().add(pattern);
try {
patternResource.save(Collections.EMPTY_MAP);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void initReferencedPatterns() {
List<Pattern> patterns = patternModel.getPatterns();
for (Pattern pattern : patterns) {
if(pattern.getName().equals(CONTAINMENT_PATTERN_NAME)){
containmentPattern = pattern;
}
if(pattern.getName().equals(REFERENCE_PATTERN_NAME)){
referencePattern = pattern;
}
if(referencePattern != null && containmentPattern != null){
break;
}
}
assertNotNull("containment pattern mustn't be null", containmentPattern);
assertNotNull("reference pattern mustn't be null", referencePattern);
}
public static void initModels() {
ResourceSet rs = new ResourceSetImpl();
// template file which will be extended by generated pattern
File file = new File(TEMPLATE_FILE);
assertTrue("template file " + file.getAbsolutePath() + " must exist", file.exists());
URI uri = URI.createFileURI(file.getAbsolutePath());
EObject model = rs.getResource(uri, true).getContents().get(0);
assertTrue("must be a PatternModel", model instanceof PatternModel);
patternModel = (PatternModel) model;
// output model
file = new File(OUTPUT_FOLDER + "/ExtractXWithRefClass." + uri.fileExtension());
if(file.exists()){
file.delete();
}
assertFalse("File " + file.getName() + " must not exist", file.exists());
uri = URI.createFileURI(file.getAbsolutePath());
patternResource = rs.createResource(uri);
assertNotNull("Pattern resource mustn't be null", patternResource);
patternResource.getContents().add(patternModel);
}
private static void initLanguages(){
// XMI
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
// Pattern language
EPackage.Registry.INSTANCE.put(EMFPatternLanguagePackage.eNS_URI, EMFPatternLanguagePackage.eINSTANCE);
Injector injector = Guice.createInjector(new EMFPatternLanguageRuntimeModule());
IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("eiq", resourceFactory);
}
}
############## generated pattern which will be added to the PatternModel ###############
pattern ExtractXWithRefClass(OrigCont: EClass, ContCont: EClass, Extract:EClass, NewCont:EClass,
MovedRef:EClass, extracts:EReference, source:EReference, target:EReference, referer:EReference,
moved:EReference, containerRef:EReference){
find containment(OrigCont, extracts, Extract);
find containment(ContCont, source, OrigCont);
find containment(ContCont, target, NewCont);
find containment(OrigCont, referer, MovedRef);
find containment(NewCont, moved, Extract);
find reference(MovedRef, containerRef, NewCont);
}
############## base template which will be extended by a generated pattern (base.eiq) ###############
import "
http://www.eclipse.org/emf/2002/Ecore"
pattern containment(Source: EClass, reference: EReference, Target: EClass){
find eAllContainments(PH_Source,reference);
ETypedElement.eType(reference,PH_Target);
find thisAndAllSuperTypes(Source, PH_Source);
find thisAndAllSuperTypes(Target, PH_Target);
neg find isEcore(Source);
}
pattern reference(Source: EClass, reference: EReference, Target: EClass){
find eAllReferences(PH_Source,reference);
ETypedElement.eType(reference,PH_Target);
neg find isAggregation(reference);
find thisAndAllSuperTypes(Source, PH_Source);
find thisAndAllSuperTypes(Target, PH_Target);
neg find isEcore(Source);
}
pattern canTransitivelyContain(Source : EClass, Target : EClass) {
find canContain+(Source, Target);
}
pattern canContain(Source: EClass, Target : EClass) {
find eAllContainments(Source,reference);
EReference.eType(reference, Target);
}
@QueryExplorer(display = false)
pattern isEcore(Element){
EClassifier.ePackage(Element,EP);
EPackage(EP);
EPackage.nsURI(EP,"
http://www.eclipse.org/emf/2002/Ecore");
}
@QueryExplorer(display = false)
pattern isAggregation(ref:EReference){
EReference.containment(ref,true);
}
// well-behaving ecore patterns
@QueryExplorer(display = false)
private pattern eStructuralFeatures(This : EClass, Target : EStructuralFeature){
EClass.eStructuralFeatures(This, Target);
}
@QueryExplorer(display = false)
pattern eAttributes(This : EClass, Target : EAttribute){
find eStructuralFeatures(This, Target);
}
@QueryExplorer(display = false)
pattern eReferences(This : EClass, Target : EReference){
find eStructuralFeatures(This, Target);
}
@QueryExplorer(display = false)
private pattern eGenericSuperTypes(This : EClass, Target : EGenericType){
EClass.eGenericSuperTypes(This, Target);
}
@QueryExplorer(display = false)
pattern eAllGenericSuperTypes(This : EClass, Target : EGenericType){
find eSuperTypes+(This, Type);
find eGenericSuperTypes(Type, Target);
} or {
find eGenericSuperTypes(This, Target);
}
@QueryExplorer(display = false)
private pattern eRawType(This : EGenericType, Target : EClass){
EGenericType.eRawType(This, Target);
}
@QueryExplorer(display = false)
pattern eSuperTypes(This : EClass, Target : EClass){
find eGenericSuperTypes(This, GenericType);
find eRawType(GenericType, Target);
}
@QueryExplorer(display = false)
pattern eAllSuperTypes(This : EClass, Target : EClass){
find eAllGenericSuperTypes(This, GenericType);
find eRawType(GenericType, Target);
}
@QueryExplorer(display = false)
private pattern thisAndAllSuperTypes(This : EClass, Target : EClass){
find eAllSuperTypes(This, Target);
} or {
This == Target;
}
@QueryExplorer(display = false)
pattern eAllStructuralFeatures(This : EClass, Target : EStructuralFeature){
find thisAndAllSuperTypes(This, Type);
find eStructuralFeatures(Type, Target);
}
@QueryExplorer(display = false)
pattern eAllAttributes(This : EClass, Target : EAttribute){
find eAllStructuralFeatures(This, Target);
}
@QueryExplorer(display = false)
pattern eAllReferences(This : EClass, Target : EReference){
find eAllStructuralFeatures(This, Target);
}
@QueryExplorer(display = false)
pattern eAllContainments(This : EClass, Target : EReference){
find eAllReferences(This, Target);
EReference.containment(Target, true);
}
@QueryExplorer(display = false)
private pattern eOperations(This : EClass, Target : EOperation){
EClass.eOperations(This, Target);
}
@QueryExplorer(display = false)
pattern eAllOperations(This : EClass, Target : EOperation){
find thisAndAllSuperTypes(This, Type);
find eOperations(Type, Target);
}
// NOTE: EMF uses the first attribute with id = true from all supertypes...
@QueryExplorer(display = false)
pattern eIDAttribute(This : EClass, Target : EAttribute){
find eAllAttributes(This, Target);
EAttribute.iD(Target, true);
}