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.BinaryValue;
024import org.apache.directory.api.ldap.model.entry.StringValue;
025import org.apache.directory.api.ldap.model.entry.Value;
026import org.apache.directory.api.ldap.model.name.Dn;
027import org.apache.directory.api.util.Strings;
028
029
030/**
031 * Comparison request implementation.
032 * 
033 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
034 */
035public class CompareRequestImpl extends AbstractAbandonableRequest implements CompareRequest
036{
037    static final long serialVersionUID = 1699731530016468977L;
038
039    /** Distinguished name identifying the compared entry */
040    private Dn name;
041
042    /** The id of the attribute used in the comparison */
043    private String attrId;
044
045    /** The value of the attribute used in the comparison */
046    private Value<?> attrVal;
047
048    /** The associated response */
049    private CompareResponse response;
050
051
052    // ------------------------------------------------------------------------
053    // Constructors
054    // ------------------------------------------------------------------------
055    /**
056     * Creates an CompareRequest implementation to compare a named entry with an
057     * attribute value assertion pair.
058     */
059    public CompareRequestImpl()
060    {
061        super( -1, MessageTypeEnum.COMPARE_REQUEST );
062    }
063
064
065    // ------------------------------------------------------------------------
066    // ComparisonRequest Interface Method Implementations
067    // ------------------------------------------------------------------------
068
069    /**
070     * Gets the distinguished name of the entry to be compared using the
071     * attribute value assertion.
072     * 
073     * @return the Dn of the compared entry.
074     */
075    @Override
076    public Dn getName()
077    {
078        return name;
079    }
080
081
082    /**
083     * {@inheritDoc}
084     */
085    @Override
086    public CompareRequest setName( Dn name )
087    {
088        this.name = name;
089
090        return this;
091    }
092
093
094    /**
095     * Gets the attribute value to use in making the comparison.
096     * 
097     * @return the attribute value to used in comparison.
098     */
099    @Override
100    public Value<?> getAssertionValue()
101    {
102        return attrVal;
103    }
104
105
106    /**
107     * {@inheritDoc}
108     */
109    @Override
110    public CompareRequest setAssertionValue( String value )
111    {
112        this.attrVal = new StringValue( value );
113
114        return this;
115    }
116
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public CompareRequest setAssertionValue( byte[] value )
123    {
124        if ( value != null )
125        {
126            this.attrVal = new BinaryValue( value );
127        }
128        else
129        {
130            this.attrVal = null;
131        }
132
133        return this;
134    }
135
136
137    /**
138     * Gets the attribute id use in making the comparison.
139     * 
140     * @return the attribute id used in comparison.
141     */
142    @Override
143    public String getAttributeId()
144    {
145        return attrId;
146    }
147
148
149    /**
150     * {@inheritDoc}
151     */
152    @Override
153    public CompareRequest setAttributeId( String attributeId )
154    {
155        this.attrId = attributeId;
156
157        return this;
158    }
159
160
161    /**
162     * {@inheritDoc}
163     */
164    @Override
165    public CompareRequest setMessageId( int messageId )
166    {
167        super.setMessageId( messageId );
168
169        return this;
170    }
171
172
173    /**
174     * {@inheritDoc}
175     */
176    @Override
177    public CompareRequest addControl( Control control )
178    {
179        return ( CompareRequest ) super.addControl( control );
180    }
181
182
183    /**
184     * {@inheritDoc}
185     */
186    @Override
187    public CompareRequest addAllControls( Control[] controls )
188    {
189        return ( CompareRequest ) super.addAllControls( controls );
190    }
191
192
193    /**
194     * {@inheritDoc}
195     */
196    @Override
197    public CompareRequest removeControl( Control control )
198    {
199        return ( CompareRequest ) super.removeControl( control );
200    }
201
202
203    // ------------------------------------------------------------------------
204    // SingleReplyRequest Interface Method Implementations
205    // ------------------------------------------------------------------------
206
207    /**
208     * Gets the protocol response message type for this request which produces
209     * at least one response.
210     * 
211     * @return the message type of the response.
212     */
213    @Override
214    public MessageTypeEnum getResponseType()
215    {
216        return MessageTypeEnum.COMPARE_RESPONSE;
217    }
218
219
220    /**
221     * The result containing response for this request.
222     * 
223     * @return the result containing response for this request
224     */
225    @Override
226    public CompareResponse getResultResponse()
227    {
228        if ( response == null )
229        {
230            response = new CompareResponseImpl( getMessageId() );
231        }
232
233        return response;
234    }
235
236
237    /**
238     * {@inheritDoc}
239     */
240    @Override
241    public int hashCode()
242    {
243        int hash = 37;
244        if ( name != null )
245        {
246            hash = hash * 17 + name.hashCode();
247        }
248        if ( attrId != null )
249        {
250            hash = hash * 17 + attrId.hashCode();
251        }
252        if ( attrVal != null )
253        {
254            hash = hash * 17 + attrVal.hashCode();
255        }
256        Value<?> reqVal = getAssertionValue();
257        if ( reqVal != null )
258        {
259            hash = hash * 17 + reqVal.hashCode();
260        }
261        hash = hash * 17 + super.hashCode();
262
263        return hash;
264    }
265
266
267    /**
268     * Checks to see if an object is equivalent to this CompareRequest.
269     * 
270     * @param obj the obj to compare with this CompareRequest
271     * @return true if the obj is equal to this request, false otherwise
272     */
273    @Override
274    public boolean equals( Object obj )
275    {
276        if ( obj == this )
277        {
278            return true;
279        }
280
281        if ( !super.equals( obj ) )
282        {
283            return false;
284        }
285
286        CompareRequest req = ( CompareRequest ) obj;
287        Dn reqName = req.getName();
288        
289        if ( ( name != null ) && ( reqName == null ) )
290        {
291            return false;
292        }
293
294        if ( ( name == null ) && ( reqName != null ) )
295            {
296                return false;
297            }
298
299        if ( ( name != null ) && ( reqName != null ) && !name.equals( req.getName() ) )
300        {
301                return false;
302            }
303
304        String reqId = req.getAttributeId();
305
306        if ( ( attrId != null ) && ( reqId == null ) )
307        {
308            return false;
309        }
310
311        if ( ( attrId == null ) && ( reqId != null ) )
312            {
313                return false;
314            }
315
316        if ( ( attrId != null ) && ( reqId != null ) && !attrId.equals( reqId ) )
317        {
318                return false;
319            }
320
321        Value<?> reqVal = req.getAssertionValue();
322
323        if ( attrVal != null )
324        {
325            if ( reqVal != null )
326            {
327                return attrVal.equals( reqVal );
328            }
329            else
330            {
331                return false;
332            }
333        }
334        else
335        {
336            return reqVal == null;
337        }
338    }
339
340
341    /**
342     * Get a String representation of a Compare Request
343     * 
344     * @return A Compare Request String
345     */
346    @Override
347    public String toString()
348    {
349        StringBuilder sb = new StringBuilder();
350
351        sb.append( "    Compare request\n" );
352        sb.append( "        Entry : '" ).append( name.toString() ).append( "'\n" );
353        sb.append( "        Attribute description : '" ).append( attrId ).append( "'\n" );
354        sb.append( "        Attribute value : '" );
355
356        if ( attrVal.isHumanReadable() )
357        {
358            sb.append( attrVal.getValue() );
359        }
360        else
361        {
362            byte[] binVal = attrVal.getBytes();
363            sb.append( Strings.utf8ToString( binVal ) ).append( '/' ).append( Strings.dumpBytes( binVal ) )
364                .append( "'\n" );
365        }
366
367        // The controls
368        sb.append( super.toString() );
369
370        return super.toString( sb.toString() );
371    }
372}