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.message;
021    
022    
023    import java.util.ArrayList;
024    import java.util.Collection;
025    import java.util.Collections;
026    import java.util.Iterator;
027    import java.util.List;
028    
029    import org.apache.directory.shared.ldap.codec.MessageTypeEnum;
030    import org.apache.directory.shared.ldap.entry.Modification;
031    import org.apache.directory.shared.ldap.entry.client.ClientModification;
032    import org.apache.directory.shared.ldap.message.internal.InternalModifyRequest;
033    import org.apache.directory.shared.ldap.message.internal.InternalModifyResponse;
034    import org.apache.directory.shared.ldap.message.internal.InternalResultResponse;
035    import org.apache.directory.shared.ldap.name.DN;
036    import org.slf4j.Logger;
037    import org.slf4j.LoggerFactory;
038    
039    
040    /**
041     * Lockable ModifyRequest implementation.
042     * 
043     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
044     * @version $Rev: 918756 $
045     */
046    public class ModifyRequestImpl extends AbstractAbandonableRequest implements InternalModifyRequest
047    {
048        static final long serialVersionUID = -505803669028990304L;
049    
050        /** The logger */
051        private static final transient Logger LOG = LoggerFactory.getLogger( ModifyRequestImpl.class );
052    
053        /** Dn of the entry to modify or PDU's <b>object</b> field */
054        private DN name;
055    
056        /** Sequence of modifications or PDU's <b>modification</b> seqence field */
057        private List<Modification> mods = new ArrayList<Modification>();
058    
059        private InternalModifyResponse response;
060    
061    
062        // ------------------------------------------------------------------------
063        // Constructors
064        // ------------------------------------------------------------------------
065    
066        /**
067         * Creates a Lockable ModifyRequest implementing object used to modify the
068         * attributes of an entry.
069         * 
070         * @param id
071         *            the sequential message identifier
072         */
073        public ModifyRequestImpl(final int id)
074        {
075            super( id, TYPE );
076        }
077    
078    
079        // ------------------------------------------------------------------------
080        // ModifyRequest Interface Method Implementations
081        // ------------------------------------------------------------------------
082        /**
083         * Gets an immutable Collection of modification items representing the
084         * atomic changes to perform on the candidate entry to modify.
085         * 
086         * @return an immutable Collection of Modification instances.
087         */
088        public Collection<Modification> getModificationItems()
089        {
090            return Collections.unmodifiableCollection( mods );
091        }
092    
093    
094        /**
095         * Gets the distinguished name of the entry to be modified by this request.
096         * This property represents the PDU's <b>object</b> field.
097         * 
098         * @return the DN of the modified entry.
099         */
100        public DN getName()
101        {
102            return name;
103        }
104    
105    
106        /**
107         * Sets the distinguished name of the entry to be modified by this request.
108         * This property represents the PDU's <b>object</b> field.
109         * 
110         * @param name
111         *            the DN of the modified entry.
112         */
113        public void setName( DN name )
114        {
115            this.name = name;
116        }
117    
118    
119        /**
120         * Adds a Modification to the set of modifications composing this modify
121         * request.
122         * 
123         * @param mod a Modification to add
124         */
125        public void addModification( Modification mod )
126        {
127            mods.add( mod );
128        }
129    
130    
131        /**
132         * Removes a Modification to the set of modifications composing this
133         * modify request.
134         * 
135         * @param mod a Modification to remove.
136         */
137        public void removeModification( Modification mod )
138        {
139            mods.remove( mod );
140        }
141    
142    
143        // ------------------------------------------------------------------------
144        // SingleReplyRequest Interface Method Implementations
145        // ------------------------------------------------------------------------
146    
147        /**
148         * Gets the protocol response message type for this request which produces
149         * at least one response.
150         * 
151         * @return the message type of the response.
152         */
153        public MessageTypeEnum getResponseType()
154        {
155            return RESP_TYPE;
156        }
157    
158    
159        /**
160         * The result containing response for this request.
161         * 
162         * @return the result containing response for this request
163         */
164        public InternalResultResponse getResultResponse()
165        {
166            if ( response == null )
167            {
168                response = new ModifyResponseImpl( getMessageId() );
169            }
170    
171            return response;
172        }
173    
174    
175        /**
176         * Checks to see if ModifyRequest stub equals another by factoring in checks
177         * for the name and modification items of the request.
178         * 
179         * @param obj
180         *            the object to compare this ModifyRequest to
181         * @return true if obj equals this ModifyRequest, false otherwise
182         */
183        public boolean equals( Object obj )
184        {
185            if ( obj == this )
186            {
187                return true;
188            }
189    
190            if ( !super.equals( obj ) )
191            {
192                return false;
193            }
194    
195            InternalModifyRequest req = ( InternalModifyRequest ) obj;
196    
197            if ( name != null && req.getName() == null )
198            {
199                return false;
200            }
201    
202            if ( name == null && req.getName() != null )
203            {
204                return false;
205            }
206    
207            if ( name != null && req.getName() != null )
208            {
209                if ( !name.equals( req.getName() ) )
210                {
211                    return false;
212                }
213            }
214    
215            if ( req.getModificationItems().size() != mods.size() )
216            {
217                return false;
218            }
219    
220            Iterator<Modification> list = req.getModificationItems().iterator();
221    
222            for ( int i = 0; i < mods.size(); i++ )
223            {
224                Modification item = list.next();
225    
226                if ( item == null )
227                {
228                    if ( mods.get( i ) != null )
229                    {
230                        return false;
231                    }
232                }
233                else
234                    
235                if ( !item.equals((ClientModification) mods.get( i ) ) )
236                {
237                    return false;
238                }
239            }
240    
241            return true;
242        }
243    
244    
245        /**
246         * Get a String representation of a ModifyRequest
247         * 
248         * @return A ModifyRequest String
249         */
250        public String toString()
251        {
252    
253            StringBuffer sb = new StringBuffer();
254    
255            sb.append( "    Modify Request\n" );
256            sb.append( "        Object : '" ).append( name ).append( "'\n" );
257    
258            if ( mods != null )
259            {
260    
261                for ( int i = 0; i < mods.size(); i++ )
262                {
263    
264                    ClientModification modification = ( ClientModification ) mods.get( i );
265    
266                    sb.append( "            Modification[" ).append( i ).append( "]\n" );
267                    sb.append( "                Operation : " );
268    
269                    switch ( modification.getOperation() )
270                    {
271                        case ADD_ATTRIBUTE:
272                            sb.append( " add\n" );
273                            break;
274    
275                        case REPLACE_ATTRIBUTE:
276                            sb.append( " replace\n" );
277                            break;
278    
279                        case REMOVE_ATTRIBUTE:
280                            sb.append( " delete\n" );
281                            break;
282                    }
283    
284                    sb.append( "                Modification\n" );
285                    sb.append( modification.getAttribute() );
286                }
287            }
288    
289            return sb.toString();
290        }
291    }