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 */
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    /** A flag used for the target. It default to OFFSET */
059    private boolean targetType = OFFSET;
060
061    private static final boolean OFFSET = true;
062    private static final boolean ASSERTION_VALUE = false;
063
064
065    /**
066     * Creates a new instance of VirtualListViewRequestImpl.
067     */
068    public VirtualListViewRequestImpl()
069    {
070        super( OID );
071    }
072
073
074    /**
075     * {@inheritDoc}
076     */
077    @Override
078    public int getBeforeCount()
079    {
080        return beforeCount;
081    }
082
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public void setBeforeCount( int beforeCount )
089    {
090        this.beforeCount = beforeCount;
091    }
092
093
094    /**
095     * {@inheritDoc}
096     */
097    @Override
098    public int getAfterCount()
099    {
100        return afterCount;
101    }
102
103
104    /**
105     * {@inheritDoc}
106     */
107    @Override
108    public void setAfterCount( int afterCount )
109    {
110        this.afterCount = afterCount;
111    }
112
113
114    /**
115     * {@inheritDoc}
116     */
117    @Override
118    public int getOffset()
119    {
120        return offset;
121    }
122
123
124    /**
125     * {@inheritDoc}
126     */
127    @Override
128    public void setOffset( int offset )
129    {
130        this.offset = offset;
131        targetType = OFFSET;
132    }
133
134
135    /**
136     * {@inheritDoc}
137     */
138    @Override
139    public int getContentCount()
140    {
141        return contentCount;
142    }
143
144
145    /**
146     * {@inheritDoc}
147     */
148    @Override
149    public void setContentCount( int contentCount )
150    {
151        this.contentCount = contentCount;
152    }
153
154
155    /**
156     * {@inheritDoc}
157     */
158    @Override
159    public byte[] getAssertionValue()
160    {
161        return assertionValue;
162    }
163
164
165    /**
166     * {@inheritDoc}
167     */
168    @Override
169    public void setAssertionValue( byte[] assertionValue )
170    {
171        this.assertionValue = assertionValue;
172        targetType = ASSERTION_VALUE;
173    }
174
175
176    /**
177     * {@inheritDoc}
178     */
179    @Override
180    public byte[] getContextId()
181    {
182        return contextId;
183    }
184
185
186    /**
187     * {@inheritDoc}
188     */
189    @Override
190    public void setContextId( byte[] contextId )
191    {
192        this.contextId = contextId;
193    }
194
195
196    /**
197     * {@inheritDoc}
198     */
199    @Override
200    public boolean hasOffset()
201    {
202        return targetType == OFFSET;
203    }
204
205
206    /**
207     * {@inheritDoc}
208     */
209    @Override
210    public boolean hasAssertionValue()
211    {
212        return targetType == ASSERTION_VALUE;
213    }
214
215
216    /**
217     * @see Object#hashCode()
218     */
219    @Override
220    public int hashCode()
221    {
222        int h = super.hashCode();
223
224        h = h * 37 + beforeCount;
225        h = h * 37 + afterCount;
226        h = h * 37 + offset;
227        h = h * 37 + contentCount;
228
229        if ( contextId != null )
230        {
231            for ( byte b : contextId )
232            {
233                h = h * 17 + b;
234            }
235        }
236
237        return h;
238    }
239
240
241    /**
242     * @see Object#equals(Object)
243     */
244    @Override
245    public boolean equals( Object o )
246    {
247        if ( !super.equals( o ) )
248        {
249            return false;
250        }
251
252        VirtualListViewRequestImpl otherControl = ( VirtualListViewRequestImpl ) o;
253
254        return ( beforeCount == otherControl.getBeforeCount() )
255            && ( afterCount == otherControl.getAfterCount() )
256            && ( offset == otherControl.getOffset() )
257            && ( contentCount == otherControl.getContentCount() )
258            && Arrays.equals( contextId, otherControl.getContextId() );
259    }
260
261
262    /**
263     * Return a String representing this VirtualListViewRequestImpl.
264     */
265    @Override
266    public String toString()
267    {
268        StringBuilder sb = new StringBuilder();
269
270        sb.append( "    Virtual List View Request Control\n" );
271        sb.append( "        oid : " ).append( getOid() ).append( '\n' );
272        sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
273        sb.append( "        beforeCount   : '" ).append( beforeCount ).append( "'\n" );
274        sb.append( "        afterCount   : '" ).append( afterCount ).append( "'\n" );
275        sb.append( "        target : \n" );
276
277        if ( targetType == OFFSET )
278        {
279            sb.append( "            offset   : '" ).append( offset ).append( "'\n" );
280            sb.append( "            contentCount   : '" ).append( contentCount ).append( "'\n" );
281        }
282        else
283        {
284            sb.append( "            assertionValue : '" ).append( Strings.utf8ToString( assertionValue ) )
285                .append( "'\n" );
286
287        }
288
289        if ( contextId != null )
290        {
291            sb.append( "        contextID   : '" ).append( Strings.dumpBytes( contextId ) ).append( "'\n" );
292        }
293
294        return sb.toString();
295    }
296}