org.eclipse.ocl.examples.impactanalyzer.instanceScope
Class PathCache

java.lang.Object
  extended by org.eclipse.ocl.examples.impactanalyzer.instanceScope.AbstractPathCache<NavigationStep>
      extended by org.eclipse.ocl.examples.impactanalyzer.instanceScope.PathCache
All Implemented Interfaces:
HashCodeChangeListener

public class PathCache
extends AbstractPathCache<NavigationStep>
implements HashCodeChangeListener

The instance scope analysis's goal is to compute NavigationStep objects for each AttributeCallExp and AssociationEndCallExp subexpression in an OCL expression's expression tree. These NavigationSteps can each be a graph, referring to other potentially composite navigation steps. The graph can even be cyclic, as in the case for recursive operation calls.

During the analysis of the traceback paths, for each subexpression visited, the NavigationPath for that node is stored in this cache.

Don't re-use an instance of this class for analyzing more than one expression when those expressions are dynamically parsed because in those cases, new operation calls are created dynamically which turn existing entries in the PathCache for self and parameter expressions of the operation called invalid. Additionally, all dependent paths would become invalid too. Identifying and removing those entries from a PathCache seems to cause more effort than using a new PathCache object for each expression analyzed, particularly given the fact that the NavigationPath assembly only has to happen once per life-time of an OCLExpression during a session.


Constructor Summary
PathCache(OppositeEndFinder oppositeEndFinder)
           
 
Method Summary
 void afterHashCodeChange(NavigationStep step, int token)
          Called after the step's SemanticIdentity hash code has changed.
 void beforeHashCodeChange(NavigationStep step, int token)
          Invoked before step's SemanticIdentity changes its hash code.
 IndirectingStep createIndirectingStepFor(OCLExpression expr, java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor)
          Creates a navigation step of type IndirectingStep which can be filled in later by the cliend and enters the placeholder step into this cache for expr.
protected  NavigationStep createStep(OCLExpression sourceExpression, org.eclipse.emf.ecore.EClass context, OperationBodyToCallMapper operationBodyToCallMapper, java.util.Stack<java.lang.String> tupleLiteralNamesToLookFor, OCLFactory oclFactory)
           
 BranchingNavigationStep getBranchingStepWithHighestNumberOfSteps(java.util.List<BranchingNavigationStep> list)
           
 java.util.List<SemanticIdentity> getSemanticIdentities(java.util.List<NavigationStep> steps)
           
protected  NavigationStep navigationStepForBranch(org.eclipse.emf.ecore.EClass sourceType, org.eclipse.emf.ecore.EClass targetType, OCLExpression expression, java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor, boolean requireExactMatchForSourceType, NavigationStep... steps)
          A non-caching, no-cache-lookup factory operation for a branching step for steps.
protected  NavigationStep navigationStepFromSequence(OCLExpression expression, java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor, NavigationStep... steps)
          A factory method for NavigationSteps that combines a sequence of navigation steps into a single new one.
 void put(OCLExpression subexpression, java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor, NavigationStep path)
          Also adds path to allNavigationSteps.
 NavigationStep reduceToCachedStep(NavigationStep step)
           
 
Methods inherited from class org.eclipse.ocl.examples.impactanalyzer.instanceScope.AbstractPathCache
getInstanceScopeAnalysis, getOppositeEndFinder, getOrCreateNavigationPath, getPathForNode, initInstanceScopeAnalysis
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PathCache

public PathCache(OppositeEndFinder oppositeEndFinder)
Method Detail

put

public void put(OCLExpression subexpression,
                java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor,
                NavigationStep path)
Also adds path to allNavigationSteps. If the source type is null and the step is not absolute, this path cache registers as a listener on the step (see NavigationStep.addSourceTypeChangeListener(SourceTypeChangeListener). If the target type is null, this path cache registers as target type listener on the step (see NavigationStep.addTargetTypeChangeListener(TargetTypeChangeListener). If the step is not marked as always empty, this path cache registers as listener for a change in the step's always-empty setting. If any of these change events are received, the respective step is re-hashed into allNavigationSteps.

Overrides:
put in class AbstractPathCache<NavigationStep>

navigationStepFromSequence

protected NavigationStep navigationStepFromSequence(OCLExpression expression,
                                                    java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor,
                                                    NavigationStep... steps)
A factory method for NavigationSteps that combines a sequence of navigation steps into a single new one. In doing so, shortcuts may be taken. For example, if the last step is an absolute step, it is returned as the result because all prior navigations are irrelevant. Also, if there is only one step in steps, that step is simply used.

The method first performs a cache lookup. Callers must make sure that the expression returned by this method will be used as the resulting step for expression. In particular, they must not create an IndirectingStep as the resulting step for expression in which the step produced by this method is only plugged in as an actual step. This would lead to the IndirectingStep being found in the cache instead of a NavigationStepSequence being constructed.

Parameters:
expression - Additionally, this is used to tell a debugging user to which OCL (sub-)expression the navigation step to create belong (see AbstractNavigationStep.getDebugInfo()). The step constructed here must be used as the resulting navigation step for expression. Callers therefore should ensure that in case this operation is called multiple times on the same object for the same expression, then the steps have to have equal semantics because subsequent calls will pull the result from the cache if available instead of creating a new one.

navigationStepForBranch

protected NavigationStep navigationStepForBranch(org.eclipse.emf.ecore.EClass sourceType,
                                                 org.eclipse.emf.ecore.EClass targetType,
                                                 OCLExpression expression,
                                                 java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor,
                                                 boolean requireExactMatchForSourceType,
                                                 NavigationStep... steps)
A non-caching, no-cache-lookup factory operation for a branching step for steps. If steps contains only one step, that step is returned without constructing a BranchingNavigationStep around it.

Parameters:
requireExactMatchForSourceType - should the source object's type match sourceType exactly?

getBranchingStepWithHighestNumberOfSteps

public BranchingNavigationStep getBranchingStepWithHighestNumberOfSteps(java.util.List<BranchingNavigationStep> list)

getSemanticIdentities

public java.util.List<SemanticIdentity> getSemanticIdentities(java.util.List<NavigationStep> steps)

reduceToCachedStep

public NavigationStep reduceToCachedStep(NavigationStep step)

createIndirectingStepFor

public IndirectingStep createIndirectingStepFor(OCLExpression expr,
                                                java.util.Stack<java.lang.String> tupleLiteralPartNamesToLookFor)
Creates a navigation step of type IndirectingStep which can be filled in later by the cliend and enters the placeholder step into this cache for expr. This mechanism can be used to create cyclic step graphs without running into an endless recursion. When a lookup happens for expr, the indirection step returned by this method will be found in this cache and therefore will not lead to an endless-recursive step creation procedure.


beforeHashCodeChange

public void beforeHashCodeChange(NavigationStep step,
                                 int token)
Description copied from interface: HashCodeChangeListener
Invoked before step's SemanticIdentity changes its hash code. When this method is called for a step, the HashCodeChangeListener.afterHashCodeChange(NavigationStep, int) is guaranteed to be called on the same listener later, immediately after the hash code has changed. Receiving this call gives the receiver the opportunity to remove the step from hashed structures in order to re-insert it later when the hash code has assumed the new value.

Specified by:
beforeHashCodeChange in interface HashCodeChangeListener
token - a token value identifying the root cause of the change by a monotonously-increasing number. This can be used in cyclic NavigationStep graphs to decide that a root cause has already been handled by a listener when it comes by a second time.

afterHashCodeChange

public void afterHashCodeChange(NavigationStep step,
                                int token)
Description copied from interface: HashCodeChangeListener
Called after the step's SemanticIdentity hash code has changed. This gives hash structures the opportunity to enter the step again.

Specified by:
afterHashCodeChange in interface HashCodeChangeListener
token - a token value identifying the root cause of the change by a monotonously-increasing number. This can be used in cyclic NavigationStep graphs to decide that a root cause has already been handled by a listener when it comes by a second time.

createStep

protected NavigationStep createStep(OCLExpression sourceExpression,
                                    org.eclipse.emf.ecore.EClass context,
                                    OperationBodyToCallMapper operationBodyToCallMapper,
                                    java.util.Stack<java.lang.String> tupleLiteralNamesToLookFor,
                                    OCLFactory oclFactory)
Specified by:
createStep in class AbstractPathCache<NavigationStep>