KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > query > FieldNavNode


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.query;
13
14 import com.versant.core.common.Debug;
15 import com.versant.core.common.CmdBitSet;
16 import com.versant.core.metadata.ClassMetaData;
17 import com.versant.core.metadata.FieldMetaData;
18 import com.versant.core.metadata.MDStatics;
19
20 import com.versant.core.common.BindingSupportImpl;
21
22 /**
23  * This node is created when a field that is a reference to a PC class is
24  * navigated in an expression. Information required to generate a subquery
25  * or join is included here. The child nodes become extra expressions for
26  * the where clause.
27  */

28 public class FieldNavNode extends UnaryNode {
29
30     public String JavaDoc lexeme;
31     /**
32      * If we were prefixed with a class cast expression then this is the
33      * type being cast to.
34      */

35     public String JavaDoc cast;
36     /**
37      * The field being navigated (normal ref or polyref). This is used to
38      * construct a join from the column(s) for this field in the src table to
39      * the primary key of the fields class.
40      */

41     public FieldMetaData fmd;
42     /**
43      * The class being referenced.
44      */

45     public ClassMetaData targetClass;
46
47     public boolean resolved;
48     /**
49      * Does this node represent an embedded field.
50      */

51     public boolean embedded;
52
53     /**
54      * The variable being accessed. This is used to locate the query for
55      * the variable.
56      */

57     public VarNode var;
58
59     public FieldNavNode() {
60     }
61
62     public Object JavaDoc accept(NodeVisitor visitor, Object JavaDoc[] results) {
63       return visitor.visitFieldNavNode(this, results);
64     }
65
66     public String JavaDoc toString() {
67         return super.toString() + " " +
68                 (cast != null ? "(" + cast + ")" : "") +
69                 (fmd != null ? fmd.toString() : lexeme) + " as " + asValue;
70     }
71
72     protected void normalizeImp() {
73         if (embedded) {
74             throw BindingSupportImpl.getInstance().internal(
75                     "This node should be dissolved");
76         }
77         super.normalizeImp();
78     }
79
80     /**
81      * Resolve field refs and so on relative to the compiler. This must
82      * recursively resolve any child nodes.
83      */

84     public void resolve(QueryParser comp, ClassMetaData cmd, boolean ordering) {
85         if (Debug.DEBUG) System.out.println("### FieldNavNode.resolve " + this);
86         if (asValue != null) childList.asValue = asValue;
87         ClassMetaData tcmd = null;
88         if (!resolved && !(parent instanceof FieldNavNode)) {
89             // this could be a variable reference
90
var = comp.findVar(lexeme);
91             if (var != null) {
92                 tcmd = resolveVariable();
93                 if (cast != null) {
94                     ClassMetaData c = comp.resolveCastType(cast)[0];
95                     if (tcmd == c) {
96                         cast = null; // redundant cast
97
} else {
98                         tcmd = c;
99                     }
100                 }
101             }
102         }
103         if (var == null) tcmd = resolveField(cmd, comp);
104         if (childList != null) {
105             childList.resolve(comp, tcmd, false);
106         }
107         if (embedded) {
108             parent.replaceChild(this, childList);
109         }
110         resolved = true;
111     }
112
113     private ClassMetaData resolveField(ClassMetaData cmd, QueryParser comp) {
114         ClassMetaData tcmd;
115
116         if (parent instanceof FieldNavNode) {
117             FieldNavNode pFnn = (FieldNavNode) parent;
118             if (pFnn.embedded) {
119                 String JavaDoc fname = pFnn.fmd.name + "/" + lexeme;
120                 FieldMetaData[] fmds = pFnn.fmd.classMetaData.fields;
121                 for (int i = 0; i < fmds.length; i++) {
122                     FieldMetaData fieldMetaData = fmds[i];
123                     if (fieldMetaData.name.equals(fname)) {
124                         fmd = this.fmd = fieldMetaData;
125                         break;
126                     }
127                 }
128             }
129         }
130
131         if (fmd == null) {
132             fmd = cmd.getFieldMetaData(lexeme);
133         }
134         if (fmd == null) {
135             throw BindingSupportImpl.getInstance().runtime(
136                     "Field '" + lexeme + "' not found on " + cmd.qname);
137         }
138         embedded = fmd.embedded;
139
140         if (fmd.category != MDStatics.CATEGORY_REF
141                 && fmd.category != MDStatics.CATEGORY_POLYREF) {
142             throw BindingSupportImpl.getInstance().runtime("Field '" + lexeme + "' on " + cmd.qname +
143                     " is not a reference to another PC class");
144         }
145         tcmd = fmd.typeMetaData;
146         if (cast != null) {
147             ClassMetaData c = comp.resolveCastType(cast)[0];
148             if (tcmd == c) {
149                 cast = null; // redundant cast
150
} else {
151                 tcmd = c;
152             }
153         } else if (tcmd == null) { // polyref
154
throw BindingSupportImpl.getInstance().runtime("Field '" + fmd.getTypeQName() + "' " +
155                     " must be cast to a persistent class to be " +
156                     "navigated in a query");
157         }
158
159         targetClass = tcmd;
160
161         if (embedded) return cmd;
162         return tcmd;
163     }
164
165     private ClassMetaData resolveVariable() {
166         ClassMetaData vcmd = var.getCmd();
167         if (vcmd == null) {
168             throw BindingSupportImpl.getInstance().runtime(
169                     "Variable '" + lexeme + "' is not of a persistent class");
170         }
171         if (!var.bound) var.insertVarBindingNode(parent);
172
173         return vcmd;
174     }
175
176     public Field visit(MemVisitor visitor, Object JavaDoc obj) {
177         return visitor.visitFieldNavNode(this, obj);
178     }
179
180     /**
181      * Return the FieldMetaData at the end of this chain.
182      */

183     public FieldMetaData getResultFmd() {
184         if (childList instanceof FieldNavNode) {
185             return ((FieldNavNode)childList).getResultFmd();
186         } else if (childList instanceof FieldNode) {
187             return ((FieldNode)childList).fmd;
188         } else {
189             throw BindingSupportImpl.getInstance().runtime("");
190         }
191     }
192
193     /**
194      * Implement this in nodes to udpate the ClassMetaData depency of the graph.
195      * This is used for query eviction.
196      *
197      * @param bitSet
198      */

199     public void updateEvictionDependency(CmdBitSet bitSet) {
200         if (targetClass != null) bitSet.addPlus(targetClass);
201     }
202
203     public Object JavaDoc arrive(NodeVisitor v, Object JavaDoc msg) {
204         return v.arriveFieldNavNode(this, msg);
205     }
206
207 }
208
Popular Tags