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

org.eclipse.ocl.Environment Maven / Gradle / Ivy

/**
 * 
 *
 * Copyright (c) 2005, 2007 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 - Refactoring to support extensibility and flexible error handling 
 *
 * 
 *
 * $Id: Environment.java,v 1.7 2010/05/03 09:32:32 ewillink Exp $
 */

package org.eclipse.ocl;

import java.util.Collection;
import java.util.List;

import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.internal.EnvironmentRegistryImpl;
import org.eclipse.ocl.lpg.BasicEnvironment;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.util.Adaptable;
import org.eclipse.ocl.util.OCLUtil;
import org.eclipse.ocl.utilities.OCLFactory;
import org.eclipse.ocl.utilities.TypedElement;
import org.eclipse.ocl.utilities.UMLReflection;

/**
 * An Environment stores the variables created while evaluating an OCL expression,
 * including self.  It also maintains the context classifier and,
 * if appropriate, operation or property.  This interface is not typically
 * used by clients of the parser API, but by providers of bindings for particular
 * UML-like metamodels.
 * 

* The generic type parameters of this interface represent the UML concepts that * the OCL parser and evaluation engine require. A binding for a particular * metamodel (e.g., Ecore or UML) is implemented as a concrete Environment * with appropriate metaclasses substituting for these type parameters. *

*

* This interface is not intended to be implemented "directly" by * providers of metamodel bindings. * It is highly recommended to extend the {@link AbstractEnvironment} class, * instead. *

* Since 1.2, the default abstract implementation of this interface * ({@link AbstractEnvironment}) implements the {@link Adaptable} protocol to * provide dynamic interface adapters. Use the * {@link OCLUtil#getAdapter(Environment, Class)} method to obtain * adapters for any environment instance. *

* * @param is substituted by the metaclass representing the metamodel's * analogue for the UML 2.x Package * @param corresponds to the UML Classifier metaclass * @param corresponds to the UML Operation metaclass * @param

corresponds to the UML Property metaclass * @param corresponds to the UML EnumerationLiteral metaclass * (Enumerations are simply represented as classifiers) * @param corresponds to the UML Parameter metaclass * @param corresponds to the UML State metaclass (for metamodels * that describe state machines) * @param corresponds to the UML CallOperationAction metaclass * (used in message expressions) * @param corresponds to the UML SendSignalAction metaclass * (used in message expressions) * @param corresponds to the UML Constraint metaclass * @param corresponds to the UML Class metaclass * @param corresponds to the UML Element metaclass * * @author Edith Schonberg (edith) * @author Christian W. Damus (cdamus) * * @see AbstractEnvironment * @see EnvironmentFactory */ public interface Environment { /** * Namespace URI of the OCL core metamodel, used for example as the * source of certain Ecore annotations. */ String OCL_NAMESPACE_URI = "http://www.eclipse.org/ocl/1.1.0/OCL"; //$NON-NLS-1$ /** * The name of the context variable 'self'. */ String SELF_VARIABLE_NAME = "self"; //$NON-NLS-1$ /** * The name of the operation result variable 'result'. */ String RESULT_VARIABLE_NAME = "result"; //$NON-NLS-1$ /** * Obtains the factory that created me, or an appropriate default factory * if I was not created using a factory. This factory can be used to create * nested environments within me. * * @return my originating factory * * @see EnvironmentFactory#createEnvironment(Environment) */ EnvironmentFactory getFactory(); /** * Obtains my parent environment, if I have one. My parent environment * implements a nesting scope of variable names, some of which names * may be shadowed by variables in my scope. * * @return my parent, or null if I am a root environment */ Environment getParent(); /** * Sets my parent environment. The parent environment should not generally * be set to null if it was not already null. * * @param env my new parent environment */ void setParent(Environment env); /** * Obtains my context package, if any. The constraints in an OCL document * need not declare a package context, but it is at least implicit as the * nearest package containing the context classifier. * * @return my context package * * @see #getContextClassifier() */ PK getContextPackage(); /** * Obtains the context classifier of this environment. This is the type * of the self context variable. * * @return the context classifier */ C getContextClassifier(); /** * Obtains the context operation of this environment, if it is an operation * context. * * @return the context operation, or null if this is not an * operation environment */ O getContextOperation(); /** * Obtains the context property of this environment, if it is a property * context. * * @return the context property, or null if this is not a * property environment */ P getContextProperty(); /** * Obtains the collection of core types representing the OCL Standard * Library. These are the singleton or generic instances of the OCL-defined * classifiers such as OclAny, Collection(T), etc. * Implementers of OCL metamodel bindings are encouraged to share a single * instance of the standard library amonst all of the Environments * constructed by a particular {@link EnvironmentFactory}. * * @return the OCL Standard Library implementation for this environment */ OCLStandardLibrary getOCLStandardLibrary(); /** * Obtains a type resolver to be used to create (and cache) concrete bindings * for the generic OCL types, based on the user model types provided by this * environment. These are the types that are parameterized by particular * user model elements: collections of particular classifiers, meta-types * for particular classifiers, message types for particular operations or * signals, and tuple types. * * @return the type resolver */ TypeResolver getTypeResolver(); /** * Queries whether the environment has any local variables defined in it. * * @return true if no local variables are defined; * false, otherwise */ boolean isEmpty(); /** * Obtains the Variable bound to a local variable name. * Does not look in parent environment scopes. * * @param name a variable name to look up * @return the matching variable, or null if not found in * this particular environment */ Variable lookupLocal(String name); /** * Obtains the Variable bound to a variable name. * Looks in parent environment scopes (recursively) for variables not * found in the local scope. * * @param name a variable name to look up * @return the matching variable, or null if not found in * this particular environment */ Variable lookup(String name); /** * Finds the package identified by the specified sequence of names * (a qualified name). * * @param names the qualified name * @return the matching package, or null if not found */ PK lookupPackage(List names); /** * Finds the classifier identified by the specified sequence of names * (a qualified name). * * @param names the qualified name * @return the matching classifier, or null if not found */ C lookupClassifier(List names); /** * Find an operation in the specified class. Used to resolve operation * calls. * * @param owner the owner type of the called operation, or null * to find an implicit owner type (in iteration expressions) * @param name the name of the called operation * @param args the arguments (expressions or variables) to be matched against * the parameter signature of the operation * * @return the matching operation, or null if not found */ O lookupOperation(C owner, String name, List> args); /** * Finds a property defined or inherited by the specified classifier. * * @param owner the owner of the property that we are looking for, or * null to find an implicit owner type (in iteration * expressions) * @param name the property name * * @return the property, or null if it could not be found */ P lookupProperty(C owner, String name); /** * Finds a reference in the specified class to the named association class. * * @param owner the referencing class to search, or * null to find an implicit owner type (in iteration * expressions) * @param name the association class name (with an initial lower case as * per the OCL convention) * @return the association class (generically as a classifier), or * null if the specified owner is not at the * end of an association with this particular name */ C lookupAssociationClassReference(C owner, String name); /** * Finds the state identified by the specified qualified name path, to * resolve an oclIsInState() operation. * * @param owner the type on which the oclIsInState() operation is * invoked * @param path the state name to seek * @return the matching state object, or null if not found * * @throws LookupException in the case that this path is * ambiguous; i.e., that it does not qualify a state reference with * the state machine name to select between same-named states in * different state machines * @throws SemanticException which usually would actually be a * LookupException (see above) */ S lookupState(C owner, List path) throws LookupException, SemanticException; /** * Retrieves a list of all possible states of the specified owner * whose paths are prefixed by the specified partial name. If the * owner is null, then the target of the oclIsInState() * operation call is implicit and must be looked up in the usual way for * implicit operation call targets. This method is used for content-assist. * * @param owner the classifier for which states are being sought. Can be * null in the case of an oclIsInState() call on an * implicit target * @param pathPrefix partial path name of the states being sought. This * can be empty to find the first level of state names * * @return the list of all possible states directly contained in the * namespace indicated by the path prefix (i.e., only one level of * state nesting) */ List getStates(C owner, List pathPrefix); /** * Finds a received signal in the specified classifier. * * @param owner the owner type of the signal reception * @param name the name of the signal * @param args the arguments (expressions or variables) matching the * properties of the signal (parameters of the reception feature) * * @return the matching signal, or null if not found */ C lookupSignal(C owner, String name, List> args); /** * Checks whether the specified OCL expression is in an operation * postcondition constraint. This is used in validating the usage of * constructs that are only valid in postconditions * (e.g., oclIsNew()). * * @param exp an OCL expression * @return true if it is in a postcondition constraint; * false, otherwise (including case of no constraint at all) */ boolean isInPostcondition(OCLExpression exp); /** * Adds a variable declaration to the environment. * If the name is null, then a new unique temporary name is generated (this * is useful for implicit variables). * * @param name the name of the variable, or null * @param elem a variable declaration * @param explicit whether this is an explicitly declared variable * * @return true if the variable was successfully added because * it wasn't already declared locally in this environment; * false, otherwise */ public boolean addElement(String name, Variable elem, boolean explicit); /** * Removes a variable when it goes out of scope. * * @param name the name of the variable to delete */ public void deleteElement(String name); /** * Returns the {@link Variable}s registered explicitly in me and any * parents that I may have. This does not include implicit variables or * variables from parent environments that are shadowed by variables in * the nested scope. * * @return my variable declarations */ public Collection> getVariables(); /** * Sets the "self" variable that is the implicit source of any property, * operation, or association class call. * * @param var the "self" variable */ public void setSelfVariable(Variable var); /** * Gets the self variable, looking it up in a parent environment if necessary. * * @return the self variable, or null if none (which should * only be the case in a root environment having only a package context, * if even that) */ public Variable getSelfVariable(); /** * Return the most appropriate matching variable to use as the implicit * source of a call to the specified property. Variables are returned based * on inner-most scope first. * * @param name the property name * * @return the matching variable, or null if no appropriate * variable can be found whose type defines a property of this name */ public Variable lookupImplicitSourceForProperty(String name); /** * Return an implicit variable that references the * named association class. Variables are returned based on inner-most * scope first. * * @param name the association class name to seek * @return the matching variable, or null if no appropriate * variable can be found whose type defines a property of this name */ public Variable lookupImplicitSourceForAssociationClass(String name); /** * Return an implicit variable declaration that defines the specified * operation signature. Variables are returned based on inner-most scope * first. * * @param name the operation name * @param args the list of arguments (expressions or variables) to match * against the operation parameters * @return the matching variable, or null if no appropriate * variable can be found whose type defines a property of this name */ public Variable lookupImplicitSourceForOperation(String name, List> args); /** * Return an implicit variable declaration that defines the specified * signal reception signature. Variables are returned based on inner-most * scope first. * * @param name the signal name * @param args the list of arguments (expressions or variables) to match * against the signal reception parameters * @return the matching variable, or null if no appropriate * variable can be found whose type defines a property of this name */ public Variable lookupImplicitSourceForSignal(String name, List> args); /** * Finds the best-matching implicit variable to use as a source for * the unqualified oclIsInState() invocation with the specified * state qualified name path. * * @param path the state name to seek * @return the implicit variable having the specified state, * or null if not found * * @throws LookupException in the case that this path is * ambiguous; i.e., that it does not qualify a state reference with * the state machine name to select between same-named states in * different state machines * @throws SemanticException which usually would actually be a * LookupException (see above) */ public Variable lookupImplicitSourceForState(List path) throws LookupException, SemanticException; /** * In processing an additional attribute definition, constructs the * property and associates it with its definition constraint. * The operation definition is local to this environment. * * @param owner the context classifier of the property definition constraint * @param variable the name and type of the property (conveniently * encapsulated in a variable) * @param constraint the definition constraint * @return the defined property */ P defineAttribute(C owner, Variable variable, CT constraint); /** * Obtains the additional attributes defined in this environment in the * context of the specified classifier. * * @param classifier a classifier * @return its additional attributes, or an empty list if none */ List

getAdditionalAttributes(C classifier); /** * In processing an additional operation definition, constructs the * operation and associates it with its definition constraint. * The operation definition is local to this environment. * * @param owner the context classifier of the property definition constraint * @param name the operation name * @param params the names and types of the parameters, if any (conveniently * encapsulated in variables) * @param constraint the definition constraint * @return the defined operation */ O defineOperation(C owner, String name, C type, List> params, CT constraint); /** * Obtains the additional operations defined in this environment in the * context of the specified classifier. * * @param classifier a classifier * @return its additional operations, or an empty list if none */ List getAdditionalOperations(C classifier); /** * Obtains the definition constraint of the specified feature, if it is an * additional attribute or operation defined via an OCL constraint. * * @param feature a property or operation * @return the definition constraint that defines it, or null * if this feature is not defined by OCL */ CT getDefinition(Object feature); /** * Removes the definition of an additional operation or property. * * @param feature an additional property or operation * * @throws IllegalArgumentException if the specified feature is * not an additional feature defined via an OCL constraint */ void undefine(Object feature); /** * Associates a property with an initial-value constraint. * The constraint is local to this environment. * * @param property an attribute * @param constraint its initial-value constraint */ void setInitConstraint(P property, CT constraint); /** * Obtains a property's with an initial-value constraint, if any. * * @param property an attribute * @return its initial-value constraint, or null if none */ CT getInitConstraint(P property); /** * Associates a property with an derived-value constraint. * The constraint is local to this environment. * * @param property an attribute * @param constraint its derived-value constraint */ void setDeriveConstraint(P property, CT constraint); /** * Obtains a property's derived-value constraint. * * @param property an attribute * @return its derived-value constraint */ CT getDeriveConstraint(P property); /** * Associates an operation with an body condition constraint. * The constraint is local to this environment. * * @param operation an operation * @param constraint its body condition constraint */ void setBodyCondition(O operation, CT constraint); /** * Obtains an operation's body condition constraint. * * @param operation an operation * @return its body condition constraint */ CT getBodyCondition(O operation); /** * Obtains a factory for the creation of types that are parameterized * by model elements. This type factory must create types that are * instances of the metaclass describing classifiers in the client * metamodel. * * @return the appropriate type factory */ OCLFactory getOCLFactory(); /** * Obtains a utility for for reflection on the UML metaclasses that are * used by the OCL abstract syntax. * * @return the appropriate reflection instance */ UMLReflection getUMLReflection(); /** * A registry of environments. The registry may be consulted to find a * default environment suitable for the introspection of a model element. * These environments will never be used for the definition of constraints * or variables. *

* This registry may be populated at run-time or, in an Eclipse environment, * statically on the org.eclipse.ocl.environments extension point. *

* * @author Christian W. Damus (cdamus) */ interface Registry { /** * The shared registry instance. */ Registry INSTANCE = new EnvironmentRegistryImpl(); /** * Obtains a suitable environment for introspection of the specified * expression. * * @param expression a parsed OCL expression * @return the matching registered environment, or null if * none is available */ Environment getEnvironmentFor(OCLExpression expression); /** * Obtains a suitable environment for introspection of the specified * model element, type (such as a collection type), or other abstract * syntax element (e.g., a variable). * * @param abstractSyntaxElement an element in or referenced by the * AST of of an OCL constraint * @return the matching registered environment, or null if * none is available */ Environment getEnvironmentFor(Object abstractSyntaxElement); /** * Adds the specified environment to the registry. * * @param environment an environment to register */ void registerEnvironment(Environment environment); /** * Removes the specified environment from the registry. * * @param environment the environment to deregister */ void deregisterEnvironment(Environment environment); } /** * Optional adapter interface for look-up methods that throw * {@link LookupException}s on abnormal failures (usually ambiguous names). * * @author Christian W. Damus (cdamus) * * @since 1.2 */ interface Lookup { /** * Finds the package identified by the specified sequence of names * (a qualified name). * * @param names the qualified name * @return the matching package, or null if not found * @throws LookupException if lookup fails due to an error such as an ambiguity */ PK tryLookupPackage(List names) throws LookupException; /** * Finds the classifier identified by the specified sequence of names * (a qualified name). * * @param names the qualified name * @return the matching classifier, or null if not found * @throws LookupException if lookup fails due to an error such as an ambiguity */ C tryLookupClassifier(List names) throws LookupException; /** * Find an operation in the specified class. Used to resolve operation * calls. * * @param owner the owner type of the called operation, or null * to find an implicit owner type (in iteration expressions) * @param name the name of the called operation * @param args the arguments (expressions or variables) to be matched against * the parameter signature of the operation * * @return the matching operation, or null if not found * @throws LookupException if lookup fails due to an error such as an ambiguity */ O tryLookupOperation(C owner, String name, List> args) throws LookupException; /** * Finds a property defined or inherited by the specified classifier. * * @param owner the owner of the property that we are looking for, or * null to find an implicit owner type (in iteration * expressions) * @param name the property name * * @return the property, or null if it could not be found * @throws LookupException if lookup fails due to an error such as an ambiguity */ P tryLookupProperty(C owner, String name) throws LookupException; /** * Finds a reference in the specified class to the named association class. * * @param owner the referencing class to search, or * null to find an implicit owner type (in iteration * expressions) * @param name the association class name (with an initial lower case as * per the OCL convention) * * @return the association class (generically as a classifier), or * null if the specified owner is not at the * end of an association with this particular name * @throws LookupException if lookup fails due to an error such as an ambiguity */ C tryLookupAssociationClassReference(C owner, String name) throws LookupException; /** * Finds a received signal in the specified classifier. * * @param owner the owner type of the signal reception * @param name the name of the signal * @param args the arguments (expressions or variables) matching the * properties of the signal (parameters of the reception feature) * * @return the matching signal, or null if not found * @throws LookupException if lookup fails due to an error such as an ambiguity */ C tryLookupSignal(C owner, String name, List> args) throws LookupException; } /** *

* An interface that merges the {@link Environment} and * {@link BasicEnvironment} interfaces that define the * behaviour realised in abstract form by {@link AbstractEnvironment}. * The purpose of this interface is primarily for internal use by the * parser and/or the particular environment implementation and its * corresponding factory. Client applications will not usually need to * use this interface. *

* This interface is not expected to be implemented by clients. It may * be implemented by custom {@link Environment} classes, but it is * recommended to extend the {@link AbstractEnvironment} class. *

* * @author Christian W. Damus (cdamus) * * @since 1.2 */ interface Internal extends BasicEnvironment, Environment { /** * Obtains my parent environment after construction. * * @return my parent */ Environment.Internal getInternalParent(); /** * Assigns me a parent environment after construction. It is not advisable * to set the parent to null if I previously had one. * * @param parent my new parent */ void setInternalParent( Environment.Internal parent); /** * Adds an OCL-defined additional ("helper") operation to * the environment. This is primarily intended for internal use by the * OCL environment implementation and should only be used for properties * defined via OCL (such as by the {@link Environment#defineOperation} method). * * @param owner the classifier in which context the attribute is defined * @param operation the additional operation */ void addHelperOperation(C owner, O operation); /** * Adds an OCL-defined additional ("helper") attribute to * the environment. This is primarily intended for internal use by the * OCL environment implementation and should only be used for properties * defined via OCL (such as by the {@link Environment#defineAttribute} method). * * @param owner the classifier in which context the attribute is defined * @param property the additional attribute */ void addHelperProperty(C owner, P property); /** * Disposes of any objects that I have created that should be cleaned * up. * * @since 1.2 */ void dispose(); } }