1 package com.atlassian.user.search.query;
2
3 import com.atlassian.user.util.Assert;
4
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.List;
9
10
11
12
13 public final class QueryValidator
14 {
15 private static final List<Class<? extends Query>> PRIMITIVE_QUERY_TYPES = Arrays.asList(UserQuery.class, GroupQuery.class, MembershipQuery.class);
16
17
18
19
20
21
22
23
24 public void assertValid(Query query) throws EntityQueryException
25 {
26 Collection<EntityQueryException> validationErrors = validateQuery(query);
27 if (!validationErrors.isEmpty())
28 throw validationErrors.iterator().next();
29 }
30
31
32
33
34
35
36
37 public Collection<EntityQueryException> validateQuery(Query query)
38 {
39 Assert.notNull(query, "Query should not be null");
40 if (query instanceof MembershipQuery)
41 {
42 throw new IllegalArgumentException("Membership queries are illegal until we verify they can be performed on" +
43 " all LDAP systems (i.e. the membership attribute must support substring matching");
44 }
45
46 if (!(query instanceof BooleanQuery))
47 return Collections.emptyList();
48
49 BooleanQuery booleanQuery = (BooleanQuery) query;
50 Class<? extends Query> queryType = getNestedQueryType(booleanQuery);
51 return validateBooleanQuery(booleanQuery, queryType);
52 }
53
54
55
56
57
58
59
60 public Collection<EntityQueryException> validateBooleanQuery(BooleanQuery booleanQuery, Class<? extends Query> queryType)
61 {
62 for (Query query : booleanQuery.getQueries())
63 {
64 if (query instanceof BooleanQuery)
65 {
66 return validateBooleanQuery((BooleanQuery) query, queryType);
67 }
68 if (!queryType.isInstance(query))
69 {
70
71 return Collections.singleton(new EntityQueryException("Boolean query type " + queryType.getName() +
72 " isn't matched by clause: " + query));
73 }
74 }
75 return Collections.emptyList();
76 }
77
78
79
80
81
82
83 private Class<? extends Query> getNestedQueryType(BooleanQuery booleanQuery) throws IllegalArgumentException
84 {
85 Query query = booleanQuery.getQueries().get(0);
86 if (query instanceof BooleanQuery)
87 {
88 return getNestedQueryType((BooleanQuery) query);
89 }
90 for (Class<? extends Query> clazz : PRIMITIVE_QUERY_TYPES)
91 {
92 if (clazz.isInstance(query)) return clazz;
93 }
94 throw new IllegalArgumentException("Clause of unknown type in boolean query: " + booleanQuery);
95 }
96
97 }