/* AppConfigurationEntry.java
   Copyright (C) 2004, 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.security.auth.login;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class AppConfigurationEntry
{
  // Fields.
  // -------------------------------------------------------------------------

  private final String loginModuleName;
  private final LoginModuleControlFlag controlFlag;
  private final Map options;

  // Constructor.
  // -------------------------------------------------------------------------

  public AppConfigurationEntry (final String loginModuleName,
                                final LoginModuleControlFlag controlFlag,
                                final Map<String, ?> options)
  {
    if (loginModuleName == null || loginModuleName.length() == 0)
      throw new IllegalArgumentException ("module name cannot be null nor empty");

    if (LoginModuleControlFlag.OPTIONAL != controlFlag &&
        LoginModuleControlFlag.REQUIRED != controlFlag &&
        LoginModuleControlFlag.REQUISITE != controlFlag &&
        LoginModuleControlFlag.SUFFICIENT != controlFlag)
      throw new IllegalArgumentException ("invalid controlFlag");

    if (options == null)
      throw new IllegalArgumentException ("options cannot be null");

    this.loginModuleName = loginModuleName;
    this.controlFlag = controlFlag;
    this.options = Collections.unmodifiableMap (new HashMap (options));
  }

  // Instance methods.
  // -------------------------------------------------------------------------

  public LoginModuleControlFlag getControlFlag()
  {
    return controlFlag;
  }

  public String getLoginModuleName()
  {
    return loginModuleName;
  }

  public Map<String, ?> getOptions()
  {
    return options;
  }

  // Object methods ----------------------------------------------------------

  public String toString()
  {

    return loginModuleName + "\t"
        + String.valueOf(controlFlag) + "\t"
        + String.valueOf(options);
  }

  // Inner class.
  // -------------------------------------------------------------------------

  public static class LoginModuleControlFlag
  {

    // Constants.
    // -----------------------------------------------------------------------

    public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag();
    public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag();
    public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag();
    public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag();

    // Constructor.
    // -----------------------------------------------------------------------

    private LoginModuleControlFlag()
    {
    }

    // Instance methods.
    // -----------------------------------------------------------------------

    public String toString()
    {
      if (this == LoginModuleControlFlag.REQUIRED)
        return "REQUIRED";
      if (this == LoginModuleControlFlag.REQUISITE)
        return "REQUISITE";
      if (this == LoginModuleControlFlag.SUFFICIENT)
        return "SUFFICIENT";
      if (this == LoginModuleControlFlag.OPTIONAL)
        return "OPTIONAL";
      return "???";
    }
  }
}
