All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.ocl.utilities.AbstractVisitor Maven / Gradle / Ivy

/**
 * 
 *
 * Copyright (c) 2005, 2008 IBM Corporation 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:
 *   IBM - Initial API and implementation
 *   E.D. Willink - Fix NPE in visiting operation call with null source
 *
 * 
 *
 * $Id: AbstractVisitor.java,v 1.7 2008/04/27 23:16:03 cdamus Exp $
 */

package org.eclipse.ocl.utilities;

import java.util.Collections;
import java.util.List;

import org.eclipse.ocl.expressions.AssociationClassCallExp;
import org.eclipse.ocl.expressions.BooleanLiteralExp;
import org.eclipse.ocl.expressions.CollectionItem;
import org.eclipse.ocl.expressions.CollectionLiteralExp;
import org.eclipse.ocl.expressions.CollectionLiteralPart;
import org.eclipse.ocl.expressions.CollectionRange;
import org.eclipse.ocl.expressions.EnumLiteralExp;
import org.eclipse.ocl.expressions.IfExp;
import org.eclipse.ocl.expressions.IntegerLiteralExp;
import org.eclipse.ocl.expressions.InvalidLiteralExp;
import org.eclipse.ocl.expressions.IterateExp;
import org.eclipse.ocl.expressions.IteratorExp;
import org.eclipse.ocl.expressions.LetExp;
import org.eclipse.ocl.expressions.MessageExp;
import org.eclipse.ocl.expressions.NullLiteralExp;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.OperationCallExp;
import org.eclipse.ocl.expressions.PropertyCallExp;
import org.eclipse.ocl.expressions.RealLiteralExp;
import org.eclipse.ocl.expressions.StateExp;
import org.eclipse.ocl.expressions.StringLiteralExp;
import org.eclipse.ocl.expressions.TupleLiteralExp;
import org.eclipse.ocl.expressions.TupleLiteralPart;
import org.eclipse.ocl.expressions.TypeExp;
import org.eclipse.ocl.expressions.UnlimitedNaturalLiteralExp;
import org.eclipse.ocl.expressions.UnspecifiedValueExp;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.expressions.VariableExp;


/**
 * 

* An abstract implementation of the {@link Visitor} API, in which subclasses * need only selectively override handleXxx(...) methods for * internal AST nodes and visitXxx(...) methods for leaf nodes. *

* The {@link #result} value is convenient for accumulating the result of the * visitation. In the subclass, simply assign/modify the result value as * necessary in the overridden visitation methods, and this framework will * ensure that it is returned as the overall value of the * {@link Visitable#accept(Visitor)} call. *

* * @author Christian W. Damus (cdamus) */ public abstract class AbstractVisitor implements Visitor { /** * Accumulator for the result of the AST visitation. */ protected T result; /** * Initializes me. */ protected AbstractVisitor() { super(); } /** * Initializes me with an initial value for my result. * * @param initialValue my initial result value */ protected AbstractVisitor(T initialValue) { this.result = initialValue; } /** * A null-safe visitation of the specified visitable. * * @param v a visitable, or null * @return null if the visitable is null; * otherwise, the result of visiting it * * @since 1.2 */ protected T safeVisit(Visitable v) { return (v == null)? null : v.accept(this); } /** * Visits the operation-call source and then its arguments. * Returns the result of {@link #handleOperationCallExp(OperationCallExp, Object, List)}. */ public T visitOperationCallExp(OperationCallExp callExp) { OCLExpression source = callExp.getSource(); T sourceResult = safeVisit(source); List argumentResults; List> arguments = callExp.getArgument(); if (arguments.isEmpty()) { argumentResults = Collections.emptyList(); } else { argumentResults = new java.util.ArrayList(arguments.size()); for (OCLExpression qual : arguments) { argumentResults.add(safeVisit(qual)); } } return handleOperationCallExp(callExp, sourceResult, argumentResults); } /** * Visits the specified operation call with the results of visiting * its source and arguments (if any). * * @param callExp the operation call expression * @param sourceResult the result of visiting the expression's source * @param argumentResults the results of visiting the expression's * arguments, or an empty list if there are no arguments * * @return the accumulated {@link #result}, by default * * @see #visitOperationCallExp(OperationCallExp) */ protected T handleOperationCallExp(OperationCallExp callExp, T sourceResult, List argumentResults) { return result; } /** * Simply returns {@link #result}. */ public T visitVariableExp(VariableExp v) { return result; } /** * Visits the property-call source and then its qualifiers (if any). * Returns the result of {@link #handlePropertyCallExp(PropertyCallExp, Object, List)}. */ public T visitPropertyCallExp(PropertyCallExp callExp) { // source is null when the property call expression is an // association class navigation qualifier T sourceResult = safeVisit(callExp.getSource()); List qualifierResults; List> qualifiers = callExp.getQualifier(); if (qualifiers.isEmpty()) { qualifierResults = Collections.emptyList(); } else { qualifierResults = new java.util.ArrayList(qualifiers.size()); for (OCLExpression qual : qualifiers) { qualifierResults.add(safeVisit(qual)); } } return handlePropertyCallExp(callExp, sourceResult, qualifierResults); } /** * Visits the specified property call with the results of visiting * its source and qualifiers (if any). Note that in the case of a property * call expression as a qualifier of an association class call, the * property call does not have a source and, therefore, the * sourceResult will be null in that case. * * @param callExp the property call expression, if there is a source * @param sourceResult the result of visiting the expression's source * @param qualifierResults the results of visiting the expression's * qualifiers, or an empty list if there are no qualifiers * * @return the accumulated {@link #result}, by default * * @see #visitPropertyCallExp(PropertyCallExp) */ protected T handlePropertyCallExp(PropertyCallExp callExp, T sourceResult, List qualifierResults) { return result; } /** * Visits the association-class-call source and then its qualifiers (if any). * Returns the result of {@link #handleAssociationClassCallExp(AssociationClassCallExp, Object, List)}. */ public T visitAssociationClassCallExp(AssociationClassCallExp callExp) { T sourceResult = safeVisit(callExp.getSource()); List qualifierResults; List> qualifiers = callExp.getQualifier(); if (qualifiers.isEmpty()) { qualifierResults = Collections.emptyList(); } else { qualifierResults = new java.util.ArrayList(qualifiers.size()); for (OCLExpression qual : qualifiers) { qualifierResults.add(safeVisit(qual)); } } return handleAssociationClassCallExp(callExp, sourceResult, qualifierResults); } /** * Visits the specified association-class call with the results of visiting * its source and qualifiers (if any). * * @param callExp the association-class call expression * @param sourceResult the result of visiting the expression's source * @param qualifierResults the results of visiting the expression's * qualifiers, or an empty list if there are no qualifiers * * @return the accumulated {@link #result}, by default * * @see #visitAssociationClassCallExp(AssociationClassCallExp) */ protected T handleAssociationClassCallExp(AssociationClassCallExp callExp, T sourceResult, List qualifierResults) { return result; } /** * Visits the variable's initialization expression (if any). * Returns the result of {@link #handleVariable(Variable, Object)}. */ public T visitVariable(Variable variable) { T initResult = safeVisit(variable.getInitExpression()); return handleVariable(variable, initResult); } /** * Visits the specified variable with the results of visiting * its initializer (if any). * * @param variable the variable * @param initResult the result of visiting the expression's initializer, * or null if it has none * * @return the accumulated {@link #result}, by default * * @see #visitVariable(Variable) */ protected T handleVariable(Variable variable, T initResult) { return result; } /** * Visits the if expression's condition, then, and else expressions. * Returns the result of {@link #handleIfExp(IfExp, Object, Object, Object)}. */ public T visitIfExp(IfExp ifExp) { return handleIfExp(ifExp, safeVisit(ifExp.getCondition()), safeVisit(ifExp.getThenExpression()), safeVisit(ifExp.getElseExpression())); } /** * Visits the specified if expression with the results of visiting * its condition, then, and else expressions. * * @param ifExp the if expression * @param conditionResult the result of visiting the expression's condition * @param thenResult the result of visiting the expression's then * @param elseResult the result of visiting the expression's else * * @return the accumulated {@link #result}, by default * * @see #visitIfExp(IfExp) */ protected T handleIfExp(IfExp ifExp, T conditionResult, T thenResult, T elseResult) { return result; } /** * Simply returns {@link #result}. */ public T visitTypeExp(TypeExp t) { return result; } /** * Visits the message expression's target and then its arguments. * Returns the result of {@link #handleMessageExp(MessageExp, Object, List)}. */ public T visitMessageExp(MessageExp messageExp) { T targetResult = safeVisit(messageExp.getTarget()); List argumentResults; List> arguments = messageExp.getArgument(); if (arguments.isEmpty()) { argumentResults = Collections.emptyList(); } else { argumentResults = new java.util.ArrayList(arguments.size()); for (OCLExpression qual : arguments) { argumentResults.add(safeVisit(qual)); } } return handleMessageExp(messageExp, targetResult, argumentResults); } /** * Visits the specified message expression with the results of visiting * its target and arguments (if any). * * @param messageExp the message expression * @param targetResult the result of visiting the expression's target * @param argumentResults the results of visiting the expression's * arguments, or an empty list if there are no arguments * * @return the accumulated {@link #result}, by default * * @see #visitMessageExp(MessageExp) */ protected T handleMessageExp(MessageExp messageExp, T targetResult, List argumentResults) { return result; } /** * Simply returns {@link #result}. */ public T visitUnspecifiedValueExp(UnspecifiedValueExp unspecExp) { return result; } /** * Simply returns {@link #result}. */ public T visitStateExp(StateExp stateExp) { return result; } /** * Simply returns {@link #result}. */ public T visitIntegerLiteralExp(IntegerLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitUnlimitedNaturalLiteralExp(UnlimitedNaturalLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitRealLiteralExp(RealLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitStringLiteralExp(StringLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitBooleanLiteralExp(BooleanLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitNullLiteralExp(NullLiteralExp literalExp) { return result; } /** * Simply returns {@link #result}. */ public T visitInvalidLiteralExp(InvalidLiteralExp literalExp) { return result; } /** * Visits the tuple literal's parts. * Returns the result of {@link #handleTupleLiteralExp(TupleLiteralExp, List)}. */ public T visitTupleLiteralExp(TupleLiteralExp literalExp) { List partResults; List> parts = literalExp.getPart(); if (parts.isEmpty()) { partResults = Collections.emptyList(); } else { partResults = new java.util.ArrayList(parts.size()); for (TupleLiteralPart part : parts) { partResults.add(safeVisit(part)); } } return handleTupleLiteralExp(literalExp, partResults); } /** * Visits the specified tuple literal expression with the results of visiting * its parts (if any). * * @param literalExp the tuple literal expression * @param partResults the results of visiting the expression's * parts, or an empty list if there are no parts * * @return the accumulated {@link #result}, by default * * @see #visitTupleLiteralExp(TupleLiteralExp) */ protected T handleTupleLiteralExp(TupleLiteralExp literalExp, List partResults) { return result; } /** * Visits the tuple literal part's value, if any. * Returns the result of {@link #handleTupleLiteralPart(TupleLiteralPart, Object)}. */ public T visitTupleLiteralPart(TupleLiteralPart part) { T valueResult = safeVisit(part.getValue()); return handleTupleLiteralPart(part, valueResult); } /** * Visits the specified tuple literal part with the results of visiting * its value (if any). * * @param part the tuple literal part * @param valueResult the result of visiting the expression's value, or * null if it has no value * * @return the accumulated {@link #result}, by default * * @see #visitTupleLiteralPart(TupleLiteralPart) */ protected T handleTupleLiteralPart(TupleLiteralPart part, T valueResult) { return result; } /** * Visits the let's variable declaration then its 'in' expression. * Returns the result of {@link #handleLetExp(LetExp, Object, Object)}. */ public T visitLetExp(LetExp letExp) { return handleLetExp(letExp, safeVisit(letExp.getVariable()), safeVisit(letExp.getIn())); } /** * Visits the specified let expression with the results of visiting * its variable and in expression. * * @param letExp the let expression * @param variableResult the result of visiting the expression's variable * @param inResult the result of visiting the expression's in expression * * @return the accumulated {@link #result}, by default * * @see #visitLetExp(LetExp) */ protected T handleLetExp(LetExp letExp, T variableResult, T inResult) { return result; } /** * Simply returns {@link #result}. */ public T visitEnumLiteralExp(EnumLiteralExp literalExp) { return result; } /** * Visits the collection literal's parts. * * Returns the result of {@link #handleCollectionLiteralExp(CollectionLiteralExp, List)}. */ public T visitCollectionLiteralExp(CollectionLiteralExp literalExp) { List partResults; List> parts = literalExp.getPart(); if (parts.isEmpty()) { partResults = Collections.emptyList(); } else { partResults = new java.util.ArrayList(parts.size()); for (CollectionLiteralPart part : parts) { partResults.add(safeVisit(part)); } } return handleCollectionLiteralExp(literalExp, partResults); } /** * Visits the specified collection literal expression with the results of visiting * its parts (if any). * * @param literalExp the collection literal expression * @param partResults the results of visiting the expression's * parts, or an empty list if there are no parts * * @return the accumulated {@link #result}, by default * * @see #visitCollectionLiteralExp(CollectionLiteralExp) */ protected T handleCollectionLiteralExp(CollectionLiteralExp literalExp, List partResults) { return result; } /** * Visits the item's item expression. * * Returns the result of {@link #handleCollectionItem(CollectionItem, Object)} */ public T visitCollectionItem(CollectionItem item) { T itemResult = safeVisit(item.getItem()); return handleCollectionItem(item, itemResult); } /** * Visits the specified collection item with the result of visiting * its item expression. * * @param item the collection item * @param itemResult the result of visiting the item's item expression * * @return the accumulated {@link #result}, by default * * @see #visitCollectionItem(CollectionItem) */ protected T handleCollectionItem(CollectionItem item, T itemResult) { return result; } /** * Visits the range's first and last expressions. * * Returns the result of {@link #handleCollectionRange(CollectionRange, Object, Object)}. */ public T visitCollectionRange(CollectionRange range) { return handleCollectionRange(range, safeVisit(range.getFirst()), safeVisit(range.getLast())); } /** * Visits the specified collection range with the results of visiting * its first and last expressions. * * @param range the collection range * @param firstResult the result of visiting the range's first expression * @param lastResult the result of visiting the range's last expression * * @return the accumulated {@link #result}, by default * * @see #visitCollectionRange(CollectionRange) */ protected T handleCollectionRange(CollectionRange range, T firstResult, T lastResult) { return result; } /** * Visits the iterator's source, then its variables, followed by its body * expression. * Returns the result of {@link #handleIteratorExp(IteratorExp, Object, List, Object)}. */ public T visitIteratorExp(IteratorExp callExp) { T sourceResult = safeVisit(callExp.getSource()); List variableResults; List> variables = callExp.getIterator(); if (variables.isEmpty()) { variableResults = Collections.emptyList(); } else { variableResults = new java.util.ArrayList(variables.size()); for (Variable iterVar : variables) { variableResults.add(safeVisit(iterVar)); } } T bodyResult = safeVisit(callExp.getBody()); return handleIteratorExp(callExp, sourceResult, variableResults, bodyResult); } /** * Visits the specified iterator expression with the results of visiting * its source, its iterator variables, and its body expression. * * @param callExp the iterator expression * @param sourceResult the result of visiting the expression's source * @param variableResults the results of visiting the expression's * iterator variables * @param bodyResult the result of visiting the expression's body * * @return the accumulated {@link #result}, by default * * @see #visitIteratorExp(IteratorExp) */ protected T handleIteratorExp(IteratorExp callExp, T sourceResult, List variableResults, T bodyResult) { return result; } /** * Visits the iterate's source, then its iterator variables, * result variable, and body expression. * Returns the result of {@link #handleIterateExp(IterateExp, Object, List, Object, Object)}. */ public T visitIterateExp(IterateExp callExp) { T sourceResult = safeVisit(callExp.getSource()); List variableResults; List> variables = callExp.getIterator(); if (variables.isEmpty()) { variableResults = Collections.emptyList(); } else { variableResults = new java.util.ArrayList(variables.size()); for (Variable iterVar : variables) { variableResults.add(safeVisit(iterVar)); } } T resultResult = safeVisit(callExp.getResult()); T bodyResult = safeVisit(callExp.getBody()); return handleIterateExp(callExp, sourceResult, variableResults, resultResult, bodyResult); } /** * Visits the specified iterate expression with the results of visiting * its source, its iterator variables, its result variable, and its body * expression. * * @param callExp the iterate expression * @param sourceResult the result of visiting the expression's source * @param variableResults the results of visiting the expression's * iterator variables * @param resultResult the result of visiting the expressions' result variable * @param bodyResult the result of visiting the expression's body * * @return the accumulated {@link #result}, by default * * @see #visitIterateExp(IterateExp) */ protected T handleIterateExp(IterateExp callExp, T sourceResult, List variableResults, T resultResult, T bodyResult) { return result; } /** * Visits the expressions context variable, its parameter variables (if any), * its result variable (if any), and finally its body expression. * * Returns the result of * {@link #handleExpressionInOCL(ExpressionInOCL, Object, Object, List, Object)}. */ public T visitExpressionInOCL(ExpressionInOCL expression) { T contextResult = safeVisit(expression.getContextVariable()); Variable resultVar = expression.getResultVariable(); T resultResult = safeVisit(resultVar); List parameterResults; List> parameters = expression.getParameterVariable(); if (parameters.isEmpty()) { parameterResults = Collections.emptyList(); } else { parameterResults = new java.util.ArrayList(parameters.size()); for (Variable iterVar : parameters) { parameterResults.add(safeVisit(iterVar)); } } T bodyResult = safeVisit(expression.getBodyExpression()); return handleExpressionInOCL(expression, contextResult, resultResult, parameterResults, bodyResult); } /** * Visits the specified expression-in-OCL with the results of visiting * its context variable, its result variable (if any), its parameter * variables (if any), and its body expression. * * @param expression the expression-in-OCL * @param contextResult the result of visiting the expression's context variable * @param resultResult the result of visiting the expressions' result variable, * or null if there is no result variable * @param parameterResults the results of visiting the expression's * parameter variables, or an empty list if there are none * @param bodyResult the result of visiting the expression's body * * @return the accumulated {@link #result}, by default * * @see #visitExpressionInOCL(ExpressionInOCL) */ protected T handleExpressionInOCL(ExpressionInOCL expression, T contextResult, T resultResult, List parameterResults, T bodyResult) { return result; } /** * Visits the constraint's specification, if any (and if the * {@link #getSpecification(Object)} method is overridden). * * Returns the result of {@link #handleConstraint(Object, Object)}. * * @see #getSpecification(Object) */ public T visitConstraint(CT constraint) { T specificationResult = safeVisit(getSpecification(constraint)); return handleConstraint(constraint, specificationResult); } /** * Visits the specified constraint with the results of visiting * its specification. * * @param constraint the constraint * @param specificationResult the result of visiting the constraint's * specification, or null if either it has none or the * {@link #getSpecification(Object)} method is not overridden * * @return the accumulated {@link #result}, by default * * #see {@link #getSpecification(Object)} * @see #visitConstraint(Object) */ protected T handleConstraint(CT constraint, T specificationResult) { return result; } /** * Overridden by subclasses interested in visiting constraints, to get the * constraint's specification. * * @param constraint a constraint * @return its specification * * @see #visitConstraint(Object) */ protected ExpressionInOCL getSpecification(CT constraint) { return null; } } //VisitorImpl




© 2015 - 2024 Weber Informatics LLC | Privacy Policy