KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > filter > jorm > lib > NavigatorOperator


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
24 package org.objectweb.medor.filter.jorm.lib;
25
26 import org.objectweb.jorm.metainfo.api.Class;
27 import org.objectweb.jorm.metainfo.api.ClassRef;
28 import org.objectweb.jorm.metainfo.api.GenClassRef;
29 import org.objectweb.jorm.metainfo.api.MetaObject;
30 import org.objectweb.jorm.metainfo.api.Reference;
31 import org.objectweb.jorm.metainfo.api.TypedElement;
32 import org.objectweb.medor.api.Field;
33 import org.objectweb.medor.api.MedorException;
34 import org.objectweb.medor.expression.api.ExpressionException;
35 import org.objectweb.medor.expression.api.MalformedExpressionException;
36 import org.objectweb.medor.expression.api.Operator;
37 import org.objectweb.medor.expression.api.ParameterOperand;
38 import org.objectweb.medor.expression.api.Operand;
39 import org.objectweb.medor.expression.api.TypingException;
40 import org.objectweb.medor.expression.api.Expression;
41 import org.objectweb.medor.expression.lib.BasicBinaryOperator;
42 import org.objectweb.medor.expression.lib.BasicOperand;
43 import org.objectweb.medor.filter.api.FieldOperand;
44 import org.objectweb.medor.query.api.PropagatedField;
45 import org.objectweb.medor.query.jorm.lib.PNameField;
46
47 import java.util.Map JavaDoc;
48 import java.util.ArrayList JavaDoc;
49
50 /**
51  * A NavigatorOperator typically represents a path expression.
52  * <p>
53  * Such an expression starts from a FieldOperand for which the origin field
54  * is a JormField of a PName type (ref).
55  */

56 public class NavigatorOperator extends BasicBinaryOperator {
57
58     protected boolean isPName;
59     private MetaObject jormMO;
60     private FieldOperand myFop;
61
62
63     /**
64      * Creates a NavigatorOperator from a FieldOperand and an attribute name.
65      * The origin field of this FieldOperand must be a JormField of a PName
66      * type (or a PropagatedField pointing to such a JormField).
67      * @param fop is the FieldOperand corresponding to the left operand.
68      * @param att is the name of the attribute to which the operator nagivates.
69      * @throws org.objectweb.medor.api.MedorException when fop does not
70      * reference a PNameField or when no field att is reachable by the
71      * PNameField.
72      */

73     public NavigatorOperator(FieldOperand fop, String JavaDoc att)
74         throws MedorException {
75         super(fop, new BasicOperand(att));
76
77         myFop = fop;
78         //Fetch the PNameField origin
79
Field f = fop.getField();
80         if (f instanceof PropagatedField) {
81             Field[] fs = ((PropagatedField) f).getOriginFields();
82             f = fs[0];
83         }
84         if (!(f instanceof PNameField))
85             throw new MedorException(
86                 "Impossible to create a NavigatorOperator without PNameField "
87                 + "as begin of expression: " + f);
88         PNameField pnf = (PNameField) f;
89         //System.out.println("pnf=" + pnf);
90

91
92         if (pnf.isClassPName()) {
93             if (pnf.isInGenClass())
94                 throw new MedorException("Impossible to navigate with a GenClass: pnf=" + pnf.getName() + " / attribut=" + att);
95             //System.out.println("pnf.isClassPName");
96
//The PName is the PName of the class
97
jormMO = getTypedElement(pnf.getMetaObjectClass(), att);
98             type = ((TypedElement) jormMO).getType();
99         }
100         else {
101             //System.out.println("!pnf.isClassPName");
102
//The PName is the PName of the reference field
103
jormMO = pnf.getReference();
104             if (jormMO instanceof ClassRef) {
105                 jormMO = getTypedElement(((ClassRef) jormMO).getMOClass(), att);
106                 //System.out.println("jormMO=" + jormMO);
107
type = ((TypedElement) jormMO).getType();
108             }
109             else if (jormMO instanceof GenClassRef) {
110                 //Be carefull it is not possible to navigate after a gen class.
111
type = ((GenClassRef) jormMO).getType();
112             }
113         }
114         if (jormMO == null)
115             throw new MedorException("No field " + att + " found");
116         isPName = jormMO instanceof Reference;
117     }
118
119     public Object JavaDoc clone(Object JavaDoc clone, Map JavaDoc obj2clone) throws CloneNotSupportedException JavaDoc {
120         clone = super.clone(clone, obj2clone);
121         ((NavigatorOperator) clone).isPName = isPName;
122         ((NavigatorOperator) clone).jormMO = jormMO;
123         return clone;
124     }
125
126     /**
127      * Creates a NavigatorOperator from a previously existing NavigatorOperator
128      * and an attribute name.
129      * @param nop is the NavigatorOperator corresponding to the left operand.
130      * @param att is the name of the attribute to which the operator nagivates.
131      * @throws org.objectweb.medor.api.MedorException when nop does not match
132      * a PName or when no field att is reachable by the PName.
133      */

134     public NavigatorOperator(NavigatorOperator nop, String JavaDoc att)
135         throws MedorException {
136         super(nop, new BasicOperand(att));
137         if (!nop.isPName())
138             throw new MedorException(
139                 "The specified Navigator operand is not a PName");
140
141         myFop = nop.getFieldOperand();
142         jormMO = nop.getMetaObject();
143         if (jormMO instanceof ClassRef) {
144             jormMO = ((ClassRef) jormMO).getMOClass().getTypedElement(att);
145             type = ((TypedElement) jormMO).getType();
146         }
147         //TODO allow nagivating GenClasses
148
else if (jormMO instanceof GenClassRef) {
149             throw new MedorException("Impossible to navigate with a GenClass: pnf=" + nop + " / attribut=" + att);
150         }
151         if (jormMO == null)
152             throw new MedorException("No field " + att + " found");
153         isPName = jormMO instanceof Reference;
154     }
155
156     /**
157      * Returns 'true' if the current path designes a field which is a
158      * reference. It returns 'false' if the current path designes a primitive
159      * field.
160      */

161     public boolean isPName() {
162         return isPName;
163     }
164
165     /**
166      * Obtains the FieldOperand at the start of the navigation.
167      * @return the FieldOperand corresponding to the start of the navigation.
168      */

169     public FieldOperand getFieldOperand() {
170         return myFop;
171     }
172
173     /**
174      * Constructs an ArrayList containing the elements of the corresponding
175      * path expression, excluding the initial FieldOperand.
176      * @return the path expression (excluding the initial FieldOperand), as
177      * an arrayList.
178      * @throws MedorException
179      */

180     public ArrayList JavaDoc getPath() throws MedorException {
181         ArrayList JavaDoc theList = new ArrayList JavaDoc();
182         return getPath(theList);
183     }
184
185     /**
186      * Starting from an input ArrayList, adds the elements of the corresponding
187      * path expression, excluding the initial FieldOperand.
188      * @param theList is the initial ArrayList into which to add the path
189      * elements
190      * @return the modified ArrayList containing the added path elements
191      * @throws MedorException
192      */

193     public ArrayList JavaDoc getPath(ArrayList JavaDoc theList) throws MedorException {
194         Expression e = getExpression(0);
195         if (! (e instanceof FieldOperand)) {
196             //case of further NavigatorOperator
197
theList = ((NavigatorOperator)e).getPath(theList);
198         }
199         try {
200             theList.add(((Operand) getExpression(1)).getString());
201         } catch (TypingException exc) {
202             throw new MedorException(exc);
203         }
204         return theList;
205     }
206
207
208     /**
209      * Returns the Jorm Meta object which describes the field that is
210      * reached by this navigator. The jorm field is never null.
211      */

212     public MetaObject getMetaObject() {
213         return jormMO;
214     }
215
216     /**
217      * Returns the String representing the operator in Java
218      * @return the String representing the operator in Java
219      */

220     public String JavaDoc getOperatorString() {
221         return Operator.NAV;
222     }
223
224     /**
225      * This operator is not evaluable, and must be transformed into JoinProject
226      * instances during the optimization step.
227      */

228     public Operand evaluate(ParameterOperand[] pos, Object JavaDoc o)
229         throws ExpressionException {
230         throw new ExpressionException("This operator is not evaluable, and must be "
231             + "transformed into JoinProjects instance during the optimization step.");
232     }
233
234     /**
235      * Checks the semantic integrity of an expression.
236      * <p>It checks that all types are compatible and prepare the expression to
237      * be evaluable.It also creates buffers where stores the result. Notes that
238      * when evaluating there is no creation of new objects. This method change
239      * the state of this expression object, it will be evaluable and not
240      * modifiable.
241      * @throws org.objectweb.medor.expression.api.MalformedExpressionException if syntax error
242      */

243     public Operand compileExpression() throws MalformedExpressionException {
244         throw new MalformedExpressionException("This operator is not evaluable,"
245             + " and must be transform edinto JoinProjects instance during the"
246             + " optimization step.");
247     }
248
249     private TypedElement getTypedElement(Class JavaDoc clazz, String JavaDoc fn) {
250         int idx = fn.length();
251         TypedElement te = null;
252         te = clazz.getTypedElement(fn);
253         while ((idx = fn.lastIndexOf(".", idx)) != -1 && te == null) {
254             te = clazz.getTypedElement(fn.substring(idx + 1, fn.length()));
255             idx--;
256         }
257         return te;
258     }
259 }
260
Popular Tags