package com.sap.emf.ocl.prepared.parameters; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EOperation; import org.eclipse.emf.ecore.EParameter; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.ocl.ecore.CallOperationAction; import org.eclipse.ocl.ecore.Constraint; import org.eclipse.ocl.ecore.OCLExpression; import org.eclipse.ocl.ecore.SendSignalAction; import org.eclipse.ocl.expressions.BooleanLiteralExp; import org.eclipse.ocl.expressions.EnumLiteralExp; import org.eclipse.ocl.expressions.IntegerLiteralExp; import org.eclipse.ocl.expressions.LiteralExp; import org.eclipse.ocl.expressions.RealLiteralExp; import org.eclipse.ocl.expressions.StringLiteralExp; import org.eclipse.ocl.utilities.AbstractVisitor; /** * Finds values in the symbol specification of the literal expressions in an {@link OCLExpression} by * walking the expression tree. Each such symbol found is turned into a corresponding {@link Parameter} * specification. If a symbol is found multiple times, an exception is thrown. If a value is not found, * an exception is thrown as well. * * @author Axel Uhl (D043530) * */ public class ParameterFinder extends AbstractVisitor<Map<Object, Parameter<?>>, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint> { private Set<Object> parameterValuesToFindInLiterals; private ParameterFactory paramFactory = ParameterFactory.INSTANCE; /** * Throws an {@link IllegalArgumentException} if the values in <code>parameteValuesToFindInLiterals</code> * is not unique considering the relation defined by their <code>equals</code> method. */ public ParameterFinder(Object... parameterValuesToFindInLiterals) { super(new HashMap<Object, Parameter<?>>()); this.parameterValuesToFindInLiterals = new HashSet<Object>(Arrays.asList(parameterValuesToFindInLiterals)); if (this.parameterValuesToFindInLiterals.size() < parameterValuesToFindInLiterals.length) { throw new IllegalArgumentException("Parameter values in "+Arrays.toString(parameterValuesToFindInLiterals)+ " not unique"); } } @Override public Map<Object, Parameter<?>> visitIntegerLiteralExp(IntegerLiteralExp<EClassifier> literalExp) { Integer symbol = literalExp.getIntegerSymbol(); lookupSymbolAndEnterInfoResultIfMatch(literalExp, symbol); return super.visitIntegerLiteralExp(literalExp); } @Override public Map<Object, Parameter<?>> visitRealLiteralExp(RealLiteralExp<EClassifier> literalExp) { Double symbol = literalExp.getRealSymbol(); lookupSymbolAndEnterInfoResultIfMatch(literalExp, symbol); return super.visitRealLiteralExp(literalExp); } @Override public Map<Object, Parameter<?>> visitStringLiteralExp(StringLiteralExp<EClassifier> literalExp) { String symbol = literalExp.getStringSymbol(); lookupSymbolAndEnterInfoResultIfMatch(literalExp, symbol); return super.visitStringLiteralExp(literalExp); } @Override public Map<Object, Parameter<?>> visitBooleanLiteralExp(BooleanLiteralExp<EClassifier> literalExp) { Boolean symbol = literalExp.getBooleanSymbol(); lookupSymbolAndEnterInfoResultIfMatch(literalExp, symbol); return super.visitBooleanLiteralExp(literalExp); } @Override public Map<Object, Parameter<?>> visitEnumLiteralExp(EnumLiteralExp<EClassifier, EEnumLiteral> literalExp) { EEnumLiteral symbol = literalExp.getReferredEnumLiteral(); lookupSymbolAndEnterInfoResultIfMatch(literalExp, symbol); return super.visitEnumLiteralExp(literalExp); } private void lookupSymbolAndEnterInfoResultIfMatch(LiteralExp<EClassifier> literalExp, Object symbol) { if (parameterValuesToFindInLiterals.contains(symbol)) { if (result.containsKey(symbol)) { throw new DuplicateParameterValueException( result.get(symbol), literalExp); } result.put(symbol, paramFactory.getParameterFor(literalExp)); } } public Map<Object, Parameter<?>> visit(OCLExpression e) { Map<Object, Parameter<?>> resultCandidate = safeVisit(e); if (result.size() < parameterValuesToFindInLiterals.size()) { throw new ParameterNotFoundException(e, parameterValuesToFindInLiterals, result.keySet()); } return resultCandidate; } }