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      */
140     public DefaultModification( ModificationOperation operation, AttributeType attributeType, String... values )
141         throws LdapInvalidAttributeValueException
142     {
143         this.operation = operation;
144         this.attribute = new DefaultAttribute( attributeType, values );
145     }
146 
147 
148     /**
149      * Creates a new instance of DefaultModification.
150      *
151      * @param operation The modification operation
152      * @param attributeType The associated attributeType
153      * @param values the associated values
154      */
155     public DefaultModification( ModificationOperation operation, AttributeType attributeType, byte[]... values )
156         throws LdapInvalidAttributeValueException
157     {
158         this.operation = operation;
159         this.attribute = new DefaultAttribute( attributeType, values );
160     }
161 
162 
163     /**
164      * Creates a new instance of DefaultModification.
165      *
166      * @param operation The modification operation
167      * @param attributeType The associated attributeType
168      * @param values the associated values
169      */
170     public DefaultModification( ModificationOperation operation, AttributeType attributeType, Value<?>... values )
171         throws LdapInvalidAttributeValueException
172     {
173         this.operation = operation;
174         this.attribute = new DefaultAttribute( attributeType, values );
175     }
176 
177 
178     /**
179      * Creates a new instance of DefaultModification with no value.
180      *
181      * @param operation The modification operation
182      * @param attributeType The associated attributeType
183      */
184     public DefaultModification( ModificationOperation operation, AttributeType attributeType )
185         throws LdapInvalidAttributeValueException
186     {
187         this.operation = operation;
188         this.attribute = new DefaultAttribute( attributeType );
189     }
190 
191 
192     /**
193      * Creates a new instance of DefaultModification.
194      *
195      * @param schemaManager The schema manager 
196      * @param modification The modification
197      */
198     public DefaultModification( SchemaManager schemaManager, Modification modification )
199     {
200         operation = modification.getOperation();
201 
202         Attribute modAttribute = modification.getAttribute();
203 
204         try
205         {
206             AttributeType at = modAttribute.getAttributeType();
207 
208             if ( at == null )
209             {
210                 at = schemaManager.lookupAttributeTypeRegistry( modAttribute.getId() );
211             }
212 
213             attribute = new DefaultAttribute( at, modAttribute );
214         }
215         catch ( LdapException ne )
216         {
217             // The attributeType is incorrect. Log, but do nothing otherwise.
218             LOG.error( I18n.err( I18n.ERR_04472, modAttribute.getId() ) );
219         }
220     }
221 
222 
223     /**
224      * {@inheritDoc}
225      */
226     public ModificationOperation getOperation()
227     {
228         return operation;
229     }
230 
231 
232     /**
233      * {@inheritDoc}
234      */
235     public void setOperation( int operation )
236     {
237         this.operation = ModificationOperation.getOperation( operation );
238     }
239 
240 
241     /**
242      * {@inheritDoc}
243      */
244     public void setOperation( ModificationOperation operation )
245     {
246         this.operation = operation;
247     }
248 
249 
250     /**
251      * {@inheritDoc}
252      */
253     public Attribute getAttribute()
254     {
255         return attribute;
256     }
257 
258 
259     /**
260      * {@inheritDoc}
261      */
262     public void setAttribute( Attribute attribute )
263     {
264         this.attribute = attribute;
265     }
266 
267 
268     /**
269      * {@inheritDoc}
270      */
271     public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
272     {
273         this.attributeType = attributeType;
274 
275         if ( attribute != null )
276         {
277             attribute.apply( attributeType );
278         }
279     }
280 
281 
282     /**
283      * {@inheritDoc}
284      */
285     public AttributeType getAttributeType()
286     {
287         return attributeType;
288     }
289 
290 
291     /**
292      * @see Object#equals(Object)
293      * @return <code>true</code> if both values are equal
294      */
295     public boolean equals( Object that )
296     {
297         // Basic equals checks
298         if ( this == that )
299         {
300             return true;
301         }
302 
303         if ( !( that instanceof Modification ) )
304         {
305             return false;
306         }
307 
308         Modification otherModification = ( Modification ) that;
309 
310         // Check the operation
311         if ( operation != otherModification.getOperation() )
312         {
313             return false;
314         }
315 
316         // Check the attribute
317         if ( attribute == null )
318         {
319             return otherModification.getAttribute() == null;
320         }
321 
322         return attribute.equals( otherModification.getAttribute() );
323     }
324 
325 
326     /**
327      * Compute the modification @see Object#hashCode
328      * @return the instance's hash code 
329      */
330     public int hashCode()
331     {
332         int h = 37;
333 
334         h += h * 17 + operation.getValue();
335         h += h * 17 + attribute.hashCode();
336 
337         return h;
338     }
339 
340 
341     /**
342      * @see java.io.Externalizable#readExternal(ObjectInput)
343      */
344     public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
345     {
346         // The operation
347         operation = ModificationOperation.getOperation( in.readInt() );
348 
349         // The EntryAttribute if we have some
350         boolean hasAttribute = in.readBoolean();
351 
352         if ( hasAttribute )
353         {
354             attribute = new DefaultAttribute();
355             attribute.readExternal( in );
356         }
357     }
358 
359 
360     /**
361      * @see java.io.Externalizable#writeExternal(ObjectOutput)
362      */
363     public void writeExternal( ObjectOutput out ) throws IOException
364     {
365         // The operation
366         out.writeInt( operation.getValue() );
367 
368         // The EntryAttribute if not null
369         if ( attribute != null )
370         {
371             out.writeBoolean( true );
372             attribute.writeExternal( out );
373         }
374         else
375         {
376             out.writeBoolean( false );
377         }
378 
379         out.flush();
380     }
381 
382 
383     /**
384      * {@inheritDoc}
385      */
386     public DefaultModification clone()
387     {
388         try
389         {
390             DefaultModification clone = ( DefaultModification ) super.clone();
391 
392             clone.attribute = this.attribute.clone();
393             return clone;
394         }
395         catch ( CloneNotSupportedException cnse )
396         {
397             return null;
398         }
399     }
400 
401 
402     /**
403      * @see Object#toString()
404      */
405     public String toString()
406     {
407         StringBuilder sb = new StringBuilder();
408 
409         sb.append( "Modification: " ).
410             append( operation ).
411             append( "\n" ).
412             append( ", attribute : " ).
413             append( attribute );
414 
415         return sb.toString();
416     }
417 }