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 *     https://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
021package org.apache.directory.api.ldap.extras.controls.vlv;
022
023
024import java.util.Arrays;
025
026import org.apache.directory.api.ldap.model.message.controls.AbstractControl;
027import org.apache.directory.api.util.Strings;
028
029
030/**
031 * Virtual List View control as specified in draft-ietf-ldapext-ldapv3-vlv-09.
032 * 
033 *  VirtualListViewRequest ::= SEQUENCE {
034 *         beforeCount    INTEGER (0..maxInt),
035 *         afterCount     INTEGER (0..maxInt),
036 *         target       CHOICE {
037 *                        byOffset        [0] SEQUENCE {
038 *                             offset          INTEGER (1 .. maxInt),
039 *                             contentCount    INTEGER (0 .. maxInt) },
040 *                        greaterThanOrEqual [1] AssertionValue },
041 *         contextID     OCTET STRING OPTIONAL }
042 * 
043 * Simplistic implementation that only supports byOffset choice.
044 *
045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
046 */
047public class VirtualListViewRequestImpl extends AbstractControl implements VirtualListViewRequest
048{
049    private int beforeCount;
050    private int afterCount;
051    private int offset;
052    private int contentCount;
053    private byte[] contextId;
054
055    /** The assertionValue */
056    private byte[] assertionValue;
057
058    private static final boolean OFFSET_CHOICE = true;
059
060    /** A flag used for the target. It default to OFFSET */
061    private boolean targetType = OFFSET_CHOICE;
062
063    private static final boolean ASSERTION_VALUE = false;
064
065
066    /**
067     * Creates a new instance of VirtualListViewRequestImpl.
068     */
069    public VirtualListViewRequestImpl()
070    {
071        super( OID );
072    }
073
074
075    /**
076     * {@inheritDoc}
077     */
078    @Override
079    public int getBeforeCount()
080    {
081        return beforeCount;
082    }
083
084
085    /**
086     * {@inheritDoc}
087     */
088    @Override
089    public void setBeforeCount( int beforeCount )
090    {
091        this.beforeCount = beforeCount;
092    }
093
094
095    /**
096     * {@inheritDoc}
097     */
098    @Override
099    public int getAfterCount()
100    {
101        return afterCount;
102    }
103
104
105    /**
106     * {@inheritDoc}
107     */
108    @Override
109    public void setAfterCount( int afterCount )
110    {
111        this.afterCount = afterCount;
112    }
113
114
115    /**
116     * {@inheritDoc}
117     */
118    @Override
119    public int getOffset()
120    {
121        return offset;
122    }
123
124
125    /**
126     * {@inheritDoc}
127     */
128    @Override
129    public void setOffset( int offset )
130    {
131        this.offset = offset;
132        targetType = OFFSET_CHOICE;
133    }
134
135
136    /**
137     * {@inheritDoc}
138     */
139    @Override
140    public int getContentCount()
141    {
142        return contentCount;
143    }
144
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override
150    public void setContentCount( int contentCount )
151    {
152        this.contentCount = contentCount;
153    }
154
155
156    /**
157     * {@inheritDoc}
158     */
159    @Override
160    public byte[] getAssertionValue()
161    {
162        return assertionValue;
163    }
164
165
166    /**
167     * {@inheritDoc}
168     */
169    @Override
170    public void setAssertionValue( byte[] assertionValue )
171    {
172        this.assertionValue = assertionValue;
173        targetType = ASSERTION_VALUE;
174    }
175
176
177    /**
178     * {@inheritDoc}
179     */
180    @Override
181    public byte[] getContextId()
182    {
183        return contextId;
184    }
185
186
187    /**
188     * {@inheritDoc}
189     */
190    @Override
191    public void setContextId( byte[] contextId )
192    {
193        this.contextId = contextId;
194    }
195
196
197    /**
198     * {@inheritDoc}
199     */
200    @Override
201    public boolean hasOffset()
202    {
203        return targetType == OFFSET_CHOICE;
204    }
205
206
207    /**
208     * {@inheritDoc}
209     */
210    @Override
211    public boolean hasAssertionValue()
212    {
213        return targetType == ASSERTION_VALUE;
214    }
215
216
217    /**
218     * @see Object#hashCode()
219     */
220    @Override
221    public int hashCode()
222    {
223        int h = super.hashCode();
224
225        h = h * 37 + beforeCount;
226        h = h * 37 + afterCount;
227        h = h * 37 + offset;
228        h = h * 37 + contentCount;
229
230        if ( contextId != null )
231        {
232            for ( byte b : contextId )
233            {
234                h = h * 17 + b;
235            }
236        }
237
238        return h;
239    }
240
241
242    /**
243     * @see Object#equals(Object)
244     */
245    @Override
246    public boolean equals( Object o )
247    {
248        if ( this == o )
249        {
250            return true;
251        }
252        
253        if ( !( o instanceof VirtualListViewRequest ) )
254        {
255            return false;
256        }
257
258        VirtualListViewRequest otherControl = ( VirtualListViewRequest ) o;
259
260        return super.equals( o )
261            && ( beforeCount == otherControl.getBeforeCount() )
262            && ( afterCount == otherControl.getAfterCount() )
263            && ( offset == otherControl.getOffset() )
264            && ( contentCount == otherControl.getContentCount() )
265            && Arrays.equals( contextId, otherControl.getContextId() );
266    }
267
268
269    /**
270     * Return a String representing this VirtualListViewRequestImpl.
271     */
272    @Override
273    public String toString()
274    {
275        StringBuilder sb = new StringBuilder();
276
277        sb.append( "    Virtual List View Request Control\n" );
278        sb.append( "        oid : " ).append( getOid() ).append( '\n' );
279        sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
280        sb.append( "        beforeCount   : '" ).append( beforeCount ).append( "'\n" );
281        sb.append( "        afterCount   : '" ).append( afterCount ).append( "'\n" );
282        sb.append( "        target : \n" );
283
284        if ( targetType == OFFSET_CHOICE )
285        {
286            sb.append( "            offset   : '" ).append( offset ).append( "'\n" );
287            sb.append( "            contentCount   : '" ).append( contentCount ).append( "'\n" );
288        }
289        else
290        {
291            sb.append( "            assertionValue : '" ).append( Strings.utf8ToString( assertionValue ) )
292                .append( "'\n" );
293
294        }
295
296        if ( contextId != null )
297        {
298            sb.append( "        contextID   : '" ).append( Strings.dumpBytes( contextId ) ).append( "'\n" );
299        }
300
301        return sb.toString();
302    }
303}