KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > optim > lib > PushNotInExpressionRule


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2003 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, S. Chassande-Barrioz, A. Lefebvre
22  */

23 package org.objectweb.medor.optim.lib;
24
25 import org.objectweb.jorm.type.api.PType;
26 import org.objectweb.medor.api.MedorException;
27 import org.objectweb.medor.expression.api.BinaryLogicalOperator;
28 import org.objectweb.medor.expression.api.BinaryOperator;
29 import org.objectweb.medor.expression.api.Comparator;
30 import org.objectweb.medor.expression.api.Expression;
31 import org.objectweb.medor.expression.lib.And;
32 import org.objectweb.medor.expression.lib.ConditionalAnd;
33 import org.objectweb.medor.expression.lib.ConditionalOr;
34 import org.objectweb.medor.expression.lib.Equal;
35 import org.objectweb.medor.expression.lib.Greater;
36 import org.objectweb.medor.expression.lib.GreaterEqual;
37 import org.objectweb.medor.expression.lib.Lower;
38 import org.objectweb.medor.expression.lib.LowerEqual;
39 import org.objectweb.medor.expression.lib.Not;
40 import org.objectweb.medor.expression.lib.NotEqual;
41 import org.objectweb.medor.expression.lib.Or;
42 import org.objectweb.medor.filter.lib.IsNull;
43 import org.objectweb.medor.query.api.FilteredQueryTree;
44 import org.objectweb.medor.query.api.QueryNode;
45 import org.objectweb.medor.query.api.QueryTree;
46 import org.objectweb.util.monolog.api.BasicLevel;
47
48 /**
49  * This class is a RewriteRule implementation which vists a tree of QueryTree
50  * in order to push the not operator in the filters.
51  * <p>
52  * Somes examples:
53  * <ul>
54  * <li> !(a && b) is replaced by (!a || !b)</li>
55  * <li>!(a > b) is replaced by (a <= b)</li>
56  * <li>!(a = b) is replaced by (a != b)</li>
57  * </ul>
58  *
59  * @author S. Chassande-Barrioz
60  */

61
62 public class PushNotInExpressionRule extends BasicRule {
63
64     public PushNotInExpressionRule() {
65         super("PushNotInExpressionRule");
66     }
67
68     /**
69      * It modifies the expressions used as filter in a (tree of) QueryTree by pushing the
70      * not operator.
71      * Somes examples:
72      * !(a && b) is replaced by (!a || !b)
73      * !(a > b) is replaced by (a <= b)
74      * !(a = b) is replaced by (a != b)
75      * ...
76      * @param qt is the query on which the rule must be applied
77      * @throws MedorException if filters are malforrmed
78      */

79     public QueryTree rewrite(QueryTree qt, QueryNode _parent)
80             throws MedorException {
81         if (qt instanceof FilteredQueryTree) {
82             ModifiedExpression me = pushNotInExpression(
83                 ((FilteredQueryTree) qt).getQueryFilter(), false);
84             if (me.isModified)
85                 ((FilteredQueryTree) qt).setQueryFilter(me.e);
86         }
87         if (qt instanceof QueryNode) {
88             QueryTree[] children = ((QueryNode) qt).getChildren();
89             for (int i = 0; i < children.length; i++) {
90                 rewrite(children[i], (QueryNode) qt);
91             }
92         }
93         return qt;
94     }
95
96     /**
97      * This recursive method push the Not operator in an expression.
98      * @param e the current expression inside which the not operator must be
99      * pushed
100      * @param hasANot is boolean which indicates if a not is currently being
101      * push
102      * @throws MedorException if the expression is mal formed.
103      */

104     public ModifiedExpression pushNotInExpression(
105         Expression e, boolean hasANot) throws MedorException {
106         log.log(BasicLevel.DEBUG, "pushNotInExpression: (" + hasANot + ", exp:" + e + ")");
107         ModifiedExpression me = new ModifiedExpression(e, false);
108         if (hasANot && e instanceof Comparator) {
109             Expression l = ((BinaryOperator) e).getExpression(0);
110             Expression r = ((BinaryOperator) e).getExpression(1);
111             me.isModified = true;
112             if (e instanceof Equal)
113                 me.e = new NotEqual(l, r);
114             else if (e instanceof NotEqual)
115                 me.e = new Equal(l, r);
116             else if (e instanceof Lower)
117                 me.e = new GreaterEqual(l, r);
118             else if (e instanceof GreaterEqual)
119                 me.e = new Lower(l, r);
120             else if (e instanceof LowerEqual)
121                 me.e = new Greater(l, r);
122             else if (e instanceof Greater)
123                 me.e = new LowerEqual(l, r);
124             else
125                 throw new MedorException(
126                     "Comparator unmanaged by this method: " + e);
127         }
128         else if (e instanceof Not)
129             return pushNotInExpression(((Not) e).getExpression(), !hasANot);
130         else if (e instanceof IsNull) {
131             if (hasANot) {
132                 ((IsNull) me.e).setNot(!((IsNull) me.e).getNot());
133                 me.isModified = true;
134             }
135         } else if (e instanceof BinaryLogicalOperator) {
136             ModifiedExpression lme = pushNotInExpression(
137                 ((BinaryOperator) e).getExpression(0), hasANot);
138             ModifiedExpression rme = pushNotInExpression(
139                 ((BinaryOperator) e).getExpression(1), hasANot);
140             if (hasANot) {
141                 me.isModified = true;
142                 if (e instanceof And)
143                     me.e = new Or(lme.e, rme.e);
144                 else if (e instanceof ConditionalAnd)
145                     me.e = new ConditionalOr(lme.e, rme.e);
146                 else if (e instanceof Or)
147                     me.e = new And(lme.e, rme.e);
148                 else if (e instanceof ConditionalOr)
149                     me.e = new ConditionalAnd(lme.e, rme.e);
150                 else
151                     throw new MedorException(
152                         "BinaryLogicalOperator unmanaged by this method: " + e);
153             }
154             else {
155                 if (lme.isModified)
156                     ((BinaryOperator) e).setExpression(0, lme.e);
157                 if (rme.isModified)
158                     ((BinaryOperator) e).setExpression(1, rme.e);
159                 me.isModified = lme.isModified || rme.isModified;
160             }
161         }
162         else if (hasANot && e.getType().getTypeCode() == PType.TYPECODE_BOOLEAN) {
163             me.e = new Not(e);
164             me.isModified = true;
165         }
166         return me;
167     }
168 }
169
Popular Tags