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     */
069    public void addAttributeType( String type ) throws LdapException
070    {
071        // do not create a new attribute if we have seen this attributeType before
072        if ( entry.get( type ) != null )
073        {
074            currentAttribute = entry.get( type );
075            return;
076        }
077
078        // fix this to use AttributeImpl(type.getString().toLowerCase())
079        currentAttribute = new DefaultAttribute( type );
080        entry.put( currentAttribute );
081    }
082
083
084    /**
085     * @return Returns the currentAttribute type.
086     */
087    public String getCurrentAttributeType()
088    {
089        return currentAttribute.getId();
090    }
091
092
093    /**
094     * Add a new value to the current attribute
095     * 
096     * @param value The value to add
097     */
098    public void addAttributeValue( String value ) throws LdapException
099    {
100        currentAttribute.add( value );
101    }
102
103
104    /**
105     * Add a new value to the current attribute
106     * 
107     * @param value The value to add
108     */
109    public void addAttributeValue( Value<?> value ) throws LdapException
110    {
111        currentAttribute.add( value );
112    }
113
114
115    /**
116     * Add a new value to the current attribute
117     * 
118     * @param value The value to add
119     */
120    public void addAttributeValue( byte[] value ) throws LdapException
121    {
122        currentAttribute.add( value );
123    }
124
125
126    // ------------------------------------------------------------------------
127    // AddRequest Interface Method Implementations
128    // ------------------------------------------------------------------------
129
130    /**
131     * Gets the distinguished name of the entry to add.
132     * 
133     * @return the Dn of the added entry.
134     */
135    public Dn getEntryDn()
136    {
137        return entry.getDn();
138    }
139
140
141    /**
142     * {@inheritDoc}
143     */
144    public AddRequest setEntryDn( Dn dn )
145    {
146        entry.setDn( dn );
147
148        return this;
149    }
150
151
152    /**
153     * {@inheritDoc}
154     */
155    public Entry getEntry()
156    {
157        return entry;
158    }
159
160
161    /**
162     * {@inheritDoc}
163     */
164    public AddRequest setEntry( Entry entry )
165    {
166        this.entry = entry;
167
168        return this;
169    }
170
171
172    /**
173     * {@inheritDoc}
174     */
175    public AddRequest setMessageId( int messageId )
176    {
177        super.setMessageId( messageId );
178
179        return this;
180    }
181
182
183    /**
184     * {@inheritDoc}
185     */
186    public AddRequest addControl( Control control )
187    {
188        return ( AddRequest ) super.addControl( control );
189    }
190
191
192    /**
193     * {@inheritDoc}
194     */
195    public AddRequest addAllControls( Control[] controls )
196    {
197        return ( AddRequest ) super.addAllControls( controls );
198    }
199
200
201    /**
202     * {@inheritDoc}
203     */
204    public AddRequest removeControl( Control control )
205    {
206        return ( AddRequest ) super.removeControl( control );
207    }
208
209
210    // ------------------------------------------------------------------------
211    // SingleReplyRequest Interface Method Implementations
212    // ------------------------------------------------------------------------
213
214    /**
215     * Gets the protocol response message type for this request which produces
216     * at least one response.
217     * 
218     * @return the message type of the response.
219     */
220    public MessageTypeEnum getResponseType()
221    {
222        return MessageTypeEnum.ADD_RESPONSE;
223    }
224
225
226    /**
227     * The result containing response for this request.
228     * 
229     * @return the result containing response for this request
230     */
231    public AddResponse getResultResponse()
232    {
233        if ( response == null )
234        {
235            response = new AddResponseImpl( getMessageId() );
236        }
237
238        return response;
239    }
240
241
242    /**
243     * Checks to see if an object is equivalent to this AddRequest. First
244     * there's a quick test to see if the obj is the same object as this one -
245     * if so true is returned. Next if the super method fails false is returned.
246     * Then the name of the entry is compared - if not the same false is
247     * returned. Lastly the attributes of the entry are compared. If they are
248     * not the same false is returned otherwise the method exists returning
249     * true.
250     * 
251     * @param obj the object to test for equality to this
252     * @return true if the obj is equal to this AddRequest, false otherwise
253     */
254    public boolean equals( Object obj )
255    {
256        // Short circuit
257        if ( this == obj )
258        {
259            return true;
260        }
261
262        // Check the object class. If null, it will exit.
263        if ( !( obj instanceof AddRequest ) )
264        {
265            return false;
266        }
267
268        if ( !super.equals( obj ) )
269        {
270            return false;
271        }
272
273        AddRequest req = ( AddRequest ) obj;
274
275        // Check the entry
276        if ( entry == null )
277        {
278            return ( req.getEntry() == null );
279        }
280        else
281        {
282            return ( entry.equals( req.getEntry() ) );
283        }
284    }
285
286
287    /**
288     * @see Object#hashCode()
289     * @return the instance's hash code 
290     */
291    public int hashCode()
292    {
293        int hash = 37;
294        hash = hash * 17 + ( entry == null ? 0 : entry.hashCode() );
295        hash = hash * 17 + ( response == null ? 0 : response.hashCode() );
296        hash = hash * 17 + super.hashCode();
297
298        return hash;
299    }
300
301
302    /**
303     * @see Object#toString()
304     */
305    public String toString()
306    {
307        StringBuilder sb = new StringBuilder();
308
309        sb.append( "    Add Request :\n" );
310
311        if ( entry == null )
312        {
313            sb.append( "            No entry\n" );
314        }
315        else
316        {
317            sb.append( entry.toString() );
318        }
319
320        return super.toString( sb.toString() );
321    }
322}