/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S. Chassande-Barrioz
*
*/
package org.objectweb.speedo.query.jdo.parser;
import org.objectweb.medor.api.Field;
import org.objectweb.medor.api.MedorException;
import org.objectweb.medor.query.api.QueryTree;
import org.objectweb.speedo.query.lib.SpeedoQueryHelper;
import org.objectweb.util.monolog.api.Logger;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
/**
* Base class with visitor utility class and default implementation of
* visit methods
*/
public class SpeedoQLAbstractVisitor extends SpeedoQueryHelper
implements SpeedoQLVisitor {
public final static String[] METHODS_OPERATOR = {
"matches", //0
"startsWith", //1
"endsWith", //2
"equals", //3
"equalsIgnoreCase", //4
"toUpperCase", //5
"toLowerCase", //6
"length", //7
"substring", //8
"contains", //9
"isEmpty" //10
};
public final static int MATCHES_OPERATOR = 0;
public final static int STARTS_WITH_OPERATOR = 1;
public final static int ENDS_WITH_OPERATOR = 2;
public final static int EQUALS_OPERATOR = 3;
public final static int EQUALS_IGNORE_CASE_OPERATOR = 4;
public final static int TO_UPPER_OPERATOR = 5;
public final static int TO_LOWER_OPERATOR = 6;
public final static int LENGTH_OPERATOR = 7;
public final static int SUBSTRING_OPERATOR = 8;
public final static int CONTAINS_OPERATOR = 9;
public final static int IS_EMPTY_OPERATOR = 10;
public final static Byte STR_OPERAND_SUBSTRING = new Byte((byte) 0);
public final static Byte BEGIN_OPERAND_SUBSTRING = new Byte((byte) 1);
public final static Byte LENGTH_OPERAND_SUBSTRING = new Byte((byte) 2);
/**
* params is an hashtable to store the parameters.
* key: name of the parameter
* value: a BasicFieldOperand
*/
protected Map params = null;
/**
* vars is an hashtable to store the variables.
* key: name of the variable
* value: the PType of the variable (from the declaration)
*/
protected Map vars = null;
/**
* int value to define the type of the IdValue object
* UNDEFINED : in case we don't know (default)
* JORM_NAME : jorm name (end point of the recursivity)
* NAVIGATION : the object is field to a field ...
* CONTAINS_IN : the id is a variable and used in a contains method
* CONTAINS_MEMBEROF : the id is a parameter and used in a contains method
*/
public final static int UNDEFINED = 0;
public final static int EXTENT = 1;
public final static int NAVIGATION = 2;
public final static int IN_COLLECTION = 3;
public final static int MEMBEROF = 4;
public final static int IS_EMPTY = 5;
public final static int IS_NOT_EMPTY = 6;
public final static String operationToString(int oc) {
switch(oc) {
case EXTENT: return "EXTENT";
case NAVIGATION: return "NAVIGATION";
case IN_COLLECTION: return "IN_COLLECTION";
case MEMBEROF: return "MEMBEROF";
case IS_EMPTY: return "IS_EMPTY";
case IS_NOT_EMPTY: return "IS_NOT_EMPTY";
case UNDEFINED:
default: return "UNDEFINED";
}
}
public String lastName;
/**
* Runtime Exception used to wrap exceptions thrown in visit methods
*/
protected class VisitorException extends RuntimeException {
Exception nestedException;
VisitorException(Exception nestedException) {
this.nestedException = nestedException;
}
Exception getNestedException() {
return nestedException;
}
}
/**
*
*/
protected String[] splitEndPath(String path, String prefix) {
String end = path.substring(prefix.length());
StringTokenizer st = new StringTokenizer(end, ".");
String[] ret = new String[st.countTokens() + 1];
ret[0] = prefix;
for (int i = 1; i < ret.length; i++) {
ret[i] = st.nextToken();
}
return ret;
}
protected String getEndString(String total) {
return total.substring(total.lastIndexOf('.') + 1, total.length());
}
/**
* return the JormField for a given path
* @param path the path of the JormField to return
* @param ids the map of (id,QueryTree)pairs;
* @throws org.objectweb.speedo.query.parser.ParseException if identification variable not found.
* @throws org.objectweb.medor.api.MedorException if corresponding fielc does not exist
*/
protected Field getMedorFieldFromPath(String path, Map ids)
throws MedorException, ParseException {
String[] paths = splitPath(path);
QueryTree qt = (QueryTree) ids.get(paths[0]);
if (paths.length > 2)
throw new Error("recursive path not implemented: " + path);
if (qt == null) {
throw new ParseException("Undeclared identification variable " + paths[0] + " in path " + path);
}
return qt.getTupleStructure().getField(path);
}
public String alias2fullname(String alias) {
int it = alias.indexOf("this.");
if (it == -1)
return alias;
else {
return curClass + "." + alias.substring(5, alias.length());
}
}
public String buildStringwithout(String[] ss, int toforget, String sep) {
StringBuffer sb = new StringBuffer();
String s = "";
for(int i=0; i<ss.length; i++) {
if (i != toforget) {
sb.append(s);
s = sep;
sb.append(ss[i]);
}
}
return sb.toString();
}
public String withoutThis(String aname) {
int it = aname.indexOf("this.");
if (it == -1)
return aname;
else {
return aname.substring(5, aname.length());
}
}
public int isMethodOperator(String str) {
for(int i=METHODS_OPERATOR.length-1; i>=0; i--) {
if (METHODS_OPERATOR[i].equals(str)) {
return i;
}
}
return -1;
}
/**
* ********************* VISITOR METHODS ***********************************
*/
/**
* Visit method to call from constructor.
* Child node visitors get a <code>java.util.Stack</code> as data parameter.
* @throws java.lang.Exception any nested exception thrown from other visit method
*/
public Object visit(SimpleNode node) throws Exception {
return visit(node, new Stack());
}
/**
* Generic visit method that traverses all child nodes
*/
public Object visit(SimpleNode node, Object data) {
return node.childrenAccept(this, data);
}
public Object visit(ASTSpeedoPrimary node, Object data) {
return null;
}
public Object visit(ASTSpeedoQL node, Object data) {
return null;
}
public Object visit(ASTPrimary node, Object data) {
return null;
}
public Object visit(ASTRelationalExpression node, Object data) {
return null;
}
public Object visit(ASTAdditiveExpression node, Object data) {
return null;
}
public Object visit(ASTUnaryExpression node, Object data) {
return null;
}
public Object visit(ASTCastExpression node, Object data) {
return null;
}
public Object visit(ASTArgumentList node, Object data) {
return null;
}
public Object visit(ASTLiteral node, Object data) {
return null;
}
public Object visit(ASTType node, Object data) {
return null;
}
public Object visit(ASTQualifiedName node, Object data) {
return null;
}
/**
* ********************* SETTER METHODS ************************************
*/
public void setParams(Map params) {
this.params = params;
}
public void setVars(Map vars) {
this.vars = vars;
}
public void setCurrentClass(String curClass) {
this.curClass = curClass;
}
}