/* * Copyright (C) 2008-2010 by Claas Wilke (claas.wilke@tu-dresden.de) * * This file is part of the OCL2Java Code Generator of Dresden OCL. * * Dresden OCL is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your option) * any later version. * * Dresden OCL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License along * with Dresden OCL. If not, see <http://www.gnu.org/licenses/>. */ package org.dresdenocl.tools.codegen.ocl2java.code.impl; import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; import java.util.Stack; import java.util.TreeMap; import java.util.TreeSet; import org.dresdenocl.essentialocl.expressions.Variable; import org.dresdenocl.pivotmodel.Type; import org.dresdenocl.tools.codegen.code.ITransformedCode; import org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment; import org.dresdenocl.tools.template.ITemplate; /** * <p> * This class provides methods to get name for variables and fields during code * transformation. * </p> * * @author Claas Wilke */ public class Ocl2JavaEnvironment implements IOcl2JavaEnvironment { /** Names for generated aspects of Body constraints having no specific name. */ public static final String BODY_ASPECT_NAME = "BodyAspect"; /** Names for generated variable for result value. */ protected static final String BODY_RESULT_VAR_NAME = "bodyResult"; /** * Names for generated aspects of Definition constraints having no specific * name. */ public static final String DEF_ASPECT_NAME = "DefAspect"; /** * Names for generated aspects of Derive constraints having no specific * name. */ public static final String DERIVE_ASPECT_NAME = "DeriveAspect"; /** * Names for generated aspects of Initial constraints having no specific * name. */ public static final String INIT_ASPECT_NAME = "InitAspect"; /** * Names for generated aspects of Invariant constraints having no specific * name. */ public static final String INV_ASPECT_NAME = "InvAspect"; /** * Names for generated aspects of Postcondition constraints having no * specific name. */ public static final String POST_ASPECT_NAME = "PostAspect"; /** * Names for generated aspects of Precondition constraints having no * specific name. */ public static final String PRE_ASPECT_NAME = "PreAspect"; /** Names for generated variable for atPre value. */ protected static final String AT_PRE_VAR_NAME = "atPreValue"; /** Names for generated variable for collection value. */ protected static final String COLLECTION_VAR_NAME = "collection"; /** Names for generated variable for compoarator value. */ protected static final String COMPARATOR_VAR_NAME = "comparator"; /** Names for generated variable for index value. */ protected static final String INDEX_VAR_NAME = "index"; /** Names for generated variable for IfExpression result value. */ protected static final String IF_EXP_RESULT_VAR_NAME = "ifExpResult"; /** Names for generated variable for iterator variable. */ protected static final String ITERATOR_EXP_ITERATOR_VAR_NAME = "anElement"; /** Names for generated variable for result value. */ protected static final String RESULT_VAR_NAME = "result"; /** Names for generated variable for to visit collections. */ protected static final String TO_VISIT_VAR_NAME = "toVisit"; /** Names for generated variable for tuple value. */ protected static final String TUPLE_VAR_NAME = "tuple"; /** * The canonical names of all classes which use the special OCL operation * allInstances(). */ protected Set<String> allInstancesClasses = new TreeSet<String>(); /** * The {@link ITransformedCode} of Expressions whose atPre value shall be * stored as key, and their transformed type and name of the variable in * which they shall be stored as {@link String} array. */ protected Map<ITransformedCode, Object[]> atPreValues = new IdentityHashMap<ITransformedCode, Object[]>(); /** Counter for names for generated variables for atPre values. */ protected int atPreVarNameCounter = 0; /** Counter for names for generated body constraint aspects. */ protected int bodyAspectNameCounter = 0; /** Counter for names for generated variables for body result values. */ protected int bodyResultVarCounter = 0; /** * The call paths of all properties which are called for Constraint * evaluation. */ protected Set<String> calledProperties = new TreeSet<String>(); /** * Contains {@link ITemplate}s of transformed Java classes which are used to * extend constrained classes. */ protected Map<String, ITemplate> classTemplates = new TreeMap<String, ITemplate>(); /** Counter for names for generated variables for collection values. */ protected int collectionVarCounter = 0; /** Counter for names for generated variables for comparator values. */ protected int comparatorVarCounter = 0; /** Counter for names for generated defintion constraint aspects. */ protected int defAspectNameCounter = 0; /** * Contains the names of methods allready defined by the names of their * classes. */ protected Map<String, Set<String>> definedMethodsByClass = new HashMap<String, Set<String>>(); /** Counter for names for generated derive constraint aspects. */ protected int deriveAspectNameCounter = 0; /** Counter for names for generated variables for index values. */ protected int indexVarCounter = 0; /** Counter for names for generated init constraint aspects. */ protected int initAspectNameCounter = 0; /** Counter for names for generated invariant constraint aspects. */ protected int invAspectNameCounter = 0; /** Counter for names for generated variables for IfExpression rsult values. */ protected int ifExpResultVarCounter = 0; /** Counter for names for generated variables for iterator variables. */ protected int iteratorExpIteratorVarCounter = 0; /** Whether or not the last transformed constraint uses the self variable. */ protected boolean isUsingSelfVariable = false; /** * Contains the name mappings for {@link Variable}s that require renaming * during code generation. */ protected Map<String, Stack<String>> mappedVariableNames = new HashMap<String, Stack<String>>(); /** * The canonical names of all classes which use the special OCL operation * oclIsNew(). */ protected Set<String> oclIsNewClasses = new TreeSet<String>(); /** Counter for names for generated postcondition constraint aspects. */ protected int postAspectNameCounter = 0; /** Counter for names for generated precondition constraint aspects. */ protected int preAspectNameCounter = 0; /** Counter for names for generated variables for result values. */ protected int resultVarCounter = 0; /** {@link Stack} used for expected return {@link Type}s. */ protected Stack<Type> returnTypeStack = new Stack<Type>(); /** Counter for names for generated variables for to visit collections. */ protected int toVisitVarCounter = 0; /** Counter for names for generated variables for tuple values. */ protected int tupleVarCounter = 0; /** Contains all names allready used for generated aspects. */ protected Set<String> usedAspectNames = new HashSet<String>(); public Ocl2JavaEnvironment() { /* * Adds some variable mappings for names that must be always rename * (reserved keywords in Java). */ Stack<String> stack = new Stack<String>(); stack.push("clazz"); mappedVariableNames.put("class", stack); stack = new Stack<String>(); stack.push("ixtends"); mappedVariableNames.put("extends", stack); stack = new Stack<String>(); stack.push("publik"); mappedVariableNames.put("public", stack); } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.IOcl22JavaEnvironment# * addAllInstancesClass(java.lang.String) */ public void addAllInstancesClass(String canonicalName) { this.allInstancesClasses.add(canonicalName); } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#addAtPreValue * (org.dresdenocl.ocl2java.code.ITransformedCode, * org.dresdenocl.pivotmodel.Type) */ public String addAtPreValue(ITransformedCode sourceCode, Type type) { String result; Object[] value; if (this.atPreValues.containsKey(sourceCode)) { result = this.atPreValues.get(sourceCode)[1].toString(); } else { result = this.getNewAtPreVarName(); value = new Object[2]; value[0] = type; value[1] = result; this.atPreValues.put(sourceCode, value); } return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#addCalledProperty * (java.lang.String) */ public void addCalledProperty(String callPath) { this.calledProperties.add(callPath); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #addDefinedMethod(java.lang.String, java.lang.String) */ public void addDefinedMethod(String methodName, String className) { Set<String> methodsOfClass = this.definedMethodsByClass.get(className); if (methodsOfClass == null) methodsOfClass = new HashSet<String>(); // no else. methodsOfClass.add(methodName); this.definedMethodsByClass.put(className, methodsOfClass); } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#addIsNewClass * (java.lang.String) */ public void addIsNewClass(String canonicalName) { this.oclIsNewClasses.add(canonicalName); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #addUsedAspectName(java.lang.String) */ public void addUsedAspectName(String name) { this.usedAspectNames.add(name); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #addVariableMapping(java.lang.String, java.lang.String) */ public void addVariableMapping(String oldName, String newName) { Stack<String> stack; if (this.mappedVariableNames.containsKey(oldName)) stack = this.mappedVariableNames.get(oldName); else stack = new Stack<String>(); stack.add(newName); this.mappedVariableNames.put(oldName, stack); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #existsMappingForVariable(java.lang.String) */ public boolean existsMappingForVariable(String name) { return this.mappedVariableNames.containsKey(name); } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.IOcl22JavaEnvironment# * getAllInstancesClasses() */ public Set<String> getAllInstancesClasses() { return this.allInstancesClasses; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#getAtPreValues * () */ public Map<ITransformedCode, Object[]> getAtPreValues() { return this.atPreValues; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#getIsNewClasses * () */ public Set<String> getIsNewClasses() { return this.oclIsNewClasses; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#getCalledProperties * () */ public Set<String> getCalledProperties() { return this.calledProperties; } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #getExpectedReturnType() */ public Type getExpectedReturnType() { if (this.returnTypeStack.isEmpty()) return null; else return this.returnTypeStack.peek(); } /* * (non-Javadoc) * @see org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment#getNewBodyResultVarName() */ public String getNewBodyResultVarName() { String result; this.bodyResultVarCounter++; result = BODY_RESULT_VAR_NAME; result += this.bodyResultVarCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.ICodeGenEnvironment# * getNewIteratorExpCollectionVarName() */ public String getNewCollectionVarName() { String result; this.collectionVarCounter++; result = COLLECTION_VAR_NAME; result += this.collectionVarCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.ICodeGenEnvironment#getNewComparatorName * () */ public String getNewComparatorName() { String result; this.comparatorVarCounter++; result = COMPARATOR_VAR_NAME; result += this.comparatorVarCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.ICodeGenEnvironment#getNewIndexVarName * () */ public String getNewIndexVarName() { String result; this.indexVarCounter++; result = INDEX_VAR_NAME; result += this.indexVarCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl22code.ICodeGenEnvironment#getNewIfExpResultName * () */ public String getNewIfExpResultName() { String result; this.ifExpResultVarCounter++; result = IF_EXP_RESULT_VAR_NAME; result += this.ifExpResultVarCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl22code.ICodeGenEnvironment# * getNewIteratorExpIteratorVarName() */ public String getNewIteratorVarName() { String result; this.iteratorExpIteratorVarCounter++; result = ITERATOR_EXP_ITERATOR_VAR_NAME; result += this.iteratorExpIteratorVarCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.ICodeGenEnvironment#getNewResultVarName * () */ public String getNewResultVarName() { String result; this.resultVarCounter++; result = RESULT_VAR_NAME; result += this.resultVarCounter; return result; } /* * (non-Javadoc) * @see org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment#getNewToVisitVarName() */ public String getNewToVisitVarName() { String result; this.toVisitVarCounter++; result = TO_VISIT_VAR_NAME; result += this.toVisitVarCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.ICodeTransformationEnvironment# * getNewTupleVarName() */ public String getNewTupleVarName() { String result; this.tupleVarCounter++; result = TUPLE_VAR_NAME; result += this.tupleVarCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.ICodeTransformationEnvironment# * getNewBodyAspectName() */ public String getNewBodyAspectName() { String result; this.bodyAspectNameCounter++; result = BODY_ASPECT_NAME; result += this.bodyAspectNameCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.ICodeTransformationEnvironment# * getNewDefAspectName() */ public String getNewDefAspectName() { String result; this.defAspectNameCounter++; result = DEF_ASPECT_NAME; result += this.defAspectNameCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.ICodeTransformationEnvironment# * getNewDeriveAspectName() */ public String getNewDeriveAspectName() { String result; this.deriveAspectNameCounter++; result = DERIVE_ASPECT_NAME; result += this.deriveAspectNameCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.ICodeGenEnvironment#getNewInitAspectName * () */ public String getNewInitAspectName() { String result; this.initAspectNameCounter++; result = INIT_ASPECT_NAME; result += this.initAspectNameCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#getNewInvAspectName * () */ public String getNewInvAspectName() { String result; this.invAspectNameCounter++; result = INV_ASPECT_NAME; result += this.invAspectNameCounter; return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.IOcl22JavaEnvironment# * getNewPostAspectName() */ public String getNewPostAspectName() { String result; this.postAspectNameCounter++; result = POST_ASPECT_NAME; result += this.postAspectNameCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#getNewPreAspectName * () */ public String getNewPreAspectName() { String result; this.preAspectNameCounter++; result = PRE_ASPECT_NAME; result += this.preAspectNameCounter; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #getVariableMapping(java.lang.String) */ public String getVariableMapping(String name) { String result = null; Stack<String> stack = this.mappedVariableNames.get(name); if (stack != null && stack.size() > 0) result = stack.peek(); return result; } /* * (non-Javadoc) * * @seeorg.dresdenocl.ocl2java.code.IOcl22JavaEnvironment# * hasAllInstancesClasses() */ public boolean hasAllInstancesClasses() { return !this.allInstancesClasses.isEmpty(); } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#hasAtPreValues * () */ public boolean hasAtPreValues() { return this.atPreValues.size() > 0; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#hasCalledProperties * () */ public boolean hasCalledProperties() { return this.calledProperties.size() > 0; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.IOcl22JavaEnvironment#hasIsNewClasses * () */ public boolean hasIsNewClasses() { return !this.oclIsNewClasses.isEmpty(); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #isMethodAlreadyDefined(java.lang.String, java.lang.String) */ public boolean isMethodAlreadyDefined(String methodName, String className) { boolean result; if (this.definedMethodsByClass.containsKey(className)) { result = this.definedMethodsByClass.get(className).contains( methodName); } else result = false; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #isUsedAspectName(java.lang.String) */ public boolean isUsedAspectName(String name) { return name != null && name.length() > 0 && this.usedAspectNames.contains(name); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #isUsingSelfVariable() */ public boolean isUsingSelfVariable() { return this.isUsingSelfVariable; } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #popExpectedReturnType() */ public Type popExpectedReturnType() { return this.returnTypeStack.pop(); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #pushExpectedReturnType(org.dresdenocl.pivotmodel.Type) */ public void pushExpectedReturnType(Type type) { this.returnTypeStack.push(type); } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #removeVariableMapping(java.lang.String) */ public boolean removeVariableMapping(String name) { boolean result; Stack<String> stack = this.mappedVariableNames.get(name); if (stack != null) { if (stack.size() == 0) { this.mappedVariableNames.remove(name); result = false; } else { stack.pop(); if (stack.size() > 0) this.mappedVariableNames.put(name, stack); else this.mappedVariableNames.remove(name); result = true; } } else result = false; return result; } /* * (non-Javadoc) * * @see * org.dresdenocl.ocl2java.code.ICodeGenEnvironment#resetAllCounters * () */ public void resetEnvironmentForNextConstraint() { this.atPreVarNameCounter = 0; this.bodyResultVarCounter = 0; this.comparatorVarCounter = 0; this.collectionVarCounter = 0; this.ifExpResultVarCounter = 0; this.indexVarCounter = 0; this.iteratorExpIteratorVarCounter = 0; this.resultVarCounter = 0; this.toVisitVarCounter = 0; this.tupleVarCounter = 0; this.allInstancesClasses.clear(); this.oclIsNewClasses.clear(); this.atPreValues.clear(); this.calledProperties.clear(); this.isUsingSelfVariable = false; } /* * (non-Javadoc) * * @see * org.dresdenocl.tools.codegen.ocl2java.code.IOcl2JavaEnvironment * #setIsUsigSelfVariable(boolean) */ public void setIsUsigSelfVariable(boolean enabled) { this.isUsingSelfVariable = enabled; } /** * <p> * A name for a Variable which stores a atPre value. * </p> * * @return A name for a Variable which stores a atPre value. */ protected String getNewAtPreVarName() { String result; this.atPreVarNameCounter++; result = AT_PRE_VAR_NAME; result += this.atPreVarNameCounter; return result; } }