1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.entry;
21
22
23 import org.apache.directory.api.i18n.I18n;
24 import org.apache.directory.api.ldap.model.exception.LdapException;
25 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
26 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
27 import org.apache.directory.api.ldap.model.schema.AttributeType;
28 import org.apache.directory.api.ldap.model.schema.LdapComparator;
29 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
30 import org.apache.directory.api.ldap.model.schema.MatchingRule;
31 import org.apache.directory.api.ldap.model.schema.Normalizer;
32 import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41
42
43
44 public abstract class AbstractValue<T> implements Value<T>
45 {
46
47 protected static final Logger LOG = LoggerFactory.getLogger( AbstractValue.class );
48
49
50 protected transient AttributeType attributeType;
51
52
53 protected T upValue;
54
55
56 protected T normalizedValue;
57
58
59 protected volatile int h;
60
61
62
63
64
65 @SuppressWarnings("unchecked")
66 @Override
67 public Value<T> clone()
68 {
69 try
70 {
71 return ( Value<T> ) super.clone();
72 }
73 catch ( CloneNotSupportedException cnse )
74 {
75
76 return null;
77 }
78 }
79
80
81
82
83
84 @Override
85 public T getReference()
86 {
87 return upValue;
88 }
89
90
91
92
93
94
95
96 @Override
97 public String getString()
98 {
99 throw new UnsupportedOperationException( "Cannot call this method on a binary value" );
100 }
101
102
103
104
105
106
107
108 @Override
109 public byte[] getBytes()
110 {
111 throw new UnsupportedOperationException( "Cannot call this method on a String value" );
112 }
113
114
115
116
117
118 @Override
119 public AttributeType getAttributeType()
120 {
121 return attributeType;
122 }
123
124
125
126
127
128
129
130
131
132 @SuppressWarnings("unchecked")
133 @Override
134 public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
135 {
136 if ( this.attributeType != null )
137 {
138
139 LOG.warn( "AttributeType {0} already applied", attributeType.getName() );
140 return;
141 }
142
143 if ( attributeType == null )
144 {
145
146 normalizedValue = upValue;
147 return;
148 }
149
150 this.attributeType = attributeType;
151
152
153
154 MatchingRule equality = attributeType.getEquality();
155
156 if ( equality != null )
157 {
158
159 Normalizer normalizer = equality.getNormalizer();
160
161 if ( normalizer != null )
162 {
163 if ( upValue != null )
164 {
165 boolean isHR = true;
166
167 if ( attributeType.getSyntax() != null )
168 {
169 isHR = attributeType.getSyntax().isHumanReadable();
170 }
171
172
173 if ( isHR != isHumanReadable() )
174 {
175
176 String message = "The '" + attributeType.getName() + "' AttributeType and values must "
177 + "both be String or binary";
178 LOG.error( message );
179 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
180 }
181
182 try
183 {
184 if ( isHumanReadable() )
185 {
186 if ( normalizedValue != null )
187 {
188 normalizedValue = ( T ) normalizer.normalize( ( String ) normalizedValue );
189 }
190 else
191 {
192 normalizedValue = ( T ) normalizer.normalize( ( String ) upValue );
193 }
194 }
195 else
196 {
197 normalizedValue = ( T ) normalizer.normalize( new BinaryValue( ( byte[] ) upValue ) )
198 .getNormReference();
199 }
200 }
201 catch ( LdapException ne )
202 {
203 String message = I18n.err( I18n.ERR_04447_CANNOT_NORMALIZE_VALUE, ne.getLocalizedMessage() );
204 LOG.info( message );
205 }
206 }
207 }
208 else
209 {
210 String message = "The '" + attributeType.getName() + "' AttributeType does not have" + " a normalizer";
211 LOG.error( message );
212 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
213 }
214 }
215 else
216 {
217
218
219 normalizedValue = upValue;
220 }
221
222
223 if ( !attributeType.isRelaxed() )
224 {
225 try
226 {
227 LdapSyntax syntax = attributeType.getSyntax();
228
229
230 if ( ( syntax != null ) && ( !isValid( syntax.getSyntaxChecker() ) ) )
231 {
232 String message = I18n.err( I18n.ERR_04473_NOT_VALID_VALUE, upValue, attributeType );
233 LOG.info( message );
234 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
235 }
236 }
237 catch ( LdapException le )
238 {
239 String message = I18n.err( I18n.ERR_04447_CANNOT_NORMALIZE_VALUE, le.getLocalizedMessage() );
240 LOG.info( message );
241 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message, le );
242 }
243 }
244
245
246 h = 0;
247 hashCode();
248 }
249
250
251
252
253
254
255
256
257
258 @SuppressWarnings("unchecked")
259 protected final LdapComparator<T> getLdapComparator() throws LdapException
260 {
261 if ( attributeType != null )
262 {
263 MatchingRule mr = attributeType.getEquality();
264
265 if ( mr != null )
266 {
267 return ( LdapComparator<T> ) mr.getLdapComparator();
268 }
269 }
270
271 return null;
272 }
273
274
275
276
277
278 @Override
279 public boolean isInstanceOf( AttributeType attributeType )
280 {
281 return ( attributeType != null )
282 && ( this.attributeType.equals( attributeType ) || this.attributeType.isDescendantOf( attributeType ) );
283 }
284
285
286
287
288
289 @Override
290 public T getNormReference()
291 {
292 if ( isNull() )
293 {
294 return null;
295 }
296
297 if ( normalizedValue == null )
298 {
299 return upValue;
300 }
301
302 return normalizedValue;
303 }
304
305
306
307
308
309 @Override
310 public final boolean isNull()
311 {
312 return upValue == null;
313 }
314
315
316
317
318
319 @Override
320 public final boolean isValid( SyntaxChecker syntaxChecker ) throws LdapInvalidAttributeValueException
321 {
322 if ( syntaxChecker == null )
323 {
324 String message = I18n.err( I18n.ERR_04139, toString() );
325 LOG.error( message );
326 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
327 }
328
329 if ( ( attributeType != null ) && attributeType.isRelaxed() )
330 {
331 return true;
332 }
333 else
334 {
335 return syntaxChecker.isValidSyntax( normalizedValue );
336 }
337 }
338
339
340
341
342
343 @Override
344 public final boolean isSchemaAware()
345 {
346 return attributeType != null;
347 }
348 }