KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > query > lib > MemberOfHelper


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2004 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, A. Lefebvre, S. Chassande-Barrioz
22  */

23 package org.objectweb.medor.query.lib;
24
25 import java.util.List JavaDoc;
26
27 import org.objectweb.medor.api.MedorException;
28 import org.objectweb.medor.expression.api.Expression;
29 import org.objectweb.medor.expression.api.MalformedExpressionException;
30 import org.objectweb.medor.expression.lib.And;
31 import org.objectweb.medor.filter.api.FieldOperand;
32 import org.objectweb.medor.filter.lib.BasicFieldOperand;
33 import org.objectweb.medor.filter.lib.MemberOf;
34 import org.objectweb.medor.lib.Log;
35 import org.objectweb.medor.query.api.PropagatedField;
36 import org.objectweb.medor.query.api.QueryLeaf;
37 import org.objectweb.medor.query.api.QueryNode;
38 import org.objectweb.medor.query.api.QueryTree;
39 import org.objectweb.medor.query.api.QueryTreeField;
40 import org.objectweb.util.monolog.api.BasicLevel;
41 import org.objectweb.util.monolog.api.Logger;
42
43 /**
44  * The MemberOfHelper class offers methods to manipulate MemberOf operators.
45  */

46 public class MemberOfHelper {
47
48     public static Logger logger = Log.getLoggerFactory()
49     .getLogger("org.objectweb.medor.query.lib.MemberOfHelper");
50
51     /**
52      * Adds a MemberOf to a query node, given the left and right ArrayLists.
53      * <p>
54      * If the QueryNode already has an expression, the MemberOf is appended with
55      * and And.
56      * <p>
57      * The field operands may, in this case, be on the same (lower level) query
58      * node. If this is the case, this method tries to un-propagates the right
59      * propagated field if possible, and places the MemberOf on this (lower
60      * level) query node.
61      * <p>
62      * It is assumed that all left fields are on the same query node, and all
63      * right fields are on the same query node.
64      *
65      * @param qn the QueryNode on which to add the MemberOf
66      * @param mofLeft the ArrayList of field operands for the left part of the
67      * MemberOf
68      * @param mofRight the ArrayList of field operands for the right part of the
69      * MemberOf
70      * @throws MalformedExpressionException returned by the MemberOf
71      * construction
72      */

73     public static void addMemberOf(QueryNode qn, List JavaDoc mofLeft, List JavaDoc mofRight)
74             throws MedorException, MalformedExpressionException {
75         int size = mofLeft.size();
76         Expression left, right;
77         for (int i = 0; i < size; i++) {
78             logger.log(BasicLevel.DEBUG, "Handling field number " +i);
79             left = (Expression) mofLeft.get(i);
80             right = (Expression) mofRight.get(i);
81             if (left instanceof FieldOperand) {
82                 QueryTreeField leftField = (QueryTreeField) ((FieldOperand) left)
83                         .getField();
84                 QueryTreeField rightField = (QueryTreeField) ((FieldOperand) right)
85                         .getField();
86                 qn = pushDown(leftField, rightField, mofLeft, mofRight, qn, i);
87             }
88         }
89         MemberOf mof = new MemberOf(mofLeft, mofRight);
90
91         if (qn.getQueryFilter() != null) {
92             qn.setQueryFilter(new And(qn.getQueryFilter(), mof));
93         } else {
94             qn.setQueryFilter(mof);
95         }
96     }
97
98     /**
99      * Recursive method which goes down the tree, and stops as soon as the two
100      * fields are not on the same query node.
101      * @param leftField
102      * @param rightField
103      * @param mofLeft
104      * @param mofRight
105      * @param qn
106      * @param i the index of the field in the MemberOf lists
107      * @return the query node on which to add the MemberOf operator
108      * @throws MalformedExpressionException
109      * @throws MedorException
110      */

111     private static QueryNode pushDown(QueryTreeField leftField,
112             QueryTreeField rightField,
113             List JavaDoc mofLeft,
114             List JavaDoc mofRight,
115             QueryNode qn,
116             int i) throws MalformedExpressionException, MedorException {
117         logger.log(BasicLevel.DEBUG, "Entering pushDown for fields " +
118                 leftField.getName() + " and " + rightField.getName());
119         QueryTree qt1 = leftField.getQueryTree();
120         QueryTree qt2 = rightField.getQueryTree();
121         if (!(qt1 instanceof QueryLeaf) && (qt1 == qt2)) {
122             logger.log(BasicLevel.DEBUG, "Fields on the same tree " + qt1);
123             //both on the same query node: try to go down one level
124
if ((rightField instanceof PropagatedField)
125                     && (leftField instanceof PropagatedField)) {
126                 QueryTreeField leftFDown = (QueryTreeField) ((PropagatedField) leftField)
127                         .getPreviousFields()[0];
128                 QueryTreeField rightFDown = (QueryTreeField) ((PropagatedField) rightField)
129                         .getPreviousFields()[0];
130                 QueryTree qtLDown = leftFDown.getQueryTree();
131                 if (qtLDown != rightFDown.getQueryTree()) {
132                     //the two fields are not on the same tree: proceed
133
logger.log(BasicLevel.DEBUG, "Propagated from fields on different trees: stop recursion");
134                     mofLeft.set(i,
135                             new BasicFieldOperand(((PropagatedField) leftField)
136                                     .getPreviousFields()[0]));
137                     mofRight.set(i,
138                             new BasicFieldOperand(
139                                     ((PropagatedField) rightField)
140                                             .getPreviousFields()[0]));
141                     //unpropagate the right field
142
((QueryNode) qt2).removeField(rightField.getName());
143                     //the MemberOf will be attached to the lower node
144
return (QueryNode) qt1;
145                 } else {
146                     logger.log(BasicLevel.DEBUG, "Propagated from fields on the same tree: go on with recursion");
147                     //the two fields are still on the same tree: go down
148
QueryNode qtPushed = pushDown(leftFDown, rightFDown, mofLeft, mofRight,
149                             (QueryNode) qtLDown, i);
150                     //unpropagate the right field
151
((QueryNode) qt2).removeField(rightField.getName());
152                     return qtPushed;
153                 }
154             } else {
155                 throw new MalformedExpressionException(
156                         "The helper cannot deal with two fields on the same query node which are not propagated fields");
157             }
158         } else {
159             return qn;
160         }
161     }
162
163 }
Popular Tags