blob: 13331f8dcd581685bdb2a9c62479e068f8290f08 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2015 The University of York and Willink Transformations.
* 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:
* Horacio Hoyos - initial API and implementation
******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.codegen.ecore.generator.Generator;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory.Descriptor.Registry;
import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenModelGeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.genmodel.util.GenModelUtil;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.importer.ecore.EcoreImporter;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.oclinecore.OCLinEcoreGeneratorAdapterFactory;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Package;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.internal.ecore.as2es.AS2Ecore;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.util.DerivedConstants;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.TracingOption;
import org.eclipse.qvtd.compiler.CompilerChain;
import org.eclipse.qvtd.compiler.CompilerChainException;
import org.eclipse.qvtd.compiler.CompilerConstants;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.Rule;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.TreeIterable;
import org.eclipse.qvtd.pivot.qvtcore.CoreModel;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
import org.eclipse.qvtd.pivot.qvtcore.QVTcoreFactory;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp;
import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
import org.eclipse.qvtd.pivot.qvtrelation.RelationModel;
import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
public class QVTr2QVTc
{
public static final @NonNull TracingOption SYNTHESIS = new TracingOption(CompilerConstants.PLUGIN_ID, "qvtr2qvtc/synthesis");
private class Issues {
public void addError(QVTr2QVTc qvTrToQVTc, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.err.println(message);
}
public void addWarning(QVTr2QVTc qvTrToQVTc, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.out.println(message);
}
public void addError(QVTr2QVTc qvTrToQVTc, String string) {
System.err.println(string);
}
public void addWarning(QVTr2QVTc qvTrToQVTc, String string) {
System.out.println(string);
}
}
protected final @NonNull EnvironmentFactory environmentFactory;
private final @NonNull Resource qvtrResource;
private final @NonNull Resource qvtcResource;
protected final @NonNull QVTcoreHelper helper;
protected final @NonNull QVTrNameGenerator nameGenerator;
/**
* Optional configuration of the NsURI of the trace package.
*/
private @Nullable String traceNsURI = null;
private final @NonNull Map<@NonNull Element, @NonNull Element> globalTarget2source = new HashMap<@NonNull Element, @NonNull Element>();
private final @NonNull Map<@NonNull Element, @NonNull List<@NonNull Element>> globalSource2targets = new HashMap<@NonNull Element, @NonNull List<@NonNull Element>>();
private final @NonNull List<org.eclipse.ocl.pivot.@NonNull Package> tracePackages = new ArrayList<org.eclipse.ocl.pivot.@NonNull Package>();
// private final @NonNull List<@NonNull Transformation> coreTransformations = new ArrayList<@NonNull Transformation>();
/**
* Mapping from each key to its corresponding identification constructor function.
*/
private final @NonNull Map<@NonNull Key, @NonNull Function> key2function = new HashMap<@NonNull Key, @NonNull Function>();
// Un-navigable opposites
//
// The Key that identifies each Class.
// FIXME can there be two keys for the same Class?
//
private final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key> class2key = new HashMap<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key>();
/**
* Mapping from each relation to its corresponding trace class.
*/
private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relation2traceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>();
/**
* Map from each relation to all the expressions that call the relation.
*/
private final @NonNull Map<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>> relation2invocations = new HashMap<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>>();
/**
* Map from each relation invocation the relation whose where predicate contains the invocation.
* @deprecated computable - no cache required
*/
@Deprecated
private final @NonNull Map<@NonNull RelationCallExp, @NonNull Relation> invocation2invokingRelation = new HashMap<@NonNull RelationCallExp, @NonNull Relation>();
private @NonNull CoreModel coreModel;
/**
* The core Transformation for each RelationalTransformation.
*/
private @NonNull Map<@NonNull RelationalTransformation, @NonNull Transformation> relationalTransformation2coreTransformation
= new HashMap<@NonNull RelationalTransformation, @NonNull Transformation>();
/**
* The trace Package for each RelationalTransformation.
*/
private @NonNull Map<@NonNull RelationalTransformation, org.eclipse.ocl.pivot.@NonNull Package> relationalTransformation2tracePackage
= new HashMap<@NonNull RelationalTransformation, org.eclipse.ocl.pivot.@NonNull Package>();
/**
* The core TypedModel for each Relational TypedModel.
*/
private @NonNull Map<@NonNull TypedModel, @NonNull TypedModel> relationalTypedModel2coreTypedModel
= new HashMap<@NonNull TypedModel, @NonNull TypedModel>();
/**
* The lazily created named Trace Properties in each Trace Class.
*/
private @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Map<@NonNull String, @NonNull Property>> traceClass2name2traceProperty
= new HashMap<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Map<@NonNull String, @NonNull Property>>();
/**
* The lazily created named Core mappings for each transformation.
*/
private @NonNull Map<@NonNull Transformation, @NonNull Map<@NonNull String, @NonNull Mapping>> transformation2name2mapping
= new HashMap<@NonNull Transformation, @NonNull Map<@NonNull String, @NonNull Mapping>>();
/**
* The root variables (in relation call order) of each relation.
*/
private @NonNull Map<@NonNull Relation, @NonNull List<@NonNull Variable>> relation2rootVariables = new HashMap<@NonNull Relation, @NonNull List<@NonNull Variable>>();
public QVTr2QVTc(@NonNull EnvironmentFactory environmentFactory, @NonNull Resource qvtrResource, @NonNull Resource qvtcResource) {
this.environmentFactory = environmentFactory;
this.qvtrResource = qvtrResource;
this.qvtcResource = qvtcResource;
// this.traceResource = traceResource;
this.helper = new QVTcoreHelper(environmentFactory);
this.nameGenerator = new QVTrNameGenerator(this);
this.coreModel = QVTcoreFactory.eINSTANCE.createCoreModel();
// Create a cache of opposite relations and copy imports
TreeIterator<EObject> it = qvtrResource.getAllContents();
while (it.hasNext()) {
EObject eo = it.next();
if (eo instanceof Key) {
analyzeKey((Key)eo);
}
if (eo instanceof Relation) {
Relation relation = (Relation)eo;
analyzeInvocations(relation);
analyzeRootVariables(relation);
}
if (eo instanceof Import) {
this.coreModel.getOwnedImports().add((Import) EcoreUtil.copy(eo));
}
}
}
protected void analyzeInvocations(@NonNull Relation callingRelation) {
Pattern wherePattern = callingRelation.getWhere();
if (wherePattern != null) {
for (Predicate predicate : wherePattern.getPredicate()) {
OCLExpression predicateExpression = predicate.getConditionExpression();
if (predicateExpression instanceof RelationCallExp) {
RelationCallExp relationInvocation = (RelationCallExp) predicateExpression;
Relation calledRelation = ClassUtil.nonNullState(relationInvocation.getReferredRelation());
List<@NonNull RelationCallExp> relationInvocations = relation2invocations.get(calledRelation);
if (relationInvocations == null) {
relationInvocations = new ArrayList<@NonNull RelationCallExp>();
relation2invocations.put(calledRelation, relationInvocations);
}
relationInvocations.add(relationInvocation);
invocation2invokingRelation.put(relationInvocation, callingRelation);
}
}
}
}
protected void analyzeKey(@NonNull Key key) {
org.eclipse.ocl.pivot.Class identifies = key.getIdentifies();
assert identifies != null;
class2key.put(identifies, key);
}
protected void analyzeRootVariables(@NonNull Relation relation) {
List<@NonNull Variable> rootVariables = new ArrayList<@NonNull Variable>();
for (@NonNull Domain rDomain : ClassUtil.nullFree(relation.getDomain())) {
for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) {
TemplateExp rRootTemplateExpression = rDomainPattern.getTemplateExpression();
if (rRootTemplateExpression != null) {
Variable rRootVariable = rRootTemplateExpression.getBindsTo();
if (rRootVariable != null) {
rootVariables.add(rRootVariable);
}
}
}
}
relation2rootVariables.put(relation, rootVariables);
}
public @Nullable Property basicGetProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException {
/*@NonNull*/ String name = rNamedElement.getName();
assert (aClass != null) && (name != null);
CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass);
return completeClass.getProperty(name);
}
public @NonNull CoreDomain createCoreDomain(@NonNull TypedModel typedModel) {
CoreDomain coreDomain = QVTcoreBaseFactory.eINSTANCE.createCoreDomain();
coreDomain.setTypedModel(typedModel);
coreDomain.setName(ClassUtil.nonNullState(typedModel.getName()));
// putTrace(coreDomain, coreRule);
GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern();
coreDomain.setGuardPattern(guardPattern);
// putTrace(guardPattern, coreRule);
BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern();
coreDomain.setBottomPattern(bottomPattern);
return coreDomain;
}
public @NonNull String createKeyFunctionName(@NonNull Key rKey) {
return nameGenerator.createKeyFunctionName(rKey);
}
public @NonNull String createKeyedVariableName(@NonNull Variable identifiedVariable) {
return nameGenerator.createKeyedVariableName(identifiedVariable);
}
/**
* Create the name Mapping for a coreTransformation.
*/
/*public*/ @NonNull Mapping createMapping(@NonNull Relation relation, @NonNull String name) {
RelationalTransformation rt = (RelationalTransformation) relation.getTransformation();
assert rt != null;
@NonNull Transformation coreTransformation = getCoreTransformation(rt);
Map<@NonNull String, @NonNull Mapping> name2mapping = transformation2name2mapping.get(coreTransformation);
if (name2mapping == null) {
name2mapping = new HashMap<@NonNull String, @NonNull Mapping>();
transformation2name2mapping.put(coreTransformation, name2mapping);
}
Mapping coreMapping = name2mapping.get(name);
assert (coreMapping == null);// {
coreMapping = helper.createMapping(name);
putGlobalTrace(coreMapping, relation);
coreMapping.setTransformation(coreTransformation);
name2mapping.put(name, coreMapping);
// }
return coreMapping;
}
public @NonNull RealizedVariable createRealizedVariable(@NonNull TypedElement typedElement) {
return createRealizedVariable(ClassUtil.nonNullState(typedElement.getName()), ClassUtil.nonNullState(typedElement.getType()));
}
public @NonNull RealizedVariable createRealizedVariable(@NonNull String name, @NonNull Type type) {
RealizedVariable realizedVariable = QVTcoreBaseFactory.eINSTANCE.createRealizedVariable();
realizedVariable.setName(name);
realizedVariable.setType(type);
realizedVariable.setIsRequired(true);
return realizedVariable;
}
public @NonNull String createTraceClassName(@NonNull Relation relation) {
return nameGenerator.createTraceClassName(relation);
}
// Save the qvtc resource
public void dispose() {
// What about the trace model? we need to separate them
//qvtcSource.getContents().addAll(traceData.getRootOutputELements());
}
public void execute() throws CompilerChainException {
transformToTracePackages();
transformToCoreTransformations();
}
public void generateModels(@NonNull GenModel genModel) {
Registry generatorAdapterDescriptorRegistry = GeneratorAdapterFactory.Descriptor.Registry.INSTANCE;
if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(GenModelGeneratorAdapterFactory.DESCRIPTOR)) {
generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, GenModelGeneratorAdapterFactory.DESCRIPTOR);
}
if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR)) {
generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR);
}
//** ResourceUtils.checkResourceSet(resourceSet);
// genModel.setCanGenerate(true);
// validate();
genModel.setValidateModel(true); // The more checks the better
// genModel.setCodeFormatting(true); // Normalize layout
genModel.setForceOverwrite(false); // Don't overwrite read-only
// files
genModel.setCanGenerate(true);
// genModel.setFacadeHelperClass(null); // Non-null gives JDT
// default NPEs
// genModel.setFacadeHelperClass(ASTFacadeHelper.class.getName()); // Bug 308069
// genModel.setValidateModel(true);
// genModel.setBundleManifest(false); // New manifests should be
// // generated manually
// genModel.setUpdateClasspath(false); // New class-paths should be
// // generated manually
// if (genModel.getComplianceLevel().compareTo(GenJDKLevel.JDK50_LITERAL) < 0) {
// genModel.setComplianceLevel(GenJDKLevel.JDK50_LITERAL);
// }
// genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container");
Diagnostic diagnostic = genModel.diagnose();
reportDiagnostics(new Issues(), diagnostic);
/*
* JavaModelManager.getJavaModelManager().initializePreferences();
* new
* JavaCorePreferenceInitializer().initializeDefaultPreferences();
*
* GenJDKLevel genSDKcomplianceLevel =
* genModel.getComplianceLevel(); String complianceLevel =
* JavaCore.VERSION_1_5; switch (genSDKcomplianceLevel) { case
* JDK60_LITERAL: complianceLevel = JavaCore.VERSION_1_6; case
* JDK14_LITERAL: complianceLevel = JavaCore.VERSION_1_4; default:
* complianceLevel = JavaCore.VERSION_1_5; } // Hashtable<?,?>
* defaultOptions = JavaCore.getDefaultOptions(); //
* JavaCore.setComplianceOptions(complianceLevel, defaultOptions);
* // JavaCore.setOptions(defaultOptions);
*/
// Generator generator = new Generator();
// generator.setInput(genModel);
Generator generator = GenModelUtil.createGenerator(genModel);
Monitor monitor = /*showProgress ? new LoggerMonitor(log) :*/ new BasicMonitor();
diagnostic = generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, monitor);
reportDiagnostics(new Issues(), diagnostic);
}
/*public*/ @NonNull Transformation getCoreTransformation(@NonNull RelationalTransformation relationalTransformation) {
return ClassUtil.nonNullState(relationalTransformation2coreTransformation.get(relationalTransformation));
}
/*public*/ @NonNull TypedModel getCoreTypedModel(@NonNull TypedModel relationTypedModel) {
return ClassUtil.nonNullState(relationalTypedModel2coreTypedModel.get(relationTypedModel));
}
/* public @NonNull DomainPattern getDomainPattern(@NonNull Domain d) {
List<@NonNull DomainPattern> pattern = ClassUtil.nullFree(((RelationDomain) d).getPattern());
assert pattern.size() == 1;
DomainPattern domainPattern = pattern.get(0);
assert domainPattern != null;
return domainPattern;
} */
public @NonNull EnvironmentFactory getEnvironmentFactory() {
return environmentFactory;
}
public @NonNull QVTcoreHelper getHelper() {
return helper;
}
/*public*/ @NonNull Relation getInvokingRelation(@NonNull RelationCallExp rInvocation) {
Relation rRelation1 = ClassUtil.nonNullState(invocation2invokingRelation.get(rInvocation));
Relation rRelation2 = (Relation) ((Predicate)rInvocation.eContainer()).getPattern().eContainer();
assert rRelation1 == rRelation2;
return rRelation1;
}
public @Nullable Key getKeyForType(@NonNull Type type) {
return class2key.get(type);
}
/*public*/ @NonNull Function getKeyFunction(@NonNull Key key) {
return ClassUtil.nonNullState(key2function.get(key));
}
public Predicate getPredicateForRelationCallExp(RelationCallExp ri) {
// TODO Auto-generated method stub
return null;
}
public @NonNull String getProjectName(@NonNull URI traceURI) {
URI trimFileExtension = traceURI.trimFileExtension();
if (trimFileExtension.isPlatform()) {
return trimFileExtension.segment(1);
}
else {
return trimFileExtension.segment(0);
}
}
/**
* Return the property of aClass whose name corresponds to rNamedElement.
* @throws CompilerChainException if no such property
*/
protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException {
Property property = getProperty(aClass, rNamedElement.getName());
if (rNamedElement instanceof Property) {
assert rNamedElement == property;
}
return property;
}
protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, /*@NonNull*/ String name) throws CompilerChainException {
assert (aClass != null) && (name != null);
CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass);
Property p = completeClass.getProperty(name);
if (p != null)
return p;
throw new CompilerChainException("No property '" + name + "' in '" + aClass + "::" + "'");
}
/**
* @return the qvtcSource
*/
public Resource getQvtcSource() {
return qvtcResource;
}
public @NonNull List<@NonNull RelationCallExp> getRelationCallExpsForRelation(@NonNull Relation relation) {
return ClassUtil.nonNullState(relation2invocations.get(relation));
}
public @NonNull List<@NonNull Variable> getRootVariables(@NonNull Relation relation) {
return ClassUtil.nonNullState(relation2rootVariables.get(relation));
}
public @NonNull StandardLibrary getStandardLibrary() {
return environmentFactory.getStandardLibrary();
}
/*public*/ org.eclipse.ocl.pivot.@NonNull Class getTraceClass(@NonNull Relation relation) {
return ClassUtil.nonNullState(relation2traceClass.get(relation));
}
/*public*/ org.eclipse.ocl.pivot.@NonNull Package getTracePackage(@NonNull RelationalTransformation relationalTransformation) {
return ClassUtil.nonNullState(relationalTransformation2tracePackage.get(relationalTransformation));
}
public @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> getUsedClasses(@NonNull TypedModel rTypedModel) {
Set<org.eclipse.ocl.pivot.@NonNull Class> usedClasses = new HashSet<org.eclipse.ocl.pivot.@NonNull Class>();
for (org.eclipse.ocl.pivot.@NonNull Package rPackage : ClassUtil.nullFree(rTypedModel.getUsedPackage())) {
usedClasses.addAll(ClassUtil.nullFree(rPackage.getOwnedClasses()));
}
return usedClasses;
}
// Create the top rules, and search the input model for the appropriate types, when possible?
public void prepare() {
try {
qvtrResource.load(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// EXIT!
} finally {
// if (qvtrModel.isLoaded()) {
//RuleFactory factory = new RuleFactory();
//rules = factory.createTopRules(this);
// ruleFactories = new Rule.Factory[] {
// RelationalTransformationToMappingTransformation.FACTORY,
// RelationToTraceClass.FACTORY
// };
// }
}
}
/*public*/ void putCoreTransformation(@NonNull RelationalTransformation relationTransformation, @NonNull Transformation coreTransformation) {
relationalTransformation2coreTransformation.put(relationTransformation, coreTransformation);
putGlobalTrace(coreTransformation, relationTransformation);
}
/*private*/ void putGlobalTrace(@NonNull Element coreElement, @NonNull Element relationElement) {
// if (relationElement != null) {
Element oldRelationElement = globalTarget2source.put(coreElement, relationElement);
assert oldRelationElement == null;
List<@NonNull Element> targets = globalSource2targets.get(relationElement);
if (targets == null) {
targets = new ArrayList<@NonNull Element> ();
globalSource2targets.put(relationElement, targets);
}
targets.add(coreElement);
// }
}
/*public*/ void putKeyFunction(@NonNull Key rKey, @NonNull Function keyFunction) {
Function oldFunction = key2function.put(rKey, keyFunction);
assert oldFunction == null;
// putTrace(traceClass, r);
}
/*public*/ void putRelationTrace(@NonNull Relation rRelation, org.eclipse.ocl.pivot.@NonNull Class traceClass) {
org.eclipse.ocl.pivot.Class oldTraceClass = relation2traceClass.put(rRelation, traceClass);
assert oldTraceClass == null;
// putTrace(traceClass, r);
}
/*public*/ void putTracePackage(@NonNull RelationalTransformation rt, org.eclipse.ocl.pivot.@NonNull Package tracePackage) {
org.eclipse.ocl.pivot.Package oldTracePackage = relationalTransformation2tracePackage.put(rt, tracePackage);
assert oldTracePackage == null;
// putTrace(tracePackage, rt);
}
public void putTypedModel(@NonNull TypedModel relationTypedModel, @NonNull TypedModel coreTypedModel) {
TypedModel oldTypedModel = relationalTypedModel2coreTypedModel.put(relationTypedModel, coreTypedModel);
assert oldTypedModel == null;
}
protected void reportDiagnostics(Issues issues, Diagnostic diagnostic) {
int severity = diagnostic.getSeverity();
if (severity != Diagnostic.OK) {
List<Diagnostic> children = diagnostic.getChildren();
if (children.size() > 0) {
for (Diagnostic child : children) {
severity = child.getSeverity();
@SuppressWarnings("unchecked") List<Object> data = (List<Object>) child.getData();
Throwable throwable = null;
String message;
if ((data.size() == 1) && (data.get(0) instanceof Throwable)) {
throwable = (Throwable) data.get(0);
data = null;
message = child.getMessage();
}
else {
message = child.toString();
}
if (severity == Diagnostic.ERROR) {
issues.addError(this, message, null, null, throwable, data);
}
else if (severity == Diagnostic.WARNING) {
issues.addWarning(this, message, null, null, throwable, data);
}
}
}
else {
if (severity == Diagnostic.ERROR) {
issues.addError(this, diagnostic.toString());
}
else if (severity == Diagnostic.WARNING) {
issues.addWarning(this, diagnostic.toString());
}
}
}
}
public void saveCore(@NonNull Resource asResource, @NonNull Map<?, ?> options) throws IOException {
asResource.getContents().add(this.coreModel);
// Copy imports
for (org.eclipse.ocl.pivot.@NonNull Package asPackage : tracePackages) {
Import asImport = helper.createImport(null, asPackage);
coreModel.getOwnedImports().add(asImport);
}
// -- scan for dangling references if this is really wanted
// for (EObject eObject : potentialOrphans) {
// if (eObject.eContainer() == null) {
// asResource.getContents().add(eObject);
// }
// }
asResource.save(options);
}
public @NonNull GenModel saveGenModel(@NonNull Resource asResource, @NonNull URI traceURI, @NonNull URI genModelURI, @Nullable Map<@NonNull String, @Nullable String> genModelOptions, @NonNull Map<Object, Object> saveOptions2, @Nullable Collection<@NonNull ? extends GenPackage> usedGenPackages) throws IOException {
URI trimFileExtension = traceURI.trimFileExtension();
String projectName = getProjectName(traceURI);
Resource genmodelResource = environmentFactory.getResourceSet().createResource(genModelURI);
@SuppressWarnings("null")@NonNull GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
genModel.getForeignModel().add(traceURI.lastSegment());
String copyrightText = genModelOptions != null ? genModelOptions.get(CompilerChain.GENMODEL_COPYRIGHT_TEXT) : null;
if (copyrightText != null) {
genModel.setCopyrightText(copyrightText);
}
if (usedGenPackages != null) {
genModel.getUsedGenPackages().addAll(usedGenPackages);
}
genModel.setModelDirectory("/" + projectName + "/test-gen");
genModel.setModelPluginID(projectName);
genModel.setModelName(trimFileExtension.lastSegment());
genModel.setBundleManifest(false);
genModel.setUpdateClasspath(false);
genModel.setImporterID(new EcoreImporter().getID());
genModel.setComplianceLevel(GenJDKLevel.JDK80_LITERAL);
genModel.setCopyrightFields(false);
genModel.setOperationReflection(true);
genModel.setImportOrganizing(true);
genModel.setRootExtendsClass(MinimalEObjectImpl.Container.class.getName());
genModel.setPluginKey("");
genmodelResource.getContents().add(genModel);
String basePrefix = genModelOptions != null ? genModelOptions.get(CompilerChain.GENMODEL_BASE_PREFIX) : null;
List<GenPackage> genPackages = genModel.getGenPackages();
for (EObject eObject : asResource.getContents()) {
if (eObject instanceof Model) {
Model asModel = (Model)eObject;
for (org.eclipse.ocl.pivot.@NonNull Package asPackage : ClassUtil.nullFree(asModel.getOwnedPackages())) {
GenPackage genPackage = genModel.createGenPackage();
EPackage ePackage = (EPackage) asPackage.getESObject();
genPackage.setEcorePackage(ePackage);
genPackage.setPrefix(ePackage.getName());
if (basePrefix != null) {
genPackage.setBasePackage(basePrefix);
}
genPackages.add(genPackage);
}
Set<org.eclipse.ocl.pivot.@NonNull Package> asPackages = new HashSet<org.eclipse.ocl.pivot.@NonNull Package>();
for (EObject element : new TreeIterable(asModel, false)) {
if (element instanceof Property) {
Property property = (Property)element;
Type type = property.getType();
while (type instanceof CollectionType) {
type = ((CollectionType)type).getElementType();
}
if (type instanceof org.eclipse.ocl.pivot.Class) {
org.eclipse.ocl.pivot.Package asPackage = ((org.eclipse.ocl.pivot.Class)type).getOwningPackage();
if (asPackage != null) {
asPackages.add(asPackage);
}
}
}
}
for (@NonNull Import asImport : ClassUtil.nullFree(asModel.getOwnedImports())) {
Namespace asNamespace = asImport.getImportedNamespace();
if (asNamespace instanceof org.eclipse.ocl.pivot.Package) {
org.eclipse.ocl.pivot.@NonNull Package asPackage = (org.eclipse.ocl.pivot.Package)asNamespace;
asPackages.add(asPackage);
}
}
List<org.eclipse.ocl.pivot.@NonNull Package> asPackageList = new ArrayList<org.eclipse.ocl.pivot.@NonNull Package>(asPackages);
Collections.sort(asPackageList, NameUtil.NAMEABLE_COMPARATOR);
for (org.eclipse.ocl.pivot.@NonNull Package asPackage : asPackageList) {
EPackage ePackage = (EPackage) asPackage.getESObject();
if (ePackage != null) {
GenPackage genPackage = null;
if (usedGenPackages != null) {
for (@NonNull GenPackage usedGenPackage : usedGenPackages) {
EPackage ecorePackage = usedGenPackage.getEcorePackage();
if ((ecorePackage != null) && ClassUtil.safeEquals(ecorePackage.getNsURI(), ePackage.getNsURI())) {
genPackage = usedGenPackage;
break;
}
}
}
if (genPackage == null) {
genPackage = genModel.createGenPackage();
genPackage.setEcorePackage(ePackage);
genPackage.setPrefix(ePackage.getName());
if (basePrefix != null) {
genPackage.setBasePackage(basePrefix);
}
genPackages.add(genPackage);
}
}
}
}
}
genModel.reconcile();
Map<Object, Object> saveOptions = new HashMap<Object, Object>(saveOptions2);
saveOptions.put(XMLResource.OPTION_ENCODING, "UTF-8");
saveOptions.put(DerivedConstants.RESOURCE_OPTION_LINE_DELIMITER, "\n");
saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
saveOptions.put(Resource.OPTION_LINE_DELIMITER, Resource.OPTION_LINE_DELIMITER_UNSPECIFIED);
genmodelResource.save(saveOptions);
return genModel;
}
public @NonNull Resource saveTrace(@NonNull Resource asResource, @NonNull URI traceURI, @NonNull URI genModelURI, @Nullable Map<@NonNull String, @Nullable String> traceOptions, @NonNull Map<?, ?> saveOptions) throws IOException {
Model root = PivotFactory.eINSTANCE.createModel();
root.setExternalURI(traceURI.toString());
asResource.getContents().add(root);
if ((traceNsURI != null) && (tracePackages.size() == 1)) {
tracePackages.get(0).setURI(traceNsURI);
}
root.getOwnedPackages().addAll(tracePackages);
AS2Ecore as2ecore = new AS2Ecore((EnvironmentFactoryInternal) environmentFactory, traceURI, null);
XMLResource ecoreResource = as2ecore.convertResource(asResource, traceURI);
ecoreResource.save(saveOptions);
return ecoreResource;
}
public void setTraceNsURI(@Nullable String traceNsURI) {
this.traceNsURI = traceNsURI;
}
public void transformToCoreTransformations() throws CompilerChainException {
for (@NonNull EObject eObject : qvtrResource.getContents()) {
if (eObject instanceof RelationModel) {
RelationModel relationModel = (RelationModel)eObject;
String externalURI = relationModel.getExternalURI();
if (externalURI.endsWith(".qvtras")) {
externalURI = externalURI.replace(".qvtras", ".qvtcas");
}
else if (externalURI.endsWith(".qvtr")) {
externalURI = externalURI.replace(".qvtr", ".qvtcas");
}
coreModel.setExternalURI(externalURI);
transformToCoreTransformationHierarchy(ClassUtil.nullFree(coreModel.getOwnedPackages()), ClassUtil.nullFree(relationModel.getOwnedPackages()));
}
}
List<@NonNull RelationalTransformation> relationalTransformations = new ArrayList<@NonNull RelationalTransformation>(relationalTransformation2coreTransformation.keySet());
Collections.sort(relationalTransformations, NameUtil.NAMEABLE_COMPARATOR);
for (@NonNull RelationalTransformation relationalTransformation : relationalTransformations) {
List<@NonNull Rule> rules = new ArrayList<@NonNull Rule>(ClassUtil.nullFree(relationalTransformation.getRule()));
Collections.sort(rules, NameUtil.NAMEABLE_COMPARATOR);
Transformation coreTransformation = getCoreTransformation(relationalTransformation);
List<@NonNull Key> rKeys = new ArrayList<@NonNull Key>(ClassUtil.nullFree(relationalTransformation.getOwnedKey()));
// Collections.sort(keys, NameUtil.NAMEABLE_COMPARATOR);
List<@NonNull TypedModel> rEnforceableTypdModels = new ArrayList<@NonNull TypedModel>();
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
for (@NonNull Domain rDomain : ClassUtil.nullFree(rule.getDomain())) {
if (rDomain.isIsEnforceable()) {
TypedModel rTypedModel = ClassUtil.nonNullState(rDomain.getTypedModel());
if (!rEnforceableTypdModels.contains(rTypedModel)) {
rEnforceableTypdModels.add(rTypedModel);
}
}
}
}
}
for (@NonNull TypedModel rTypedModel : rEnforceableTypdModels) {
Set<org.eclipse.ocl.pivot.@NonNull Class> usedClasses = getUsedClasses(rTypedModel);
for (@NonNull Key rKey : rKeys) {
org.eclipse.ocl.pivot.@NonNull Class identifiedClass = ClassUtil.nonNullState(rKey.getIdentifies());
if (usedClasses.contains(identifiedClass)) {
QVTr2QVTc.SYNTHESIS.println("key " + rKey);
KeyToFunctionForIdentification keyToMapping = new KeyToFunctionForIdentification(this, rKey);
Function cKeyFunction = keyToMapping.transform();
putKeyFunction(rKey, cKeyFunction);
coreTransformation.getOwnedOperations().add(cKeyFunction);
}
}
}
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
Relation rRelation = (Relation)rule;
if (rRelation.isIsTopLevel()) {
QVTr2QVTc.SYNTHESIS.println("topLevel " + rRelation);
TopLevelRelationToMappingForEnforcement topLevelRelationToMappingForEnforcement = new TopLevelRelationToMappingForEnforcement(this, rRelation);
topLevelRelationToMappingForEnforcement.transform();
}
}
}
// }
// for (@NonNull RelationalTransformation relationalTransformation : relationalTransformations) {
// List<@NonNull Rule> rules = new ArrayList<@NonNull Rule>(ClassUtil.nullFree(relationalTransformation.getRule()));
// Collections.sort(rules, NameUtil.NAMEABLE_COMPARATOR);
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
Relation rRelation = (Relation)rule;
if (!rRelation.isIsTopLevel()) {
InvokedRelationToMappingForEnforcement invokedRelationToMappingForEnforcement = new InvokedRelationToMappingForEnforcement(this, rRelation);
invokedRelationToMappingForEnforcement.transform();
}
}
}
CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getOwnedOperations()));
CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getRule()));
}
/* for (@NonNull Transformation coreTransformation : relationalTransformation2coreTransformation.values()) {
List<DebugTraceBack> debugTraceBacks = coreTransformation.getOwnedDebugTraceBacks();
for (@NonNull Element target : target2source.keySet()) {
if (QVTbaseUtil.getContainingTransformation(target) == coreTransformation) {
DebugTraceBack traceBack = QVTbaseFactory.eINSTANCE.createDebugTraceBack();
traceBack.setTarget(target);
// FIXME true source URI traceBack.getSources().add(target2source.get(target));
debugTraceBacks.add(traceBack);
}
}
// CompilerUtil.normalizeNameables(debugTraceBacks);
} */
}
private void transformToCoreTransformationHierarchy(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> corePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) {
for (org.eclipse.ocl.pivot.@NonNull Package relationPackage : relationPackages) {
String name = relationPackage.getName();
assert name != null;
org.eclipse.ocl.pivot.@NonNull Package corePackage = helper.createPackage(name, relationPackage.getNsPrefix(), relationPackage.getURI());
corePackages.add(corePackage);
for (org.eclipse.ocl.pivot.@NonNull Class relationClass : ClassUtil.nullFree(relationPackage.getOwnedClasses())) {
if (relationClass instanceof RelationalTransformation) {
RelationalTransformationToMappingTransformation relationalTransformationToMappingTransformation = new RelationalTransformationToMappingTransformation(this);
Transformation coreTransformation = relationalTransformationToMappingTransformation.doRelationalTransformationToMappingTransformation((RelationalTransformation)relationClass);
corePackage.getOwnedClasses().add(coreTransformation);
CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getRule()));
}
}
CompilerUtil.normalizeNameables(ClassUtil.nullFree(corePackage.getOwnedClasses()));
transformToCoreTransformationHierarchy(ClassUtil.nullFree(corePackage.getOwnedPackages()), ClassUtil.nullFree(relationPackage.getOwnedPackages()));
}
}
public @NonNull List<@NonNull Package> transformToTracePackages() {
for (@NonNull EObject eObject : qvtrResource.getContents()) {
if (eObject instanceof RelationModel) {
transformToTracePackageHierarchy(tracePackages, ClassUtil.nullFree(((RelationModel)eObject).getOwnedPackages()));
CompilerUtil.normalizeNameables(tracePackages);
}
}
return tracePackages;
}
private void transformToTracePackageHierarchy(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> tracePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) {
for (org.eclipse.ocl.pivot.@NonNull Package relationPackage : relationPackages) {
for (org.eclipse.ocl.pivot.@NonNull Class relationClass : ClassUtil.nullFree(relationPackage.getOwnedClasses())) {
if (relationClass instanceof RelationalTransformation) {
RelationalTransformationToTracePackage relationalTransformationToTracePackage = new RelationalTransformationToTracePackage(this);
org.eclipse.ocl.pivot.Package tracePackage = relationalTransformationToTracePackage.doRelationalTransformationToTracePackage((RelationalTransformation)relationClass);
tracePackages.add(tracePackage);
}
}
transformToTracePackageHierarchy(tracePackages, ClassUtil.nullFree(relationPackage.getOwnedPackages()));
}
}
/**
* Lazily create the name Property for a traceClass with a type.
*/
/*public*/ @NonNull Property whenTraceProperty(org.eclipse.ocl.pivot.@NonNull Class traceClass, @NonNull String name, @NonNull Type type, boolean isRequired) {
Map<@NonNull String, @NonNull Property> name2traceProperty = traceClass2name2traceProperty.get(traceClass);
if (name2traceProperty == null) {
name2traceProperty = new HashMap<@NonNull String, @NonNull Property>();
traceClass2name2traceProperty.put(traceClass, name2traceProperty);
}
Property traceProperty = name2traceProperty.get(name);
if (traceProperty == null) {
traceProperty = PivotFactory.eINSTANCE.createProperty();
traceProperty.setName(name);
traceProperty.setType(type);
traceProperty.setIsRequired(isRequired);
name2traceProperty.put(name, traceProperty);
traceProperty.setOwningClass(traceClass);
if (!(type instanceof DataType)) {
Property oppositeProperty = PivotFactory.eINSTANCE.createProperty();
oppositeProperty.setName(traceClass.getName()); // FIXME unique, mutable Class
oppositeProperty.setType(traceClass);
oppositeProperty.setIsRequired(true);
oppositeProperty.setIsImplicit(true);
oppositeProperty.setOwningClass((org.eclipse.ocl.pivot.@NonNull Class)type);
traceProperty.setOpposite(oppositeProperty);
oppositeProperty.setOpposite(traceProperty);
// putTrace(oppositeProperty, type);
}
// putTrace(traceProperty, traceClass);
}
else {
assert traceProperty.getType() == type;
}
return traceProperty;
}
}