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   *    https://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          // Default empty constructor
63      }
64  
65  
66      /**
67       * Creates a new instance of DefaultModification.
68       *
69       * @param operation The modification operation
70       * @param attribute The associated attribute 
71       */
72      public DefaultModification( ModificationOperation operation, Attribute attribute )
73      {
74          this.operation = operation;
75          this.attribute = attribute;
76      }
77  
78  
79      /**
80       * Creates a new instance of DefaultModification.
81       *
82       * @param operation The modification operation
83       * @param attributeId The associated attribute ID
84       * @param values the associated values
85       */
86      public DefaultModification( ModificationOperation operation, String attributeId, String... values )
87      {
88          this.operation = operation;
89          this.attribute = new DefaultAttribute( attributeId, values );
90      }
91  
92  
93      /**
94       * Creates a new instance of DefaultModification.
95       *
96       * @param operation The modification operation
97       * @param attributeId The associated attribute ID
98       * @param values the associated values
99       */
100     public DefaultModification( ModificationOperation operation, String attributeId, byte[]... values )
101     {
102         this.operation = operation;
103         this.attribute = new DefaultAttribute( attributeId, values );
104     }
105 
106 
107     /**
108      * Creates a new instance of DefaultModification.
109      *
110      * @param operation The modification operation
111      * @param attributeId The associated attribute ID
112      * @param values the associated values
113      */
114     public DefaultModification( ModificationOperation operation, String attributeId, Value... values )
115     {
116         this.operation = operation;
117         this.attribute = new DefaultAttribute( attributeId, values );
118     }
119 
120 
121     /**
122      * Creates a new instance of DefaultModification with no value
123      *
124      * @param operation The modification operation
125      * @param attributeId The associated attribute ID
126      */
127     public DefaultModification( ModificationOperation operation, String attributeId )
128     {
129         this.operation = operation;
130         this.attribute = new DefaultAttribute( attributeId );
131     }
132 
133 
134     /**
135      * Creates a new instance of DefaultModification.
136      *
137      * @param operation The modification operation
138      * @param attributeType The associated attributeType
139      * @param values the associated values
140      * @throws LdapInvalidAttributeValueException If the value is invalid
141      */
142     public DefaultModification( ModificationOperation operation, AttributeType attributeType, String... values )
143         throws LdapInvalidAttributeValueException
144     {
145         this.operation = operation;
146         this.attribute = new DefaultAttribute( attributeType, values );
147     }
148 
149 
150     /**
151      * Creates a new instance of DefaultModification.
152      *
153      * @param operation The modification operation
154      * @param attributeType The associated attributeType
155      * @param values the associated values
156      * @throws LdapInvalidAttributeValueException If the value is invalid
157      */
158     public DefaultModification( ModificationOperation operation, AttributeType attributeType, byte[]... values )
159         throws LdapInvalidAttributeValueException
160     {
161         this.operation = operation;
162         this.attribute = new DefaultAttribute( attributeType, values );
163     }
164 
165 
166     /**
167      * Creates a new instance of DefaultModification.
168      *
169      * @param operation The modification operation
170      * @param attributeType The associated attributeType
171      * @param values the associated values
172      * @throws LdapInvalidAttributeValueException If the value is invalid
173      */
174     public DefaultModification( ModificationOperation operation, AttributeType attributeType, Value... values )
175         throws LdapInvalidAttributeValueException
176     {
177         this.operation = operation;
178         this.attribute = new DefaultAttribute( attributeType, values );
179     }
180 
181 
182     /**
183      * Creates a new instance of DefaultModification with no value.
184      *
185      * @param operation The modification operation
186      * @param attributeType The associated attributeType
187      * @throws LdapInvalidAttributeValueException If the value is invalid
188      */
189     public DefaultModification( ModificationOperation operation, AttributeType attributeType )
190         throws LdapInvalidAttributeValueException
191     {
192         this.operation = operation;
193         this.attribute = new DefaultAttribute( attributeType );
194     }
195 
196 
197     /**
198      * Creates a new instance of DefaultModification.
199      *
200      * @param schemaManager The schema manager 
201      * @param modification The modification
202      */
203     public DefaultModification( SchemaManager schemaManager, Modification modification )
204     {
205         operation = modification.getOperation();
206 
207         Attribute modAttribute = modification.getAttribute();
208 
209         try
210         {
211             AttributeType at = modAttribute.getAttributeType();
212 
213             if ( at == null )
214             {
215                 at = schemaManager.lookupAttributeTypeRegistry( modAttribute.getId() );
216             }
217 
218             attribute = new DefaultAttribute( at, modAttribute );
219         }
220         catch ( LdapException ne )
221         {
222             // The attributeType is incorrect. Log, but do nothing otherwise.
223             LOG.error( I18n.err( I18n.ERR_13230_INCORRECT_ATTRIBUTE, modAttribute.getId() ) );
224         }
225     }
226 
227 
228     /**
229      * {@inheritDoc}
230      */
231     @Override
232     public ModificationOperation getOperation()
233     {
234         return operation;
235     }
236 
237 
238     /**
239      * {@inheritDoc}
240      */
241     @Override
242     public void setOperation( int operation )
243     {
244         this.operation = ModificationOperation.getOperation( operation );
245     }
246 
247 
248     /**
249      * {@inheritDoc}
250      */
251     @Override
252     public void setOperation( ModificationOperation operation )
253     {
254         this.operation = operation;
255     }
256 
257 
258     /**
259      * {@inheritDoc}
260      */
261     @Override
262     public Attribute getAttribute()
263     {
264         return attribute;
265     }
266 
267 
268     /**
269      * {@inheritDoc}
270      */
271     @Override
272     public void setAttribute( Attribute attribute )
273     {
274         this.attribute = attribute;
275     }
276 
277 
278     /**
279      * {@inheritDoc}
280      */
281     @Override
282     public void apply( AttributeType attributeType ) throws LdapInvalidAttributeValueException
283     {
284         this.attributeType = attributeType;
285 
286         if ( attribute != null )
287         {
288             attribute.apply( attributeType );
289         }
290     }
291 
292 
293     /**
294      * @return The associated AttributeType
295      */
296     public AttributeType getAttributeType()
297     {
298         return attributeType;
299     }
300 
301 
302     /**
303      * @see Object#equals(Object)
304      * @return <code>true</code> if both values are equal
305      */
306     @Override
307     public boolean equals( Object that )
308     {
309         // Basic equals checks
310         if ( this == that )
311         {
312             return true;
313         }
314 
315         if ( !( that instanceof Modification ) )
316         {
317             return false;
318         }
319 
320         Modification otherModification = ( Modification ) that;
321 
322         // Check the operation
323         if ( operation != otherModification.getOperation() )
324         {
325             return false;
326         }
327 
328         // Check the attribute
329         if ( attribute == null )
330         {
331             return otherModification.getAttribute() == null;
332         }
333 
334         return attribute.equals( otherModification.getAttribute() );
335     }
336 
337 
338     /**
339      * Compute the modification @see Object#hashCode
340      * @return the instance's hash code 
341      */
342     @Override
343     public int hashCode()
344     {
345         int h = 37;
346 
347         h += h * 17 + operation.getValue();
348         h += h * 17 + attribute.hashCode();
349 
350         return h;
351     }
352 
353 
354     /**
355      * @see java.io.Externalizable#readExternal(ObjectInput)
356      */
357     @Override
358     public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
359     {
360         // The operation
361         operation = ModificationOperation.getOperation( in.readInt() );
362 
363         // The EntryAttribute if we have some
364         boolean hasAttribute = in.readBoolean();
365 
366         if ( hasAttribute )
367         {
368             attribute = new DefaultAttribute();
369             attribute.readExternal( in );
370         }
371     }
372 
373 
374     /**
375      * @see java.io.Externalizable#writeExternal(ObjectOutput)
376      */
377     @Override
378     public void writeExternal( ObjectOutput out ) throws IOException
379     {
380         // The operation
381         out.writeInt( operation.getValue() );
382 
383         // The EntryAttribute if not null
384         if ( attribute != null )
385         {
386             out.writeBoolean( true );
387             attribute.writeExternal( out );
388         }
389         else
390         {
391             out.writeBoolean( false );
392         }
393 
394         out.flush();
395     }
396 
397 
398     /**
399      * {@inheritDoc}
400      */
401     @Override
402     public DefaultModification clone()
403     {
404         try
405         {
406             DefaultModification clone = ( DefaultModification ) super.clone();
407 
408             clone.attribute = this.attribute.clone();
409             return clone;
410         }
411         catch ( CloneNotSupportedException cnse )
412         {
413             return null;
414         }
415     }
416 
417 
418     /**
419      * @see Object#toString()
420      */
421     @Override
422     public String toString()
423     {
424         StringBuilder sb = new StringBuilder();
425 
426         sb.append( "Modification: " ).
427             append( operation ).
428             append( ", [" ).
429             append( attribute.getId() );
430         
431         if ( attribute.size() == 0 )
432         {
433             if ( operation == ModificationOperation.INCREMENT_ATTRIBUTE )
434             { 
435                 sb.append( " : 1" );
436             }
437         }
438         else
439         {
440             sb.append( " : " ).append( attribute );
441         }
442         
443         sb.append( "]" );
444 
445         return sb.toString();
446     }
447 }