// AutoLookupDirectory.java
// $Id: AutoLookupDirectory.java,v 1.7 1997/09/24 13:13:32 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.cvs ;

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

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

/**
 * A special version of DirectoryResource that can fetch a file
 * from CVS directly if it is not already here.
 * It can alos do an automatic update, depending on a flag
 */

public class AutoLookupDirectory extends PutableDirectory {

    private CvsDirectory cvs = null ;

    /**
     * Attribute index, tell if we must update the resource everytime it is
     * acceded (not recommended as it generates many cvs commands)
     */

    private static int ATTR_AUTOUPDATE = -1;

    static {
	Attribute   a = null ;
	Class     cls = null;

	try {
	    cls     = Class.forName("w3c.jigsaw.cvs.AutoLookupDirectory") ;
	} catch (Exception ex) {
	    ex.printStackTrace() ;
	    System.exit(1) ;
	}
	// The browsable flag:
	a = new BooleanAttribute("autoupdate"
				 , Boolean.FALSE
				 , Attribute.EDITABLE) ;
	ATTR_AUTOUPDATE = AttributeRegistry.registerAttribute(cls, a) ;
    }

    /**
     * Get the appropriate CVS manager for the directory we handle.
     * @return A CvsDirectory instance.
     * @exception HTTPException If we couldn't get the manager.
     */

    protected synchronized CvsDirectory getCvsManager() 
	throws CvsException
    {
	if ( cvs == null ) {
	    cvs = CvsDirectory.getManager(getDirectory()
					  , getServer().getProperties());
	}
	return cvs;
    }

	    
    /**
     * tell if we must always do an update.
     */

    public boolean isAutoUpdatable() {
	return getBoolean(ATTR_AUTOUPDATE, false);
    }

   /**
     * Lookup the resource having the given name in this directory.
     * if the resource is not present, it will try to fetch it from
     * the Cvs repository.
     * @param name The name of the resource.
     * @return A resource instance, or <strong>null</strong>.
     */

    public Resource lookup(String name)
	throws InvalidResourceException
    {
	Resource resource = super.lookup(name) ;
	if ( resource != null ) {
	    // If it's a FileResource, and cvs update enabled, do it:
	    if ( isAutoUpdatable() && (resource instanceof FileResource)) {
		FileResource fr = (FileResource) resource;
		String filename = fr.getFilename();
		if (filename == null)
		  filename = name;
		try {
		    if (getCvsManager().status(filename)!=CVS.FILE_OK)
			getCvsManager().update(filename);
		} catch (CvsException ex) {
		    String msg = "cvs update \""+filename+"\" failed.";
		    getServer().errlog(this, msg);
		}
	    }
	    return resource ; 
	} else {
	    // This may be an unchecked out directory:
	    try {
		if ( getCvsManager().getDirectoryStatus(name) == CVS.DIR_NCO )
		    getCvsManager().updateDirectory(name);
	    } catch (CvsException ex) {
		String msg = "cvs update -d \""+name+"\" failed.";
		getServer().errlog(this, msg);
		return null;
	    }
	    // Checking out the directory succeeded, retry lookup:
	    return super.lookup(name);
	}
    }

}
