1 2 12 package com.versant.core.ejb.query; 13 14 import com.versant.core.metadata.ModelMetaData; 15 import com.versant.core.metadata.FieldMetaData; 16 import com.versant.core.metadata.ClassMetaData; 17 import com.versant.core.common.BindingSupportImpl; 18 import com.versant.core.common.Debug; 19 20 import java.util.HashMap ; 21 import java.util.Map ; 22 import java.util.Iterator ; 23 import java.util.ArrayList ; 24 import java.io.PrintStream ; 25 26 30 public class ResolveContext { 31 32 private final ModelMetaData mmd; 33 private final Map idVarMap = new HashMap (16); 34 private NavRoot[] roots = new NavRoot[2]; 35 private int rootCount; 36 37 private Map paramMap; private boolean usingPositionalParameters; 39 40 private ParamUsage[] NO_PARAMS = new ParamUsage[0]; 41 42 47 public static class ParamUsage { 48 49 private ParameterNode paramNode; 50 private ParamUsage next; 51 private int index; 52 public Object storeObject; 53 54 public ParamUsage(ParameterNode paramNode, int index) { 55 this.paramNode = paramNode; 56 this.index = index; 57 } 58 59 public ParameterNode getParamNode() { 60 return paramNode; 61 } 62 63 public ParamUsage getNext() { 64 return next; 65 } 66 67 71 public int getIndex() { 72 return index; 73 } 74 } 75 76 public ResolveContext(ModelMetaData mmd) { 77 this.mmd = mmd; 78 } 79 80 public ModelMetaData getModelMetaData() { 81 return mmd; 82 } 83 84 90 public RuntimeException createUserException(String msg, Node node) { 91 return BindingSupportImpl.getInstance().invalidOperation(msg); 92 } 93 94 98 public NavBase getIdVar(String identifier) { 99 return (NavBase)idVarMap.get(identifier); 100 } 101 102 105 public void addIdVar(String identifier, NavBase navBase) { 106 idVarMap.put(identifier, navBase); 107 if (navBase instanceof NavRoot) { 108 if (rootCount == roots.length) { 109 NavRoot[] a = new NavRoot[rootCount * 2]; 110 System.arraycopy(roots, 0, a, 0, rootCount); 111 roots = a; 112 } 113 roots[rootCount++] = (NavRoot)navBase; 114 } 115 } 116 117 120 public int getRootCount() { 121 return rootCount; 122 } 123 124 127 public NavRoot getRoot(int index) { 128 if (Debug.DEBUG) { 129 if (index >= rootCount) { 130 throw BindingSupportImpl.getInstance().internal( 131 "index >= rootCount: " + index + " >= " + rootCount); 132 } 133 } 134 return roots[index]; 135 } 136 137 140 public void checkIdVarDoesNotExist(String identifier, Node node) { 141 NavBase dup = getIdVar(identifier); 142 if (dup != null) { 143 throw createUserException("Duplicate identification variable: " + 144 identifier, node); 145 } 146 } 147 148 152 public NavBase checkIdVarExists(String identifier, Node node) { 153 NavBase ans = getIdVar(identifier); 154 if (ans == null) { 155 throw createUserException("Unknown identification variable: " + 156 identifier, node); 157 } 158 return ans; 159 } 160 161 165 public NavBase resolveJoinPath(PathNode path, boolean outer, boolean fetch) { 166 return resolveJoinPath(path, outer, fetch, path.size()); 167 } 168 169 174 public NavBase resolveJoinPath(PathNode path, boolean outer, boolean fetch, 175 int sz) { 176 String idVarName = path.get(0); 177 NavBase pos = checkIdVarExists(idVarName, path); 178 for (int i = 1; i < sz; i++) { 179 String name = path.get(i); 180 NavField f = pos.findChild(name, outer, fetch); 181 if (f == null) { 182 ClassMetaData cmd = pos.getNavClassMetaData(); 183 if (cmd == null) { 184 throw createUserException("Field " + f.getFmd().getQName() + 185 " may not be navigated", path); 186 } 187 FieldMetaData fmd = cmd.getFieldMetaData(name); 188 if (fmd == null) { 189 throw createUserException("No such field '" + name + 190 "' on " + cmd.qname, path); 191 } 192 f = new NavField(fmd, pos, outer, fetch); 193 } 194 pos = f; 195 } 196 return pos; 197 } 198 199 public ParamUsage addParameterNode(ParameterNode param) { 200 if (paramMap == null) { 201 usingPositionalParameters = param.isPositional(); 202 paramMap = new HashMap (8); 203 } else { 204 if (usingPositionalParameters != param.isPositional()) { 205 throw createUserException( 206 "Positional and named parameters may not be mixed", param); 207 } 208 } 209 ParamUsage ans = new ParamUsage(param, paramMap.size()); 210 Object key = param.getName(); 211 ParamUsage u = (ParamUsage)paramMap.get(key); 212 if (u != null) { 213 for (; u.next != null; u = u.next); 214 u.next = ans; 215 } else { 216 paramMap.put(key, ans); 217 } 218 return ans; 219 } 220 221 224 public boolean isUsingPositionalParameters() { 225 return usingPositionalParameters; 226 } 227 228 232 public ParamUsage[] getParameters() { 233 if (paramMap == null) { 234 return NO_PARAMS; 235 } 236 ParamUsage[] ans = new ParamUsage[paramMap.size()]; 237 for (Iterator i = paramMap.entrySet().iterator(); i.hasNext(); ) { 238 Map.Entry e = (Map.Entry )i.next(); 239 ParamUsage u = (ParamUsage)e.getValue(); 240 ans[u.index] = u; 241 } 242 return ans; 243 } 244 245 249 public ParamUsage getFirstParamUsage(Object nameOrPosition) { 250 ParamUsage ans = (ParamUsage)paramMap.get(nameOrPosition); 251 if (ans == null) { 252 throw BindingSupportImpl.getInstance().internal( 253 "No usage found for " + nameOrPosition); 254 } 255 return ans; 256 } 257 258 261 public void dump(PrintStream out) { 262 out.println("Roots (" + rootCount + ")"); 263 for (int i = 0; i < rootCount; i++) { 264 out.println("[" + i + "] " + getRoot(i)); 265 } 266 } 267 268 } 269 270 | Popular Tags |