/******************************************************************************* * Copyright (c) 2013, 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.oclinjunit; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.examples.codegen.analyzer.AS2CGVisitor; import org.eclipse.ocl.examples.codegen.analyzer.CodeGenAnalyzer; import org.eclipse.ocl.examples.codegen.cgmodel.CGClass; import org.eclipse.ocl.examples.codegen.cgmodel.CGModelFactory; import org.eclipse.ocl.examples.codegen.cgmodel.CGOperation; import org.eclipse.ocl.examples.codegen.cgmodel.CGPackage; import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter; import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement; import org.eclipse.ocl.examples.codegen.java.ImportUtils; import org.eclipse.ocl.examples.codegen.java.JavaCodeGenerator; import org.eclipse.ocl.examples.codegen.java.JavaGlobalContext; import org.eclipse.ocl.examples.codegen.java.JavaLocalContext; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.ids.TypeId; import org.eclipse.ocl.pivot.internal.complete.CompleteEnvironmentInternal; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal; import org.eclipse.ocl.pivot.utilities.ClassUtil; /** * JUnitCodeGenerator supports generation of an ExpressionInOCL for execution in a JUNit test. * The ExpressionInOCL is wrpapped in an Operation in a Class with a static INSTANCE to provide * the polymorphic implementation of a LibraryOperation. */ public class JUnitCodeGenerator extends JavaCodeGenerator { public static @NonNull String generateClassFile(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull ExpressionInOCL query, @NonNull String packageName, @NonNull String className) { CompleteEnvironmentInternal completeEnvironment = environmentFactory.getMetamodelManager().getCompleteEnvironment(); boolean savedIsCodeGenerator = completeEnvironment.isCodeGeneration(); try { completeEnvironment.setCodeGeneration(true); // Workaround for BUG 452621 JUnitCodeGenerator expressionInOCL2Class = new JUnitCodeGenerator(environmentFactory, true); return expressionInOCL2Class.generate(query, packageName, className); } finally { completeEnvironment.setCodeGeneration(savedIsCodeGenerator); } } protected final @NonNull JavaGlobalContext<JUnitCodeGenerator> globalContext = new JavaGlobalContext<JUnitCodeGenerator>(this); protected final @NonNull CodeGenAnalyzer cgAnalyzer; protected JUnitCodeGenerator(@NonNull EnvironmentFactoryInternal environmentFactory, boolean useNullAnnotations) { super(environmentFactory); getOptions().setUseNullAnnotations(useNullAnnotations); cgAnalyzer = new CodeGenAnalyzer(this); } protected @NonNull CGPackage createCGPackage(@NonNull ExpressionInOCL expInOcl, @NonNull String packageName, @NonNull String className) { CGPackage cgPackage = CGModelFactory.eINSTANCE.createCGPackage(); cgPackage.setName(packageName); // CGClass cgClass = CGModelFactory.eINSTANCE.createCGClass(); cgClass.setName(className); cgPackage.getClasses().add(cgClass); // Variable contextVariable = expInOcl.getOwnedContext(); if (contextVariable != null) { contextVariable.setIsRequired(false); // May be null for test } AS2CGVisitor as2cgVisitor = new JUnitAS2CGVisitor(cgAnalyzer); CGValuedElement cgBody = (CGValuedElement) ClassUtil.nonNullState(expInOcl.accept(as2cgVisitor)); CGOperation cgOperation = CGModelFactory.eINSTANCE.createCGLibraryOperation(); List<CGParameter> cgParameters = cgOperation.getParameters(); JavaLocalContext<?> localContext = globalContext.getLocalContext(cgOperation); if (localContext != null) { CGParameter evaluatorParameter = localContext.createEvaluatorParameter(); if (evaluatorParameter != null) { cgParameters.add(evaluatorParameter); } CGParameter typeIdParameter = localContext.createTypeIdParameter(); if (typeIdParameter != null) { cgParameters.add(typeIdParameter); } } if (contextVariable != null) { CGParameter cgContext = as2cgVisitor.getParameter(contextVariable, null); cgParameters.add(cgContext); } for (@SuppressWarnings("null")@NonNull Variable parameterVariable : expInOcl.getOwnedParameters()) { CGParameter cgParameter = as2cgVisitor.getParameter(parameterVariable, null); cgParameters.add(cgParameter); } cgOperation.setAst(expInOcl); Type type = expInOcl.getType(); assert type != null; TypeId asTypeId = PivotUtilInternal.getBehavioralType(type).getTypeId(); cgOperation.setTypeId(cgAnalyzer.getTypeId(asTypeId)); cgOperation.setName(globalContext.getEvaluateName()); cgOperation.setBody(cgBody); cgClass.getOperations().add(cgOperation); return cgPackage; } protected @NonNull String generate(@NonNull ExpressionInOCL expInOcl, @NonNull String packageName, @NonNull String className) { CGPackage cgPackage = createCGPackage(expInOcl, packageName, className); optimize(cgPackage); List<CGValuedElement> sortedGlobals = prepareGlobals(); JUnitCG2JavaClassVisitor cg2JavaClassVisitor = new JUnitCG2JavaClassVisitor(this, expInOcl, sortedGlobals); cg2JavaClassVisitor.safeVisit(cgPackage); Set<String> allImports = cg2JavaClassVisitor.getAllImports(); Map<@NonNull String, @Nullable String> long2ShortImportNames = ImportUtils.getLong2ShortImportNames(allImports); return ImportUtils.resolveImports(cg2JavaClassVisitor.toString(), long2ShortImportNames, false); } @Override public @NonNull CodeGenAnalyzer getAnalyzer() { return cgAnalyzer; } @Override public @NonNull JavaGlobalContext<JUnitCodeGenerator> getGlobalContext() { return globalContext; } }