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.future;
021
022
023import java.util.concurrent.ExecutionException;
024import java.util.concurrent.Future;
025import java.util.concurrent.TimeUnit;
026import java.util.concurrent.TimeoutException;
027
028
029/**
030 * A Future to manage StartTLS handshake
031 *
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 */
034public class HandshakeFuture implements Future<Boolean>
035{
036    /** A flag set to TRUE when the handshake has been completed */
037    private volatile boolean done = false;
038
039    /** flag to determine if this future is cancelled */
040    protected boolean cancelled = false;
041
042    /**
043     * Creates a new instance of HandshakeFuture.
044     */
045    public HandshakeFuture()
046    {
047        // Nothing to initialize...
048    }
049
050
051    /**
052     * Cancel the Future
053     *
054     */
055    public synchronized void cancel()
056    {
057        // set the cancel flag first
058        cancelled = true;
059        
060        // Notify the future
061        notifyAll();
062    }
063
064
065    /**
066     * Set the Future to done when the TLS handshake has completed
067     */
068    public synchronized void secured()
069    {
070        done = true;
071        
072        notifyAll();
073    }
074
075
076    /**
077     * {@inheritDoc}
078     */
079    @Override
080    public synchronized boolean cancel( boolean mayInterruptIfRunning )
081    {
082        if ( cancelled )
083        {
084            return cancelled;
085        }
086
087        // set the cancel flag first
088        cancelled = true;
089
090        // Notify the future
091        notifyAll();
092
093        return cancelled;
094    }
095
096
097    /**
098     * {@inheritDoc}
099     */
100    @Override
101    public synchronized Boolean get() throws InterruptedException, ExecutionException
102    {
103        while ( !done && !cancelled )
104        {
105            wait();
106        }
107        
108        return done;
109    }
110
111
112    /**
113     * {@inheritDoc}
114     */
115    @Override
116    public synchronized Boolean get( long timeout, TimeUnit unit ) throws InterruptedException, ExecutionException, TimeoutException
117    {
118        wait( unit.toMillis( timeout ) );
119        
120        return done;
121    }
122
123
124    /**
125     * {@inheritDoc}
126     */
127    @Override
128    public boolean isCancelled()
129    {
130        return cancelled;
131    }
132
133
134    /**
135     * {@inheritDoc}
136     */
137    @Override
138    public boolean isDone()
139    {
140        return done;
141    }
142
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public String toString()
149    {
150        StringBuilder sb = new StringBuilder();
151    
152        sb.append( "HandshakeFuture, completed: " ).append( done ).append( ", cancelled: " ).append( cancelled );
153    
154        return sb.toString();
155    }
156}