blob: ee9a51a49df2ce093131d89f71d597f1b41b6a5a [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.DataType;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.Model;
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.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
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.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.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.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.CollectionTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
public class QVTrToQVTc
{
public static final @NonNull TracingOption SYNTHESIS = new TracingOption(CompilerConstants.PLUGIN_ID, "qvtr2qvtc/synthesis");
private class Issues {
public void addError(QVTrToQVTc qvTrToQVTc, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.err.println(message);
}
public void addWarning(QVTrToQVTc qvTrToQVTc, String message,
Object object, Object object2, Throwable throwable,
List<Object> data) {
System.out.println(message);
}
public void addError(QVTrToQVTc qvTrToQVTc, String string) {
System.err.println(string);
}
public void addWarning(QVTrToQVTc 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;
/**
* 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>();
private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relationToTraceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>();
// Un-navigable opposites
//
// The Key that identifies each Class.
// FIXME can there be two keys for the sane Class?
//
private final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key> class2key = new HashMap<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key>();
private final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> variable2templateExp = new HashMap<@NonNull Variable, @NonNull TemplateExp>();
private final @NonNull Map<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>> relationCallExpsForRelation = new HashMap<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>>();
private final @NonNull Map<@NonNull RelationCallExp, @NonNull Relation> rInvocation2invokingRelation = 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 lazily created named CoreDomain in each Rule.
*/
private @NonNull Map<@NonNull Rule, @NonNull Map<@NonNull String, @NonNull CoreDomain>> rule2name2coreDomain
= new HashMap<@NonNull Rule, @NonNull Map<@NonNull String, @NonNull CoreDomain>>();
/**
* 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>>();
public QVTrToQVTc(@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.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) {
Key key = (Key)eo;
org.eclipse.ocl.pivot.Class identifies = key.getIdentifies();
assert identifies != null;
class2key.put(identifies, key);
}
// Populate bindsTo of DomainPattern
if (eo instanceof Pattern) {
Pattern p = (Pattern) eo;
for (Predicate pred : p.getPredicate()) {
OCLExpression conditionExpression = pred.getConditionExpression();
assert conditionExpression != null;
p.getBindsTo().addAll(getVarsOfExp(conditionExpression));
}
if (eo instanceof DomainPattern) {
DomainPattern dp = (DomainPattern) eo;
TemplateExp te = dp.getTemplateExpression();
dp.getBindsTo().add(te.getBindsTo());
if (te instanceof ObjectTemplateExp) {
dp.getBindsTo().addAll(getNestedBindToVariable((ObjectTemplateExp) te));
}
}
}
if (eo instanceof TemplateExp) {
TemplateExp te = (TemplateExp) eo;
Variable bindsTo = te.getBindsTo();
assert bindsTo != null;
variable2templateExp.put(bindsTo, te);
}
if (eo instanceof RelationCallExp) {
RelationCallExp ri = (RelationCallExp) eo;
Relation r = ri.getReferredRelation();
assert r != null;
Predicate p = (Predicate) ri.eContainer();
Pattern pattern = p.getPattern();
if (pattern.eContainer() instanceof Relation) {
Relation ir = (Relation) pattern.eContainer();
if (ir.getWhere() == pattern) {
List<RelationCallExp> relationCallExps = relationCallExpsForRelation.get(r);
if (relationCallExps != null) {
relationCallExps.add(ri);
} else {
List<RelationCallExp> callExps = new ArrayList<RelationCallExp>();
callExps.add(ri);
relationCallExpsForRelation.put(r, callExps);
}
rInvocation2invokingRelation.put(ri, ir);
}
}
}
if (eo instanceof Import) {
this.coreModel.getOwnedImports().add((Import) EcoreUtil.copy(eo));
}
}
}
public @NonNull Mapping createMapping() {
Mapping coreMapping = QVTcoreFactory.eINSTANCE.createMapping();
GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern();
coreMapping.setGuardPattern(guardPattern);
BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern();
coreMapping.setBottomPattern(bottomPattern);
return coreMapping;
}
// 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*/ @NonNull Transformation getCoreTransformation(@NonNull RelationalTransformation relationalTransformation) {
return ClassUtil.nonNullState(relationalTransformation2coreTransformation.get(relationalTransformation));
}
/* 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 Relation getInvokingRelationForRelationCallExp(@NonNull RelationCallExp rInvocation) {
return ClassUtil.nonNullState(rInvocation2invokingRelation.get(rInvocation));
}
public @Nullable Key getKeyforType(@NonNull Type type) {
return class2key.get(type);
}
// TODO bug 453863 // ?? this is suspect for more than 2 domains. // FIXME What is 'shared'? a) any two domains b) output/any-input c) all domains
/**
* Return the variables that are used by more than one domain of the relation and so must be middle variables.
*/
public @NonNull Set<@NonNull Variable> getMiddleDomainVariables(@NonNull Relation rRelation) {
Set<@NonNull Variable> rDomainVariables = new HashSet<@NonNull Variable>();
Set<@NonNull Variable> rMiddleDomainVariables = new HashSet<@NonNull Variable>();
for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) {
for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) {
for (@NonNull Variable rVariable : ClassUtil.nullFree(rDomainPattern.getBindsTo())) {
if (!rDomainVariables.add(rVariable)) {
rMiddleDomainVariables.add(rVariable); // Accumulate second (and higher) usages
}
}
}
}
return rMiddleDomainVariables;
}
private @NonNull Set<@NonNull Variable> getNestedBindToVariable(@NonNull ObjectTemplateExp ote) {
Set<@NonNull Variable> vars = new HashSet<@NonNull Variable>();
for (PropertyTemplateItem p : ote.getPart()) {
OCLExpression e = p.getValue();
assert e != null;
if (e instanceof ObjectTemplateExp) {
Variable bindsTo = ((ObjectTemplateExp)e).getBindsTo();
assert bindsTo != null;
vars.add(bindsTo);
vars.addAll(getNestedBindToVariable((ObjectTemplateExp) e));
} else {
vars.addAll(getVarsOfExp(e));
}
}
return vars;
}
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 qvtcSource
*/
public Resource getQvtcSource() {
return qvtcResource;
}
public @NonNull List<@NonNull RelationCallExp> getRelationCallExpsForRelation(@NonNull Relation r) {
return ClassUtil.nonNullState(relationCallExpsForRelation.get(r));
}
/* ============= Queries ============= */
public @NonNull StandardLibrary getStandardLibrary() {
return environmentFactory.getStandardLibrary();
}
/*public*/ @Nullable TemplateExp getTemplateExpression(@NonNull Variable dv) {
return variable2templateExp.get(dv);
}
/*public*/ org.eclipse.ocl.pivot.@NonNull Class getTraceClass(@NonNull Relation relation) {
return ClassUtil.nonNullState(relationToTraceClass.get(relation));
}
/*public*/ org.eclipse.ocl.pivot.@NonNull Package getTracePackage(@NonNull RelationalTransformation relationalTransformation) {
return ClassUtil.nonNullState(relationalTransformation2tracePackage.get(relationalTransformation));
}
/*
* Get variables occurring in an OCL expression
*/
public @NonNull Set<@NonNull Variable> getVarsOfExp(@NonNull OCLExpression e) {
Set<@NonNull Variable> variables = new HashSet<@NonNull Variable>();
for (EObject eObject : new TreeIterable(e, true)) {
if (eObject instanceof VariableExp) {
VariableDeclaration referredVariable = ((VariableExp)eObject).getReferredVariable();
if (referredVariable instanceof Variable) {
variables.add((Variable)referredVariable);
}
}
else if (eObject instanceof Variable) {
variables.add((Variable)eObject);
}
else if (eObject instanceof TemplateExp) {
Variable bindsTo = ((TemplateExp)eObject).getBindsTo();
if (bindsTo != null) {
variables.add(bindsTo);
}
if (eObject instanceof CollectionTemplateExp) {
Variable rest = ((CollectionTemplateExp)eObject).getRest();
if (rest != null) {
variables.add(rest);
}
}
}
}
return variables;
}
// 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 putRelationTrace(@NonNull Relation r, org.eclipse.ocl.pivot.@NonNull Class traceClass) {
relationToTraceClass.put(r, traceClass);
// putTrace(traceClass, r);
}
/*public*/ void putTracePackage(@NonNull RelationalTransformation rt, org.eclipse.ocl.pivot.@NonNull Package tracePackage) {
relationalTransformation2tracePackage.put(rt, tracePackage);
// putTrace(tracePackage, rt);
}
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 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 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);
transformToCoreTransformations(ClassUtil.nullFree(coreModel.getOwnedPackages()), ClassUtil.nullFree(relationModel.getOwnedPackages()));
// CompilerUtil.normalizeNameables(coreTransformations);
}
}
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);
for (@NonNull Rule rule : rules) {
if (rule instanceof Relation) {
Relation rRelation = (Relation)rule;
if (rRelation.isIsTopLevel()) {
QVTrToQVTc.SYNTHESIS.println("topLevel " + rRelation);
TopLevelRelationToMappingForEnforcement topLevelRelationToMappingForEnforcement = new TopLevelRelationToMappingForEnforcement(this, rRelation);
topLevelRelationToMappingForEnforcement.doTopLevelRelationToMappingForEnforcement();
}
}
}
// }
// 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.doInvokedRelationToMappingForEnforcement();
}
}
}
}
/* 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 transformToCoreTransformations(@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);
}
}
transformToCoreTransformations(ClassUtil.nullFree(corePackage.getOwnedPackages()), ClassUtil.nullFree(relationPackage.getOwnedPackages()));
}
}
public @NonNull List<@NonNull Package> transformToTracePackages() {
for (@NonNull EObject eObject : qvtrResource.getContents()) {
if (eObject instanceof RelationModel) {
transformToTracePackages(tracePackages, ClassUtil.nullFree(((RelationModel)eObject).getOwnedPackages()));
CompilerUtil.normalizeNameables(tracePackages);
}
}
return tracePackages;
}
private void transformToTracePackages(@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);
}
}
transformToTracePackages(tracePackages, ClassUtil.nullFree(relationPackage.getOwnedPackages()));
}
}
/**
* Lazily create the name CoreDomain for a coreRule.
*/
/*public*/ @NonNull CoreDomain whenCoreDomain(@NonNull Rule coreRule, @NonNull String name) {
Map<@NonNull String, @NonNull CoreDomain> name2coreDomain = rule2name2coreDomain.get(coreRule);
if (name2coreDomain == null) {
name2coreDomain = new HashMap<@NonNull String, @NonNull CoreDomain>();
rule2name2coreDomain.put(coreRule, name2coreDomain);
}
CoreDomain coreDomain = name2coreDomain.get(name);
if (coreDomain == null) {
coreDomain = QVTcoreBaseFactory.eINSTANCE.createCoreDomain();
coreDomain.setName(name);
coreDomain.setRule(coreRule);
name2coreDomain.put(name, coreDomain);
// putTrace(coreDomain, coreRule);
GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern();
coreDomain.setGuardPattern(guardPattern);
// putTrace(guardPattern, coreRule);
BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern();
coreDomain.setBottomPattern(bottomPattern);
// putTrace(bottomPattern, coreRule);
}
return coreDomain;
}
/**
* Lazily create the name Mapping for a coreTransformation.
*/
/*public*/ @NonNull Mapping whenMapping(@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);
if (coreMapping == null) {
coreMapping = createMapping();
putGlobalTrace(coreMapping, relation);
coreMapping.setName(name);
coreMapping.setTransformation(coreTransformation);
name2mapping.put(name, coreMapping);
}
return coreMapping;
}
/**
* 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;
}
}