View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.model.entry;
21  
22  
23  import java.io.IOException;
24  import java.io.ObjectInput;
25  import java.io.ObjectOutput;
26  
27  import org.apache.directory.api.i18n.I18n;
28  import org.apache.directory.api.ldap.model.exception.LdapException;
29  import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
30  import org.apache.directory.api.ldap.model.schema.AttributeType;
31  import org.apache.directory.api.ldap.model.schema.SchemaManager;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  
36  /**
37   * An internal implementation for a ModificationItem. The name has been
38   * chosen so that it does not conflict with @see ModificationItem
39   *
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  public class DefaultModification implements Modification
43  {
44      /** The modification operation */
45      private ModificationOperation operation;
46  
47      /** The attribute which contains the modification */
48      private Attribute attribute;
49  
50      /** The AtributeType */
51      private AttributeType attributeType;
52  
53      /** logger for reporting errors that might not be handled properly upstream */
54      protected static final Logger LOG = LoggerFactory.getLogger( Modification.class );
55  
56  
57      /**
58       * Creates a new instance of DefaultModification.
59       */
60      public DefaultModification()
61      {
62      }
63  
64  
65      /**
66       * Creates a new instance of DefaultModification.
67       *
68       * @param operation The modification operation
69       * @param attribute The associated attribute 
70       */
71      public DefaultModification( ModificationOperation operation, Attribute attribute )
72      {
73          this.operation = operation;
74          this.attribute = attribute;
75      }
76  
77  
78      /**
79       * Creates a new instance of DefaultModification.
80       *
81       * @param operation The modification operation
82       * @param attributeId The associated attribute ID
83       * @param values the associated values
84       */
85      public DefaultModification( ModificationOperation operation, String attributeId, String... values )
86      {
87          this.operation = operation;
88          this.attribute = new DefaultAttribute( attributeId, values );
89      }
90  
91  
92      /**
93       * Creates a new instance of DefaultModification.
94       *
95       * @param operation The modification operation
96       * @param attributeId The associated attribute ID
97       * @param values the associated values
98       */
99      public DefaultModification( ModificationOperation operation, String attributeId, byte[]... values )
100     {
101         this.operation = operation;
102         this.attribute = new DefaultAttribute( attributeId, values );
103     }
104 
105 
106     /**
107      * Creates a new instance of DefaultModification.
108      *
109      * @param operation The modification operation
110      * @param attributeId The associated attribute ID
111      * @param values the associated values
112      */
113     public DefaultModification( ModificationOperation operation, String attributeId, Value<?>... values )
114     {
115         this.operation = operation;
116         this.attribute = new DefaultAttribute( attributeId, values );
117     }
118 
119 
120     /**
121      * Creates a new instance of DefaultModification with no value
122      *
123      * @param operation The modification operation
124      * @param attributeId The associated attribute ID
125      */
126     public DefaultModification( ModificationOperation operation, String attributeId )
127     {
128         this.operation = operation;
129         this.attribute = new DefaultAttribute( attributeId );
130     }
131 
132 
133     /**
134      * Creates a new instance of DefaultModification.
135      *
136      * @param operation The modification operation
137      * @param attributeType The associated attributeType
138      * @param values the associated values
139      * @throws LdapInvalidAttributeValueException If one of the value is not valid
140      */
141     public DefaultModification( ModificationOperation operation, AttributeType attributeType, String... values )
142         throws LdapInvalidAttributeValueException
143     {
144         this.operation = operation;
145         this.attribute = new DefaultAttribute( attributeType, values );
146     }
147 
148 
149     /**
150      * Creates a new instance of DefaultModification.
151      *
152      * @param operation The modification operation
153      * @param attributeType The associated attributeType
154      * @param values the associated values
155      * @throws LdapInvalidAttributeValueException If one of the value is not valid
156      */
157     public DefaultModification( ModificationOperation operation, AttributeType attributeType, byte[]... values )
158         throws LdapInvalidAttributeValueException
159     {
160         this.operation = operation;
161         this.attribute = new DefaultAttribute( attributeType, values );
162     }
163 
164 
165     /**
166      * Creates a new instance of DefaultModification.
167      *
168      * @param operation The modification operation
169      * @param attributeType The associated attributeType
170      * @param values the associated values
171      * @throws LdapInvalidAttributeValueException If one of the value is not valid
172      */
173     public DefaultModification( ModificationOperation operation, AttributeType attributeType, Value<?>... values )
174         throws LdapInvalidAttributeValueException
175     {
176         this.operation = operation;
177         this.attribute = new DefaultAttribute( attributeType, values );
178     }
179 
180 
181     /**
182      * Creates a new instance of DefaultModification with no value.
183      *
184      * @param operation The modification operation
185      * @param attributeType The associated attributeType
186      * @throws LdapInvalidAttributeValueException If one of the value is not valid
187      */
188     public DefaultModification( ModificationOperation operation, AttributeType attributeType )
189         throws LdapInvalidAttributeValueException
190     {
191         this.operation = operation;
192         this.attribute = new DefaultAttribute( attributeType );
193     }
194 
195 
196     /**
197      * Creates a new instance of DefaultModification.
198      *
199      * @param schemaManager The schema manager 
200      * @param modification The modification
201      */
202     public DefaultModification( SchemaManager schemaManager, Modification modification )
203     {
204         operation = modification.getOperation();
205 
206         Attribute modAttribute = modification.getAttribute();
207 
208         try
209         {
210             AttributeType at = modAttribute.getAttributeType();
211 
212             if ( at == null )
213             {
214                 at = schemaManager.lookupAttributeTypeRegistry( modAttribute.getId() );
215             }
216 
217             attribute = new DefaultAttribute( at, modAttribute );
218         }
219         catch ( LdapException ne )
220         {
221             // The attributeType is incorrect. Log, but do nothing otherwise.
222             LOG.error( I18n.err( I18n.ERR_04472, modAttribute.getId() ) );
223         }
224     }
225 
226 
227     /**
228      * {@inheritDoc}
229      */
230     @Override
231     public ModificationOperation getOperation()
232     {
233         return operation;
234     }
235 
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public void setOperation( int operation )
242     {
243         this.operation = ModificationOperation.getOperation( operation );
244     }
245 
246 
247     /**
248      * {@inheritDoc}
249      */
250     @Override
251     public void setOperation( ModificationOperation operation )
252     {
253         this.operation = operation;
254     }
255 
256 
257     /**
258      * {@inheritDoc}
259      */
260     @Override
261     public Attribute getAttribute()
262     {
263         return attribute;
264     }
265 
266 
267     /**
268      * {@inheritDoc}
269      */
270     @Override
271     public void setAttribute( Attribute attribute )
272     {
273         this.attribute = attribute;
274     }
275 
276 
277     /**
278      * {@inheritDoc}
279      */
280     @Override
281     public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
282     {
283         this.attributeType = attributeType;
284 
285         if ( attribute != null )
286         {
287             attribute.apply( attributeType );
288         }
289     }
290 
291 
292     /**
293      * @return The associated AttributeType
294      */
295     public AttributeType getAttributeType()
296     {
297         return attributeType;
298     }
299 
300 
301     /**
302      * @see Object#equals(Object)
303      * @return <code>true</code> if both values are equal
304      */
305     @Override
306     public boolean equals( Object that )
307     {
308         // Basic equals checks
309         if ( this == that )
310         {
311             return true;
312         }
313 
314         if ( !( that instanceof Modification ) )
315         {
316             return false;
317         }
318 
319         Modification otherModification = ( Modification ) that;
320 
321         // Check the operation
322         if ( operation != otherModification.getOperation() )
323         {
324             return false;
325         }
326 
327         // Check the attribute
328         if ( attribute == null )
329         {
330             return otherModification.getAttribute() == null;
331         }
332 
333         return attribute.equals( otherModification.getAttribute() );
334     }
335 
336 
337     /**
338      * Compute the modification @see Object#hashCode
339      * @return the instance's hash code 
340      */
341     @Override
342     public int hashCode()
343     {
344         int h = 37;
345 
346         h += h * 17 + operation.getValue();
347         h += h * 17 + attribute.hashCode();
348 
349         return h;
350     }
351 
352 
353     /**
354      * @see java.io.Externalizable#readExternal(ObjectInput)
355      */
356     @Override
357     public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
358     {
359         // The operation
360         operation = ModificationOperation.getOperation( in.readInt() );
361 
362         // The EntryAttribute if we have some
363         boolean hasAttribute = in.readBoolean();
364 
365         if ( hasAttribute )
366         {
367             attribute = new DefaultAttribute();
368             attribute.readExternal( in );
369         }
370     }
371 
372 
373     /**
374      * @see java.io.Externalizable#writeExternal(ObjectOutput)
375      */
376     @Override
377     public void writeExternal( ObjectOutput out ) throws IOException
378     {
379         // The operation
380         out.writeInt( operation.getValue() );
381 
382         // The EntryAttribute if not null
383         if ( attribute != null )
384         {
385             out.writeBoolean( true );
386             attribute.writeExternal( out );
387         }
388         else
389         {
390             out.writeBoolean( false );
391         }
392 
393         out.flush();
394     }
395 
396 
397     /**
398      * {@inheritDoc}
399      */
400     @Override
401     public DefaultModification clone()
402     {
403         try
404         {
405             DefaultModification clone = ( DefaultModification ) super.clone();
406 
407             clone.attribute = this.attribute.clone();
408             return clone;
409         }
410         catch ( CloneNotSupportedException cnse )
411         {
412             return null;
413         }
414     }
415 
416 
417     /**
418      * @see Object#toString()
419      */
420     @Override
421     public String toString()
422     {
423         StringBuilder sb = new StringBuilder();
424 
425         sb.append( "Modification: " ).
426             append( operation ).
427             append( "\n" ).
428             append( ", attribute : " ).
429             append( attribute );
430 
431         return sb.toString();
432     }
433 }