1 19 package org.apache.cayenne.access.jdbc; 20 21 import java.util.HashMap ; 22 import java.util.Map ; 23 24 import org.apache.cayenne.ejbql.EJBQLCompiledExpression; 25 import org.apache.cayenne.ejbql.EJBQLException; 26 import org.apache.cayenne.query.SQLResultSetMapping; 27 import org.apache.cayenne.query.SQLTemplate; 28 29 35 class EJBQLTranslationContext { 36 37 private Map tableAliases; 38 private Map boundParameters; 39 private StringBuffer mainBuffer; 40 private StringBuffer currentBuffer; 41 private EJBQLCompiledExpression compiledExpression; 42 private Map attributes; 43 private Map reusableJoins; 44 private Map parameters; 45 private int columnAliasPosition; 46 47 EJBQLTranslationContext(EJBQLCompiledExpression compiledExpression, Map parameters) { 48 this.compiledExpression = compiledExpression; 49 this.mainBuffer = new StringBuffer (); 50 this.currentBuffer = mainBuffer; 51 this.parameters = parameters; 52 } 53 54 SQLTemplate getQuery() { 55 String sql = mainBuffer.length() > 0 ? mainBuffer.toString() : null; 56 SQLTemplate query = new SQLTemplate(compiledExpression 57 .getRootDescriptor() 58 .getObjectClass(), sql); 59 query.setParameters(boundParameters); 60 return query; 61 } 62 63 67 void markCurrentPosition(String marker) { 68 findOrCreateMarkedBuffer(marker); 70 71 String internalMarker = (String ) getAttribute(marker); 72 73 StringBuffer current = this.currentBuffer; 75 76 try { 77 switchToMainBuffer(); 78 append("${").append(internalMarker).append("}"); 79 } 80 finally { 81 this.currentBuffer = current; 82 } 83 } 84 85 89 void switchToMarker(String marker) { 90 this.currentBuffer = (StringBuffer ) findOrCreateMarkedBuffer(marker); 91 } 92 93 void switchToMainBuffer() { 94 this.currentBuffer = this.mainBuffer; 95 } 96 97 private StringBuffer findOrCreateMarkedBuffer(String marker) { 98 StringBuffer buffer; 99 100 String internalMarker = (String ) getAttribute(marker); 101 if (internalMarker == null) { 102 buffer = new StringBuffer (); 103 internalMarker = bindParameter(buffer, "marker"); 104 105 setAttribute(marker, internalMarker); 107 } 108 else { 109 Object object = boundParameters.get(internalMarker); 110 if (!(object instanceof StringBuffer )) { 111 throw new IllegalArgumentException ( 112 "Invalid or missing buffer for marker: " + marker); 113 } 114 115 buffer = (StringBuffer ) object; 116 } 117 118 return buffer; 119 } 120 121 125 Object getAttribute(String name) { 126 return attributes != null ? attributes.get(name) : null; 127 } 128 129 133 void setAttribute(String var, Object value) { 134 if (attributes == null) { 135 attributes = new HashMap (); 136 } 137 138 attributes.put(var, value); 139 } 140 141 144 EJBQLTranslationContext append(String chunk) { 145 currentBuffer.append(chunk); 146 return this; 147 } 148 149 152 EJBQLTranslationContext append(char chunk) { 153 currentBuffer.append(chunk); 154 return this; 155 } 156 157 160 EJBQLTranslationContext trim(int n) { 161 int len = currentBuffer.length(); 162 163 if (len >= n) { 164 currentBuffer.delete(len - n, len); 165 } 166 return this; 167 } 168 169 EJBQLCompiledExpression getCompiledExpression() { 170 return compiledExpression; 171 } 172 173 String bindPositionalParameter(int position) { 174 return bindParameter(parameters.get(new Integer (position))); 175 } 176 177 String bindNamedParameter(String name) { 178 return bindParameter(parameters.get(name)); 179 } 180 181 184 String bindParameter(Object value) { 185 return bindParameter(value, "id"); 186 } 187 188 void rebindParameter(String boundName, Object newValue) { 189 boundParameters.put(boundName, newValue); 190 } 191 192 196 String bindParameter(Object value, String prefix) { 197 if (boundParameters == null) { 198 boundParameters = new HashMap (); 199 } 200 201 String var = prefix + boundParameters.size(); 202 boundParameters.put(var, value); 203 return var; 204 } 205 206 Object getBoundParameter(String name) { 207 return boundParameters != null ? boundParameters.get(name) : null; 208 } 209 210 217 String registerReusableJoin(String sourceIdPath, String relationship, String targetId) { 218 if (reusableJoins == null) { 219 reusableJoins = new HashMap (); 220 } 221 222 String key = sourceIdPath + ":" + relationship; 223 224 String oldId = (String ) reusableJoins.put(key, targetId); 225 if (oldId != null) { 226 reusableJoins.put(key, oldId); 228 return oldId; 229 } 230 231 return null; 232 } 233 234 238 String getTableAlias(String idPath, String tableName) { 239 240 StringBuffer keyBuffer = new StringBuffer (); 241 242 245 int dot = idPath.indexOf('.'); 246 if (dot > 0) { 247 keyBuffer.append(idPath.substring(0, dot).toLowerCase()).append( 248 idPath.substring(dot)); 249 } 250 else { 251 keyBuffer.append(idPath.toLowerCase()); 252 } 253 254 String key = keyBuffer.append(':').append(tableName).toString(); 255 256 String alias; 257 258 if (tableAliases != null) { 259 alias = (String ) tableAliases.get(key); 260 } 261 else { 262 tableAliases = new HashMap (); 263 alias = null; 264 } 265 266 if (alias == null) { 267 alias = "t" + tableAliases.size(); 268 tableAliases.put(key, alias); 269 } 270 271 return alias; 272 } 273 274 277 String nextColumnAlias() { 278 279 SQLResultSetMapping resultSetMapping = compiledExpression.getResultSetMapping(); 280 if (resultSetMapping == null) { 281 throw new EJBQLException( 282 "No result set mapping exists for expression, can't map column aliases"); 283 } 284 285 return (String ) resultSetMapping.getColumnResults().get(columnAliasPosition++); 286 } 287 } 288 | Popular Tags |