1 package com.genimen.djeneric.repository.oql; 2 3 import java.io.UnsupportedEncodingException ; 4 import java.util.ArrayList ; 5 import java.util.HashMap ; 6 import java.util.Iterator ; 7 import java.util.StringTokenizer ; 8 9 import com.genimen.djeneric.language.Messages; 10 import com.genimen.djeneric.repository.DjExtent; 11 import com.genimen.djeneric.repository.DjProperty; 12 import com.genimen.djeneric.repository.DjPropertyType; 13 import com.genimen.djeneric.repository.DjRelation; 14 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException; 15 import com.genimen.djeneric.repository.oql.core.DjOqlParserEngine; 16 import com.genimen.djeneric.repository.oql.core.ParseException; 17 import com.genimen.djeneric.repository.oql.core.SimpleNode; 18 import com.genimen.djeneric.repository.oql.core.TokenMgrError; 19 import com.genimen.djeneric.repository.oql.core.util.JoinDefinition; 20 import com.genimen.djeneric.util.DjLogger; 21 22 public class DjOqlWhereTranslator 23 { 24 ArrayList _parameters = null; 25 HashMap _allJoins; 26 HashMap _allExtents; 27 HashMap _path2AliasMapping; 28 SimpleNode _tree; 29 String _rootAlias; 30 boolean _resultIsUnique = true; 31 32 public String translateWhere(DjExtent extent, String rootAlias, String where) throws ParseException 33 { 34 try 35 { 36 rootAlias = rootAlias.toLowerCase(); 37 _rootAlias = rootAlias; 38 _tree = DjOqlParserEngine.parseExpression(where); 39 40 ArrayList allPaths = new ArrayList (); 41 _tree.addPaths(allPaths); 42 43 _allJoins = collectAllJoins(extent, allPaths); 44 45 int uidCounter = 1; 46 47 uidCounter = setRootAliasses(_allJoins, rootAlias, uidCounter); 49 50 chainAliasses(_allJoins, uidCounter); 52 53 _allExtents = collectExtents(_allJoins, rootAlias, extent); 55 56 _path2AliasMapping = collectMappings(_allJoins, rootAlias); 58 59 StringBuffer result = new StringBuffer (where.length() * 2 + 100); 60 61 constructFromWhere(_tree, _allJoins, _allExtents, _path2AliasMapping, result); 62 63 _parameters = new ArrayList (); 64 _tree.collectParameters(_parameters); 65 66 return result.toString(); 67 } 68 catch (UnsupportedEncodingException e) 69 { 70 DjLogger.log(e); 71 throw new ParseException(e.getMessage()); 72 } 73 catch (ObjectNotDefinedException e) 74 { 75 throw new ParseException(e, 0, 0); 76 } 77 catch (TokenMgrError e) 78 { 79 throw new ParseException(e.getMessage(), e.line, e.column); 80 } 81 } 82 83 public String translateAgain(DjExtent extent) throws ParseException 84 { 85 try 86 { 87 _allExtents.put(_rootAlias, extent); 88 StringBuffer result = new StringBuffer (500); 89 constructFromWhere(_tree, _allJoins, _allExtents, _path2AliasMapping, result); 90 return result.toString(); 91 } 92 catch (ObjectNotDefinedException e) 93 { 94 throw new ParseException(e, 0, 0); 95 } 96 } 97 98 private void constructFromWhere(SimpleNode tree, HashMap allJoins, HashMap allExtents, HashMap path2AliasMapping, 99 StringBuffer result) throws ParseException, ObjectNotDefinedException 100 { 101 result.append("from "); 102 Iterator it = allExtents.keySet().iterator(); 103 while (it.hasNext()) 104 { 105 String alias = it.next().toString(); 106 DjExtent ext = (DjExtent) allExtents.get(alias); 107 result.append(ext.getName()); 108 result.append(" "); 109 result.append(alias); 110 if (it.hasNext()) 111 { 112 result.append(",\n "); 113 } 114 } 115 result.append("\nwhere ("); 116 117 tree.translate(result, path2AliasMapping); 118 result.append(")"); 119 if (allJoins.size() > 0) 120 { 121 result.append("\nand ("); 122 it = allJoins.keySet().iterator(); 123 while (it.hasNext()) 124 { 125 String key = it.next().toString(); 126 JoinDefinition jd = (JoinDefinition) allJoins.get(key); 127 result.append(jd.getJoin()); 128 if (it.hasNext()) result.append("\nand "); 129 } 130 result.append(")"); 131 } 132 } 133 134 private HashMap collectAllJoins(DjExtent extent, ArrayList allPaths) throws ObjectNotDefinedException, ParseException 135 { 136 HashMap allJoins = new HashMap (); 137 138 Iterator it = allPaths.iterator(); 139 while (it.hasNext()) 140 { 141 String path = it.next().toString(); 142 143 if (path.indexOf('.') != -1) 145 { 146 StringTokenizer st = new StringTokenizer (path, "."); 147 DjExtent currentExtent = extent; 148 StringBuffer pathPart = new StringBuffer (100); 149 150 while (st.hasMoreTokens()) 151 { 152 String propertyName = st.nextToken(); 153 154 if (pathPart.length() > 0) pathPart.append("."); 155 pathPart.append(propertyName); 156 157 DjPropertyType type; 158 159 boolean reverseJoin = false; 160 if (currentExtent.hasDetailRelation(propertyName)) 161 { 162 DjRelation rel = currentExtent.getDetailRelation(propertyName); 163 type = rel.getDetailExtent(); 164 propertyName = rel.getDetailProperty().getName(); 165 reverseJoin = true; 166 _resultIsUnique = false; 168 } 169 else 170 { 171 DjProperty property = currentExtent.getProperty(propertyName); 172 type = property.getType(); 173 } 174 175 DjExtent toExtent = null; 176 if (st.hasMoreTokens()) 177 { 178 if (!(type instanceof DjExtent)) 179 { 180 throw new ParseException(Messages.getString("DjOqlWhereTranslator.PropertyInPathNotObject", propertyName, 181 path)); 182 } 183 toExtent = (DjExtent) type; 184 } 185 if (toExtent != null) 186 { 187 JoinDefinition join = new JoinDefinition(currentExtent, toExtent, propertyName, reverseJoin); 188 allJoins.put(pathPart.toString(), join); 189 } 190 currentExtent = toExtent; 191 } 192 } 193 } 194 return allJoins; 195 } 196 197 private HashMap collectMappings(HashMap allJoins, String rootAlias) 198 { 199 HashMap result = new HashMap (); 200 result.put("", rootAlias); 202 203 Iterator it = allJoins.keySet().iterator(); 204 while (it.hasNext()) 205 { 206 String path = it.next().toString(); 207 JoinDefinition join = (JoinDefinition) allJoins.get(path); 208 result.put(path, join.getToAlias()); 209 } 210 211 return result; 212 } 213 214 private HashMap collectExtents(HashMap allJoins, String rootAlias, DjExtent rootExtent) 215 { 216 HashMap result = new HashMap (); 217 218 220 result.put(rootAlias, rootExtent); 221 222 Iterator it = allJoins.keySet().iterator(); 223 while (it.hasNext()) 224 { 225 String path = it.next().toString(); 226 JoinDefinition join = (JoinDefinition) allJoins.get(path); 227 String alias = join.getAlias(); 228 if (alias.equals(rootAlias) && join.getExtent() != rootExtent) 229 { 230 System.err.println("Internal error: alias clashes with root extent " + join.getExtent()); 231 Thread.dumpStack(); 232 } 233 else 234 { 235 result.put(alias, join.getExtent()); 236 } 237 } 238 239 it = allJoins.keySet().iterator(); 241 while (it.hasNext()) 242 { 243 String path = it.next().toString(); 244 JoinDefinition join = (JoinDefinition) allJoins.get(path); 245 String alias = join.getToAlias(); 246 if (!result.containsKey(alias)) 247 { 248 if (alias.equals(rootAlias) && join.getExtent() != rootExtent) 249 { 250 System.err.println("Internal error: alias clashes with root extent " + join.getExtent()); 251 Thread.dumpStack(); 252 } 253 else result.put(alias, join.getToExtent()); 254 } 255 } 256 257 return result; 258 } 259 260 private int chainAliasses(HashMap allJoins, int uid) throws ParseException 261 { 262 263 boolean doneOne = true; 264 265 while (doneOne) 266 { 267 doneOne = false; 268 Iterator it = allJoins.keySet().iterator(); 269 while (it.hasNext()) 270 { 271 String path = it.next().toString(); 272 JoinDefinition tail = (JoinDefinition) allJoins.get(path); 273 if (!tail.isFromAliasSet()) 274 { 275 int idx = path.lastIndexOf('.'); 276 String fromPath = path.substring(0, idx); 277 JoinDefinition head = (JoinDefinition) allJoins.get(fromPath); 278 if (head.isToAliasSet()) 279 { 280 tail.setFromAlias(head.getToAlias()); 281 tail.setToAlias(uid++); 282 doneOne = true; 283 } 284 } 285 } 286 } 287 288 Iterator it = allJoins.keySet().iterator(); 290 while (it.hasNext()) 291 { 292 String path = it.next().toString(); 293 JoinDefinition join = (JoinDefinition) allJoins.get(path); 294 if (!join.aliassesSet()) throw new ParseException(Messages.getString("DjOqlWhereTranslator.CouldNotSetAliasFor", 295 join)); 296 } 297 298 return uid; 299 } 300 301 private int setRootAliasses(HashMap allJoins, String alias, int uid) 302 { 303 Iterator it = allJoins.keySet().iterator(); 304 while (it.hasNext()) 305 { 306 String path = it.next().toString(); 307 if (path.indexOf('.') == -1) 308 { 309 JoinDefinition join = (JoinDefinition) allJoins.get(path); 310 join.setFromAlias(alias); 311 join.setToAlias(uid++); 312 } 313 } 314 return uid; 315 } 316 317 public ArrayList getParameters() 318 { 319 return _parameters; 320 } 321 322 public SimpleNode getTree() 323 { 324 return _tree; 325 } 326 327 public boolean isResultUnique() 328 { 329 return _resultIsUnique; 330 } 331 } | Popular Tags |