package net.sf.acegisecurity;

/**
 * An abstract implementation of the {@link AuthenticationManager}.
 *
 * @author Wesley Hall
 * @version $Id: $
 */
public abstract class AbstractAuthenticationManager implements AuthenticationManager
{
    /**
     * <p>
     * An implementation of the <code>authenticate</code> method that calls the
     * abstract method <code>doAuthenticatation</code> to do its work.
     * </p>
     *
     * <p>
     * If doAuthenticate throws an <code>AuthenticationException</code> then
     * the exception is populated with the failed <code>Authentication</code>
     * object that failed.
     * </p>
     *
     * @param authentication the authentication request object
     *
     * @return a fully authenticated object including credentials
     *
     * @throws AuthenticationException if authentication fails
     */
    public final Authentication authenticate(Authentication authentication)
       throws AuthenticationException {
        try {
            return doAuthentication(authentication);
        } catch (AuthenticationException e) {
            e.setAuthentication(authentication);
            throw e;
        }
    }

    /**
     * <p>
     * Concrete implementations of this class override this method to provide
     * the authentication service.
     * </p>
     *
     * <p>
     * The contract for this method is documented in the {@link AuthenticationManager#authenticate(net.sf.acegisecurity.Authentication)}.
     * </p>
     *
     * @param authentication the authentication request object
     *
     * @return a fully authenticated object including credentials
     *
     * @throws AuthenticationException if authentication fails
     */
    protected abstract Authentication doAuthentication(Authentication authentication)
       throws AuthenticationException;
}
