package agg.attribute.impl;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import agg.attribute.handler.AttrHandler;
import agg.attribute.handler.HandlerExpr;
import agg.util.Disposable;
/**
* Contains declarations and values of context variables; Note that this class
* does NOT implement the AttrContext interface; The actual implementation for
* it is the wrapper class ContextView, which allows to restrict access to a
* context while sharing actual state (variables, conditions, mappings). An
* example are the different access rights of the left and the right rule side
* in graph transformation.
*
* @see ContextView
* @author $Author: olga $
* @version $Id: ContextCore.java,v 1.23 2010/08/23 07:30:49 olga Exp $
*/
public class ContextCore extends ManagedObject implements Serializable,
Disposable {
static final long serialVersionUID = 4267479295340570839L;
/** Kind of mapping in this context, PLAIN_MAP or MATCH_MAP. */
protected int mapStyle;
/** Parent context of this context, chain of inheritance. */
protected ContextCore parent = null;
/**
* Table of mappings. (Hashtable of Vectors of TupleMapping, key is the
* target object)
*/
protected Hashtable<ValueTuple, Vector<TupleMapping>> mappings = new Hashtable<ValueTuple, Vector<TupleMapping>>();
/** Conditions of this context. */
protected CondTuple conditions;
/** Variables and parameters of this context. */
protected VarTuple variables;
/** Flag; when set, mapping removals are deferred. */
transient protected boolean isFrozen = false;
/** Container with deferred mapping removals. */
transient protected Vector<TupleMapping> delayedMappingRemovals = null;
transient private String errorMsg;
transient private boolean variableContext = false;
// /** Zaehlt die Objekte */
// transient private static int COUNTER = 0;
/**
* Creating a new root context.
*
* @param mapStyle
* The kind of mapping that is done within this context; it is
* one of:
* <dl>
* <dt> -
* <dd> 'AttrMapping.PLAIN_MAP': In Graph Transform.: rule
* mapping
* <dt> -
* <dd> 'AttrMapping.MATCH_MAP': In Graph Transformation:
* matching
* </dl>
*/
public ContextCore(AttrTupleManager manager, int mapStyle) {
this(manager, mapStyle, null);
}
/**
* Creating a new child context.
*
* @param mapStyle
* The kind of mapping that is allowed within this context; it is
* one of:
* <dl>
* <dt> -
* <dd> 'AttrMapping.PLAIN_MAP': In Graph Transform.: rule
* mapping
* <dt> -
* <dd> 'AttrMapping.MATCH_MAP': In Graph Transformation:
* matching
* </dl>
* @param parent
* The parent of the new context
*/
public ContextCore(AttrTupleManager manager, int mapStyle,
ContextCore parent) {
super(manager);
this.mapStyle = mapStyle;
this.parent = parent;
this.errorMsg = "";
VarTuple parentVars = null;
CondTuple parentCond = null;
if (parent != null) {
this.variableContext = parent.isVariableContext();
parentVars = parent.getVariables();
parentCond = parent.getConditions();
}
this.variables = new VarTuple(manager, new ContextView(manager, this),
parentVars);
this.conditions = new CondTuple(manager, new ContextView(manager, this),
parentCond);
// COUNTER++;
}
/**
* Creates a new VarTuple instance and rewrites the already existing VarTuple instance.
*/
public void resetVariableTuple() {
VarTuple parentVars = this.parent != null? this.parent.getVariables(): null;
this.variables = new VarTuple(this.manager, new ContextView(this.manager, this), parentVars);
}
/**
* Creates a new CondTuple instance and rewrites the already existing CondTuple instance.
*/
public void resetConditionTuple() {
CondTuple parentCond = this.parent != null? this.parent.getConditions(): null;
this.conditions = new CondTuple(this.manager, new ContextView(this.manager, this), parentCond);
}
public void makeCopyOf(ContextCore context) {
this.mapStyle = context.mapStyle;
this.errorMsg = "";
this.variableContext = context.isVariableContext();
this.variables = new VarTuple(this.manager, new ContextView(this.manager, this), null);
this.variables.makeCopyOf(context.getVariables());
this.conditions = new CondTuple(this.manager, new ContextView(this.manager, this), null);
this.conditions.makeCopyOf(context.getConditions());
}
public void dispose() {
if (this.delayedMappingRemovals != null)
this.delayedMappingRemovals.removeAllElements();
this.delayedMappingRemovals = null;
this.manager = null;
this.parent = null;
if (this.conditions != null) {
this.conditions.dispose();
this.conditions = null;
}
if (this.variables != null) {
this.variables.dispose();
this.variables = null;
}
}
protected final void finalize() {
if (this.delayedMappingRemovals != null || this.manager != null || this.parent != null
|| this.conditions != null || this.variables != null)
dispose();
// COUNTER--;
}
public String getErrorMsg() {
return this.errorMsg;
}
public void clearErrorMsg() {
this.errorMsg = "";
}
public CondTuple getConditions() {
return this.conditions;
}
public VarTuple getVariables() {
return this.variables;
}
/** Checking if this context is "frozen". */
public boolean isFrozen() {
return this.isFrozen;
}
/**
* Switching on of the freeze mode; mapping removals are deferred until
* 'defreeze()' is called.
*/
public void freeze() {
if (this.delayedMappingRemovals == null) {
this.delayedMappingRemovals = new Vector<TupleMapping>(30);
}
this.isFrozen = true;
}
/** Perform mapping removals which were delayed during the freeze mode. */
public void defreeze() {
this.isFrozen = false;
performDelayedRemove();
}
/**
* A variable context mins that mainly variables will be used as values of
* the graph objects of a graph, so if a rule / match attribute context has
* an attribute condition, it cannot be evaluated and will get TRUE as
* result. This feature is mainly used for critical pair analysis, where the
* attribute conditions will be handled especially. Do not use this setting
* for common transformation.
*/
public void setVariableContext(boolean b) {
this.variableContext = b;
if (this.parent != null) {
this.parent.setVariableContext(b);
}
}
/**
* @see agg.attribute.impl#setVariableContext(boolean b)
*/
public boolean isVariableContext() {
return this.variableContext;
}
/** Getting the mapping style (match or plain). */
public int getAllowedMapping() {
return this.mapStyle;
}
/** Adding a new mapping to this context. */
public void addMapping(TupleMapping mapping) {
// Thread.dumpStack();
ValueTuple target = mapping.getTarget();
Vector<TupleMapping> mappingsToTarget = this.mappings.get(target);
if (mappingsToTarget == null) {
mappingsToTarget = new Vector<TupleMapping>();
this.mappings.put(target, mappingsToTarget);
}
mappingsToTarget.addElement(mapping);
}
/** returns all mappings */
protected Hashtable<ValueTuple, Vector<TupleMapping>> getMapping() {
return this.mappings;
}
/**
* Returns Vector of mappings (TupleMapping) to a target object.
*/
public Vector<TupleMapping> getMappingsToTarget(ValueTuple target) {
Vector<TupleMapping> mappingsToValue = this.mappings.get(target);
return mappingsToValue;
}
/**
* Removing a mapping.
*
* @return 'true' if the mapping was contained in this context at all,
* 'false' otherwise.
*/
public boolean removeMapping(TupleMapping mapping) {
ValueTuple target = mapping.getTarget();
Vector<TupleMapping> mappingsToTarget = this.mappings.get(target);
if (mappingsToTarget == null) {
return false;
}
if (this.isFrozen()) {
if (!mappingsToTarget.contains(mapping)) {
return false;
}
this.delayedMappingRemovals.addElement(mapping);
} else {
mapping.removeNow();
}
return mappingsToTarget.removeElement(mapping);
}
public void removeAllMappings() {
final Enumeration<ValueTuple> keys = this.mappings.keys();
while (keys.hasMoreElements()) {
ValueTuple key = keys.nextElement();
Vector<TupleMapping> mappingsToTarget = this.mappings.get(key);
for (int i=0; i<mappingsToTarget.size(); i++) {
TupleMapping mapping = mappingsToTarget.get(i);
mapping.removeNow();
}
mappingsToTarget.clear();
}
this.mappings.clear();
}
/** Removing the mappings in the 'delayedMappingRemovals' container. */
private void performDelayedRemove() {
if (this.delayedMappingRemovals != null) {
int size = this.delayedMappingRemovals.size();
for (int i = 0; i < size; i++) {
this.delayedMappingRemovals.elementAt(i).removeNow();
}
this.delayedMappingRemovals.removeAllElements();
}
}
/**
* Tests if a variable has already been declared in this context or in any
* of its parents;
*
* @param name
* The name of the variable
* @return 'true' if "name" is declared, 'false' otherwise
*/
public boolean isDeclared(String name) {
return (getVariables() != null && getVariables().isDeclared(name));
}
/**
* Adding a new declaration; "name" is a key and must not have been
* previously used for a declaration in this context or any of its parents.
*
* @param name
* The name of the variable to declare
* @param type
* The type of the variable
* @return 'true' on success, 'false' otherwise
*/
public boolean addDecl(AttrHandler handler, String type, String name) {
if (this.variables != null) {
try {
this.variables.declare(handler, type, name);
return true;
} catch (AttrImplException ex) {
return false;
}
}
return false;
}
/**
* Removing a declaration from this context; Parent contextes are NOT
* considered; Does nothing if the variable "name" is not declared;
*
* @param name
* The name of the variable to remove
*/
public void removeDecl(String name) {
getVariables().deleteLeafDeclaration(name);
}
/**
* Getting the declaration (type) of a variable;
*
* @param name
* The name of the variable
* @return Type of the specified variable
* @exception NoSuchVariableException
* If no variable 'name' is declared
*/
public DeclMember getDecl(String name) throws NoSuchVariableException {
DeclMember t = getVariables().getTupleType().getDeclMemberAt(name);
return t;
}
/**
* Checking if a variable can be set to a given value without violating the
* application conditions. Note: if the conditions are violated already,
* this method returns 'true' for any 'value', unless 'value' contradicts a
* previously set non-null value for the variable.
*/
public boolean canSetValue(String name, ValueMember value) {
ValueMember prevValue;
boolean doesBreakCondition = false;
this.errorMsg = "";
prevValue = getVariables().getVarMemberAt(name);
if (prevValue == null) {
this.errorMsg = "No such variable: " + name;
return false;
}
if (prevValue.getExpr() == null) {
// CONDITION CHECK WIRD HIER NICHT MEHR GEMACHT,
// SONDERN IN Completion_CSP
/*
* if(!getConditions().isDefinite(name) ||
* getConditions().isTrue(name)){ setValue( name, value );
* if(getConditions().isDefinite(name) &&
* !getConditions().isTrue(name)){ this.errorMsg = "Attribute condition [
* "+getConditions().getFailedConditionAsString()+ " ] failed.";
* doesBreakCondition = true; } removeValue( name ); }
*/
return !doesBreakCondition;
} else if (prevValue.equals(value)) {
return true;
} else {
this.errorMsg = "Cannot set attribute value.";
return false;
}
}
/**
* Setting a variable value.
*
* @param name
* Name of the variable to assign to
* @param value
* Value to assign
* @exception NoSuchVariableException
* If the name is not declared in this context.
*/
public void setValue(String name, ValueMember value)
throws NoSuchVariableException {
VarMember vm = getVariables().getVarMemberAt(name);
if (vm == null)
throw new NoSuchVariableException(name);
HandlerExpr he = value.getExpr();
vm.unifyWith(he);
if (value.getExprAsText().equals("null")) {
vm.setExprAsText("null");
}
}
/**
* Removing a variable
*
* @param name
* Name of the variable to remove
* @exception NoSuchVariableException
* If the name is not declared in this context.
*/
public void removeValue(String name) throws NoSuchVariableException {
if (isDeclared(name))
getVariables().getVarMemberAt(name).undoUnification();
else
; // throw new NoSuchVariableException( name );
}
/**
* Getting the value of a variable.
*
* @param name
* Name of the variable to get the value from
* @exception NoSuchVariableException
* If the name is not declared in this context.
*/
public ValueMember getValue(String name) {
ValueMember value;
value = getVariables().getVarMemberAt(name);
if (value == null)
throw new NoSuchVariableException(name);
return value;
}
}
/*
* $Log: ContextCore.java,v $
* Revision 1.23 2010/08/23 07:30:49 olga
* tuning
*
* Revision 1.22 2010/04/28 15:15:39 olga
* tuning
*
* Revision 1.21 2010/04/27 12:20:07 olga
* addDecl: null pointer bug fixed
*
* Revision 1.20 2010/03/31 22:47:22 olga
* tuning
*
* Revision 1.19 2010/03/31 21:08:13 olga
* tuning
*
* Revision 1.18 2010/03/08 15:37:22 olga
* code optimizing
*
* Revision 1.17 2009/11/26 17:37:15 olga
* tests
*
* Revision 1.16 2009/03/12 10:57:44 olga
* some changes in CPA of managing names of the attribute variables.
*
* Revision 1.15 2008/07/14 07:35:46 olga
* Applicability of RS - new option added, more tuning
* Node animation - new animation parameter added,
* Undo edit manager - possibility to disable it when graph transformation
* because it costs much more time and memory
*
* Revision 1.14 2008/05/19 09:19:32 olga
* Applicability of Rule Sequence - reworking
*
* Revision 1.13 2007/12/10 08:42:58 olga
* CPA of grammar with node type inheritance for attributed graphs - bug fixed
*
* Revision 1.12 2007/12/03 08:35:13 olga
* - Some bugs fixed in visualization of morphism mappings after deleting and creating
* nodes, edges
* - implemented: matching with non-injective NAC and Match morphism
*
* Revision 1.11 2007/11/01 09:58:13 olga
* Code refactoring: generic types- done
*
* Revision 1.10 2007/09/17 10:50:00 olga
* Bug fixed in graph transformation by rules with NACs and PACs .
* AGG help docus extended by new implemented features.
*
* Revision 1.9 2007/09/10 13:05:18 olga
* In this update:
* - package xerces2.5.0 is not used anymore;
* - class com.objectspace.jgl.Pair is replaced by the agg own generic class agg.util.Pair;
* - bugs fixed in: usage of PACs in rules; match completion;
* usage of static method calls in attr. conditions
* - graph editing: added some new features
* Revision 1.8 2007/05/07 07:59:30 olga CSP:
* extentions of CSP variables concept
*
* Revision 1.7 2007/01/11 10:21:19 olga Optimized Version 1.5.1beta , free for
* tests
*
* Revision 1.6 2006/12/13 13:32:58 enrico reimplemented code
*
* Revision 1.5 2006/11/01 11:17:29 olga Optimized agg sources of CSP algorithm,
* match usability, graph isomorphic copy, node/edge type multiplicity check for
* injective rule and match
*
* Revision 1.4 2006/08/02 09:00:57 olga Preliminary version 1.5.0 with -
* multiple node type inheritance, - new implemented evolutionary graph layouter
* for graph transformation sequences
*
* Revision 1.3 2006/01/16 09:36:43 olga Extended attr. setting
*
* Revision 1.2 2005/10/24 09:04:49 olga GUI tuning
*
* Revision 1.1 2005/08/25 11:56:57 enrico *** empty log message ***
*
* Revision 1.2 2005/07/11 09:30:20 olga This is test version AGG V1.2.8alfa .
* What is new: - saving rule option <disabled> - setting trigger rule for layer -
* display attr. conditions in gragra tree view - CPA algorithm <dependencies> -
* creating and display CPA graph with conflicts and/or dependencies based on
* (.cpx) file
*
* Revision 1.1 2005/05/30 12:58:04 olga Version with Eclipse
*
* Revision 1.14 2004/12/20 14:53:47 olga Changes because of matching
* optimisation.
*
* Revision 1.13 2004/10/25 14:24:37 olga Fehlerbehandlung bei CPs und
* Aenderungen im zusammenhang mit termination-Modul in AGG
*
* Revision 1.12 2004/09/13 10:21:14 olga Einige Erweiterungen und
* Fehlerbeseitigung bei CPs und Graph Grammar Transformation
*
* Revision 1.11 2004/06/28 08:09:55 olga Folgefehler Besetigung nach der
* Anpassung der Attributekomponente fuer CPs
*
* Revision 1.10 2004/06/23 08:26:56 olga CPs sind endlich OK.
*
* Revision 1.9 2004/06/09 11:32:53 olga Attribute-Eingebe/Bedingungen : NAC
* kann jetzt eigene Variablen und Bedingungen haben. CP Berechnung korregiert.
*
* Revision 1.8 2004/04/15 10:49:47 olga Kommentare
*
* Revision 1.7 2004/03/18 17:41:53 olga
*
* rrektur an CPs und XML converter
*
* Revision 1.6 2004/02/12 17:44:02 olga Post Application Condition und alles
* was damit zusammen haengt wird erstmal zurueckgestellt.
*
* Revision 1.5 2004/02/05 17:53:38 olga Auswertung von Attr.Conditions
* optimiert
*
* Revision 1.4 2003/12/18 16:25:49 olga Tests.
*
* Revision 1.3 2003/03/05 18:24:21 komm sorted/optimized import statements
*
* Revision 1.2 2002/09/23 12:23:56 komm added type graph in xt_basis, editor
* and GUI
*
* Revision 1.1.1.1 2002/07/11 12:17:01 olga Imported sources
*
* Revision 1.11 2000/03/14 10:57:32 shultzke Transformieren von Variablen auf
* Variablen sollte jetzt funktionieren
*
*/