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 javax.naming.directory.InvalidAttributeValueException;
026    
027    /**
028     * A generic interface mocking the Attribute JNDI interface. This interface
029     * will be the base interface for the ServerAttribute and ClientAttribute.
030     *
031     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
032     * @version $Rev$, $Date$
033     */
034    public interface EntryAttribute extends Iterable<Value<?>>, Cloneable, Externalizable
035    {
036        /**
037         * Adds some values to this attribute. If the new values are already present in
038         * the attribute values, the method has no effect.
039         * <p>
040         * The new values are added at the end of list of values.
041         * </p>
042         * <p>
043         * This method returns the number of values that were added.
044         * </p>
045         * <p>
046         * If the value's type is different from the attribute's type,
047         * a conversion is done. For instance, if we try to set some String
048         * into a Binary attribute, we just store the UTF-8 byte array 
049         * encoding for this String.
050         * </p>
051         * <p>
052         * If we try to store some byte[] in a HR attribute, we try to 
053         * convert those byte[] assuming they represent an UTF-8 encoded
054         * String. Of course, if it's not the case, the stored value will
055         * be incorrect.
056         * </p>
057         * <p>
058         * It's the responsibility of the caller to check if the stored
059         * values are consistent with the attribute's type.
060         * </p>
061         * <p>
062         * The caller can set the HR flag in order to enforce a type for 
063         * the current attribute, otherwise this type will be set while
064         * adding the first value, using the value's type to set the flag.
065         * </p>
066         *
067         * @param vals some new values to be added which may be null
068         * @return the number of added values, or 0 if none has been added
069         */
070        int add( String... vals );
071    
072    
073        /**
074         * Adds some values to this attribute. If the new values are already present in
075         * the attribute values, the method has no effect.
076         * <p>
077         * The new values are added at the end of list of values.
078         * </p>
079         * <p>
080         * This method returns the number of values that were added.
081         * </p>
082         * If the value's type is different from the attribute's type,
083         * a conversion is done. For instance, if we try to set some String
084         * into a Binary attribute, we just store the UTF-8 byte array 
085         * encoding for this String.
086         * If we try to store some byte[] in a HR attribute, we try to 
087         * convert those byte[] assuming they represent an UTF-8 encoded
088         * String. Of course, if it's not the case, the stored value will
089         * be incorrect.
090         * <br>
091         * It's the responsibility of the caller to check if the stored
092         * values are consistent with the attribute's type.
093         * <br>
094         * The caller can set the HR flag in order to enforce a type for 
095         * the current attribute, otherwise this type will be set while
096         * adding the first value, using the value's type to set the flag.
097         *
098         * @param vals some new values to be added which may be null
099         * @return the number of added values, or 0 if none has been added
100         */
101        int add( byte[]... vals );
102    
103    
104        /**
105         * Adds some values to this attribute. If the new values are already present in
106         * the attribute values, the method has no effect.
107         * <p>
108         * The new values are added at the end of list of values.
109         * </p>
110         * <p>
111         * This method returns the number of values that were added.
112         * </p>
113         * <p>
114         * If the value's type is different from the attribute's type,
115         * a conversion is done. For instance, if we try to set some 
116         * StringValue into a Binary attribute, we just store the UTF-8 
117         * byte array encoding for this StringValue.
118         * </p>
119         * <p>
120         * If we try to store some BinaryValue in a HR attribute, we try to 
121         * convert those BinaryValue assuming they represent an UTF-8 encoded
122         * String. Of course, if it's not the case, the stored value will
123         * be incorrect.
124         * </p>
125         * <p>
126         * It's the responsibility of the caller to check if the stored
127         * values are consistent with the attribute's type.
128         * </p>
129         * <p>
130         * The caller can set the HR flag in order to enforce a type for 
131         * the current attribute, otherwise this type will be set while
132         * adding the first value, using the value's type to set the flag.
133         * </p>
134         * <p>
135         * <b>Note : </b>If the entry contains no value, and the unique added value
136         * is a null length value, then this value will be considered as
137         * a binary value.
138         * </p>
139         * @param vals some new values to be added which may be null
140         * @return the number of added values, or 0 if none has been added
141         */
142        int add( Value<?>... val );
143        
144        
145        /**
146         * Remove all the values from this attribute.
147         */
148        void clear();
149        
150        
151        /**
152         * @return A clone of the current object
153         */
154        EntryAttribute clone();
155    
156    
157        /**
158         * <p>
159         * Indicates whether the specified values are some of the attribute's values.
160         * </p>
161         * <p>
162         * If the Attribute is not HR, the values will be converted to byte[]
163         * </p>
164         *
165         * @param vals the values
166         * @return true if this attribute contains all the values, otherwise false
167         */
168        boolean contains( String... vals );
169    
170    
171        /**
172         * <p>
173         * Indicates whether the specified values are some of the attribute's values.
174         * </p>
175         * <p>
176         * If the Attribute is HR, the values will be converted to String
177         * </p>
178         *
179         * @param vals the values
180         * @return true if this attribute contains all the values, otherwise false
181         */
182        boolean contains( byte[]... vals );
183    
184    
185        /**
186         * <p>
187         * Indicates whether the specified values are some of the attribute's values.
188         * </p>
189         * <p>
190         * If the Attribute is HR, the binary values will be converted to String before
191         * being checked.
192         * </p>
193         *
194         * @param vals the values
195         * @return true if this attribute contains all the values, otherwise false
196         */
197        boolean contains( Value<?>... vals );
198    
199    
200        /**
201         * <p>
202         * Get the first value of this attribute. If there is none, 
203         * null is returned.
204         * </p>
205         * <p>
206         * Note : even if we are storing values into a Set, one can assume
207         * the values are ordered following the insertion order.
208         * </p>
209         * <p> 
210         * This method is meant to be used if the attribute hold only one value.
211         * </p>
212         * 
213         *  @return The first value for this attribute.
214         */
215        Value<?> get();
216    
217    
218        /**
219         * Returns an iterator over all the attribute's values.
220         * <p>
221         * The effect on the returned enumeration of adding or removing values of
222         * the attribute is not specified.
223         * </p>
224         * <p>
225         * This method will throw any <code>NamingException</code> that occurs.
226         * </p>
227         *
228         * @return an enumeration of all values of the attribute
229         */
230        Iterator<Value<?>> getAll();
231    
232    
233        /**
234         * <p>
235         * Get the nth value of this attribute. If there is none, 
236         * null is returned.
237         * </p>
238         * <p>
239         * Note : even if we are storing values into a Set, one can assume
240         * the values are ordered following the insertion order.
241         * </p>
242         * <p> 
243         * 
244         * @param i the index  of the value to get
245         *  @return The nth value for this attribute.
246         */
247        Value<?> get( int i );
248        
249        
250        /**
251         * <p>
252         * Get the byte[] value, if and only if the value is known to be Binary,
253         * otherwise a InvalidAttributeValueException will be thrown
254         * </p>
255         * <p>
256         * Note that this method returns the first value only.
257         * </p>
258         *
259         * @return The value as a byte[]
260         * @throws InvalidAttributeValueException If the value is a String
261         */
262        byte[] getBytes() throws InvalidAttributeValueException;
263        
264        
265        /**
266         * Get's the attribute identifier for this entry.  This is the value
267         * that will be used as the identifier for the attribute within the
268         * entry.  
269         *
270         * @return the identifier for this attribute
271         */
272        String getId();
273    
274        
275        /**
276         * Get's the user provided identifier for this entry.  This is the value
277         * that will be used as the identifier for the attribute within the
278         * entry.  If this is a commonName attribute for example and the user
279         * provides "COMMONname" instead when adding the entry then this is
280         * the format the user will have that entry returned by the directory
281         * server.  To do so we store this value as it was given and track it
282         * in the attribute using this property.
283         *
284         * @return the user provided identifier for this attribute
285         */
286        String getUpId();
287        
288        
289        /**
290         * <p>
291         * Tells if the attribute is Human Readable. 
292         * </p>
293         * <p>This flag is set by the caller, or implicitly when adding String 
294         * values into an attribute which is not yet declared as Binary.
295         * </p> 
296         * @return
297         */
298        boolean isHR();
299    
300        
301        /**
302         * <p>
303         * Get the String value, if and only if the value is known to be a String,
304         * otherwise a InvalidAttributeValueException will be thrown
305         * </p>
306         * <p>
307         * Note that this method returns the first value only.
308         * </p>
309         *
310         * @return The value as a String
311         * @throws InvalidAttributeValueException If the value is a byte[]
312         */
313        String getString() throws InvalidAttributeValueException;
314    
315        
316        /**
317         * Puts some values to this attribute.
318         * <p>
319         * The new values will replace the previous values.
320         * </p>
321         * <p>
322         * This method returns the number of values that were put.
323         * </p>
324         *
325         * @param val some values to be put which may be null
326         * @return the number of added values, or 0 if none has been added
327         */
328        int put( String... vals );
329    
330    
331        /**
332         * Puts some values to this attribute.
333         * <p>
334         * The new values will replace the previous values.
335         * </p>
336         * <p>
337         * This method returns the number of values that were put.
338         * </p>
339         *
340         * @param val some values to be put which may be null
341         * @return the number of added values, or 0 if none has been added
342         */
343        int put( byte[]... vals );
344    
345        
346        /**
347         * Puts some values to this attribute.
348         * <p>
349         * The new values are replace the previous values.
350         * </p>
351         * <p>
352         * This method returns the number of values that were put.
353         * </p>
354         *
355         * @param val some values to be put which may be null
356         * @return the number of added values, or 0 if none has been added
357         */
358        int put( Value<?>... vals );
359    
360    
361        /**
362         * <p>
363         * Puts a list of values into this attribute.
364         * </p>
365         * <p>
366         * The new values will replace the previous values.
367         * </p>
368         * <p>
369         * This method returns the number of values that were put.
370         * </p>
371         *
372         * @param vals the values to be put
373         * @return the number of added values, or 0 if none has been added
374         */
375        int put( List<Value<?>> vals );
376    
377    
378        /**
379         * <p>
380         * Removes all the  values that are equal to the given values.
381         * </p>
382         * <p>
383         * Returns true if all the values are removed.
384         * </p>
385         * <p>
386         * If the attribute type is not HR, then the values will be first converted
387         * to byte[]
388         * </p>
389         *
390         * @param vals the values to be removed
391         * @return true if all the values are removed, otherwise false
392         */
393        boolean remove( String... vals );
394        
395        
396        /**
397         * <p>
398         * Removes all the  values that are equal to the given values.
399         * </p>
400         * <p>
401         * Returns true if all the values are removed. 
402         * </p>
403         * <p>
404         * If the attribute type is HR, then the values will be first converted
405         * to String
406         * </p>
407         *
408         * @param vals the values to be removed
409         * @return true if all the values are removed, otherwise false
410         */
411        boolean remove( byte[]... val );
412    
413    
414        /**
415         * <p>
416         * Removes all the  values that are equal to the given values.
417         * </p>
418         * <p>
419         * Returns true if all the values are removed.
420         * </p>
421         * <p>
422         * If the attribute type is HR and some value which are not String, we
423         * will convert the values first (same thing for a non-HR attribute).
424         * </p>
425         *
426         * @param vals the values to be removed
427         * @return true if all the values are removed, otherwise false
428         */
429        boolean remove( Value<?>... vals );
430    
431        
432        /**
433         * <p>
434         * Set the attribute to Human Readable or to Binary. 
435         * </p>
436         * @param isHR <code>true</code> for a Human Readable attribute, 
437         * <code>false</code> for a Binary attribute.
438         */
439        void setHR( boolean isHR );
440    
441        
442        /**
443         * Set the normalized ID. The ID will be lowercased, and spaces
444         * will be trimmed. 
445         *
446         * @param id The attribute ID
447         * @throws IllegalArgumentException If the ID is empty or null or
448         * resolve to an empty value after being trimmed
449         */
450        public void setId( String id );
451    
452        
453        /**
454         * Set the user provided ID. It will also set the ID, normalizing
455         * the upId (removing spaces before and after, and lowercasing it)
456         *
457         * @param upId The attribute ID
458         * @throws IllegalArgumentException If the ID is empty or null or
459         * resolve to an empty value after being trimmed
460         */
461        public void setUpId( String upId );
462    
463        
464        /**
465          * Retrieves the number of values in this attribute.
466          *
467          * @return the number of values in this attribute, including any values
468          * wrapping a null value if there is one
469          */
470        int size();
471    }