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.ldap.client.api;
021
022
023import static org.apache.directory.api.ldap.model.message.ResultCodeEnum.processResponse;
024
025import java.util.concurrent.atomic.AtomicInteger;
026
027import org.apache.directory.api.ldap.codec.api.LdapApiService;
028import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
029import org.apache.directory.api.ldap.model.exception.LdapException;
030import org.apache.directory.api.ldap.model.message.BindRequest;
031import org.apache.directory.api.ldap.model.message.BindRequestImpl;
032import org.apache.directory.api.ldap.model.message.BindResponse;
033import org.apache.directory.api.ldap.model.message.Control;
034import org.apache.directory.api.ldap.model.name.Dn;
035import org.apache.directory.api.ldap.model.schema.SchemaManager;
036import org.apache.directory.api.util.Strings;
037import org.apache.mina.core.service.IoHandlerAdapter;
038import org.slf4j.Logger;
039import org.slf4j.LoggerFactory;
040
041
042/**
043 * An abstract LdapConnection class gathering the common behavior of LdapConnection
044 * concrete classes.
045 * 
046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047 */
048public abstract class AbstractLdapConnection extends IoHandlerAdapter implements LdapConnection
049{
050    /** logger for reporting errors that might not be handled properly upstream */
051    private static final Logger LOG = LoggerFactory.getLogger( AbstractLdapConnection.class );
052
053    /** the schema manager */
054    protected SchemaManager schemaManager;
055
056    /** A Message ID which is incremented for each operation */
057    protected AtomicInteger messageId;
058
059    /** the ldap codec service */
060    protected LdapApiService codec;
061
062
063    /**
064     * Creates a new instance of an AbstractLdapConnection
065     */
066    protected AbstractLdapConnection()
067    {
068        this( LdapApiServiceFactory.getSingleton() );
069    }
070
071    protected AbstractLdapConnection( LdapApiService codec )
072    {
073        messageId = new AtomicInteger( 0 );
074        this.codec = codec;
075    }
076
077
078    /**
079     * {@inheritDoc}
080     */
081    @Override
082    public void bind( Dn name ) throws LdapException
083    {
084        byte[] credBytes = Strings.EMPTY_BYTES;
085
086        BindRequest bindRequest = new BindRequestImpl();
087        bindRequest.setDn( name );
088        bindRequest.setCredentials( credBytes );
089
090        BindResponse bindResponse = bind( bindRequest );
091
092        processResponse( bindResponse );
093    }
094
095
096    /**
097     * {@inheritDoc}
098     */
099    @Override
100    public void bind( String name ) throws LdapException
101    {
102        LOG.debug( "Bind request : {}", name );
103
104        bind( new Dn( schemaManager, name ), null );
105    }
106
107
108    /**
109     * {@inheritDoc}
110     */
111    @Override
112    public void bind( String name, String credentials ) throws LdapException
113    {
114        bind( new Dn( schemaManager, name ), credentials );
115    }
116
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public void bind( Dn name, String credentials ) throws LdapException
123    {
124        byte[] credBytes = credentials == null ? Strings.EMPTY_BYTES : Strings.getBytesUtf8( credentials );
125
126        BindRequest bindRequest = new BindRequestImpl();
127        bindRequest.setDn( name );
128        bindRequest.setCredentials( credBytes );
129
130        BindResponse bindResponse = bind( bindRequest );
131
132        processResponse( bindResponse );
133    }
134
135
136    /**
137     * Create a complete BindRequest ready to be sent.
138     *
139     * @param name The DN to bind with
140     * @param credentials The user's password
141     * @param saslMechanism The SASL mechanism to use
142     * @param controls The controls to send
143     * @return The created BindRequest
144     * @throws LdapException If the creation failed
145     */
146    protected BindRequest createBindRequest( String name, byte[] credentials, String saslMechanism, Control... controls )
147        throws LdapException
148    {
149        // Set the new messageId
150        BindRequest bindRequest = new BindRequestImpl();
151
152        // Set the version
153        bindRequest.setVersion3( true );
154
155        // Set the name
156        bindRequest.setName( name );
157
158        // Set the credentials
159        if ( Strings.isEmpty( saslMechanism ) )
160        {
161            // Simple bind
162            bindRequest.setSimple( true );
163            bindRequest.setCredentials( credentials );
164        }
165        else
166        {
167            // SASL bind
168            bindRequest.setSimple( false );
169            bindRequest.setCredentials( credentials );
170            bindRequest.setSaslMechanism( saslMechanism );
171        }
172
173        // Add the controls
174        if ( ( controls != null ) && ( controls.length != 0 ) )
175        {
176            bindRequest.addAllControls( controls );
177        }
178
179        return bindRequest;
180    }
181}