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    public Dn getEntryDn()
140    {
141        return entry.getDn();
142    }
143
144
145    /**
146     * {@inheritDoc}
147     */
148    public AddRequest setEntryDn( Dn dn )
149    {
150        entry.setDn( dn );
151
152        return this;
153    }
154
155
156    /**
157     * {@inheritDoc}
158     */
159    public Entry getEntry()
160    {
161        return entry;
162    }
163
164
165    /**
166     * {@inheritDoc}
167     */
168    public AddRequest setEntry( Entry entry )
169    {
170        this.entry = entry;
171
172        return this;
173    }
174
175
176    /**
177     * {@inheritDoc}
178     */
179    public AddRequest setMessageId( int messageId )
180    {
181        super.setMessageId( messageId );
182
183        return this;
184    }
185
186
187    /**
188     * {@inheritDoc}
189     */
190    public AddRequest addControl( Control control )
191    {
192        return ( AddRequest ) super.addControl( control );
193    }
194
195
196    /**
197     * {@inheritDoc}
198     */
199    public AddRequest addAllControls( Control[] controls )
200    {
201        return ( AddRequest ) super.addAllControls( controls );
202    }
203
204
205    /**
206     * {@inheritDoc}
207     */
208    public AddRequest removeControl( Control control )
209    {
210        return ( AddRequest ) super.removeControl( control );
211    }
212
213
214    // ------------------------------------------------------------------------
215    // SingleReplyRequest Interface Method Implementations
216    // ------------------------------------------------------------------------
217
218    /**
219     * Gets the protocol response message type for this request which produces
220     * at least one response.
221     * 
222     * @return the message type of the response.
223     */
224    public MessageTypeEnum getResponseType()
225    {
226        return MessageTypeEnum.ADD_RESPONSE;
227    }
228
229
230    /**
231     * The result containing response for this request.
232     * 
233     * @return the result containing response for this request
234     */
235    public AddResponse getResultResponse()
236    {
237        if ( response == null )
238        {
239            response = new AddResponseImpl( getMessageId() );
240        }
241
242        return response;
243    }
244
245
246    /**
247     * Checks to see if an object is equivalent to this AddRequest. First
248     * there's a quick test to see if the obj is the same object as this one -
249     * if so true is returned. Next if the super method fails false is returned.
250     * Then the name of the entry is compared - if not the same false is
251     * returned. Lastly the attributes of the entry are compared. If they are
252     * not the same false is returned otherwise the method exists returning
253     * true.
254     * 
255     * @param obj the object to test for equality to this
256     * @return true if the obj is equal to this AddRequest, false otherwise
257     */
258    public boolean equals( Object obj )
259    {
260        // Short circuit
261        if ( this == obj )
262        {
263            return true;
264        }
265
266        // Check the object class. If null, it will exit.
267        if ( !( obj instanceof AddRequest ) )
268        {
269            return false;
270        }
271
272        if ( !super.equals( obj ) )
273        {
274            return false;
275        }
276
277        AddRequest req = ( AddRequest ) obj;
278
279        // Check the entry
280        if ( entry == null )
281        {
282            return ( req.getEntry() == null );
283        }
284        else
285        {
286            return ( entry.equals( req.getEntry() ) );
287        }
288    }
289
290
291    /**
292     * @see Object#hashCode()
293     * @return the instance's hash code 
294     */
295    public int hashCode()
296    {
297        int hash = 37;
298        hash = hash * 17 + ( entry == null ? 0 : entry.hashCode() );
299        hash = hash * 17 + ( response == null ? 0 : response.hashCode() );
300        hash = hash * 17 + super.hashCode();
301
302        return hash;
303    }
304
305
306    /**
307     * @see Object#toString()
308     */
309    public String toString()
310    {
311        StringBuilder sb = new StringBuilder();
312
313        sb.append( "    Add Request :\n" );
314
315        if ( entry == null )
316        {
317            sb.append( "            No entry\n" );
318        }
319        else
320        {
321            sb.append( entry.toString() );
322        }
323
324        return super.toString( sb.toString() );
325    }
326}