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     */
020    package org.apache.directory.shared.ldap.entry.client;
021    
022    import java.io.IOException;
023    import java.io.ObjectInput;
024    import java.io.ObjectOutput;
025    
026    import javax.naming.directory.DirContext;
027    
028    import org.apache.directory.shared.ldap.entry.EntryAttribute;
029    import org.apache.directory.shared.ldap.entry.Modification;
030    import org.apache.directory.shared.ldap.entry.ModificationOperation;
031    
032    /**
033     * An internal implementation for a ModificationItem. The name has been
034     * chosen so that it does not conflict with @see ModificationItem
035     *
036     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037     * @version $Rev$, $Date$
038     */
039    public class ClientModification implements Modification
040    {
041        /** The modification operation */
042        private ModificationOperation operation;
043        
044        /** The attribute which contains the modification */
045        private EntryAttribute attribute;
046     
047        
048        /**
049         * 
050         * Creates a new instance of ClientModification.
051         *
052         * @param operation The modification operation
053         * @param attribute The asociated attribute 
054         */
055        public ClientModification( ModificationOperation operation, EntryAttribute attribute )
056        {
057            this.operation = operation;
058            this.attribute = attribute;
059        }
060        
061        
062        /**
063         * 
064         * Creates a new instance of ClientModification.
065         */
066        public ClientModification()
067        {
068        }
069        
070        
071        /**
072         * 
073         * Creates a new instance of ClientModification.
074         *
075         * @param operation The modification operation
076         * @param attribute The asociated attribute 
077         */
078        public ClientModification( int operation, EntryAttribute attribute )
079        {
080            setOperation( operation );
081            this.attribute = attribute;
082        }
083        
084        
085        /**
086         *  @return the operation
087         */
088        public ModificationOperation getOperation()
089        {
090            return operation;
091        }
092        
093        
094        /**
095         * Store the modification operation
096         *
097         * @param operation The DirContext value to assign
098         */
099        public void setOperation( int operation )
100        {
101            switch ( operation )
102            {
103                case DirContext.ADD_ATTRIBUTE :
104                    this.operation = ModificationOperation.ADD_ATTRIBUTE;
105                    break;
106    
107                case DirContext.REPLACE_ATTRIBUTE :
108                    this.operation = ModificationOperation.REPLACE_ATTRIBUTE;
109                    break;
110                
111                case DirContext.REMOVE_ATTRIBUTE :
112                    this.operation = ModificationOperation.REMOVE_ATTRIBUTE;
113                    break;
114            }
115        }
116    
117        
118        /**
119         * Store the modification operation
120         *
121         * @param operation The DirContext value to assign
122         */
123        public void setOperation( ModificationOperation operation )
124        {
125            this.operation = operation;
126        }
127            
128        
129        /**
130         * @return the attribute containing the modifications
131         */
132        public EntryAttribute getAttribute()
133        {
134            return attribute;
135        }
136        
137        
138        /**
139         * Set the attribute's modification
140         *
141         * @param attribute The modified attribute 
142         */
143        public void setAttribute( EntryAttribute attribute )
144        {
145            this.attribute = attribute;
146        }
147        
148        
149        /**
150         * @see Object#equals(Object)
151         * @return <code>true</code> if both values are equal
152         */
153        public boolean equals( Object o )
154        {
155            // Basic equals checks
156            if ( this == o )
157            {
158                return true;
159            }
160            
161            if ( ! (o instanceof ClientModification ) )
162            {
163                return false;
164            }
165            
166            Modification otherModification = (ClientModification)o;
167            
168            // Check the operation
169            if ( !operation.equals( otherModification.getOperation() ) )
170            {
171                return false;
172            }
173    
174            
175            // Check the attribute
176            if ( attribute == null )
177            {
178                return otherModification.getAttribute() == null;
179            }
180            
181            return attribute.equals( otherModification.getAttribute() );
182        }
183        
184        
185        /**
186         * Compute the modification @see Object#hashCode
187         * @return the instance's hash code 
188         */
189        public int hashCode()
190        {
191            int h = 37;
192            
193            h += h*17 + operation.getValue();
194            h += h*17 + attribute.hashCode();
195            
196            return h;
197        }
198        
199    
200        /**
201         * @see java.io.Externalizable#readExternal(ObjectInput)
202         */
203        public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
204        {
205            // Read the operation
206            int op = in.readInt();
207            
208            operation = ModificationOperation.getOperation( op );
209            
210            // Read the attribute
211            attribute = (EntryAttribute)in.readObject();
212        }
213        
214        
215        /**
216         * @see java.io.Externalizable#writeExternal(ObjectOutput)
217         */
218        public void writeExternal( ObjectOutput out ) throws IOException
219        {
220            // Write the operation
221            out.writeInt( operation.getValue() );
222            
223            // Write the attribute
224            out.writeObject( attribute );
225            
226            out.flush();
227        }
228        
229        
230        /**
231         * Clone a modification
232         * 
233         * @return  a copied instance of the current modification
234         */
235        public ClientModification clone()
236        {
237            try
238            {
239                ClientModification clone = (ClientModification)super.clone();
240                
241                clone.attribute = this.attribute.clone();
242                return clone;
243            }
244            catch ( CloneNotSupportedException cnse )
245            {
246                return null;
247            }
248        }
249        
250        
251        /**
252         * @see Object#toString()
253         */
254        public String toString()
255        {
256            StringBuilder sb = new StringBuilder();
257            
258            sb.append( "Modification: " ).
259                append( operation ).
260                append( "\n" ).
261                append( ", attribute : " ).
262                append( attribute );
263            
264            return sb.toString();
265        }
266    }