1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.search.expression;
18
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.Map;
22
23 import net.sf.ehcache.Element;
24 import net.sf.ehcache.search.SearchException;
25 import net.sf.ehcache.search.attribute.AttributeExtractor;
26 import net.sf.ehcache.search.attribute.AttributeType;
27
28 /***
29 * Criteria for inclusion in a given Collection (presumably a Set) of values
30 *
31 * @author teck
32 */
33 public class InCollection extends BaseCriteria {
34
35 private final String attributeName;
36 private final Collection<?> values;
37 private final AttributeType type;
38 private final boolean empty;
39
40 /***
41 * Constructor
42 *
43 * @param attributeName attribute name
44 * @param values
45 */
46 public InCollection(String attributeName, Collection<?> values) {
47 if (attributeName == null || values == null) {
48 throw new NullPointerException();
49 }
50 this.attributeName = attributeName;
51 this.values = values;
52 this.empty = values.isEmpty();
53
54 if (!empty) {
55 this.type = verifyCommonType();
56 } else {
57 this.type = null;
58 }
59 }
60
61 /***
62 * Return attributeName
63 *
64 * @return String attribute name
65 */
66 public String getAttributeName() {
67 return this.attributeName;
68 }
69
70 /***
71 * Return values.
72 *
73 * @return Collection<?> values
74 */
75 public Collection<?> values() {
76 return Collections.unmodifiableCollection(this.values);
77 }
78
79 private AttributeType verifyCommonType() {
80 if (values.isEmpty()) {
81 throw new AssertionError();
82 }
83
84 AttributeType rv = null;
85 for (Object value : values) {
86 if (value == null) {
87 throw new NullPointerException("null element in set");
88 }
89
90 AttributeType at = AttributeType.typeFor(attributeName, value);
91 if (rv == null) {
92 rv = at;
93 } else if (at != rv) {
94 throw new SearchException("Multiple types detected in collection: " + at + " and " + rv);
95 }
96 }
97 return rv;
98 }
99
100 /***
101 * {@inheritDoc}
102 */
103 public boolean execute(Element e, Map<String, AttributeExtractor> attributeExtractors) {
104 if (empty) {
105 return false;
106 }
107
108 Object attrValue = attributeExtractors.get(attributeName).attributeFor(e, attributeName);
109 if (attrValue == null) {
110 return false;
111 } else {
112 AttributeType attrType = AttributeType.typeFor(getAttributeName(), attrValue);
113 if (!type.equals(attrType)) {
114 throw new SearchException("Expecting attribute of type " + type.name() + " but was " + attrType.name());
115 }
116 if (AttributeType.STRING.equals(type)) {
117 for (Object o : values) {
118 if (attrValue.toString().equalsIgnoreCase(o.toString())) {
119 return true;
120 }
121 }
122 return false;
123 } else {
124 return values.contains(attrValue);
125 }
126 }
127 }
128
129 }