001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.directory.shared.ldap.entry;
020    
021    import java.io.Externalizable;
022    import java.util.Iterator;
023    import java.util.List;
024    
025    import org.apache.directory.shared.ldap.exception.LdapException;
026    import org.apache.directory.shared.ldap.exception.LdapInvalidAttributeValueException;
027    import org.apache.directory.shared.ldap.schema.AttributeType;
028    import org.apache.directory.shared.ldap.schema.SyntaxChecker;
029    
030    /**
031     * A generic interface mocking the Attribute JNDI interface. This interface
032     * will be the base interface for the ServerAttribute and ClientAttribute.
033     *
034     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
035     * @version $Rev$, $Date$
036     */
037    public interface EntryAttribute extends Iterable<Value<?>>, Cloneable, Externalizable
038    {
039        /**
040         * Adds some values to this attribute. If the new values are already present in
041         * the attribute values, the method has no effect.
042         * <p>
043         * The new values are added at the end of list of values.
044         * </p>
045         * <p>
046         * This method returns the number of values that were added.
047         * </p>
048         * <p>
049         * If the value's type is different from the attribute's type,
050         * a conversion is done. For instance, if we try to set some String
051         * into a Binary attribute, we just store the UTF-8 byte array 
052         * encoding for this String.
053         * </p>
054         * <p>
055         * If we try to store some byte[] in a HR attribute, we try to 
056         * convert those byte[] assuming they represent an UTF-8 encoded
057         * String. Of course, if it's not the case, the stored value will
058         * be incorrect.
059         * </p>
060         * <p>
061         * It's the responsibility of the caller to check if the stored
062         * values are consistent with the attribute's type.
063         * </p>
064         * <p>
065         * The caller can set the HR flag in order to enforce a type for 
066         * the current attribute, otherwise this type will be set while
067         * adding the first value, using the value's type to set the flag.
068         * </p>
069         *
070         * @param vals some new values to be added which may be null
071         * @return the number of added values, or 0 if none has been added
072         */
073        int add( String... vals );
074    
075    
076        /**
077         * Adds some values to this attribute. If the new values are already present in
078         * the attribute values, the method has no effect.
079         * <p>
080         * The new values are added at the end of list of values.
081         * </p>
082         * <p>
083         * This method returns the number of values that were added.
084         * </p>
085         * If the value's type is different from the attribute's type,
086         * a conversion is done. For instance, if we try to set some String
087         * into a Binary attribute, we just store the UTF-8 byte array 
088         * encoding for this String.
089         * If we try to store some byte[] in a HR attribute, we try to 
090         * convert those byte[] assuming they represent an UTF-8 encoded
091         * String. Of course, if it's not the case, the stored value will
092         * be incorrect.
093         * <br>
094         * It's the responsibility of the caller to check if the stored
095         * values are consistent with the attribute's type.
096         * <br>
097         * The caller can set the HR flag in order to enforce a type for 
098         * the current attribute, otherwise this type will be set while
099         * adding the first value, using the value's type to set the flag.
100         *
101         * @param vals some new values to be added which may be null
102         * @return the number of added values, or 0 if none has been added
103         */
104        int add( byte[]... vals );
105    
106    
107        /**
108         * Adds some values to this attribute. If the new values are already present in
109         * the attribute values, the method has no effect.
110         * <p>
111         * The new values are added at the end of list of values.
112         * </p>
113         * <p>
114         * This method returns the number of values that were added.
115         * </p>
116         * <p>
117         * If the value's type is different from the attribute's type,
118         * a conversion is done. For instance, if we try to set some 
119         * StringValue into a Binary attribute, we just store the UTF-8 
120         * byte array encoding for this StringValue.
121         * </p>
122         * <p>
123         * If we try to store some BinaryValue in a HR attribute, we try to 
124         * convert those BinaryValue assuming they represent an UTF-8 encoded
125         * String. Of course, if it's not the case, the stored value will
126         * be incorrect.
127         * </p>
128         * <p>
129         * It's the responsibility of the caller to check if the stored
130         * values are consistent with the attribute's type.
131         * </p>
132         * <p>
133         * The caller can set the HR flag in order to enforce a type for 
134         * the current attribute, otherwise this type will be set while
135         * adding the first value, using the value's type to set the flag.
136         * </p>
137         * <p>
138         * <b>Note : </b>If the entry contains no value, and the unique added value
139         * is a null length value, then this value will be considered as
140         * a binary value.
141         * </p>
142         * @param vals some new values to be added which may be null
143         * @return the number of added values, or 0 if none has been added
144         */
145        int add( Value<?>... val );
146        
147        
148        /**
149         * Remove all the values from this attribute.
150         */
151        void clear();
152        
153        
154        /**
155         * @return A clone of the current object
156         */
157        EntryAttribute clone();
158    
159    
160        /**
161         * <p>
162         * Indicates whether the specified values are some of the attribute's values.
163         * </p>
164         * <p>
165         * If the Attribute is not HR, the values will be converted to byte[]
166         * </p>
167         *
168         * @param vals the values
169         * @return true if this attribute contains all the values, otherwise false
170         */
171        boolean contains( String... vals );
172    
173    
174        /**
175         * <p>
176         * Indicates whether the specified values are some of the attribute's values.
177         * </p>
178         * <p>
179         * If the Attribute is HR, the values will be converted to String
180         * </p>
181         *
182         * @param vals the values
183         * @return true if this attribute contains all the values, otherwise false
184         */
185        boolean contains( byte[]... vals );
186    
187    
188        /**
189         * <p>
190         * Indicates whether the specified values are some of the attribute's values.
191         * </p>
192         * <p>
193         * If the Attribute is HR, the binary values will be converted to String before
194         * being checked.
195         * </p>
196         *
197         * @param vals the values
198         * @return true if this attribute contains all the values, otherwise false
199         */
200        boolean contains( Value<?>... vals );
201    
202    
203        /**
204         * Get the attribute type associated with this ServerAttribute.
205         *
206         * @return the attributeType associated with this entry attribute
207         */
208        AttributeType getAttributeType();
209    
210        
211        /**
212         * <p>
213         * Set the attribute type associated with this ServerAttribute.
214         * </p>
215         * <p>
216         * The current attributeType will be replaced. It is the responsibility of
217         * the caller to insure that the existing values are compatible with the new
218         * AttributeType
219         * </p>
220         *
221         * @param attributeType the attributeType associated with this entry attribute
222         */
223        void setAttributeType( AttributeType attributeType );
224    
225        
226        /**
227         * <p>
228         * Check if the current attribute type is of the expected attributeType
229         * </p>
230         * <p>
231         * This method won't tell if the current attribute is a descendant of 
232         * the attributeType. For instance, the "CN" serverAttribute will return
233         * false if we ask if it's an instance of "Name". 
234         * </p> 
235         *
236         * @param attributeId The AttributeType ID to check
237         * @return True if the current attribute is of the expected attributeType
238         * @throws LdapInvalidAttributeValueException If there is no AttributeType
239         */
240        boolean instanceOf( String attributeId ) throws LdapInvalidAttributeValueException;
241    
242        
243        /**
244         * <p>
245         * Get the first value of this attribute. If there is none, 
246         * null is returned.
247         * </p>
248         * <p>
249         * Note : even if we are storing values into a Set, one can assume
250         * the values are ordered following the insertion order.
251         * </p>
252         * <p> 
253         * This method is meant to be used if the attribute hold only one value.
254         * </p>
255         * 
256         *  @return The first value for this attribute.
257         */
258        Value<?> get();
259    
260    
261        /**
262         * Returns an iterator over all the attribute's values.
263         * <p>
264         * The effect on the returned enumeration of adding or removing values of
265         * the attribute is not specified.
266         * </p>
267         * <p>
268         * This method will throw any <code>NamingException</code> that occurs.
269         * </p>
270         *
271         * @return an enumeration of all values of the attribute
272         */
273        Iterator<Value<?>> getAll();
274    
275    
276        /**
277         * <p>
278         * Get the nth value of this attribute. If there is none, 
279         * null is returned.
280         * </p>
281         * <p>
282         * Note : even if we are storing values into a Set, one can assume
283         * the values are ordered following the insertion order.
284         * </p>
285         * <p> 
286         * 
287         * @param i the index  of the value to get
288         *  @return The nth value for this attribute.
289         */
290        Value<?> get( int i );
291        
292        
293        /**
294         * <p>
295         * Get the byte[] value, if and only if the value is known to be Binary,
296         * otherwise a InvalidAttributeValueException will be thrown
297         * </p>
298         * <p>
299         * Note that this method returns the first value only.
300         * </p>
301         *
302         * @return The value as a byte[]
303         * @throws LdapInvalidAttributeValueException If the value is a String
304         */
305        byte[] getBytes() throws LdapInvalidAttributeValueException;
306        
307        
308        /**
309         * Get's the attribute identifier for this entry.  This is the value
310         * that will be used as the identifier for the attribute within the
311         * entry.  
312         *
313         * @return the identifier for this attribute
314         */
315        String getId();
316    
317        
318        /**
319         * Get's the user provided identifier for this entry.  This is the value
320         * that will be used as the identifier for the attribute within the
321         * entry.  If this is a commonName attribute for example and the user
322         * provides "COMMONname" instead when adding the entry then this is
323         * the format the user will have that entry returned by the directory
324         * server.  To do so we store this value as it was given and track it
325         * in the attribute using this property.
326         *
327         * @return the user provided identifier for this attribute
328         */
329        String getUpId();
330        
331        
332        /**
333         * <p>
334         * Tells if the attribute is Human Readable. 
335         * </p>
336         * <p>This flag is set by the caller, or implicitly when adding String 
337         * values into an attribute which is not yet declared as Binary.
338         * </p> 
339         * @return
340         */
341        boolean isHR();
342    
343        
344        /**
345         * <p>
346         * Get the String value, if and only if the value is known to be a String,
347         * otherwise a InvalidAttributeValueException will be thrown
348         * </p>
349         * <p>
350         * Note that this method returns the first value only.
351         * </p>
352         *
353         * @return The value as a String
354         * @throws LdapInvalidAttributeValueException If the value is a byte[]
355         */
356        String getString() throws LdapInvalidAttributeValueException;
357    
358        
359        /**
360         * Puts some values to this attribute.
361         * <p>
362         * The new values will replace the previous values.
363         * </p>
364         * <p>
365         * This method returns the number of values that were put.
366         * </p>
367         *
368         * @param val some values to be put which may be null
369         * @return the number of added values, or 0 if none has been added
370         */
371        int put( String... vals );
372    
373    
374        /**
375         * Puts some values to this attribute.
376         * <p>
377         * The new values will replace the previous values.
378         * </p>
379         * <p>
380         * This method returns the number of values that were put.
381         * </p>
382         *
383         * @param val some values to be put which may be null
384         * @return the number of added values, or 0 if none has been added
385         */
386        int put( byte[]... vals );
387    
388        
389        /**
390         * Puts some values to this attribute.
391         * <p>
392         * The new values are replace the previous values.
393         * </p>
394         * <p>
395         * This method returns the number of values that were put.
396         * </p>
397         *
398         * @param val some values to be put which may be null
399         * @return the number of added values, or 0 if none has been added
400         */
401        int put( Value<?>... vals );
402    
403    
404        /**
405         * <p>
406         * Puts a list of values into this attribute.
407         * </p>
408         * <p>
409         * The new values will replace the previous values.
410         * </p>
411         * <p>
412         * This method returns the number of values that were put.
413         * </p>
414         *
415         * @param vals the values to be put
416         * @return the number of added values, or 0 if none has been added
417         */
418        int put( List<Value<?>> vals );
419    
420    
421        /**
422         * <p>
423         * Removes all the  values that are equal to the given values.
424         * </p>
425         * <p>
426         * Returns true if all the values are removed.
427         * </p>
428         * <p>
429         * If the attribute type is not HR, then the values will be first converted
430         * to byte[]
431         * </p>
432         *
433         * @param vals the values to be removed
434         * @return true if all the values are removed, otherwise false
435         */
436        boolean remove( String... vals );
437        
438        
439        /**
440         * <p>
441         * Removes all the  values that are equal to the given values.
442         * </p>
443         * <p>
444         * Returns true if all the values are removed. 
445         * </p>
446         * <p>
447         * If the attribute type is HR, then the values will be first converted
448         * to String
449         * </p>
450         *
451         * @param vals the values to be removed
452         * @return true if all the values are removed, otherwise false
453         */
454        boolean remove( byte[]... val );
455    
456    
457        /**
458         * <p>
459         * Removes all the  values that are equal to the given values.
460         * </p>
461         * <p>
462         * Returns true if all the values are removed.
463         * </p>
464         * <p>
465         * If the attribute type is HR and some value which are not String, we
466         * will convert the values first (same thing for a non-HR attribute).
467         * </p>
468         *
469         * @param vals the values to be removed
470         * @return true if all the values are removed, otherwise false
471         */
472        boolean remove( Value<?>... vals );
473    
474        
475        /**
476         * <p>
477         * Set the attribute to Human Readable or to Binary. 
478         * </p>
479         * @param isHR <code>true</code> for a Human Readable attribute, 
480         * <code>false</code> for a Binary attribute.
481         */
482        void setHR( boolean isHR );
483    
484        
485        /**
486         * Set the normalized ID. The ID will be lowercased, and spaces
487         * will be trimmed. 
488         *
489         * @param id The attribute ID
490         * @throws IllegalArgumentException If the ID is empty or null or
491         * resolve to an empty value after being trimmed
492         */
493        public void setId( String id );
494    
495        
496        /**
497         * Set the user provided ID. It will also set the ID, normalizing
498         * the upId (removing spaces before and after, and lowercasing it)
499         *
500         * @param upId The attribute ID
501         * @throws IllegalArgumentException If the ID is empty or null or
502         * resolve to an empty value after being trimmed
503         */
504        public void setUpId( String upId );
505    
506    
507        /**
508         * <p>
509         * Set the user provided ID. If we have none, the upId is assigned
510         * the attributetype's name. If it does not have any name, we will
511         * use the OID.
512         * </p>
513         * <p>
514         * If we have an upId and an AttributeType, they must be compatible. :
515         *  - if the upId is an OID, it must be the AttributeType's OID
516         *  - otherwise, its normalized form must be equals to ones of
517         *  the attributeType's names.
518         * </p>
519         * <p>
520         * In any case, the ATtributeType will be changed. The caller is responsible for
521         * the present values to be compatoble with the new AttributeType.
522         * </p>
523         * 
524         * @param upId The attribute ID
525         * @param attributeType The associated attributeType
526         */
527        void setUpId( String upId, AttributeType attributeType );
528    
529        
530        /**
531          * Retrieves the number of values in this attribute.
532          *
533          * @return the number of values in this attribute, including any values
534          * wrapping a null value if there is one
535          */
536        int size();
537        
538        
539        /**
540         * <p>
541         * Checks to see if this attribute is valid along with the values it contains.
542         * </p>
543         * <p>
544         * An attribute is valid if :
545         * <li>All of its values are valid with respect to the attributeType's syntax checker</li>
546         * <li>If the attributeType is SINGLE-VALUE, then no more than a value should be present</li>
547         *</p>
548         * @return true if the attribute and it's values are valid, false otherwise
549         * @throws LdapException  if there is a failure to check syntaxes of values
550         */
551        boolean isValid() throws LdapException;
552    
553    
554        /**
555         * Checks to see if this attribute is valid along with the values it contains.
556         *
557         * @param checker The syntax checker
558         * @return true if the attribute and it's values are valid, false otherwise
559         * @throws LdapException if there is a failure to check syntaxes of values
560         */
561        boolean isValid( SyntaxChecker checker) throws LdapException;
562        
563        
564        /**
565         * Convert the ServerAttribute to a ClientAttribute
566         *
567         * @return An instance of ClientAttribute
568         */
569        EntryAttribute toClientAttribute();
570    }