1 2 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 28 public class FieldNavNode extends UnaryNode { 29 30 public String lexeme; 31 35 public String cast; 36 41 public FieldMetaData fmd; 42 45 public ClassMetaData targetClass; 46 47 public boolean resolved; 48 51 public boolean embedded; 52 53 57 public VarNode var; 58 59 public FieldNavNode() { 60 } 61 62 public Object accept(NodeVisitor visitor, Object [] results) { 63 return visitor.visitFieldNavNode(this, results); 64 } 65 66 public String 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 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 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; } 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 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; } else { 151 tcmd = c; 152 } 153 } else if (tcmd == null) { 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 obj) { 177 return visitor.visitFieldNavNode(this, obj); 178 } 179 180 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 199 public void updateEvictionDependency(CmdBitSet bitSet) { 200 if (targetClass != null) bitSet.addPlus(targetClass); 201 } 202 203 public Object arrive(NodeVisitor v, Object msg) { 204 return v.arriveFieldNavNode(this, msg); 205 } 206 207 } 208 | Popular Tags |