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 public abstract class AbstractValue<T> implements Value<T>
43 {
44
45 protected static final Logger LOG = LoggerFactory.getLogger( AbstractValue.class );
46
47
48 protected transient AttributeType attributeType;
49
50
51 protected T wrappedValue;
52
53
54 protected T normalizedValue;
55
56
57 protected volatile int h;
58
59
60
61
62
63 @SuppressWarnings("unchecked")
64 public Value<T> clone()
65 {
66 try
67 {
68 return ( Value<T> ) super.clone();
69 }
70 catch ( CloneNotSupportedException cnse )
71 {
72
73 return null;
74 }
75 }
76
77
78
79
80
81 public T getReference()
82 {
83 return wrappedValue;
84 }
85
86
87
88
89
90
91
92 public String getString()
93 {
94 throw new UnsupportedOperationException( "Cannot call this method on a binary value" );
95 }
96
97
98
99
100
101
102
103 public byte[] getBytes()
104 {
105 throw new UnsupportedOperationException( "Cannot call this method on a String value" );
106 }
107
108
109
110
111
112 public AttributeType getAttributeType()
113 {
114 return attributeType;
115 }
116
117
118
119
120
121
122
123
124
125 @SuppressWarnings("unchecked")
126 protected void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
127 {
128 if ( attributeType == null )
129 {
130
131 normalizedValue = wrappedValue;
132 return;
133 }
134
135 this.attributeType = attributeType;
136
137
138
139 MatchingRule equality = attributeType.getEquality();
140
141 if ( equality != null )
142 {
143
144 Normalizer normalizer = equality.getNormalizer();
145
146 if ( normalizer != null )
147 {
148 if ( wrappedValue != null )
149 {
150 boolean isHR = attributeType.getSyntax().isHumanReadable();
151
152 if ( isHR != isHumanReadable() )
153 {
154 String message = "The '" + attributeType.getName() + "' AttributeType and values must " +
155 "both be String or binary";
156 LOG.error( message );
157 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
158 }
159
160 try
161 {
162 if ( isHumanReadable() )
163 {
164 normalizedValue = ( T ) normalizer.normalize( ( String ) wrappedValue );
165 }
166 else
167 {
168 normalizedValue = ( T ) normalizer.normalize( new BinaryValue( ( byte[] ) wrappedValue ) )
169 .getNormReference();
170 }
171 }
172 catch ( LdapException ne )
173 {
174 String message = I18n.err( I18n.ERR_04447_CANNOT_NORMALIZE_VALUE, ne.getLocalizedMessage() );
175 LOG.info( message );
176 }
177 }
178 }
179 else
180 {
181 String message = "The '" + attributeType.getName() + "' AttributeType does not have" +
182 " a normalizer";
183 LOG.error( message );
184 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
185 }
186 }
187 else
188 {
189
190
191 normalizedValue = wrappedValue;
192 }
193
194
195 try
196 {
197 LdapSyntax syntax = attributeType.getSyntax();
198
199
200 if ( ( syntax != null ) && ( !isValid( syntax.getSyntaxChecker() ) ) )
201 {
202 String message = I18n.err( I18n.ERR_04473_NOT_VALID_VALUE, wrappedValue, attributeType );
203 LOG.info( message );
204 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
205 }
206 }
207 catch ( LdapException le )
208 {
209 String message = I18n.err( I18n.ERR_04447_CANNOT_NORMALIZE_VALUE, le.getLocalizedMessage() );
210 LOG.info( message );
211 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message, le );
212 }
213
214
215 h = 0;
216 hashCode();
217 }
218
219
220
221
222
223
224
225
226
227 @SuppressWarnings("unchecked")
228 protected final LdapComparator<T> getLdapComparator() throws LdapException
229 {
230 if ( attributeType != null )
231 {
232 MatchingRule mr = attributeType.getEquality();
233
234 if ( mr != null )
235 {
236 return ( LdapComparator<T> ) mr.getLdapComparator();
237 }
238 }
239
240 return null;
241 }
242
243
244
245
246
247 public boolean isInstanceOf( AttributeType attributeType )
248 {
249 return ( attributeType != null ) &&
250 ( this.attributeType.equals( attributeType ) ||
251 this.attributeType.isDescendantOf( attributeType ) );
252 }
253
254
255
256
257
258 public T getNormReference()
259 {
260 if ( isNull() )
261 {
262 return null;
263 }
264
265 if ( normalizedValue == null )
266 {
267 return wrappedValue;
268 }
269
270 return normalizedValue;
271 }
272
273
274
275
276
277 public final boolean isNull()
278 {
279 return wrappedValue == null;
280 }
281
282
283
284
285
286 public final boolean isValid( SyntaxChecker syntaxChecker ) throws LdapInvalidAttributeValueException
287 {
288 if ( syntaxChecker == null )
289 {
290 String message = I18n.err( I18n.ERR_04139, toString() );
291 LOG.error( message );
292 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, message );
293 }
294
295 return syntaxChecker.isValidSyntax( normalizedValue );
296 }
297
298
299
300
301
302 public final boolean isSchemaAware()
303 {
304 return attributeType != null;
305 }
306 }