1 56 package org.objectstyle.cayenne.project.validator; 57 58 import java.util.Iterator ; 59 60 import org.objectstyle.cayenne.access.QueryEngine; 61 import org.objectstyle.cayenne.exp.Expression; 62 import org.objectstyle.cayenne.exp.ExpressionException; 63 import org.objectstyle.cayenne.exp.TraversalHelper; 64 import org.objectstyle.cayenne.map.DataMap; 65 import org.objectstyle.cayenne.map.Entity; 66 import org.objectstyle.cayenne.project.ProjectPath; 67 import org.objectstyle.cayenne.query.Ordering; 68 import org.objectstyle.cayenne.query.Query; 69 import org.objectstyle.cayenne.query.SelectQuery; 70 import org.objectstyle.cayenne.util.Util; 71 72 78 public class SelectQueryValidator extends TreeNodeValidator { 79 80 public void validateObject(ProjectPath treeNodePath, Validator validator) { 81 SelectQuery query = (SelectQuery) treeNodePath.getObject(); 82 83 validateName(query, treeNodePath, validator); 84 85 Entity root = validateRoot(query, treeNodePath, validator); 87 88 if (root != null) { 90 validateQualifier(root, query.getQualifier(), treeNodePath, validator); 91 92 Iterator orderings = query.getOrderings().iterator(); 93 while (orderings.hasNext()) { 94 validateOrdering( 95 root, 96 (Ordering) orderings.next(), 97 treeNodePath, 98 validator); 99 } 100 101 Iterator prefecthes = query.getPrefetches().iterator(); 102 while (prefecthes.hasNext()) { 103 validatePrefetch( 104 root, 105 (String ) prefecthes.next(), 106 treeNodePath, 107 validator); 108 } 109 } 110 } 111 112 protected Entity validateRoot(Query query, ProjectPath path, Validator validator) { 113 DataMap map = (DataMap) path.firstInstanceOf(DataMap.class); 114 if (query.getRoot() == null && map != null) { 115 validator.registerWarning("Query has no root", path); 116 return null; 117 } 118 119 if (query.getRoot() == map) { 120 return null; 122 } 123 124 if (map == null) { 125 return (query.getRoot() instanceof Entity) ? (Entity) query.getRoot() : null; 127 } 128 129 if (query.getRoot() instanceof Class ) { 131 return null; 132 } 133 134 QueryEngine parent = (QueryEngine) path.firstInstanceOf(QueryEngine.class); 136 137 if (parent == null) { 138 return null; 139 } 140 141 Entity entity = parent.getEntityResolver().lookupObjEntity(query); 142 if (entity == null) { 143 entity = parent.getEntityResolver().lookupDbEntity(query); 144 } 145 146 if (entity == null) { 148 validator.registerWarning("Unknown query root.", path); 149 return null; 150 } 151 152 return entity; 153 } 154 155 protected void validateName(Query query, ProjectPath path, Validator validator) { 156 String name = query.getName(); 157 158 if (Util.isEmptyString(name)) { 160 validator.registerError("Unnamed SelectQuery.", path); 161 return; 162 } 163 164 DataMap map = (DataMap) path.getObjectParent(); 165 if (map == null) { 166 return; 167 } 168 169 171 Iterator it = map.getQueries().iterator(); 172 while (it.hasNext()) { 173 Query otherQuery = (Query) it.next(); 174 if (otherQuery == query) { 175 continue; 176 } 177 178 if (name.equals(otherQuery.getName())) { 179 validator.registerError("Duplicate Query name: " + name + ".", path); 180 break; 181 } 182 } 183 } 184 185 protected void validateQualifier( 186 Entity entity, 187 Expression qualifier, 188 ProjectPath path, 189 Validator validator) { 190 191 try { 192 testExpression(entity, qualifier); 193 } 194 catch (ExpressionException e) { 195 validator.registerWarning(buildValidationMessage( 196 e, 197 "Invalid path in qualifier"), path); 198 } 199 } 200 201 protected void validateOrdering( 202 Entity entity, 203 Ordering ordering, 204 ProjectPath path, 205 Validator validator) { 206 207 if (ordering == null) { 208 return; 209 } 210 211 try { 212 testExpression(entity, ordering.getSortSpec()); 213 } 214 catch (ExpressionException e) { 215 validator 216 .registerWarning(buildValidationMessage(e, "Invalid ordering"), path); 217 } 218 } 219 220 protected void validatePrefetch( 221 Entity entity, 222 String prefetch, 223 ProjectPath path, 224 Validator validator) { 225 226 if (prefetch == null) { 227 return; 228 } 229 230 try { 231 testExpression(entity, Expression.fromString(prefetch)); 232 } 233 catch (ExpressionException e) { 234 validator 235 .registerWarning(buildValidationMessage(e, "Invalid prefetch"), path); 236 } 237 } 238 239 private void testExpression(Entity rootEntity, Expression exp) 240 throws ExpressionException { 241 242 if (exp != null) { 243 exp.traverse(new EntityExpressionValidator(rootEntity)); 244 } 245 } 246 247 private String buildValidationMessage(ExpressionException e, String prefix) { 248 StringBuffer buffer = new StringBuffer (prefix); 249 if (e.getExpressionString() != null) { 250 buffer.append(": '").append(e.getExpressionString()).append("'"); 251 } 252 253 buffer.append("."); 254 return buffer.toString(); 255 } 256 257 final class EntityExpressionValidator extends TraversalHelper { 258 259 Entity rootEntity; 260 261 EntityExpressionValidator(Entity rootEntity) { 262 this.rootEntity = rootEntity; 263 } 264 265 public void startNode(Expression node, Expression parentNode) { 266 if (node.getType() == Expression.OBJ_PATH 268 || node.getType() == Expression.DB_PATH) { 269 node.evaluate(rootEntity); 271 } 272 } 273 } 274 } | Popular Tags |