/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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.catalina.cluster.session;


import java.util.Arrays;
import java.util.List;
import org.apache.catalina.Realm;


/**
 * Generic implementation of <strong>java.security.Principal</strong> that
 * is available for use by <code>Realm</code> implementations.
 * The GenericPrincipal does NOT implement serializable and I didn't want to change that implementation
 * hence I implemented this one instead.
 * @author Filip Hanik
 * @version $Revision$ $Date$
 */
import org.apache.catalina.realm.GenericPrincipal;
public class SerializablePrincipal  implements java.io.Serializable {


    // ----------------------------------------------------------- Constructors

    public SerializablePrincipal()
    {
        super();
    }
    /**
     * Construct a new Principal, associated with the specified Realm, for the
     * specified username and password.
     *
     * @param realm The Realm that owns this Principal
     * @param name The username of the user represented by this Principal
     * @param password Credentials used to authenticate this user
     */
    public SerializablePrincipal(Realm realm, String name, String password) {

        this(realm, name, password, null);

    }


    /**
     * Construct a new Principal, associated with the specified Realm, for the
     * specified username and password, with the specified role names
     * (as Strings).
     *
     * @param realm The Realm that owns this principal
     * @param name The username of the user represented by this Principal
     * @param password Credentials used to authenticate this user
     * @param roles List of roles (must be Strings) possessed by this user
     */
    public SerializablePrincipal(Realm realm, String name, String password,
                            List roles) {

        super();
        this.realm = realm;
        this.name = name;
        this.password = password;
        if (roles != null) {
            this.roles = new String[roles.size()];
            this.roles = (String[]) roles.toArray(this.roles);
            if (this.roles.length > 0)
                Arrays.sort(this.roles);
        }

    }


    // ------------------------------------------------------------- Properties


    /**
     * The username of the user represented by this Principal.
     */
    protected String name = null;

    public String getName() {
        return (this.name);
    }


    /**
     * The authentication credentials for the user represented by
     * this Principal.
     */
    protected String password = null;

    public String getPassword() {
        return (this.password);
    }


    /**
     * The Realm with which this Principal is associated.
     */
    protected transient Realm realm = null;

    public Realm getRealm() {
        return (this.realm);
    }

    public void setRealm(Realm realm) {
        this.realm = realm;
    }




    /**
     * The set of roles associated with this user.
     */
    protected String roles[] = new String[0];

    public String[] getRoles() {
        return (this.roles);
    }


    // --------------------------------------------------------- Public Methods




    /**
     * Return a String representation of this object, which exposes only
     * information that should be public.
     */
    public String toString() {

        StringBuffer sb = new StringBuffer("SerializablePrincipal[");
        sb.append(this.name);
        sb.append("]");
        return (sb.toString());

    }

    public static SerializablePrincipal createPrincipal(GenericPrincipal principal)
    {
        if ( principal==null) return null;
        return new SerializablePrincipal(principal.getRealm(),
                                         principal.getName(),
                                         principal.getPassword(),
                                         principal.getRoles()!=null?Arrays.asList(principal.getRoles()):null);
    }

    public GenericPrincipal getPrincipal( Realm realm )
    {
        return new GenericPrincipal(realm,name,password,getRoles()!=null?Arrays.asList(getRoles()):null);
    }
    
    public static GenericPrincipal readPrincipal(java.io.ObjectInputStream in, Realm realm) throws java.io.IOException{
        String name = in.readUTF();
        String pwd = in.readUTF();
        int size = in.readInt();
        String[] roles = new String[size];
        for ( int i=0; i<size; i++ ) roles[i] = in.readUTF();
        return new GenericPrincipal(realm,name,pwd,Arrays.asList(roles));
    }
    
    public static void writePrincipal(GenericPrincipal p, java.io.ObjectOutputStream out) throws java.io.IOException {
        out.writeUTF(p.getName());
        out.writeUTF(p.getPassword());
        String[] roles = p.getRoles();
        if ( roles == null ) roles = new String[0];
        out.writeInt(roles.length);
        for ( int i=0; i<roles.length; i++ ) out.writeUTF(roles[i]);
    }


}
