// RealmsCatalog.java
// $Id: RealmsCatalog.java,v 1.7 1997/07/02 14:32:29 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.auth;

import java.util.*;
import java.io.*;

import w3c.tools.store.*;
import w3c.jigsaw.http.*;
import w3c.jigsaw.resources.*;

public class RealmsCatalog implements ResourceStoreHolder {
    /**
     * Our realm repository.
     */
    protected File repository = null ;
    /**
     * Our realm's store.
     */
    protected ResourceStore store = null ;
    /**
     * Our associated server.
     */
    protected httpd server = null ;

    /**
     * Acquire the store.
     * Should only be called from a synchronized method.
     */

    protected synchronized void acquireStore() {
	if ( store != null )
	    return ;
	ResourceStoreManager manager = server.getResourceStoreManager() ;
	store = manager.loadResourceStore(this, getRepository());
	return ;
    }

    /**
     * Get our repository.
     */

    public File getRepository() {
	return repository;
    }

    /**
     * Load the given realm and return the AuthRealm instance.
     * @param name The realm identifier.
     */

    public synchronized AuthRealm loadRealm(String name) {
	acquireStore() ;
	if ( store == null )
	    return null ;
	Hashtable defs = new Hashtable(1) ;
	defs.put("server", server) ;
	try {
	    return (AuthRealm) store.loadResource(name, defs) ;
	} catch (InvalidResourceException ex) {
	    String msg = ("Unable to restore authentication realm \""
			  + name + "\" from catalog \"" + store 
			  +"\", details: "+ex.getMessage());
	    server.errlog(this, msg);
	}
	// not reached:
	return null;
    }

    /**
     * Enumerate the list of available realms.
     */

    public synchronized Enumeration enumerateRealmNames() {
	acquireStore() ;
	if ( store == null )
	    return null ;
	return store.enumerateResourceIdentifiers() ;
    }

    /**
     * register the given new realm.
     * @param realm The new realm to register.
     */

    public synchronized void registerRealm(AuthRealm realm) {
	acquireStore() ;
	if ( store == null )
	    throw new RuntimeException ("no store !");
	realm.setValue("server", server) ;
	store.addResource(realm) ;
    }

    /**
     * Unregister the given realm from the catalog.
     * @param name The name of the catalog.
     */

    public synchronized void unregisterRealm(String name) {
	acquireStore() ;
	if ( store == null )
	    return ;
	store.removeResource(name) ;
    }

    /**
     * Save the catalog back to disk.
     */

    public synchronized void save() {
	if (store != null)
	    store.save() ;
    }

    /**
     * ResourceStoreHolder implementation - Unload the store.
     * @param st The store to unload.
     * @return A boolean <strong>true</strong> if store was successfully
     *    unloaded.
     */

    public synchronized boolean acceptStoreUnload(ResourceStore st) {
	if ( st != store ) 
	    throw new RuntimeException("ResourceStoreManager inconsistent.");
	return true ;
    }

    /**
     * The resource store asks us to shutdown our associated store.
     * @param st The store to shutdown.
     */

    public void notifyStoreShutdown(ResourceStore st) {
	if ( st != store ) 
	    throw new RuntimeException("ResourceStoreManager inconsistent.");
	store = null ;
    }

    /**
     * ResourceStoreHolder implementation - Save our store.
     * @param st The store to be saved.
     * @return A boolean <strong>true</strong> if saving the store is now
     *    not modified.
     */

    public void notifyStoreStabilize(ResourceStore st) {
	return;
    }

    public RealmsCatalog(httpd server) {
	this.server     = server ;
	this.repository = new File(server.getAuthDirectory(), "realms.db");
    }

    public RealmsCatalog(httpd server, String repository) {
	String rep = repository;
	this.server     = server ;
	if(!repository.endsWith(".db"))
	    rep = rep + ".db";
	this.repository = new File(server.getAuthDirectory(), rep);
    }
}
