Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 17BBC11DA3 for ; Wed, 16 Apr 2014 08:12:40 +0000 (UTC) Received: (qmail 35418 invoked by uid 500); 16 Apr 2014 08:12:39 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 35347 invoked by uid 500); 16 Apr 2014 08:12:38 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 35335 invoked by uid 99); 16 Apr 2014 08:12:38 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Apr 2014 08:12:38 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Apr 2014 08:12:33 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BD11A238889B; Wed, 16 Apr 2014 08:12:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1587828 - in /directory/shared/trunk/ldap/extras: codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/ codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/ codec/src/test/java/org/apache/directory/api/... Date: Wed, 16 Apr 2014 08:12:13 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140416081213.BD11A238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Wed Apr 16 08:12:12 2014 New Revision: 1587828 URL: http://svn.apache.org/r1587828 Log: Added the AdDirSync control (the first part. The response will come later) Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSync.java directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncImpl.java directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponse.java directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponseImpl.java directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncContainer.java directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncDecorator.java directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncFactory.java directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncGrammar.java directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncStatesEnum.java directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/ directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncControlTest.java Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSync.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSync.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSync.java (added) +++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSync.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + +import org.apache.directory.api.ldap.model.message.Control; + +/** + * The DirSync control, as described in http://tools.ietf.org/html/draft-armijo-ldap-dirsync-00. + * We use the same control for both the SearchRequest and the SearchResultDone. Here is the + * ASN/1 description of the SearchRequest control : + * + *
+ * Repl    Control ::= SEQUENCE {
+ *     controlType             1.2.840.113556.1.4.841
+ *     controlValue            replControlValue
+ *     criticality             TRUE
+ * }
+ * 
+ * realReplControlValue ::= SEQUENCE {
+ *     parentsFirst            integer
+ *     maxAttributeCount       integer
+ *     cookie                  OCTET STRING
+ * }
+ * 
+ * + * @author Apache Directory Project + * + */ +public interface AdDirSync extends Control +{ + + /** This control OID */ + static final String OID = "1.3.6.1.4.1.4203.1.9.1.3"; + + /** + * @return 1 if the parents are guaranteed to be returned before the children. + */ + int getParentFirst(); + + + /** + * @param parentFirst The parentFirst flag. A value of 1 will tell the server to return the parents first. + */ + void setParentFirst( int parentFirst ); + + + /** + * @return The maximum number of attributes to be returned + */ + int getMaxAttributeCount(); + + + /** + * @param maxAttributeCount The maximum number of attributes to be returned + */ + void setMaxAttributeCount( int maxAttributeCount ); + + + /** + * @return The cookie used while processing the successive DirSync operations + */ + byte[] getCookie(); + + + /** + * @param cookie The cookie to send to the server. It's the value found in the response control. Should be null + * for the first control. + */ + void setCookie( byte[] cookie ); +} Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncImpl.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncImpl.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncImpl.java (added) +++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncImpl.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.directory.api.ldap.extras.controls.ad; + +import java.util.Arrays; + +import org.apache.directory.api.ldap.extras.controls.syncrepl.syncDone.SyncDoneValue; +import org.apache.directory.api.ldap.model.message.controls.AbstractControl; +import org.apache.directory.api.util.Strings; + +/** + * + * @author Apache Directory Project + */ +public class AdDirSyncImpl extends AbstractControl implements AdDirSync +{ + /** A flag used to tell the server to return the parent before the children */ + int parentFirst = 1; + + /** The maximum number of attributes to return */ + int maxAttributeCount = 0; + + /** The DirSync cookie */ + private byte[] cookie; + + /** + * Creates an instance of the DirSync control + */ + public AdDirSyncImpl() + { + super( OID, Boolean.TRUE ); + } + + + /** + * {@inheritDoc} + */ + public int getParentFirst() + { + return parentFirst; + } + + + /** + * {@inheritDoc} + */ + public void setParentFirst( int parentFirst ) + { + this.parentFirst = parentFirst; + } + + + /** + * {@inheritDoc} + */ + public int getMaxAttributeCount() + { + return maxAttributeCount; + } + + + /** + * {@inheritDoc} + */ + public void setMaxAttributeCount( int maxAttributeCount ) + { + this.maxAttributeCount = maxAttributeCount; + } + + + /** + * {@inheritDoc} + */ + public byte[] getCookie() + { + return cookie; + } + + + /** + * {@inheritDoc} + */ + public void setCookie( byte[] cookie ) + { + this.cookie = cookie; + } + + + /** + * @see Object#hashCode() + */ + @Override + public int hashCode() + { + int h = 37; + + h = h * 17 + super.hashCode(); + h = h * 17 + parentFirst; + h = h * 17 + maxAttributeCount; + + if ( cookie != null ) + { + for ( byte b : cookie ) + { + h = h * 17 + b; + } + } + + return h; + } + + + /** + * @see Object#equals(Object) + */ + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + + if ( !( o instanceof AdDirSync ) ) + { + return false; + } + + AdDirSync otherControl = ( AdDirSync ) o; + + return ( maxAttributeCount == otherControl.getMaxAttributeCount() ) && + ( parentFirst == otherControl.getParentFirst() ) && + ( Arrays.equals( cookie, otherControl.getCookie() ) && + ( isCritical() == otherControl.isCritical() ) ); + } + + + /** + * @see Object#toString() + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( " DirSync control :\n" ); + sb.append( " oid : " ).append( getOid() ).append( '\n' ); + sb.append( " critical : " ).append( isCritical() ).append( '\n' ); + sb.append( " parentFirst : '" ).append( getParentFirst() ).append( "'\n" ); + sb.append( " maxAttributeCount : '" ).append( getMaxAttributeCount() ).append( "'\n" ); + sb.append( " cookie : '" ).append( Strings.dumpBytes( getCookie() ) ).append( "'\n" ); + + return sb.toString(); + } +} Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponse.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponse.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponse.java (added) +++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponse.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + +import org.apache.directory.api.ldap.model.message.Control; + +/** + * + * @author Apache Directory Project + */ +public interface AdDirSyncResponse extends Control +{ + +} Added: directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponseImpl.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponseImpl.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponseImpl.java (added) +++ directory/shared/trunk/ldap/extras/codec-api/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncResponseImpl.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + +/** + * + * @author Apache Directory Project + */ +public class AdDirSyncResponseImpl +{ + +} Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncContainer.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncContainer.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncContainer.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncContainer.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + + +import org.apache.directory.api.asn1.ber.AbstractContainer; +import org.apache.directory.api.ldap.codec.api.LdapApiService; + + +/** + * + * ASN.1 container for AD DirSync control. + * + * @author Apache Directory Project + */ +public class AdDirSyncContainer extends AbstractContainer +{ + /** adDirSync */ + private AdDirSync control; + + private LdapApiService codec; + + + /** + * + * Creates a new AdDirSyncControl Container object. + * + */ + public AdDirSyncContainer( LdapApiService codec ) + { + super(); + this.codec = codec; + this.control = new AdDirSyncDecorator( codec ); + grammar = AdDirSyncGrammar.getInstance(); + setTransition( AdDirSyncStatesEnum.START_STATE ); + } + + + /** + * + * Creates a new AdDirSyncControl object. + * + */ + public AdDirSyncContainer( LdapApiService codec, AdDirSync control ) + { + super(); + this.codec = codec; + this.control = control; + grammar = AdDirSyncGrammar.getInstance(); + setTransition( AdDirSyncStatesEnum.START_STATE ); + } + + + /** + * @return the AdDirSyncControlCodec object + */ + public AdDirSync getAdDirSyncControl() + { + return control; + } + + + /** + * Set a AdDirSyncControlCodec Object into the container. It will be completed + * by the ldapDecoder. + * + * @param control the AdDirSyncControlCodec to set. + */ + public void setAdDirSyncControl( AdDirSync control ) + { + this.control = control; + } + + + public LdapApiService getCodecService() + { + return codec; + } + + + /** + * clean the container + */ + @Override + public void clean() + { + super.clean(); + control = null; + } +} Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncDecorator.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncDecorator.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncDecorator.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncDecorator.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,246 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + +import java.nio.ByteBuffer; + +import org.apache.directory.api.asn1.Asn1Object; +import org.apache.directory.api.asn1.DecoderException; +import org.apache.directory.api.asn1.EncoderException; +import org.apache.directory.api.asn1.ber.Asn1Decoder; +import org.apache.directory.api.asn1.ber.tlv.BerValue; +import org.apache.directory.api.asn1.ber.tlv.TLV; +import org.apache.directory.api.asn1.ber.tlv.UniversalTag; +import org.apache.directory.api.i18n.I18n; +import org.apache.directory.api.ldap.codec.api.ControlDecorator; +import org.apache.directory.api.ldap.codec.api.LdapApiService; +import org.apache.directory.api.util.Strings; + +public class AdDirSyncDecorator extends ControlDecorator implements AdDirSync +{ + /** The global length for this control */ + private int adDirSyncLength; + + /** An instance of this decoder */ + private static final Asn1Decoder decoder = new Asn1Decoder(); + + + /** + * Creates a new instance of AdDirSyncControlCodec. + */ + public AdDirSyncDecorator( LdapApiService codec ) + { + super( codec, new AdDirSyncImpl() ); + } + + + /** + * Creates a new instance of AdDirSyncDecorator. + * + * @param codec The LDAP codec + * @param control The control to be decorated + */ + public AdDirSyncDecorator( LdapApiService codec, AdDirSync control ) + { + super( codec, control ); + } + + + /** + * Compute the AdDirSync length. + * 0x30 L1 + * | + * +--> 0x02 0x0(1-4) nnn (parentFirst) + * +--> 0x02 0x0(1-4) nnn (maxAttributeCount) + * +--> 0x04 L2 xkcd!!!... (cookie) + */ + @Override + public int computeLength() + { + // the parentFirst flag length + adDirSyncLength = 1 + TLV.getNbBytes( getParentFirst() ) + BerValue.getNbBytes( getParentFirst() ); + + // the maxAttributeCount length + adDirSyncLength += 1 + TLV.getNbBytes( getMaxAttributeCount() ) + BerValue.getNbBytes( getMaxAttributeCount() ); + + // cookie's length + byte[] cookie = getCookie(); + + if ( cookie == null ) + { + adDirSyncLength += 1 + 1; + } + else + { + adDirSyncLength += 1 + TLV.getNbBytes( cookie.length ) + cookie.length; + } + + valueLength = 1 + TLV.getNbBytes( adDirSyncLength ) + adDirSyncLength; + + // Call the super class to compute the global control length + return valueLength; + } + + + /** + * Encode the AdDirSync control + * + * @param buffer The encoded sink + * @return A ByteBuffer that contains the encoded PDU + * @throws EncoderException If anything goes wrong while encoding. + */ + @Override + public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException + { + if ( buffer == null ) + { + throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); + } + + // Encode the SEQ + buffer.put( UniversalTag.SEQUENCE.getValue() ); + buffer.put( TLV.getBytes( adDirSyncLength ) ); + + // Encode the ParentFirst flag + BerValue.encode( buffer, getParentFirst() ); + + // Encode the MaxAttributeCount + BerValue.encode( buffer, getMaxAttributeCount() ); + + // Encode the cookie + BerValue.encode( buffer, getCookie() ); + + return buffer; + } + + + /** + * {@inheritDoc} + */ + @Override + public byte[] getValue() + { + if ( value == null ) + { + try + { + computeLength(); + ByteBuffer buffer = ByteBuffer.allocate( valueLength ); + + // Encode the SEQ + buffer.put( UniversalTag.SEQUENCE.getValue() ); + buffer.put( TLV.getBytes( adDirSyncLength ) ); + + // Encode the ParentFirst flag + BerValue.encode( buffer, getParentFirst() ); + + // Encode the MaxAttributeCount + BerValue.encode( buffer, getMaxAttributeCount() ); + + // Encode the cookie + BerValue.encode( buffer, getCookie() ); + + value = buffer.array(); + } + catch ( Exception e ) + { + return null; + } + } + + return value; + } + + + /** + * {@inheritDoc} + */ + public int getParentFirst() + { + return getDecorated().getParentFirst(); + } + + + /** + * {@inheritDoc} + */ + public void setParentFirst( int parentFirst ) + { + getDecorated().setParentFirst( parentFirst ); + } + + + /** + * {@inheritDoc} + */ + public int getMaxAttributeCount() + { + return getDecorated().getMaxAttributeCount(); + } + + + /** + * {@inheritDoc} + */ + public void setMaxAttributeCount( int maxAttributeCount ) + { + getDecorated().setMaxAttributeCount( maxAttributeCount ); + } + + + /** + * {@inheritDoc} + */ + public byte[] getCookie() + { + return getDecorated().getCookie(); + } + + + /** + * {@inheritDoc} + */ + public void setCookie( byte[] cookie ) + { + // Copy the bytes + if ( !Strings.isEmpty( cookie ) ) + { + byte[] copy = new byte[cookie.length]; + System.arraycopy( cookie, 0, copy, 0, cookie.length ); + getDecorated().setCookie( copy ); + } + else + { + getDecorated().setCookie( null ); + } + } + + + /** + * {@inheritDoc} + */ + public Asn1Object decode( byte[] controlBytes ) throws DecoderException + { + ByteBuffer bb = ByteBuffer.wrap( controlBytes ); + AdDirSyncContainer container = new AdDirSyncContainer( getCodecService(), this ); + decoder.decode( bb, container ); + return this; + } +} Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncFactory.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncFactory.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncFactory.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncFactory.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + + +import org.apache.directory.api.ldap.codec.api.CodecControl; +import org.apache.directory.api.ldap.codec.api.ControlFactory; +import org.apache.directory.api.ldap.codec.api.LdapApiService; + + +/** + * A {@link ControlFactory} which creates {@link AdDirSync} controls. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class AdDirSyncFactory implements ControlFactory +{ + /** The codec for this factory */ + private LdapApiService codec; + + + /** + * Creates a new instance of AdDirSyncFactory. + * + * @param codec The codec for this factory. + */ + public AdDirSyncFactory( LdapApiService codec ) + { + this.codec = codec; + } + + + /** + * {@inheritDoc} + */ + public String getOid() + { + return AdDirSync.OID; + } + + + /** + * {@inheritDoc} + */ + public CodecControl newCodecControl() + { + return new AdDirSyncDecorator( codec ); + } + + + /** + * {@inheritDoc} + */ + public CodecControl newCodecControl( AdDirSync control ) + { + return new AdDirSyncDecorator( codec, control ); + } +} Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncGrammar.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncGrammar.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncGrammar.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncGrammar.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,213 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + + +import org.apache.directory.api.asn1.DecoderException; +import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; +import org.apache.directory.api.asn1.ber.grammar.Grammar; +import org.apache.directory.api.asn1.ber.grammar.GrammarAction; +import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; +import org.apache.directory.api.asn1.ber.tlv.BerValue; +import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder; +import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; +import org.apache.directory.api.asn1.ber.tlv.UniversalTag; +import org.apache.directory.api.util.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * + * Implementation of AdDirSync Control. All the actions are declared in + * this class. As it is a singleton, these declaration are only done once. + * + * The decoded grammar is as follows : + * + *
+ * realReplControlValue ::= SEQUENCE {
+ *     parentsFirst            integer
+ *     maxAttributeCount       integer
+ *     cookie                  OCTET STRING
+ * }
+ * 
+ * + * @author Apache Directory Project + */ +public final class AdDirSyncGrammar extends AbstractGrammar +{ + + /** the logger */ + private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncGrammar.class ); + + /** speedup for logger */ + private static final boolean IS_DEBUG = LOG.isDebugEnabled(); + + /** AdDirSyncControlGrammar singleton instance */ + private static final AdDirSyncGrammar INSTANCE = new AdDirSyncGrammar(); + + + /** + * + * Creates a new instance of AdDirSyncControlGrammar. + * + */ + @SuppressWarnings("unchecked") + private AdDirSyncGrammar() + { + setName( AdDirSyncGrammar.class.getName() ); + + super.transitions = new GrammarTransition[AdDirSyncStatesEnum.LAST_AD_DIR_SYNC_STATE.ordinal()][256]; + + /** + * Transition from initial state to AdDirSync sequence + * AdDirSync ::= SEQUENCE { + * ... + * + * Initialize the adSyncDir object + */ + super.transitions[AdDirSyncStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition( + AdDirSyncStatesEnum.START_STATE, AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE, + UniversalTag.SEQUENCE.getValue(), + new GrammarAction( "Initialization" ) + { + public void action( AdDirSyncContainer container ) throws DecoderException + { + } + } ); + + + /** + * transition from start to parentFirst + * realReplControlValue ::= SEQUENCE { + * parentsFirst integer + * .... + * } + */ + super.transitions[AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER + .getValue()] = + new GrammarTransition( AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE, + AdDirSyncStatesEnum.PARENT_FIRST_STATE, UniversalTag.INTEGER.getValue(), + new GrammarAction( "Set AdDirSyncControl parentFirst" ) + { + public void action( AdDirSyncContainer container ) throws DecoderException + { + BerValue value = container.getCurrentTLV().getValue(); + + try + { + int parentFirst = IntegerDecoder.parse( value ); + + if ( IS_DEBUG ) + { + LOG.debug( "parentFirst = {}", parentFirst ); + } + + container.getAdDirSyncControl().setParentFirst( parentFirst ); + } + catch ( IntegerDecoderException ide ) + { + String msg = "Error while decoding the AdDirSync parentFirst : " + ide.getMessage(); + LOG.error( msg, ide ); + throw new DecoderException( msg ); + } + } + } ); + + + /** + * transition from parentFirst to maxAttributeCount + * realReplControlValue ::= SEQUENCE { + * parentsFirst integer + * maxAttributeCount integer + * .... + * } + */ + super.transitions[AdDirSyncStatesEnum.PARENT_FIRST_STATE.ordinal()][UniversalTag.INTEGER + .getValue()] = + new GrammarTransition( AdDirSyncStatesEnum.PARENT_FIRST_STATE, + AdDirSyncStatesEnum.MAX_ATTRIBUTE_COUNT_STATE, UniversalTag.INTEGER.getValue(), + new GrammarAction( "Set AdDirSyncControl maxAttributeCount" ) + { + public void action( AdDirSyncContainer container ) throws DecoderException + { + BerValue value = container.getCurrentTLV().getValue(); + + try + { + int maxAttributeCount = IntegerDecoder.parse( value ); + + if ( IS_DEBUG ) + { + LOG.debug( "maxAttributeCount = {}", maxAttributeCount ); + } + + container.getAdDirSyncControl().setMaxAttributeCount( maxAttributeCount ); + } + catch ( IntegerDecoderException ide ) + { + String msg = "Error while decoding the AdDirSync maxAttributeCount : " + ide.getMessage(); + LOG.error( msg, ide ); + throw new DecoderException( msg ); + } + } + } ); + + + /** + * transition from maxAttributeCount to cookie + * ... + * maxAttributeCount integer + * cookie OCTET STRING + * } + */ + super.transitions[AdDirSyncStatesEnum.MAX_ATTRIBUTE_COUNT_STATE.ordinal()][UniversalTag.OCTET_STRING + .getValue()] = + new GrammarTransition( AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE, + AdDirSyncStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), + new GrammarAction( "Set AdDirSyncControl cookie" ) + { + public void action( AdDirSyncContainer container ) throws DecoderException + { + BerValue value = container.getCurrentTLV().getValue(); + + byte[] cookie = value.getData(); + + if ( IS_DEBUG ) + { + LOG.debug( "cookie = {}", Strings.dumpBytes( cookie ) ); + } + + container.getAdDirSyncControl().setCookie( cookie ); + + container.setGrammarEndAllowed( true ); + } + } ); + } + + + /** + * @return the singleton instance of the AdDirSyncControlGrammar + */ + public static Grammar getInstance() + { + return INSTANCE; + } +} Added: directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncStatesEnum.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncStatesEnum.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncStatesEnum.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/main/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncStatesEnum.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + + +import org.apache.directory.api.asn1.ber.grammar.Grammar; +import org.apache.directory.api.asn1.ber.grammar.States; + + +/** + * ASN.1 grammar constants of AdDirSync Control. + * + * @author Apache Directory Project + */ +public enum AdDirSyncStatesEnum implements States +{ + + /** The END_STATE */ + END_STATE, + + /***/ + START_STATE, + + /** sequence start state */ + AD_DIR_SYNC_SEQUENCE_STATE, + + /** parentFirst value state */ + PARENT_FIRST_STATE, + + /** maxAttributeCount value state */ + MAX_ATTRIBUTE_COUNT_STATE, + + /** cookie value state */ + COOKIE_STATE, + + /** terminal state */ + LAST_AD_DIR_SYNC_STATE; + + /** + * Get the grammar name + * + * @param grammar The grammar code + * @return The grammar name + */ + public String getGrammarName( int grammar ) + { + return "AD_DIR_SYNC_GRAMMAR"; + } + + + /** + * Get the grammar name + * + * @param grammar The grammar class + * @return The grammar name + */ + public String getGrammarName( Grammar grammar ) + { + if ( grammar instanceof AdDirSyncGrammar ) + { + return "AD_DIR_SYNC_GRAMMAR"; + } + + return "UNKNOWN GRAMMAR"; + } + + + /** + * Get the string representing the state + * + * @param state The state number + * @return The String representing the state + */ + public String getState( int state ) + { + return ( ( state == END_STATE.ordinal() ) ? "AD_DIR_SYNC_GRAMMAR" : this.name() ); + } + + + /** + * {@inheritDoc} + */ + public boolean isEndState() + { + return this == END_STATE; + } + + + /** + * {@inheritDoc} + */ + public AdDirSyncStatesEnum getStartState() + { + return START_STATE; + } +} Added: directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncControlTest.java URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncControlTest.java?rev=1587828&view=auto ============================================================================== --- directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncControlTest.java (added) +++ directory/shared/trunk/ldap/extras/codec/src/test/java/org/apache/directory/api/ldap/extras/controls/ad/AdDirSyncControlTest.java Wed Apr 16 08:12:12 2014 @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.directory.api.ldap.extras.controls.ad; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.nio.ByteBuffer; + +import org.apache.directory.api.asn1.DecoderException; +import org.apache.directory.api.asn1.EncoderException; +import org.apache.directory.api.ldap.extras.AbstractCodecServiceTest; +import org.apache.directory.api.util.Strings; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.mycila.junit.concurrent.Concurrency; +import com.mycila.junit.concurrent.ConcurrentJunitRunner; + + +/** + * + * TestCase for AdDirSyncControlCodec . + * + * @author Apache Directory Project + */ +@RunWith(ConcurrentJunitRunner.class) +@Concurrency() +public class AdDirSyncControlTest extends AbstractCodecServiceTest +{ + @Test + public void testAdDirSyncControl() throws Exception + { + ByteBuffer bb = ByteBuffer.allocate( 0x0E ); + + bb.put( new byte[] + { + 0x30, 0x0C, + 0x02, 0x01, 0x00, // parentFirst (false) + 0x02, 0x01, 0x00, // maxAttributeCount (no limit) + 0x04, 0x04, 'x', 'k', 'c', 'd' // the cookie + } ); + + bb.flip(); + + AdDirSync decorator = new AdDirSyncDecorator( codec ); + + AdDirSync adDirSync = ( AdDirSync ) ( ( AdDirSyncDecorator ) decorator ).decode( bb.array() ); + + assertEquals( 0, adDirSync.getParentFirst() ); + assertEquals( 0, adDirSync.getMaxAttributeCount() ); + assertEquals( "xkcd", Strings.utf8ToString( adDirSync.getCookie() ) ); + + // test encoding + try + { + ByteBuffer buffer = ( ( AdDirSyncDecorator ) adDirSync ).encode( ByteBuffer + .allocate( ( ( AdDirSyncDecorator ) adDirSync ).computeLength() ) ); + String expected = Strings.dumpBytes( bb.array() ); + String decoded = Strings.dumpBytes( buffer.array() ); + assertEquals( expected, decoded ); + } + catch ( EncoderException e ) + { + fail( e.getMessage() ); + } + } + + + @Test + public void testAdDirSyncControlNoCookie() throws Exception + { + ByteBuffer bb = ByteBuffer.allocate( 0x0A ); + + bb.put( new byte[] + { + 0x30, 0x08, + 0x02, 0x01, 0x00, // parentFirst (false) + 0x02, 0x01, 0x00, // maxAttributeCount (no limit) + 0x04, 0x00 // the cookie + } ); + + bb.flip(); + + AdDirSync decorator = new AdDirSyncDecorator( codec ); + + AdDirSync adDirSync = ( AdDirSync ) ( ( AdDirSyncDecorator ) decorator ).decode( bb.array() ); + + assertEquals( 0, adDirSync.getParentFirst() ); + assertEquals( 0, adDirSync.getMaxAttributeCount() ); + assertEquals( "", Strings.utf8ToString( adDirSync.getCookie() ) ); + + // test encoding + try + { + ByteBuffer buffer = ( ( AdDirSyncDecorator ) adDirSync ).encode( ByteBuffer + .allocate( ( ( AdDirSyncDecorator ) adDirSync ).computeLength() ) ); + String expected = Strings.dumpBytes( bb.array() ); + String decoded = Strings.dumpBytes( buffer.array() ); + assertEquals( expected, decoded ); + } + catch ( EncoderException e ) + { + fail( e.getMessage() ); + } + } + + + @Test + public void testAdDirSyncControlAbsentCookie() throws Exception + { + ByteBuffer bb = ByteBuffer.allocate( 0x08 ); + + bb.put( new byte[] + { + 0x30, 0x06, + 0x02, 0x01, 0x00, // parentFirst (false) + 0x02, 0x01, 0x00 // maxAttributeCount (no limit) + } ); + + bb.flip(); + + AdDirSync decorator = new AdDirSyncDecorator( codec ); + + try + { + ( ( AdDirSyncDecorator ) decorator ).decode( bb.array() ); + fail(); + } + catch ( DecoderException de ) + { + // expected + } + } + + + @Test + public void testAdDirSyncControlAbsentParentFirst() throws Exception + { + ByteBuffer bb = ByteBuffer.allocate( 0x07 ); + + bb.put( new byte[] + { + 0x30, 0x05, + 0x02, 0x01, 0x00, // maxAttributeCount (no limit) + 0x04, 0x00 // cookie + } ); + + bb.flip(); + + AdDirSync decorator = new AdDirSyncDecorator( codec ); + + try + { + ( ( AdDirSyncDecorator ) decorator ).decode( bb.array() ); + fail(); + } + catch ( DecoderException de ) + { + // expected + } + } + + + @Test + public void testAdDirSyncControlEmpty() throws Exception + { + ByteBuffer bb = ByteBuffer.allocate( 0x02 ); + + bb.put( new byte[] + { + 0x30, 0x00, + } ); + + bb.flip(); + + AdDirSync decorator = new AdDirSyncDecorator( codec ); + + try + { + ( ( AdDirSyncDecorator ) decorator ).decode( bb.array() ); + fail(); + } + catch ( DecoderException de ) + { + // expected + } + } +}