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 */
020package org.apache.directory.api.ldap.model.message;
021
022
023import org.apache.directory.api.ldap.model.entry.Attribute;
024import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
025import org.apache.directory.api.ldap.model.entry.DefaultEntry;
026import org.apache.directory.api.ldap.model.entry.Entry;
027import org.apache.directory.api.ldap.model.entry.Value;
028import org.apache.directory.api.ldap.model.exception.LdapException;
029import org.apache.directory.api.ldap.model.name.Dn;
030
031
032/**
033 * Lockable add request implementation.
034 * 
035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
036 */
037public class AddRequestImpl extends AbstractAbandonableRequest implements AddRequest
038{
039    static final long serialVersionUID = 7534132448349520346L;
040
041    /** A MultiMap of the new entry's attributes and their values */
042    private Entry entry;
043
044    private AddResponse response;
045
046    /** The current attribute being decoded */
047    private Attribute currentAttribute;
048
049
050    // ------------------------------------------------------------------------
051    // Constructors
052    // ------------------------------------------------------------------------
053
054    /**
055     * Creates an AddRequest implementation to create a new entry.
056     */
057    public AddRequestImpl()
058    {
059        super( -1, MessageTypeEnum.ADD_REQUEST );
060        entry = new DefaultEntry();
061    }
062
063
064    /**
065     * Create a new attributeValue
066     * 
067     * @param type The attribute's name (called 'type' in the grammar)
068     * @throws LdapException If the type can't be added
069     */
070    public void addAttributeType( String type ) throws LdapException
071    {
072        // do not create a new attribute if we have seen this attributeType before
073        if ( entry.get( type ) != null )
074        {
075            currentAttribute = entry.get( type );
076            return;
077        }
078
079        // fix this to use AttributeImpl(type.getString().toLowerCase())
080        currentAttribute = new DefaultAttribute( type );
081        entry.put( currentAttribute );
082    }
083
084
085    /**
086     * @return Returns the currentAttribute type.
087     */
088    public String getCurrentAttributeType()
089    {
090        return currentAttribute.getId();
091    }
092
093
094    /**
095     * Add a new value to the current attribute
096     * 
097     * @param value The value to add
098     * @throws LdapException If the value can't be added
099     */
100    public void addAttributeValue( String value ) throws LdapException
101    {
102        currentAttribute.add( value );
103    }
104
105
106    /**
107     * Add a new value to the current attribute
108     * 
109     * @param value The value to add
110     * @throws LdapException If the value can't be added
111     */
112    public void addAttributeValue( Value<?> value ) throws LdapException
113    {
114        currentAttribute.add( value );
115    }
116
117
118    /**
119     * Add a new value to the current attribute
120     * 
121     * @param value The value to add
122     * @throws LdapException If the value can't be added
123     */
124    public void addAttributeValue( byte[] value ) throws LdapException
125    {
126        currentAttribute.add( value );
127    }
128
129
130    // ------------------------------------------------------------------------
131    // AddRequest Interface Method Implementations
132    // ------------------------------------------------------------------------
133
134    /**
135     * Gets the distinguished name of the entry to add.
136     * 
137     * @return the Dn of the added entry.
138     */
139    @Override
140    public Dn getEntryDn()
141    {
142        return entry.getDn();
143    }
144
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override
150    public AddRequest setEntryDn( Dn dn )
151    {
152        entry.setDn( dn );
153
154        return this;
155    }
156
157
158    /**
159     * {@inheritDoc}
160     */
161    @Override
162    public Entry getEntry()
163    {
164        return entry;
165    }
166
167
168    /**
169     * {@inheritDoc}
170     */
171    @Override
172    public AddRequest setEntry( Entry entry )
173    {
174        this.entry = entry;
175
176        return this;
177    }
178
179
180    /**
181     * {@inheritDoc}
182     */
183    @Override
184    public AddRequest setMessageId( int messageId )
185    {
186        super.setMessageId( messageId );
187
188        return this;
189    }
190
191
192    /**
193     * {@inheritDoc}
194     */
195    @Override
196    public AddRequest addControl( Control control )
197    {
198        return ( AddRequest ) super.addControl( control );
199    }
200
201
202    /**
203     * {@inheritDoc}
204     */
205    @Override
206    public AddRequest addAllControls( Control[] controls )
207    {
208        return ( AddRequest ) super.addAllControls( controls );
209    }
210
211
212    /**
213     * {@inheritDoc}
214     */
215    @Override
216    public AddRequest removeControl( Control control )
217    {
218        return ( AddRequest ) super.removeControl( control );
219    }
220
221
222    // ------------------------------------------------------------------------
223    // SingleReplyRequest Interface Method Implementations
224    // ------------------------------------------------------------------------
225
226    /**
227     * Gets the protocol response message type for this request which produces
228     * at least one response.
229     * 
230     * @return the message type of the response.
231     */
232    @Override
233    public MessageTypeEnum getResponseType()
234    {
235        return MessageTypeEnum.ADD_RESPONSE;
236    }
237
238
239    /**
240     * The result containing response for this request.
241     * 
242     * @return the result containing response for this request
243     */
244    @Override
245    public AddResponse getResultResponse()
246    {
247        if ( response == null )
248        {
249            response = new AddResponseImpl( getMessageId() );
250        }
251
252        return response;
253    }
254
255
256    /**
257     * Checks to see if an object is equivalent to this AddRequest. First
258     * there's a quick test to see if the obj is the same object as this one -
259     * if so true is returned. Next if the super method fails false is returned.
260     * Then the name of the entry is compared - if not the same false is
261     * returned. Lastly the attributes of the entry are compared. If they are
262     * not the same false is returned otherwise the method exists returning
263     * true.
264     * 
265     * @param obj the object to test for equality to this
266     * @return true if the obj is equal to this AddRequest, false otherwise
267     */
268    @Override
269    public boolean equals( Object obj )
270    {
271        // Short circuit
272        if ( this == obj )
273        {
274            return true;
275        }
276
277        // Check the object class. If null, it will exit.
278        if ( !( obj instanceof AddRequest ) )
279        {
280            return false;
281        }
282
283        if ( !super.equals( obj ) )
284        {
285            return false;
286        }
287
288        AddRequest req = ( AddRequest ) obj;
289
290        // Check the entry
291        if ( entry == null )
292        {
293            return req.getEntry() == null;
294        }
295        else
296        {
297            return entry.equals( req.getEntry() );
298        }
299    }
300
301
302    /**
303     * @see Object#hashCode()
304     * @return the instance's hash code 
305     */
306    @Override
307    public int hashCode()
308    {
309        int hash = 37;
310        hash = hash * 17 + ( entry == null ? 0 : entry.hashCode() );
311        hash = hash * 17 + ( response == null ? 0 : response.hashCode() );
312        hash = hash * 17 + super.hashCode();
313
314        return hash;
315    }
316
317
318    /**
319     * @see Object#toString()
320     */
321    @Override
322    public String toString()
323    {
324        StringBuilder sb = new StringBuilder();
325
326        sb.append( "    Add Request :\n" );
327
328        if ( entry == null )
329        {
330            sb.append( "            No entry\n" );
331        }
332        else
333        {
334            sb.append( entry.toString() );
335        }
336
337        return super.toString( sb.toString() );
338    }
339}