KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > jorm > rdb > FilterManager


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.jorm.rdb;
19
20 import org.objectweb.speedo.query.parser.SpeedoQLVisitor;
21 import org.objectweb.speedo.query.parser.SimpleNode;
22 import org.objectweb.speedo.query.parser.ASTSpeedoPrimary;
23 import org.objectweb.speedo.query.parser.ASTSpeedoQL;
24 import org.objectweb.speedo.query.parser.ASTPrimary;
25 import org.objectweb.speedo.query.parser.ASTRelationalExpression;
26 import org.objectweb.speedo.query.parser.ASTAdditiveExpression;
27 import org.objectweb.speedo.query.parser.ASTUnaryExpression;
28 import org.objectweb.speedo.query.parser.ASTCastExpression;
29 import org.objectweb.speedo.query.parser.ASTArgumentList;
30 import org.objectweb.speedo.query.parser.ASTLiteral;
31 import org.objectweb.speedo.query.parser.ASTType;
32 import org.objectweb.speedo.query.parser.ASTQualifiedName;
33 import org.objectweb.speedo.query.parser.SpeedoQLConstants;
34 import org.objectweb.speedo.query.parser.SpeedoQL;
35 import org.objectweb.speedo.query.parser.ParseException;
36 import org.objectweb.speedo.api.SpeedoException;
37 import org.objectweb.speedo.metadata.SpeedoClass;
38 import org.objectweb.medor.expression.api.Expression;
39 import org.objectweb.medor.expression.api.Operator;
40 import org.objectweb.medor.expression.api.Operand;
41 import org.objectweb.medor.expression.lib.ConditionalOr;
42 import org.objectweb.medor.expression.lib.ConditionalAnd;
43 import org.objectweb.medor.expression.lib.Or;
44 import org.objectweb.medor.expression.lib.And;
45 import org.objectweb.medor.expression.lib.Equal;
46 import org.objectweb.medor.expression.lib.NotEqual;
47 import org.objectweb.medor.expression.lib.Lower;
48 import org.objectweb.medor.expression.lib.Greater;
49 import org.objectweb.medor.expression.lib.GreaterEqual;
50 import org.objectweb.medor.expression.lib.LowerEqual;
51 import org.objectweb.medor.expression.lib.Plus;
52 import org.objectweb.medor.expression.lib.Minus;
53 import org.objectweb.medor.expression.lib.Mult;
54 import org.objectweb.medor.expression.lib.DivideBy;
55 import org.objectweb.medor.expression.lib.UMinus;
56 import org.objectweb.medor.expression.lib.Bitwize;
57 import org.objectweb.medor.expression.lib.Not;
58 import org.objectweb.medor.expression.lib.BasicOperand;
59 import org.objectweb.util.monolog.api.BasicLevel;
60 import org.objectweb.util.monolog.api.Logger;
61 import org.objectweb.jorm.mapper.rdb.metainfo.RdbFilter;
62 import org.objectweb.jorm.type.api.PTypeSpace;
63
64 import java.util.Stack JavaDoc;
65 import java.io.CharArrayReader JavaDoc;
66
67 /**
68  * It manages the filter dedicated to the filtered inheritance mapping.
69  *
70  * @author S.Chassande-Barrioz
71  */

72 public class FilterManager {
73
74     private Logger logger;
75     private boolean debug = false;
76     private FilterParser parser = new FilterParser();
77
78     public FilterManager(Logger logger) {
79         this.logger = logger;
80     }
81
82     public FilterParser getParser() {
83         return parser;
84     }
85
86     public void assignFilter(String JavaDoc filter,
87                              RdbFilter rdbFilter,
88                              SpeedoClass sc,
89                              String JavaDoc projectName,
90                              String JavaDoc mapperName) throws SpeedoException {
91         debug = logger != null && logger.isLoggable(BasicLevel.DEBUG);
92         Expression medorExpression = parser.parse(filter);
93         if (!isJormPredicate(medorExpression)) {
94             throw new SpeedoException(
95                 "The specified filter is not supported, \n\tclass"
96                 + sc.getFQName() + "\n\tfilter=" + filter);
97         }
98         rdbFilter.setExpression(medorExpression);
99     }
100
101     public class FilterParser implements SpeedoQLVisitor {
102         private Expression expression;
103         private String JavaDoc tab = "";
104
105         public synchronized Expression parse(String JavaDoc filter) throws SpeedoException {
106             try {
107                 visit(new SpeedoQL(new CharArrayReader JavaDoc(filter.toCharArray())).SpeedoQL());
108                 return expression;
109             } catch (ParseException e) {
110                 throw new SpeedoException(
111                     "Impossible to parse the filter and to create AST", e);
112             } catch (SpeedoException e) {
113                 throw e;
114             } catch (Exception JavaDoc e) {
115                 throw new SpeedoException("Impossible to parse the filter", e);
116             }
117         }
118
119         // IMPLEMENTATION OF THE SpeedoQLVisitor INTERFACE //
120
//-------------------------------------------------//
121

122         public Object JavaDoc visit(ASTPrimary node, Object JavaDoc data) {
123             visit((SimpleNode) node, data);
124             return null;
125         }
126
127         public Object JavaDoc visit(ASTSpeedoPrimary node, Object JavaDoc data) {
128             visit((SimpleNode) node, data);
129             Stack JavaDoc stack = (Stack JavaDoc) data;
130             expression = (Expression) stack.pop();
131             return null;
132         }
133
134         public Object JavaDoc visit(ASTRelationalExpression node, Object JavaDoc data) {
135             logger.log(BasicLevel.DEBUG, tab + "Visit RelationalExpression: " + node);
136             tab += '\t';
137             visit((SimpleNode) node, data);
138             tab = tab.substring(1);
139             Stack JavaDoc stack = (Stack JavaDoc) data;
140             if (stack.size() > 0) {
141                 if (debug) {
142                     logger.log(BasicLevel.DEBUG, "manage relational expression: "
143                         + "(children: " + node.jjtGetNumChildren()
144                         + ", stack: " + stack.size()
145                         + ", peek:" + stack.peek() + ")");
146                 }
147                 for (int i = 0; (i < (node.jjtGetNumChildren() - 1) && stack.size() > 0); i++) {
148                     int op = ((Integer JavaDoc) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue();
149                     if (usedInRelationalExpresssion(op)) {
150                         Object JavaDoc child2 = stack.pop();
151                         Object JavaDoc child1 = stack.pop();
152                         if (debug) {
153                             logger.log(BasicLevel.DEBUG, "pop child1: " + child1);
154                             logger.log(BasicLevel.DEBUG, "pop child2: " + child2);
155                         }
156                         Expression ret = null;
157                         switch (op) {
158                         case SpeedoQLConstants.OR:
159                             ret = new ConditionalOr((Expression) child1, (Expression) child2);
160                             break;
161                         case SpeedoQLConstants.AND:
162                             ret = new ConditionalAnd((Expression) child1, (Expression) child2);
163                             break;
164                         case SpeedoQLConstants.BITWISEOR:
165                             ret = new Or((Expression) child1, (Expression) child2);
166                             break;
167                         case SpeedoQLConstants.BITWISEXOR:
168                             ret = null;
169                             break;
170                         case SpeedoQLConstants.BITWISEAND:
171                             ret = new And((Expression) child1, (Expression) child2);
172                             break;
173                         case SpeedoQLConstants.EQ:
174                             ret = new Equal((Expression) child1, (Expression) child2);
175                             break;
176                         case SpeedoQLConstants.NEQ:
177                             ret = new NotEqual((Expression) child1, (Expression) child2);
178                             break;
179                         case SpeedoQLConstants.LT:
180                             ret = new Lower((Expression) child1, (Expression) child2);
181                             break;
182                         case SpeedoQLConstants.GT:
183                             ret = new Greater((Expression) child1, (Expression) child2);
184                             break;
185                         case SpeedoQLConstants.GTE:
186                             ret = new GreaterEqual((Expression) child1, (Expression) child2);
187                             break;
188                         case SpeedoQLConstants.LTE:
189                             ret = new LowerEqual((Expression) child1, (Expression) child2);
190                             break;
191                         }
192                         if (debug) {
193                             logger.log(BasicLevel.DEBUG, "push(" + ret + ")");
194                         }
195                         stack.push(ret);
196                     }
197                 }
198             }
199             if (debug) {
200                 logger.log(BasicLevel.DEBUG, "children:" + node.jjtGetNumChildren()
201                     + " / stack: " + stack.size());
202                 logger.log(BasicLevel.DEBUG, tab + "End of Visit RelationalExpression: " + node);
203             }
204             return null;
205         }
206
207         public Object JavaDoc visit(ASTAdditiveExpression node, Object JavaDoc data) {
208             logger.log(BasicLevel.DEBUG, tab + "Visit AdditiveExpression: " + node);
209             tab += '\t';
210             visit((SimpleNode) node, data);
211             tab = tab.substring(1);
212             Stack JavaDoc stack = (Stack JavaDoc) data;
213             if (stack.size() > 0) {
214                 Expression ret = (Expression) stack.pop();
215                 for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) {
216                     logger.log(BasicLevel.DEBUG, "Visit AdditiveExpression... children...[" + i + "]");
217
218                     switch (((Integer JavaDoc) node.ops.get(node.jjtGetNumChildren() - 2 - i)).intValue()) {
219
220                     case SpeedoQLConstants.PLUS:
221                         ret = new Plus((Expression) stack.pop(), ret);
222                         break;
223                     case SpeedoQLConstants.MINUS:
224                         ret = new Minus((Expression) stack.pop(), ret);
225                         break;
226                     case SpeedoQLConstants.MULT:
227                         ret = new Mult((Expression) stack.pop(), ret);
228                         break;
229                     case SpeedoQLConstants.DIV:
230                         ret = new DivideBy((Expression) stack.pop(), ret);
231                         break;
232                     default:
233
234                     }
235                 }
236                 ((Stack JavaDoc) data).push(ret);
237             }
238             logger.log(BasicLevel.DEBUG, tab + "End of Visit AdditiveExpression: " + node);
239             return null;
240         }
241
242         public Object JavaDoc visit(ASTUnaryExpression node, Object JavaDoc data) {
243             logger.log(BasicLevel.DEBUG, tab + "Visit UnaryExpression" + node);
244             tab += '\t';
245             visit((SimpleNode) node, data);
246             tab = tab.substring(1);
247             Stack JavaDoc stack = (Stack JavaDoc) data;
248             if (stack.size() > 0) {
249                 Object JavaDoc o = stack.pop();
250                 if (node.ops.size() > 0) {
251                     switch (((Integer JavaDoc) node.ops.get(0)).intValue()) {
252                     case SpeedoQLConstants.MINUS:
253                         o = new UMinus((Expression) o);
254                         break;
255                     case SpeedoQLConstants.BITWISECOMPL:
256                         o = new Bitwize((Expression) o);
257                         break;
258                     case SpeedoQLConstants.NOT:
259                         logger.log(BasicLevel.DEBUG, "NOT(" + o + "): " + node);
260                         o = new Not((Expression) o);
261                         break;
262                     }
263                 }
264                 ((Stack JavaDoc) data).push(o);
265             }
266             logger.log(BasicLevel.DEBUG, tab + "End of Visit UnaryExpression: " + node);
267             return null;
268         }
269
270         public Object JavaDoc visit(ASTCastExpression node, Object JavaDoc data) {
271             return null;
272         }
273
274         public Object JavaDoc visit(ASTArgumentList node, Object JavaDoc data) {
275             return null;
276         }
277
278         public Object JavaDoc visit(ASTLiteral node, Object JavaDoc data) {
279             if (node.value instanceof Integer JavaDoc) {
280                 ((Stack JavaDoc) data).push(new BasicOperand(((Integer JavaDoc) node.value).intValue()));
281             } else if (node.value instanceof Float JavaDoc) {
282                 ((Stack JavaDoc) data).push(new BasicOperand(((Float JavaDoc) node.value).floatValue()));
283             } else if (node.value instanceof Character JavaDoc) {
284                 ((Stack JavaDoc) data).push(new BasicOperand(((Character JavaDoc) node.value).charValue()));
285             } else if (node.value instanceof String JavaDoc) {
286                 String JavaDoc s = (String JavaDoc) (node.value);
287                 s = s.substring(1, s.length() - 1);
288                 ((Stack JavaDoc) data).push(new BasicOperand(s));
289             } else if (node.value instanceof Boolean JavaDoc) {
290                 ((Stack JavaDoc) data).push(new BasicOperand(((Boolean JavaDoc) node.value).booleanValue()));
291             }
292             return null;
293         }
294
295         public Object JavaDoc visit(ASTType node, Object JavaDoc data) {
296             logger.log(BasicLevel.DEBUG, "Visit Type: " + node);
297             return null;
298         }
299
300         public Object JavaDoc visit(ASTQualifiedName node, Object JavaDoc data) {
301             ((Stack JavaDoc) data).push(new BasicOperand((String JavaDoc) node.value));
302             return null;
303         }
304
305
306         /**
307          * Visit method to call from constructor.
308          * Child node visitors get a <code>java.util.Stack</code> as data parameter.
309          * @throws java.lang.Exception any nested exception thrown from other visit method
310          */

311         public Object JavaDoc visit(SimpleNode node) throws Exception JavaDoc {
312             return visit(node, new Stack JavaDoc());
313         }
314
315         /**
316          * Generic visit method that traverses all child nodes
317          */

318         public Object JavaDoc visit(SimpleNode node, Object JavaDoc data) {
319             return node.childrenAccept(this, data);
320         }
321
322         public Object JavaDoc visit(ASTSpeedoQL node, Object JavaDoc data) {
323             return null;
324         }
325
326         private boolean usedInRelationalExpresssion(int op) {
327             switch (op) {
328             case SpeedoQLConstants.OR:
329             case SpeedoQLConstants.AND:
330             case SpeedoQLConstants.BITWISEOR:
331             case SpeedoQLConstants.BITWISEXOR:
332             case SpeedoQLConstants.BITWISEAND:
333             case SpeedoQLConstants.EQ:
334             case SpeedoQLConstants.NEQ:
335             case SpeedoQLConstants.LT:
336             case SpeedoQLConstants.GT:
337             case SpeedoQLConstants.GTE:
338             case SpeedoQLConstants.LTE:
339                 logger.log(BasicLevel.DEBUG, "node useful");
340                 return true;
341             default:
342                 logger.log(BasicLevel.DEBUG, "node useless");
343                 return false;
344             }
345         }
346
347     }
348     // OTHER METHODS //
349
//---------------//
350

351     /**
352      * Calculates if an expression can be used as Jorm predicate as inheritance
353      * filter.
354      * @param e is the medor Expression to analyze.
355      * @return true if the expression is compatible.
356      */

357     private boolean isJormPredicate(Expression e) {
358         return isSimpleOperator(e)
359             || (e instanceof ConditionalAnd
360             && isJormPredicate(((Operator) e).getExpression(0))
361             && isJormPredicate(((Operator) e).getExpression(1)));
362     }
363
364     private boolean isSimpleOperator(Expression e) {
365         boolean res = e instanceof Equal
366             || e instanceof Greater
367             || e instanceof GreaterEqual
368             || e instanceof Lower
369             || e instanceof LowerEqual;
370         if (res == false) {
371             return false;
372         }
373         Operator op = (Operator) e;
374
375         if (!(op.getExpression(0) instanceof Operand
376             && op.getExpression(1) instanceof Operand)) {
377             return false;
378         }
379         Operand o0 = (Operand) op.getExpression(0);
380         Operand o1 = (Operand) op.getExpression(1);
381         if (o0.getType().getTypeCode() == PTypeSpace.STRING.getTypeCode()) {
382             return true;
383         } else if (o1.getType().getTypeCode() == PTypeSpace.STRING.getTypeCode()) {
384             //reverse the order: column name at left
385
op.setExpression(0, o1);
386             op.setExpression(1, o0);
387             return true;
388         } else {
389             return false;
390         }
391     }
392 }
393
Popular Tags