1 23 24 29 30 package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc; 31 32 import java.util.*; 33 34 import com.sun.jdo.spi.persistence.utility.I18NHelper; 35 36 import com.sun.jdo.api.persistence.support.JDOQueryException; 37 import com.sun.jdo.api.persistence.support.JDOUnsupportedOptionException; 38 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 39 40 46 public class VariableTable 47 { 48 51 protected final static ResourceBundle messages = 52 I18NHelper.loadBundle(VariableTable.class); 53 54 59 static class VarInfo 60 { 61 64 JQLAST constraint; 65 66 69 Set used; 70 71 75 String dependsOn; 76 77 80 int status; 81 82 static final int UNCHECKED = 0; 83 static final int IN_PROGRESS = 1; 84 static final int CHECKED = 2; 85 86 VarInfo() 87 { 88 this.constraint = null; 89 this.used = new HashSet(); 90 this.dependsOn = null; 91 this.status = UNCHECKED; 92 } 93 94 VarInfo(VarInfo other) 95 { 96 this.constraint = other.constraint; 97 this.used = new HashSet(other.used); 98 this.dependsOn = other.dependsOn; 99 this.status = other.status; 100 } 101 } 102 103 104 private ErrorMsg errorMsg; 105 106 107 private List declaredVars; 108 109 110 private Map varInfos; 111 112 115 public VariableTable(ErrorMsg errorMsg) 116 { 117 this.errorMsg = errorMsg; 118 declaredVars = new ArrayList(); 119 varInfos = new HashMap(); 120 } 121 122 126 public VariableTable(VariableTable other) 127 { 128 errorMsg = other.errorMsg; 129 declaredVars = other.declaredVars; 130 varInfos = new HashMap(); 131 for (Iterator i = other.varInfos.entrySet().iterator(); i.hasNext();) 132 { 133 Map.Entry entry = (Map.Entry)i.next(); 134 varInfos.put(entry.getKey(), new VarInfo((VarInfo)entry.getValue())); 135 } 136 } 137 138 142 public void add(String name) 143 { 144 declaredVars.add(name); 145 varInfos.put(name, new VarInfo()); 147 } 148 149 153 public void markUsed(JQLAST variable, String dependendVar) 154 { 155 String name = variable.getText(); 156 VarInfo entry = (VarInfo)varInfos.get(name); 157 if (entry == null) 158 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 159 "jqlc.variabletable.markused.varnotfound", name)); 161 entry.used.add(variable); 162 if (dependendVar != null) 163 { 164 VarInfo dependendVarInfo = (VarInfo)varInfos.get(dependendVar); 165 if (dependendVarInfo.dependsOn != null) 166 throw new JDOFatalInternalException(I18NHelper.getMessage( 167 messages, 168 "jqlc.variabletable.markused.multidep", dependendVar, dependendVarInfo.dependsOn, name)); 170 dependendVarInfo.dependsOn = name; 171 } 172 } 173 174 178 public void markConstraint(JQLAST variable, JQLAST expr) 179 { 180 String name = variable.getText(); 181 VarInfo entry = (VarInfo)varInfos.get(name); 182 if (entry == null) 183 throw new JDOFatalInternalException(I18NHelper.getMessage( 184 messages, 185 "jqlc.variabletable.markconstraint.varnotfound", name)); 187 String old = (entry.constraint==null ? null : entry.constraint.getText()); 188 if ((old != null) && !old.equals(expr.getText())) 189 { 190 errorMsg.unsupported(variable.getLine(), variable.getColumn(), 191 I18NHelper.getMessage(messages, "jqlc.variabletable.markconstraint.multiple", name)); 193 } 194 entry.constraint = expr; 195 } 196 197 200 public void merge(VariableTable other) 201 { 202 for (Iterator i = declaredVars.iterator(); i.hasNext();) 203 { 204 String name = (String )i.next(); 205 VarInfo info = (VarInfo)varInfos.get(name); 206 VarInfo otherInfo = (VarInfo)other.varInfos.get(name); 207 208 if ((info.constraint == null) && (info.used.size() == 0)) 210 { 211 info.constraint = otherInfo.constraint; 212 info.used = otherInfo.used; 213 info.dependsOn = otherInfo.dependsOn; 214 info.status = otherInfo.status; 215 continue; 216 } 217 218 if ((otherInfo.constraint == null) && (otherInfo.used.size() == 0)) 220 { 221 continue; 222 } 223 224 if ((info.constraint != null) && (otherInfo.constraint != null)) 227 { 228 if (!otherInfo.constraint.getText().equals(info.constraint.getText())) 229 { 230 throw new JDOUnsupportedOptionException( 231 I18NHelper.getMessage(messages, "jqlc.variabletable.merge.different", name)); } 233 } 234 else 237 { 238 info.constraint = null; 239 info.dependsOn = null; 240 info.status = VarInfo.UNCHECKED; 241 } 242 243 info.used.addAll(otherInfo.used); 245 } 246 } 247 248 251 public void checkConstraints() 252 { 253 for (Iterator i = declaredVars.iterator(); i.hasNext();) 255 { 256 String name = (String )i.next(); 257 VarInfo info = (VarInfo)varInfos.get(name); 258 checkConstraint(name, info); 259 } 260 } 261 262 protected void checkConstraint(String variable, VarInfo info) 263 { 264 switch (info.status) 265 { 266 case VarInfo.UNCHECKED: 267 info.status = VarInfo.IN_PROGRESS; 269 break; 270 case VarInfo.IN_PROGRESS: 271 throw new JDOUnsupportedOptionException( 273 I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.cycle", variable)); 275 case VarInfo.CHECKED: 276 return; 278 } 279 280 if (info.dependsOn != null) 281 { 282 VarInfo dependendVarInfo = (VarInfo)varInfos.get(info.dependsOn); 283 checkConstraint(info.dependsOn, dependendVarInfo); 284 } 285 286 if ((info.constraint != null) && (info.used.size() == 0)) 287 { 288 throw new JDOUnsupportedOptionException( 289 I18NHelper.getMessage(messages, "jqlc.variabletable.checkconstraint.unused", variable)); 291 } 292 293 attachConstraintToUsedAST(info); 294 info.status = VarInfo.CHECKED; 295 } 296 297 300 protected void attachConstraintToUsedAST(VarInfo info) 301 { 302 for (Iterator i = info.used.iterator(); i.hasNext();) 303 { 304 JQLAST varNode = (JQLAST)i.next(); 305 if (varNode.getFirstChild() == null) 306 varNode.setFirstChild(JQLAST.Factory.getInstance().dupTree(info.constraint)); 307 } 308 } 309 310 } 311 | Popular Tags |