1 package com.trendmicro.grid.acl.metadata;
2
3 import net.sf.tinyjee.collections.Filter;
4 import net.sf.tinyjee.collections.FilteredCollection;
5 import net.sf.tinyjee.collections.FilteredSet;
6
7 import java.util.Collection;
8 import java.util.LinkedHashMap;
9 import java.util.Map;
10 import java.util.Set;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class ValidatedMetaMap extends LinkedHashMap<String, Meta> implements Cloneable {
28
29 private static final long serialVersionUID = 3532083475416802063L;
30
31 private static final ValidatorResolver NULL_RESOLVER = new ValidatorResolver() {
32 @Override
33 public Validator getValidator() {
34 return null;
35 }
36 };
37
38 transient ValidatorResolver validatorResolver;
39
40
41
42
43 public ValidatedMetaMap() {
44 setValidatorResolver(ValidationContext.getInstance());
45 }
46
47
48
49
50
51
52
53 public ValidatedMetaMap(int initialCapacity, ValidatorResolver validatorResolver) {
54 super(initialCapacity);
55 setValidatorResolver(validatorResolver);
56 }
57
58 public ValidatorResolver getValidatorResolver() {
59 return validatorResolver;
60 }
61
62 public void setValidatorResolver(ValidatorResolver resolver) {
63 this.validatorResolver = resolver == null ? NULL_RESOLVER : resolver;
64 }
65
66
67
68
69
70
71 public Validator getValidator() {
72 return validatorResolver.getValidator();
73 }
74
75
76
77
78 public void assertValuesAreValidForWrite() {
79 final Validator validator = validatorResolver.getValidator();
80 if (validator != null) {
81 for (Meta meta : super.values())
82 assertIsValidAndWritable(validator, meta.getName(), meta);
83 }
84 }
85
86 private void assertIsValidAndWritable(final Validator validator, final String key, final Meta value) {
87 if (!validator.isWritable(key)) {
88 throw new IllegalStateException("Cannot write the meta element named as '" + key +
89 "'. It is not allowed to set or change the value in the current context.");
90 }
91
92 if (!validator.isValid(value)) {
93 throw new IllegalArgumentException("Cannot write the meta element '" + value + "'. " +
94 "The format of the element is invalid with regards to the active meta data profile " +
95 "within the current context.");
96 }
97 }
98
99
100
101
102 @Override
103 public Meta get(Object key) {
104 final Validator validator = validatorResolver.getValidator();
105 if (validator == null || validator.isReadable((String) key))
106 return super.get(key);
107 return null;
108 }
109
110
111
112
113 @Override
114 public Meta put(String key, Meta value) {
115 final Validator validator = validatorResolver.getValidator();
116
117
118 if (validator != null && containsKey(key))
119 assertIsValidAndWritable(validator, key, value);
120 return super.put(key, value);
121 }
122
123
124
125
126
127
128 void putWithoutValidation(Meta value) {
129 super.put(value.getName(), value);
130 }
131
132
133
134
135 @Override
136 public void putAll(Map<? extends String, ? extends Meta> m) {
137 final Validator validator = validatorResolver.getValidator();
138 if (validator != null) {
139
140
141 for (Map.Entry<? extends String, ? extends Meta> entry : m.entrySet())
142 if (containsKey(entry.getKey()))
143 assertIsValidAndWritable(validator, entry.getKey(), entry.getValue());
144 }
145 super.putAll(m);
146 }
147
148
149
150
151 @Override
152 public Meta remove(Object key) {
153 final Validator validator = validatorResolver.getValidator();
154 if (validator != null && !validator.isWritable((String) key)) {
155 throw new IllegalStateException("Cannot remove the meta element named as '" + key +
156 "'. It is not allowed to change the value in the current context.");
157 }
158
159 return super.remove(key);
160 }
161
162
163
164
165 @Override
166 public Set<String> keySet() {
167 final Validator validator = validatorResolver.getValidator();
168 if (validator == null)
169 return super.keySet();
170 else {
171 return new FilteredSet<String>(super.keySet(), new Filter<String>() {
172 @Override
173 public boolean accept(String value) {
174 return validator.isReadable(value);
175 }
176 });
177 }
178 }
179
180
181
182
183 @Override
184 public Collection<Meta> values() {
185 final Validator validator = validatorResolver.getValidator();
186 if (validator == null)
187 return super.values();
188 else {
189 return new FilteredCollection<Meta>(super.values(), new Filter<Meta>() {
190 @Override
191 public boolean accept(Meta value) {
192 return value == null || validator.isReadable(value.getName());
193 }
194 });
195 }
196 }
197
198
199
200
201 @Override
202 public Set<Map.Entry<String, Meta>> entrySet() {
203 final Validator validator = validatorResolver.getValidator();
204 if (validator == null)
205 return super.entrySet();
206 else {
207 return new FilteredSet<Map.Entry<String, Meta>>(super.entrySet(), new Filter<Map.Entry<String, Meta>>() {
208 @Override
209 public boolean accept(Map.Entry<String, Meta> value) {
210 return validator.isReadable(value.getKey());
211 }
212 });
213 }
214 }
215
216
217
218
219
220
221 Collection<Meta> valuesWithoutValidation() {
222 return super.values();
223 }
224
225
226
227
228 @Override
229 public ValidatedMetaMap clone() {
230 return (ValidatedMetaMap) super.clone();
231 }
232 }