/******************************************************************************* * Copyright (c) 2012, 2015 CEA LIST and others. * 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: * E.D.Willink(CEA LIST) - Initial API and implementation *******************************************************************************/ package org.eclipse.ocl.examples.codegen.oclinecore; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.URIUtil; import org.eclipse.emf.codegen.ecore.genmodel.GenAnnotation; import org.eclipse.emf.codegen.ecore.genmodel.GenClass; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; 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.common.EMFPlugin; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.BasicMonitor; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EOperation; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.common.OCLCommon; import org.eclipse.ocl.common.OCLConstants; import org.eclipse.ocl.common.internal.options.CodeGenerationMode; import org.eclipse.ocl.common.internal.options.CommonOptions; import org.eclipse.ocl.examples.codegen.common.PivotQueries; import org.eclipse.ocl.examples.codegen.generator.AbstractGenModelHelper; import org.eclipse.ocl.examples.codegen.java.ImportUtils; import org.eclipse.ocl.examples.codegen.model.CGLibrary; import org.eclipse.ocl.pivot.Constraint; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.Operation; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.internal.ecore.as2es.AS2Ecore; import org.eclipse.ocl.pivot.internal.ecore.es2as.Ecore2AS; import org.eclipse.ocl.pivot.internal.manager.MetamodelManagerInternal; import org.eclipse.ocl.pivot.internal.utilities.AS2Moniker; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.internal.utilities.OCLInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotConstantsInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal; import org.eclipse.ocl.pivot.resource.BasicProjectManager; import org.eclipse.ocl.pivot.resource.ProjectManager; import org.eclipse.ocl.pivot.util.PivotPlugin; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.ocl.pivot.utilities.PivotConstants; import org.eclipse.ocl.pivot.utilities.PivotUtil; import org.eclipse.uml2.codegen.ecore.genmodel.util.UML2GenModelUtil; public class OCLinEcoreGenModelGeneratorAdapter extends GenBaseGeneratorAdapter { public static final @NonNull String OCL_GENMODEL_URI = "http://www.eclipse.org/OCL/GenModel"; public static final @NonNull String USE_DELEGATES_KEY = "Use Delegates"; public static final @NonNull String USE_NULL_ANNOTATIONS_KEY = "Use Null Annotations"; /** * Return true if the genModel has a {@link #OCL_GENMODEL_URI} GenAnnotation with a * {@link #USE_DELEGATES_KEY} detail set to true, or if there is no such GenAnnotation and the * global preference {@link CommonOptions#CODE_GENERATION_MODE} * has been set to {@link CodeGenerationMode#DELEGATED} */ public static boolean useDelegates(@NonNull GenModel genModel) { GenAnnotation genAnnotation = genModel.getGenAnnotation(OCL_GENMODEL_URI); if (genAnnotation != null) { EMap<String, String> details = genAnnotation.getDetails(); if (details.containsKey(USE_DELEGATES_KEY)) { return Boolean.valueOf(details.get(USE_DELEGATES_KEY)); } } CodeGenerationMode preference = CommonOptions.CODE_GENERATION_MODE.getPreferredValue(); if (preference == CodeGenerationMode.DELEGATED) { return true; } return false; } /** * Return true if the genModel has a {@link #OCL_GENMODEL_URI} GenAnnotation with a * {@link #USE_NULL_ANNOTATIONS_KEY} detail set to true. */ public static boolean useNullAnnotations(@NonNull GenModel genModel) { GenAnnotation genAnnotation = genModel.getGenAnnotation(OCL_GENMODEL_URI); if (genAnnotation != null) { EMap<String, String> details = genAnnotation.getDetails(); if (details.containsKey(USE_NULL_ANNOTATIONS_KEY)) { return Boolean.valueOf(details.get(USE_NULL_ANNOTATIONS_KEY)); } } // CodeGenerationMode preference = OCLCommon.getPreference(CommonOptions.CODE_GENERATION_MODE, null); // if (preference == CodeGenerationMode.DELEGATED) { // return true; // } return false; } protected static interface Edit { void undo(); } /** * OCLinEcoreStateAdapter caches properties of the input model during doPreGenerate and accumulates all * in-memory modifications so that they are reverted during doPostGenerate. */ protected class OCLinEcoreStateAdapter implements Adapter { protected class AddEAnnotation implements Edit { private final @NonNull List<EAnnotation> eAnnotations; private final @NonNull EAnnotation eAnnotation; @SuppressWarnings("null") public AddEAnnotation(/*@NonNull*/ List<EAnnotation> eAnnotations, @NonNull EAnnotation eAnnotation) { this.eAnnotations = eAnnotations; this.eAnnotation = eAnnotation; eAnnotations.add(eAnnotation); } @Override public void undo() { eAnnotations.remove(eAnnotation); } } protected class AddEOperation implements Edit { private final @NonNull List<EOperation> eOperations; private final @NonNull EOperation eOperation; @SuppressWarnings("null") public AddEOperation(/*@NonNull*/ List<EOperation> eOperations, @NonNull EOperation eOperation) { this.eOperations = eOperations; this.eOperation = eOperation; eOperations.add(eOperation); } @Override public void undo() { eOperations.remove(eOperation); } } protected class AddModelPluginVariable implements Edit { private final @NonNull String modelPluginVariable; public AddModelPluginVariable(@NonNull String modelPluginVariable) { this.modelPluginVariable = modelPluginVariable; genModel.getModelPluginVariables().add(modelPluginVariable); } @Override public void undo() { genModel.getModelPluginVariables().remove(modelPluginVariable); } } protected class RemoveEAnnotation implements Edit { private final @NonNull EAnnotation eAnnotation; private final @NonNull List<EAnnotation> eAnnotations; private final int index; @SuppressWarnings("null") public RemoveEAnnotation(@NonNull EAnnotation eAnnotation) { this.eAnnotation = eAnnotation; this.eAnnotations = ((EModelElement)eAnnotation.eContainer()).getEAnnotations(); this.index = eAnnotations.indexOf(eAnnotation); eAnnotations.remove(eAnnotation); } @Override public void undo() { eAnnotations.add(index, eAnnotation); } } protected class SetEAnnotationDetail implements Edit { private final @NonNull EAnnotation eAnnotation; private final @NonNull String detailName; private final int index; private final @Nullable String value; public SetEAnnotationDetail(@NonNull EAnnotation eAnnotation, @NonNull String detailName) { // RemoveEAnnotationDetail this.eAnnotation = eAnnotation; this.detailName = detailName; EMap<String, String> details = eAnnotation.getDetails(); this.index = details.indexOf(detailName); this.value = details.get(detailName); if (index >= 0) { details.remove(index); } } public SetEAnnotationDetail(@NonNull EAnnotation eAnnotation, @NonNull String detailName, @Nullable String value) { this.eAnnotation = eAnnotation; this.detailName = detailName; EMap<String, String> details = eAnnotation.getDetails(); this.index = details.indexOf(detailName); this.value = details.put(detailName, value); } @Override public void undo() { EMap<String, String> details = eAnnotation.getDetails(); if (index < 0) { details.remove(detailName); } else { details.put(detailName, value); int newIndex = details.indexOf(detailName); if (newIndex != index) { details.move(index, newIndex); } } } } protected class SetInvocationDelegates implements Edit { private final @NonNull EPackage ePackage; private final @NonNull List<String> invocationDelegates; @SuppressWarnings("null") public SetInvocationDelegates(@NonNull EPackage ePackage) { this.ePackage = ePackage; this.invocationDelegates = EcoreUtil.getInvocationDelegates(ePackage); EcoreUtil.setInvocationDelegates(ePackage, pruneDelegates(invocationDelegates)); } @Override public void undo() { EcoreUtil.setInvocationDelegates(ePackage, invocationDelegates); } } protected class SetSettingDelegates implements Edit { private final @NonNull EPackage ePackage; private final @NonNull List<String> settingDelegates; @SuppressWarnings("null") public SetSettingDelegates(@NonNull EPackage ePackage) { this.ePackage = ePackage; this.settingDelegates = EcoreUtil.getSettingDelegates(ePackage); EcoreUtil.setSettingDelegates(ePackage, pruneDelegates(settingDelegates)); } @Override public void undo() { EcoreUtil.setSettingDelegates(ePackage, settingDelegates); } } protected class SetValidationDelegates implements Edit { private final @NonNull EPackage ePackage; private final @NonNull List<String> validationDelegates; @SuppressWarnings("null") public SetValidationDelegates(@NonNull EPackage ePackage) { this.ePackage = ePackage; this.validationDelegates = EcoreUtil.getValidationDelegates(ePackage); EcoreUtil.setValidationDelegates(ePackage, pruneDelegates(validationDelegates)); } @Override public void undo() { EcoreUtil.setValidationDelegates(ePackage, validationDelegates); } } protected final @NonNull OCLInternal ocl; protected final @NonNull GenModel genModel; /** * The Java source text defining the constants used by operation and property bodies that must be emitted * as part of the Tables class. */ private @NonNull Map<@NonNull GenPackage, @NonNull String> constantTexts = new HashMap<@NonNull GenPackage, @NonNull String>(); /** * The edits applied to the in-memory GenModel that must be undone during postGenerate. */ private @NonNull List<Edit> edits = new ArrayList<Edit>(); private OCLinEcoreStateAdapter(@NonNull GenModel genModel) { Resource eResource = genModel.eResource(); ResourceSet resourceSet = eResource != null ? eResource.getResourceSet() : null; EnvironmentFactoryInternal environmentFactory = resourceSet != null ? PivotUtilInternal.findEnvironmentFactory(resourceSet) : null; if (environmentFactory == null) { ProjectManager projectMap = BasicProjectManager.createDefaultProjectManager(); projectMap.initializeResourceSet(resourceSet); this.ocl = OCLInternal.newInstance(projectMap, resourceSet); } else { this.ocl = OCLInternal.newInstance(environmentFactory); } this.genModel = genModel; genModel.eAdapters().add(this); } protected void addEAnnotationDetail(@NonNull EModelElement eModelElement, /*@NonNull*/ String sourceURI, @NonNull String detailName, @NonNull String value) { EAnnotation eAnnotation = eModelElement.getEAnnotation(sourceURI); if (eAnnotation == null) { eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); eAnnotation.setSource(sourceURI); edits.add(new AddEAnnotation(eModelElement.getEAnnotations(), eAnnotation)); } edits.add(new SetEAnnotationDetail(eAnnotation, detailName, value)); } protected void addEOperation(@NonNull EClass eClass, @NonNull EOperation eOperation) { edits.add(new AddEOperation(eClass.getEOperations(), eOperation)); } protected void addModelPluginVariable(@NonNull String modelPluginVariable) { edits.add(new AddModelPluginVariable(modelPluginVariable)); } protected void convertConstraintToOperation(@NonNull Ecore2AS ecore2as, @NonNull GenModel genModel, @NonNull EClass eClass, @NonNull String key, @NonNull String body, @Nullable String message) { org.eclipse.ocl.pivot.Class pType = ecore2as.getCreated(org.eclipse.ocl.pivot.Class.class, eClass); if (pType != null) { List<Constraint> ownedInvariants = pType.getOwnedInvariants(); for (Constraint rule : ownedInvariants) { String ruleName = rule.getName(); if (ruleName == null) { ruleName = ""; } if (ruleName.equals(key)) { String prefix = UML2GenModelUtil.getInvariantPrefix(genModel); if (prefix == null) { prefix = ""; } EOperation eOperation = AS2Ecore.createConstraintEOperation(rule, prefix + ruleName, null); addEOperation(eClass, eOperation); ecore2as.addMapping(eOperation, rule); if (message != null) { body = PivotUtil.createTupleValuedConstraint(body, null, message); } addEAnnotationDetail(eOperation, PivotConstants.OCL_DELEGATE_URI_PIVOT, "body", body); } } } } protected void convertConstraintsToOperations(@NonNull MetamodelManagerInternal metamodelManager) { List<GenPackage> genPackages = genModel.getAllGenPackagesWithClassifiers(); for (GenPackage genPackage : genPackages) { EPackage ecorePackage = genPackage.getEcorePackage(); Resource ecoreResource = ecorePackage.eResource(); if (ecoreResource != null) { Ecore2AS ecore2as = Ecore2AS.getAdapter(ecoreResource, metamodelManager.getEnvironmentFactory()); for (GenClass genClass : genPackage.getGenClasses()) { EClass eClass = genClass.getEcoreClass(); if (eClass != null) { List<EAnnotation> obsoleteAnnotations = null; for (EAnnotation eAnnotation : eClass.getEAnnotations()) { String source = eAnnotation.getSource(); if (OCLCommon.isDelegateURI(source)) { @SuppressWarnings("deprecation") String messageAnnotationDetailSuffix = PivotConstantsInternal.MESSAGE_ANNOTATION_DETAIL_SUFFIX; EMap<String, String> details = eAnnotation.getDetails(); for (String key : details.keySet()) { if ((key != null) && !key.endsWith(messageAnnotationDetailSuffix)) { String expression = details.get(key); String messageExpression = details.get(key + messageAnnotationDetailSuffix); if (expression != null) { convertConstraintToOperation(ecore2as, genModel, eClass, key, expression, messageExpression); } } } if (obsoleteAnnotations == null) { obsoleteAnnotations = new ArrayList<EAnnotation>(); } obsoleteAnnotations.add(eAnnotation); } if (EcorePackage.eNS_URI.equals(source)) { removeEAnnotationDetail(eAnnotation, "constraints"); } } if (obsoleteAnnotations != null) { for (EAnnotation eAnnotation : obsoleteAnnotations) { removeEAnnotation(eAnnotation); } } genClass.initialize(eClass); } } } } } /** * Create a Map of feature identification to body to be embedded in the EMF model. * @throws IOException */ public @NonNull Map<@NonNull String, @NonNull String> createFeatureBodies(@NonNull GenModel genModel) throws IOException { Map<@NonNull String, @NonNull String> allResults = new HashMap<@NonNull String, @NonNull String>(); @SuppressWarnings("null")@NonNull List<GenPackage> allGenPackagesWithClassifiers = genModel.getAllGenPackagesWithClassifiers(); List<@NonNull GenPackage> genPackages = ClassUtil.nullFree(allGenPackagesWithClassifiers); for (GenPackage genPackage : genPackages) { OCLinEcoreCodeGenerator.generatePackage(genPackage, allResults, constantTexts); } List<@NonNull String> resultsKeys = new ArrayList<@NonNull String>(allResults.keySet()); Collections.sort(resultsKeys); return allResults; } public void dispose() { genModel.eAdapters().remove(this); for (int i = edits.size(); --i >= 0; ) { Edit edit = edits.get(i); edit.undo(); } ocl.dispose(); } public @NonNull Map<@NonNull GenPackage, @NonNull String> getConstantTexts() { return constantTexts; } protected @NonNull OCLinEcoreGenModelGeneratorAdapter getGenModelGeneratorAdapter() { return OCLinEcoreGenModelGeneratorAdapter.this; } public @NonNull MetamodelManagerInternal getMetamodelManager() { return ocl.getMetamodelManager(); } @Override public @NonNull GenModel getTarget() { return genModel; } protected void installJavaBodies(@NonNull MetamodelManagerInternal metamodelManager, @NonNull GenModel genModel, @NonNull Map<String, String> results) { List<GenPackage> genPackages = genModel.getAllGenPackagesWithClassifiers(); for (GenPackage genPackage : genPackages) { EPackage ecorePackage = genPackage.getEcorePackage(); Resource ecoreResource = ecorePackage.eResource(); if (ecoreResource != null) { Ecore2AS ecore2as = Ecore2AS.getAdapter(ecoreResource, metamodelManager.getEnvironmentFactory()); for (GenClass genClass : genPackage.getGenClasses()) { EClass eClass = genClass.getEcoreClass(); if (eClass != null) { for (@SuppressWarnings("null")@NonNull EOperation eOperation : eClass.getEOperations()) { installOperation(ecore2as, eOperation, results); } for (@SuppressWarnings("null")@NonNull EStructuralFeature eFeature : eClass.getEStructuralFeatures()) { installProperty(ecore2as, eFeature, results); } } } } } } protected void installOperation(@NonNull Ecore2AS ecore2as, @NonNull EOperation eOperation, @NonNull Map<String, String> results) { Element pOperation = ecore2as.getCreated(Element.class, eOperation); String fragmentURI = null; if (pOperation instanceof Operation) { fragmentURI = EcoreUtil.getURI(pOperation).fragment().toString(); } else if (pOperation instanceof Constraint) { Constraint constraint = (Constraint) pOperation; fragmentURI = EcoreUtil.getURI(constraint.eContainer()).fragment().toString() + "==" + constraint.getName(); } String body = fragmentURI != null ? results.get(fragmentURI) : null; if ((body == null) || ((body = body.trim()).length() == 0)) { String javaBody = EcoreUtil.getAnnotation(eOperation, GenModelPackage.eNS_URI, "body"); if (javaBody != null) { return; // Leave an existing Java body unaffected } body = "throw new UnsupportedOperationException(); // FIXME Unimplemented " + (pOperation != null ? AS2Moniker.toString(pOperation) : ""); } addEAnnotationDetail(eOperation, GenModelPackage.eNS_URI, "body", body); removeEAnnotation(eOperation.getEAnnotation(OCLConstants.OCL_DELEGATE_URI)); removeEAnnotation(eOperation.getEAnnotation(OCLConstants.OCL_DELEGATE_URI_LPG)); removeEAnnotation(eOperation.getEAnnotation(PivotConstants.OCL_DELEGATE_URI_PIVOT)); removeEAnnotation(eOperation.getEAnnotation(UML2GenModelUtil.UML2_GEN_MODEL_PACKAGE_1_1_NS_URI)); } protected void installProperty(@NonNull Ecore2AS ecore2as, @NonNull EStructuralFeature eFeature, @NonNull Map<String, String> results) { Property pProperty = ecore2as.getCreated(Property.class, eFeature); String fragmentURI = EcoreUtil.getURI(pProperty).fragment().toString(); String body = results.get(fragmentURI); if (body == null) { String javaBody = EcoreUtil.getAnnotation(eFeature, GenModelPackage.eNS_URI, "get"); if (javaBody != null) { return; // Leave an existing Java body unaffected } body = "throw new UnsupportedOperationException(); // FIXME Unimplemented " + (pProperty != null ? AS2Moniker.toString(pProperty) : ""); } addEAnnotationDetail(eFeature, GenModelPackage.eNS_URI, "get", body); // addEAnnotationDetail(eFeature, GenModelPackage.eNS_URI, "body", body); removeEAnnotation(eFeature.getEAnnotation(OCLConstants.OCL_DELEGATE_URI)); removeEAnnotation(eFeature.getEAnnotation(OCLConstants.OCL_DELEGATE_URI_LPG)); removeEAnnotation(eFeature.getEAnnotation(PivotConstants.OCL_DELEGATE_URI_PIVOT)); removeEAnnotation(eFeature.getEAnnotation(UML2GenModelUtil.UML2_GEN_MODEL_PACKAGE_1_1_NS_URI)); } /** * Eliminate all OCL validation/setting/invocation delegates. */ protected void pruneDelegates(@NonNull GenModel genModel) { for (GenPackage genPackage : genModel.getAllGenPackagesWithClassifiers()) { EPackage ePackage = genPackage.getEcorePackage(); if ((ePackage != null) && hasDelegates(ePackage)) { edits.add(new SetValidationDelegates(ePackage)); edits.add(new SetSettingDelegates(ePackage)); edits.add(new SetInvocationDelegates(ePackage)); } } } protected @NonNull List<String> pruneDelegates(@Nullable List<String> oldDelegates) { List<String> newDelegates = new ArrayList<String>(); if (oldDelegates != null) { for (String aDelegate : oldDelegates) { if (!OCLCommon.isDelegateURI(aDelegate)) { newDelegates.add(aDelegate); } } } return newDelegates; } protected void removeEAnnotation(@Nullable EAnnotation oclAnnotation) { if (oclAnnotation != null) { edits.add(new RemoveEAnnotation(oclAnnotation)); } } protected void removeEAnnotationDetail(@NonNull EAnnotation eAnnotation, @NonNull String detailName) { edits.add(new SetEAnnotationDetail(eAnnotation, detailName)); } @Override public boolean isAdapterForType(Object type) { return false; } @Override public void notifyChanged(Notification notification) {} @Override public void setTarget(Notifier newTarget) { assert (newTarget == null) || (newTarget == genModel); } } public OCLinEcoreGenModelGeneratorAdapter(@NonNull OCLinEcoreGeneratorAdapterFactory generatorAdapterFactory) { super(generatorAdapterFactory); } protected void createDispatchTables(@NonNull GenModel genModel, @NonNull Monitor monitor) throws IOException { try { Map<@NonNull GenPackage, @NonNull String> constantTexts = getStateAdapter(genModel).getConstantTexts(); String lineDelimiter = getLineDelimiter(genModel); genModel.setLineDelimiter(lineDelimiter); File projectFolder = getProjectFolder(genModel); List<GenPackage> genPackages = genModel.getAllGenPackagesWithClassifiers(); for (@SuppressWarnings("null")@NonNull GenPackage genPackage : genPackages) { OCLinEcoreTables generateTables = new OCLinEcoreTables(genPackage); String tablesClass = generateTables.getTablesClassName(); String dir = genPackage.getReflectionPackageName().replace(".", "/"); String constants = constantTexts.get(genPackage); generateTables.generateTablesClass(constants); String str = generateTables.toString(); File tablesFolder = new File(projectFolder, dir); tablesFolder.mkdirs(); File file = new File(tablesFolder, tablesClass + ".java"); FileWriter testFile = new FileWriter(file); testFile.append(str); testFile.close(); } } finally { genModel.setLineDelimiter(null); } } @Override protected Diagnostic doPostGenerate(Object object, Object projectType) { assert object != null; GenModel genModel = (GenModel) object; OCLinEcoreStateAdapter stateAdapter = findStateAdapter(genModel); if (stateAdapter != null) { stateAdapter.dispose(); stateAdapter = null; } return super.doPostGenerate(object, projectType); } @Override protected Diagnostic doPreGenerate(Object object, Object projectType) { assert object != null; GenModel genModel = (GenModel) object; try { if ((projectType == MODEL_PROJECT_TYPE) && !useDelegates(genModel) && hasDelegates(genModel)) { OCLinEcoreStateAdapter stateAdapter = getStateAdapter(genModel); List<String> modelPluginVariables = genModel.getModelPluginVariables(); if (!modelPluginVariables.contains(PivotPlugin.PLUGIN_ID)) { // FIXME delete me BUG 401862 stateAdapter.addModelPluginVariable(PivotPlugin.PLUGIN_ID); } if (!modelPluginVariables.contains("org.eclipse.ocl.examples.codegen")) { // FIXME delete me BUG 401862 stateAdapter.addModelPluginVariable("org.eclipse.ocl.examples.codegen"); } if (useNullAnnotations(genModel) && !modelPluginVariables.contains("org.eclipse.jdt.annotation")) { stateAdapter.addModelPluginVariable("org.eclipse.jdt.annotation"); } for (GenPackage genPackage : genModel.getAllGenPackagesWithClassifiers()) { createImportManager(genPackage.getReflectionPackageName(), genPackage.getFactoryInterfaceName() + AbstractGenModelHelper.TABLES_CLASS_SUFFIX); // Only used to suppress NPE } Resource genResource = genModel.eResource(); ResourceSet resourceSet = genResource.getResourceSet(); if (resourceSet == null) { throw new NullPointerException("No ResourceSet for genmodel"); } MetamodelManagerInternal metamodelManager = stateAdapter.getMetamodelManager(); metamodelManager.getStandardLibrary().getOclAnyType(); for (GenPackage genPackage : genModel.getGenPackages()) { EPackage ecorePackage = genPackage.getEcorePackage(); org.eclipse.ocl.pivot.Package asPackage = metamodelManager.getASOfEcore(org.eclipse.ocl.pivot.Package.class, ecorePackage); assert asPackage != null; } metamodelManager.installRoot(CGLibrary.getDefaultModel()); stateAdapter.convertConstraintsToOperations(metamodelManager); Map<@NonNull String, @NonNull String> results = stateAdapter.createFeatureBodies(genModel); for (String key : results.keySet()) { String oldBody = results.get(key); assert oldBody != null; String newBody = ImportUtils.rewriteManagedImports(oldBody, null); // FIXME transfer imports between CG sessions results.put(key, newBody); } stateAdapter.installJavaBodies(metamodelManager, genModel, results); stateAdapter.pruneDelegates(genModel); } } catch (Exception e) { Throwable t = e instanceof WrappedException ? ((WrappedException)e).getCause() : e;; BasicDiagnostic thisDiagnostic = new BasicDiagnostic(Diagnostic.ERROR, getClass().getPackage().getName(), 0, "Failed to pre-generate " + genModel.getModelPluginID() + " constraints", new Object[]{t}); Diagnostic thatDiagnostic = super.doPreGenerate(object, projectType); if (thatDiagnostic.getSeverity() == Diagnostic.OK) { return thisDiagnostic; } else { thatDiagnostic.getChildren().add(thisDiagnostic); return thatDiagnostic; } } return super.doPreGenerate(object, projectType); } protected @Nullable OCLinEcoreStateAdapter findStateAdapter(@NonNull GenModel genModel) { for (Adapter adapter : genModel.eAdapters()) { if ((adapter instanceof OCLinEcoreStateAdapter) && (((OCLinEcoreStateAdapter)adapter).getGenModelGeneratorAdapter() == this)) { return (OCLinEcoreStateAdapter) adapter; } } return null; } @Override protected Diagnostic generateModel(Object object, Monitor monitor) { assert object != null; GenModel genModel = (GenModel) object; OCLinEcoreStateAdapter stateAdapter = findStateAdapter(genModel); try { // if (!useDelegates(genModel) && hadDelegates.contains(genModel)) { if (stateAdapter != null) { monitor.beginTask("", 4); monitor.subTask("Generating Dispatch Tables"); ensureProjectExists (genModel.getModelDirectory(), genModel, MODEL_PROJECT_TYPE, genModel.isUpdateClasspath(), createMonitor(monitor, 1)); if (getImportManager() == null) { for (GenPackage genPackage : genModel.getAllGenPackagesWithClassifiers()) { createImportManager(genPackage.getReflectionPackageName(), genPackage.getFactoryInterfaceName() + AbstractGenModelHelper.TABLES_CLASS_SUFFIX); // Only used to suppress NPE } } createDispatchTables(genModel, monitor); monitor.worked(1); monitor.worked(1); if (EMFPlugin.IS_ECLIPSE_RUNNING) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); String modelProjectDirectory = genModel.getModelProjectDirectory(); IProject modelProject = workspace.getRoot().getProject(modelProjectDirectory); modelProject.refreshLocal(IResource.DEPTH_INFINITE, BasicMonitor.toIProgressMonitor(monitor)); } monitor.worked(1); } } catch (Exception e) { BasicDiagnostic thisDiagnostic = new BasicDiagnostic(Diagnostic.ERROR, getClass().getPackage().getName(), 0, "Failed to generate " + genModel.getModelPluginID() + " tables and bodies", new Object[]{e}); // Diagnostic thatDiagnostic = super.generateModel(object, monitor); // if (thatDiagnostic.getSeverity() == Diagnostic.OK) { return thisDiagnostic; // } // else { // thatDiagnostic.getChildren().add(thisDiagnostic); // return thatDiagnostic; // } } return super.generateModel(object, monitor); } /** * Deduce the required line delimiter from the usage in the .project file. */ protected String getLineDelimiter(GenModel genModel) { String modelProjectDirectory = genModel.getModelProjectDirectory() + "/.project"; URI workspacePath = URI.createURI(modelProjectDirectory); String targetFileEncoding = getEncoding(workspacePath); return getLineDelimiter(workspacePath, targetFileEncoding); } protected @NonNull File getProjectFolder(@NonNull GenModel genModel) { String modelProjectDirectory = genModel.getModelProjectDirectory(); String modelDirectory = genModel.getModelDirectory(); if (EMFPlugin.IS_ECLIPSE_RUNNING) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject modelProject = workspace.getRoot().getProject(modelProjectDirectory); IPath javaSource = new Path(modelDirectory); IFolder folder = modelProject.getParent().getFolder(javaSource); java.net.URI locationURI = ClassUtil.nonNullState(folder.getLocationURI()); return ClassUtil.nonNullState(URIUtil.toFile(locationURI)); } else { URI locationURI = URI.createPlatformResourceURI(modelDirectory, true); ResourceSet resourceSet = genModel.eResource().getResourceSet(); URIConverter uriConverter = resourceSet != null ? resourceSet.getURIConverter() : URIConverter.INSTANCE; URI normalizedURI = uriConverter.normalize(locationURI); return new File(normalizedURI.toFileString()); } } protected @NonNull OCLinEcoreStateAdapter getStateAdapter(@NonNull GenModel genModel) { for (Adapter adapter : genModel.eAdapters()) { if ((adapter instanceof OCLinEcoreStateAdapter) && (((OCLinEcoreStateAdapter)adapter).getGenModelGeneratorAdapter() == this)) { return (OCLinEcoreStateAdapter) adapter; } } return new OCLinEcoreStateAdapter(genModel); } protected boolean hasConstraints(org.eclipse.ocl.pivot.Class pivotClass) { if (pivotClass.getOwnedInvariants().size() > 0) { return true; } for (Operation operation : PivotQueries.getOperations(pivotClass)) { if (operation.getOwnedPreconditions().size() > 0) { return true; } if (operation.getOwnedPostconditions().size() > 0) { return true; } if (operation.getBodyExpression() != null) { return true; } } for (Property property : PivotQueries.getProperties(pivotClass)) { if (property.getOwnedExpression() != null) { return true; } } return false; } /** * Return true if any local GenPackage is for an EPackage that has OCL validation/setting/invocation delegates. */ protected boolean hasDelegates(@NonNull GenModel genModel) { for (GenPackage genPackage : genModel.getAllGenPackagesWithClassifiers()) { EPackage ePackage = genPackage.getEcorePackage(); if ((ePackage != null) && hasDelegates(ePackage)) { return true; } } return false; } protected boolean hasDelegates(@NonNull EPackage ePackage) { List<String> validationDelegates = EcoreUtil.getValidationDelegates(ePackage); for (String validationDelegate : validationDelegates) { if (OCLCommon.isDelegateURI(validationDelegate)) { return true; } } List<String> settingDelegates = EcoreUtil.getSettingDelegates(ePackage); for (String settingDelegate : settingDelegates) { if (OCLCommon.isDelegateURI(settingDelegate)) { return true; } } List<String> invocationDelegates = EcoreUtil.getInvocationDelegates(ePackage); for (String invocationDelegate : invocationDelegates) { if (OCLCommon.isDelegateURI(invocationDelegate)) { return true; } } return false; } }