1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.impl.common.attribute;
17
18 import com.google.common.collect.Iterables;
19 import org.kuali.rice.core.api.criteria.AndPredicate;
20 import org.kuali.rice.core.api.criteria.CompositePredicate;
21 import org.kuali.rice.core.api.criteria.CriteriaValue;
22 import org.kuali.rice.core.api.criteria.MultiValuedPredicate;
23 import org.kuali.rice.core.api.criteria.OrPredicate;
24 import org.kuali.rice.core.api.criteria.Predicate;
25 import org.kuali.rice.core.api.criteria.PropertyPathPredicate;
26 import org.kuali.rice.core.api.criteria.QueryByCriteria;
27 import org.kuali.rice.core.api.criteria.SingleValuedPredicate;
28 import org.kuali.rice.core.api.criteria.Transform;
29
30 import java.util.ArrayList;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Set;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36
37 import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
38
39
40
41
42
43 public final class AttributeTransform implements Transform<QueryByCriteria, QueryByCriteria> {
44
45 private static final Transform<QueryByCriteria, QueryByCriteria> INSTANCE = new AttributeTransform();
46 private static final String ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE = "attributeDetails.attributeValue";
47 private static final String ATTRIBUTE_DETAILS_ATTRIBUTE_NAME = "attributeDetails.kimAttribute.attributeName";
48 private static final String ATTRIBUTES_REGEX = "^attributes\\[\\w*\\]$";
49 private static final Pattern ATTRIBUTES_PATTERN = Pattern.compile(ATTRIBUTES_REGEX);
50
51 private AttributeTransform() {
52
53 }
54
55 @Override
56 public QueryByCriteria apply(final QueryByCriteria input) {
57 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(input);
58 builder.setPredicates(applyPredicate(input.getPredicate()));
59 return builder.build();
60 }
61
62 private Predicate applyPredicate(final Predicate input) {
63 if (input instanceof PropertyPathPredicate) {
64 String pp = ((PropertyPathPredicate) input).getPropertyPath();
65 if (isAttributesPredicate(pp)) {
66 final String attributeName = pp.substring(pp.indexOf('[') + 1, pp.indexOf(']'));
67
68 final Predicate attrValue;
69 if (input instanceof SingleValuedPredicate) {
70 final CriteriaValue<?> value = ((SingleValuedPredicate) input).getValue();
71 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE, value.getValue());
72 } else if (input instanceof MultiValuedPredicate) {
73 final Set<? extends CriteriaValue<?>> values = ((MultiValuedPredicate) input).getValues();
74 List<Object> l = new ArrayList<Object>();
75 for (CriteriaValue<?> v : values) {
76 l.add(v.getValue());
77 }
78
79 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE, l.toArray());
80 } else {
81 attrValue = dynConstruct(input.getClass().getSimpleName(), ATTRIBUTE_DETAILS_ATTRIBUTE_VALUE);
82 }
83 return and(equal(ATTRIBUTE_DETAILS_ATTRIBUTE_NAME, attributeName), attrValue);
84 }
85 } else if (input instanceof CompositePredicate) {
86 return applyCompositePredicate((CompositePredicate) input);
87 }
88
89 return input;
90 }
91
92 private Predicate applyCompositePredicate(final CompositePredicate input) {
93 Set<Predicate> appliedPredicates = new HashSet<Predicate>();
94
95 for (Predicate predicate : input.getPredicates()) {
96 appliedPredicates.add(applyPredicate(predicate));
97 }
98
99 Predicate[] appliedPredicatesArray = Iterables.toArray(appliedPredicates, Predicate.class);
100
101 if (input instanceof AndPredicate) {
102 return and(appliedPredicatesArray);
103 } else if (input instanceof OrPredicate) {
104 return or(appliedPredicatesArray);
105 }
106
107 return input;
108 }
109
110 private boolean isAttributesPredicate(String pp) {
111 Matcher matcher = ATTRIBUTES_PATTERN.matcher(pp);
112 return matcher.matches();
113 }
114
115 public static Transform<QueryByCriteria, QueryByCriteria> getInstance() {
116 return INSTANCE;
117 }
118 }