1 19 20 package org.apache.cayenne.project.validator; 21 22 import java.util.Iterator ; 23 24 import org.apache.cayenne.access.QueryEngine; 25 import org.apache.cayenne.exp.Expression; 26 import org.apache.cayenne.exp.ExpressionException; 27 import org.apache.cayenne.exp.TraversalHelper; 28 import org.apache.cayenne.map.DataMap; 29 import org.apache.cayenne.map.Entity; 30 import org.apache.cayenne.project.ProjectPath; 31 import org.apache.cayenne.query.Ordering; 32 import org.apache.cayenne.query.PrefetchTreeNode; 33 import org.apache.cayenne.query.Query; 34 import org.apache.cayenne.query.SelectQuery; 35 import org.apache.cayenne.util.Util; 36 37 43 public class SelectQueryValidator extends TreeNodeValidator { 44 45 public void validateObject(ProjectPath treeNodePath, Validator validator) { 46 SelectQuery query = (SelectQuery) treeNodePath.getObject(); 47 48 validateName(query, treeNodePath, validator); 49 50 Entity root = validateRoot(query, treeNodePath, validator); 52 53 if (root != null) { 55 validateQualifier(root, query.getQualifier(), treeNodePath, validator); 56 57 Iterator orderings = query.getOrderings().iterator(); 58 while (orderings.hasNext()) { 59 validateOrdering( 60 root, 61 (Ordering) orderings.next(), 62 treeNodePath, 63 validator); 64 } 65 66 if (query.getPrefetchTree() != null) { 67 Iterator prefetches = query 68 .getPrefetchTree() 69 .nonPhantomNodes() 70 .iterator(); 71 while (prefetches.hasNext()) { 72 validatePrefetch(root, ((PrefetchTreeNode) prefetches.next()) 73 .getPath(), treeNodePath, validator); 74 } 75 } 76 } 77 } 78 79 protected Entity validateRoot(SelectQuery query, ProjectPath path, Validator validator) { 80 DataMap map = (DataMap) path.firstInstanceOf(DataMap.class); 81 if (query.getRoot() == null && map != null) { 82 validator.registerWarning("Query has no root", path); 83 return null; 84 } 85 86 if (query.getRoot() == map) { 87 return null; 89 } 90 91 if (map == null) { 92 return (query.getRoot() instanceof Entity) ? (Entity) query.getRoot() : null; 94 } 95 96 if (query.getRoot() instanceof Entity) { 97 return (Entity) query.getRoot(); 98 } 99 100 if (query.getRoot() instanceof Class ) { 102 return null; 103 } 104 105 if (query.getRoot() instanceof String ) { 107 108 QueryEngine parent = (QueryEngine) path.firstInstanceOf(QueryEngine.class); 109 110 if (parent != null) { 111 return parent.getEntityResolver().getObjEntity((String ) query.getRoot()); 112 } 113 } 114 115 return null; 116 } 117 118 protected void validateName(Query query, ProjectPath path, Validator validator) { 119 String name = query.getName(); 120 121 if (Util.isEmptyString(name)) { 123 validator.registerError("Unnamed SelectQuery.", path); 124 return; 125 } 126 127 DataMap map = (DataMap) path.getObjectParent(); 128 if (map == null) { 129 return; 130 } 131 132 134 Iterator it = map.getQueries().iterator(); 135 while (it.hasNext()) { 136 Query otherQuery = (Query) it.next(); 137 if (otherQuery == query) { 138 continue; 139 } 140 141 if (name.equals(otherQuery.getName())) { 142 validator.registerError("Duplicate Query name: " + name + ".", path); 143 break; 144 } 145 } 146 } 147 148 protected void validateQualifier( 149 Entity entity, 150 Expression qualifier, 151 ProjectPath path, 152 Validator validator) { 153 154 try { 155 testExpression(entity, qualifier); 156 } 157 catch (ExpressionException e) { 158 validator.registerWarning(buildValidationMessage( 159 e, 160 "Invalid path in qualifier"), path); 161 } 162 } 163 164 protected void validateOrdering( 165 Entity entity, 166 Ordering ordering, 167 ProjectPath path, 168 Validator validator) { 169 170 if (ordering == null) { 171 return; 172 } 173 174 try { 175 testExpression(entity, ordering.getSortSpec()); 176 } 177 catch (ExpressionException e) { 178 validator 179 .registerWarning(buildValidationMessage(e, "Invalid ordering"), path); 180 } 181 } 182 183 protected void validatePrefetch( 184 Entity entity, 185 String prefetch, 186 ProjectPath path, 187 Validator validator) { 188 189 if (prefetch == null) { 190 return; 191 } 192 193 try { 194 testExpression(entity, Expression.fromString(prefetch)); 195 } 196 catch (ExpressionException e) { 197 validator 198 .registerWarning(buildValidationMessage(e, "Invalid prefetch"), path); 199 } 200 } 201 202 private void testExpression(Entity rootEntity, Expression exp) 203 throws ExpressionException { 204 205 if (exp != null) { 206 exp.traverse(new EntityExpressionValidator(rootEntity)); 207 } 208 } 209 210 private String buildValidationMessage(ExpressionException e, String prefix) { 211 StringBuffer buffer = new StringBuffer (prefix); 212 if (e.getExpressionString() != null) { 213 buffer.append(": '").append(e.getExpressionString()).append("'"); 214 } 215 216 buffer.append("."); 217 return buffer.toString(); 218 } 219 220 final class EntityExpressionValidator extends TraversalHelper { 221 222 Entity rootEntity; 223 224 EntityExpressionValidator(Entity rootEntity) { 225 this.rootEntity = rootEntity; 226 } 227 228 public void startNode(Expression node, Expression parentNode) { 229 if (node.getType() == Expression.OBJ_PATH 231 || node.getType() == Expression.DB_PATH) { 232 node.evaluate(rootEntity); 234 } 235 } 236 } 237 } 238 | Popular Tags |