package agg.attribute.handler.impl.javaExpr; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Vector; import agg.attribute.AttrVariableMember; import agg.attribute.handler.AttrHandlerException; import agg.attribute.handler.HandlerExpr; import agg.attribute.handler.SymbolTable; import agg.attribute.impl.AttrSession; import agg.attribute.impl.ContextView; import agg.attribute.impl.VerboseControl; import agg.attribute.parser.javaExpr.Jex; import agg.attribute.parser.javaExpr.Node; /** * @version $Id: JexExpr.java,v 1.16 2010/09/23 08:13:35 olga Exp $ * @author $Author: olga $ */ public class JexExpr extends Object implements HandlerExpr { static protected Jex parser = new Jex(); protected JexHandler handler; protected JexType type; // protected String text; /** The value of an attribute */ protected Object value; /** Represents the abstract syntax tree of an expression */ protected Node ast; protected int property = Jex.PARSE_ERROR; public static final long serialVersionUID = 268212822469784946L; public JexExpr() { } public JexExpr(String exprString, boolean asValue, JexType type) throws AttrHandlerException { // AttrSession.logPrintln(VerboseControl.logTrace, // "JexExpr:\n->Constructor"); if (asValue) { this.assignValue(exprString, type); } else { this.type = type; // this.text = exprString.trim(); this.property = parser.parse(exprString.trim()); this.ast = parser.getAST(); // if (VerboseControl.logTrace) { // AttrSession.logPrintln(VerboseControl.logTrace, "konstant: " // + isConstant() + "\nvariable: " + isVariable() // + "\nkomplex: " + isComplex()); // this.ast.dump("JexExpr: "); // } if (isConstant()) { evaluate(null); } // else value = new String(text); } // AttrSession.logPrintln(VerboseControl.logTrace, // "JexExpr:\n<-Construktor"); } public JexExpr(Object value, JexType type) throws AttrHandlerException { this.assignValue(value, type); } protected void assignValue(Object avalue, JexType atype) throws AttrHandlerException { // AttrSession.logPrintln(VerboseControl.logTrace, // "JexExpr:\n->assignValue"); Class<?> clazz = atype.getClazz(); if( this.value != null && !clazz.isInstance( this.value )) { // System.out.println("JexExpr.assignValue: " // +this.value.toString() // + " is not an instance of " // + clazz.toString()); throw new AttrHandlerException( this.value.toString() + " is not an instance of " + clazz.toString()); } this.type = atype; this.value = avalue; // this.text = (this.value == null ? "null" : this.value.toString()); // if( this.value != null && this.value instanceof String ) { // this.text = "\"" + this.text + "\""; // } this.property = Jex.IS_CONSTANT; // if (this.value instanceof HandlerExpr) { // System.out.println("JexExpr.assignValue:: "+ value); // } // AttrSession.logPrintln(VerboseControl.logTrace, // "JexExpr:\n<-assignValue"); } static public Jex getParser() { return parser; } public JexHandler getHandler() { if (this.type != null) return this.type.handler; return null; } /** * Getting the string representation of this value. Overrides the * "toString()" method of the "Object" class. */ public String toString() { return getString(); } public boolean equals(HandlerExpr expr) { JexExpr testObject = (JexExpr) expr; boolean result = true; if (testObject == null || getHandler() != testObject.getHandler() || !this.type.equals(testObject.type)) { result = false; } else if (this.value != null && testObject.value != null) { result = this.value.equals(testObject.value); } else { if (this.value == null && testObject.value == null) { // result = text.equals( testObject.text ); /* Dieser Fall tritt ein wenn null als Value eingegeben wird. */ if (this.ast == null && testObject.ast == null) return true; if (this.ast != null && testObject.ast != null) { result = this.ast.equals(testObject.ast); // TO DO: die equals Methode soll in Abstr Baum rein!! result = this.ast.toString().equals(testObject.ast.toString()); } else result = false; } else result = false; } return result; } public Object getValue() { return this.value; } public JexType getType() { return this.type; } protected void copyFrom(HandlerExpr expr) { JexExpr from = (JexExpr) expr; this.type = from.type; this.value = from.value; this.property = from.property; if (from.ast != null) { // try{ // from.ast.getString() kopiert keine Objecte // TODO // this.property = parser.parse( from.ast.getString() ); // ast = parser.getAST(); this.ast = from.ast.copy(); // } // catch(AttrHandlerException ahe){ // ast = from.ast; // } } else { this.ast = null; this.property = from.property; } // text = new String( from.text ); } public HandlerExpr getCopy() { JexExpr copy = new JexExpr(); copy.copyFrom(this); return copy; } public void check(SymbolTable symtab) throws AttrHandlerException { if (this.property == Jex.IS_CONSTANT) { return; } if (getHandler() != null && this.type != null) { getHandler().adaptParser(); parser.check(getString(), this.type.getClazz(), symtab); } } public void checkConstant(SymbolTable symtab) throws AttrHandlerException { if (this.property == Jex.IS_CONSTANT) { if (getHandler() != null && this.type != null) { getHandler().adaptParser(); parser.check(getString(), this.type.getClazz(), symtab); } } } public void evaluate(SymbolTable symtab) throws AttrHandlerException { if (VerboseControl.logTrace) { AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr:\n->evaluate()"); AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr: text " + getString() + " vor interpret aufruf"); AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr: value " + this.value + " vor interpret aufruf"); AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr: symtab " + symtab + " vor interpret aufruf"); if (symtab instanceof ContextView) { ContextView context = (ContextView) symtab; AttrSession.logAttrInstance(context.getVariables(), "JexExpr: Variablen"); AttrSession.logPrintln("JexExpr: Variablen:" + context.getVariables().getNumberOfEntries()); for (int i = 0; i < context.getVariables().getNumberOfEntries(); i++) { AttrSession.logPrintln("JexExpr: Variablen bei " + i + ": " + ((AttrVariableMember) context.getVariables() .getMemberAt(i)).getExprAsText()); } } else AttrSession.logPrintln("JexExpr: symtab ist kein ContextView"); } // falls ein matchmapping existiert, nur dann soll ausgewertet werden. // boolean matchMapping = true; // ContextView contextView = null; // if(symtab instanceof ContextView) // contextView = (ContextView)symtab; // if(contextView != null){ // matchMapping = contextView.getAllowedMapping() == // AttrMapping.MATCH_MAP; // AttrSession.logPrintln(VerboseControl.logTrace,"werte ausdruck aus // mit mapping: "+contextView.getAllowedMapping()); // } if (this.value == null) { // wir gehen erstmal davon aus, dass die Expression zu einer // Konstanten ausgewertet wird. this.property = Jex.IS_CONSTANT; if (getHandler() != null && this.type != null) { getHandler().adaptParser(); if (symtab != null && mustRewrite(symtab)) { this.value = null; try { // AttrSession.logPrintln(VerboseControl.logJexParser, // "JexExpr.evaluate: rewrite"); parser.rewrite(getAST(), this.type.getClazz(), symtab); this.property = Jex.IS_COMPLEX; } catch (AttrHandlerException ex) { // AttrSession.logPrintln(VerboseControl.logJexParser, // "JexExpr.evaluate: rewriting failed. " // + ex.getMessage()); throw new AttrHandlerException( "JexExpr.evaluate:: required type: " + this.type.toString() + " - rewriting failed. " + ex.getMessage() + " - value failed."); } } else if (this.ast != null) { try { // AttrSession.logPrintln(VerboseControl.logJexParser, // "JexExpr.evaluate: interpret"); this.value = parser.interpret(this.ast, this.type.getClazz(), symtab); } catch (AttrHandlerException ex) { // AttrSession.logPrintln(VerboseControl.logJexParser, // "JexExpr.evaluate: interpretting failed. " // + ex.getMessage()); if (ex.getMessage() != null) { throw new AttrHandlerException( "JexExpr.evaluate:: required type: " + this.type.toString() + " - interpretting failed. "); } } } } else this.value = null; } if (VerboseControl.logTrace) { AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr: value " + this.value + " nach evaluate"); AttrSession.logPrintln(VerboseControl.logTrace, "JexExpr:\n<-evaluate()"); } } /** Checks the expression if there is any variable which must be rewritten */ protected boolean mustRewrite(SymbolTable symtab) { Vector<String> v = new Vector<String>(); getAllVariables(v); boolean result = false; for (int i = 0; i < v.size() && !result; i++) { String s = v.elementAt(i); HandlerExpr he = symtab.getExpr(s); if (he != null) { result = !he.isConstant(); } } return result; } public boolean isConstant() { return (this.property == Jex.IS_CONSTANT); } public boolean isVariable() { return (this.property == Jex.IS_VARIABLE); } public boolean isComplex() { return (this.property == Jex.IS_COMPLEX); } protected boolean isAssignableTo(JexExpr expr, SymbolTable symtab) { if (expr == null || symtab == null) { return false; } if (this.isConstant() && expr.isVariable()) { JexExpr currentAssignment = (JexExpr) symtab.getExpr(expr .getString()); if (currentAssignment == null || ((this.value != null) && this.value .equals(currentAssignment.value))) { return true; } } return false; } /** * checks if both expression fit together */ public boolean isUnifiableWith(HandlerExpr expr, SymbolTable symtab) { if (this.type == null) { return false; } JexExpr testObject = (JexExpr) expr; if (testObject == null || getHandler() != testObject.getHandler() || !this.type.equals(testObject.type)) { return false; } // AttrSession.logPrintln(VerboseControl.logMapping, // "JexExpr: Expr not null, Handler are equal, Type are equal"); boolean result = true; /* * es gibt 3 Moeglichkeiten: * 1. beide Ausdruecke sind konstant und sie sind gleich (die ersten drei Zeilen) * 2. der eine kann dem anderen zugewiesen werden. * 3. der andere kann dem einen zugewiesen werden (Umkehrung) */ result = result && isConstant(); result = result && expr.isConstant(); result = result && equals(expr); result = result || isAssignableTo(testObject, symtab); result = result || testObject.isAssignableTo(this, symtab); return result; } /** represents the expression as a string */ public String getString() { String result; if (this.value != null) { result = this.value.toString(); if (this.value instanceof String) result = "\"" + result + "\""; } else { if (this.ast != null) result = this.ast.getString(); else result = "null"; } return result; } /** Returns the abstract syntax tree which represents the expression */ public Node getAST() { return this.ast; } /** * fills the vector with the names of all variables which occur in this * abstract syntax tree */ public void getAllVariables(Vector<String> v) { if (getAST() != null) getAST().getAllVariablesinExpression(v); } /*************************************************************************** * LOAD - SAVE * ********************************************************************* */ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ObjectInputStream.GetField gf = ois.readFields(); /* reading fields */ this.handler = (JexHandler) gf.get("handler", null); this.type = (JexType) gf.get("type", null); /** The value of an attribute */ this.value = gf.get("value", null); this.property = gf.get("property", Jex.PARSE_ERROR); /** Represents the abstract syntax tree of an expression */ this.ast = (Node) gf.get("ast", null); if (this.ast == null && this.value == null) { String text = (String) gf.get("text", null); if (text != null) { JexExpr newExpr = null; try { newExpr = new JexExpr(text, false, this.type); } catch (AttrHandlerException ahe) { throw new RuntimeException(ahe.getMessage()); } this.ast = newExpr.ast; this.property = newExpr.property; } } } } /* * $Log: JexExpr.java,v $ * Revision 1.16 2010/09/23 08:13:35 olga * tuning * * Revision 1.15 2010/03/31 21:07:29 olga * tuning * * Revision 1.14 2010/03/18 18:14:04 olga * null pointer bug fixed * * Revision 1.13 2010/03/08 15:37:01 olga * code optimizing * * Revision 1.12 2009/11/26 10:56:55 olga * tuning * * Revision 1.11 2009/03/19 09:31:06 olga * CPE: attr check improved * * Revision 1.10 2008/12/04 14:30:02 olga * Node Type Inheritance: init of parent attributes - bug fixed * * Revision 1.9 2007/11/05 09:18:19 olga * code tuning * * Revision 1.8 2007/11/01 09:58:19 olga * Code refactoring: generic types- done * * Revision 1.7 2007/09/10 13:05:46 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.6 2007/03/28 10:00:51 olga - extensive * changes of Node/Edge Type Editor, - first Undo implementation for graphs and * Node/edge Type editing and transformation, - new / reimplemented options for * layered transformation, for graph layouter - enable / disable for NACs, attr * conditions, formula - GUI tuning * * Revision 1.5 2006/12/13 13:32:58 enrico reimplemented code * * Revision 1.4 2006/11/02 10:41:26 enrico interface extension for AGG * * Revision 1.3 2006/04/10 09:19:30 olga Import Type Graph, Import Graph - * tuning. Attr. member type check: if class does not exist. Graph constraints * for a layer of layered grammar. * * Revision 1.2 2006/01/16 09:36:24 olga Extended attr. setting * * Revision 1.1 2005/08/25 11:57:00 enrico *** empty log message *** * * Revision 1.1 2005/05/30 12:58:04 olga Version with Eclipse * * Revision 1.11 2004/12/20 14:53:47 olga Changes because of matching * optimisation. * * Revision 1.10 2004/01/15 16:43:38 olga ... * * Revision 1.9 2003/07/10 14:02:39 olga Tests * * Revision 1.8 2003/03/05 18:24:28 komm sorted/optimized import statements * * Revision 1.7 2003/01/15 11:33:55 olga System.out Umleitung abgeschaltet * * Revision 1.6 2002/12/20 11:36:16 olga Tests * * Revision 1.5 2002/12/20 11:25:00 olga Tests * * Revision 1.4 2002/12/18 09:15:19 olga Testausgaben raus * * Revision 1.3 2002/11/25 14:56:24 olga Der Fehler unter Windows 2000 im * AttributEditor ist endlich behoben. Es laeuft aber mit Java1.3.0 laeuft * endgueltig nicht. Also nicht Java1.3.0 benutzen! * * Revision 1.2 2002/11/11 09:41:07 olga Nur Testausgaben * * Revision 1.1.1.1 2002/07/11 12:17:00 olga Imported sources * * Revision 1.19 2001/05/14 12:05:36 olga Unwesentlich. Testausgaben wieder * raus. * * Revision 1.18 2001/02/15 15:59:55 olga Einige Aenderungen wegen XML * * Revision 1.17 2000/12/21 09:48:47 olga In dieser Version wurden XML und GUI * Reimplementierung zusammen gefuehrt. * * Revision 1.16.6.1 2000/12/04 13:25:50 olga Erste Stufe der GUI * Reimplementierung abgeschlossen: - AGGAppl.java optimiert - Print eingebaut * (GraGraPrint.java) - GraGraTreeView.java, GraGraEditor.java optimiert - Event * eingebaut - GraTra umgestellt * * Revision 1.16 2000/06/15 06:53:12 shultzke equals fuer JexType anstatt * Objectvergleich * * Revision 1.15 2000/06/05 14:07:20 shultzke Debugausgaben fuer V1.0.0b * geloescht * * Revision 1.14 2000/05/24 16:17:28 olga Error bei Transformation mit Condotion * beseitigt. Error bei Variablen in der rechten Regelseite auch beseitigt. * * Revision 1.13 2000/05/24 10:01:05 olga Aenderungen wegen dem Fehler in DISAGG : * Match Konstante auf Konstante * * Revision 1.12 2000/05/17 11:33:32 shultzke diverse Aenderungen. Version von * Olga wird erwartet * * Revision 1.11 2000/04/05 12:08:43 shultzke serialVersionUID aus V1.0.0 * generiert * * Revision 1.10 2000/03/15 08:17:58 olga Die Aenderungen betraffen nur * serialVersionUID in einigen Files, um alte Beispiele zu laden. Noch zu * klaeren od wir die alte Beispiele am Leben erhalten wollen. * * Revision 1.9 2000/03/14 10:57:14 shultzke Transformieren von Variablen auf * Variablen sollte jetzt funktionieren * * Revision 1.8 2000/03/03 11:39:41 shultzke Aus der Expression den String durch * abstrakten Syntaxbaum ersetzt */