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 extends TypedElement> 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 extends TypedElement> 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 extends TypedElement> 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 extends TypedElement> 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 extends TypedElement> 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 extends TypedElement> 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();
}
}