// CvsEntryResource.java
// $Id: CvsEntryResource.java,v 1.2 1998/02/03 15:28:01 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.cvs ;

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

import org.w3c.cvs.* ;
import org.w3c.www.http.* ;
import org.w3c.jigsaw.http.* ;
import org.w3c.jigsaw.frames.* ;
import org.w3c.jigsaw.resources.*;
import org.w3c.tools.resources.*;
import org.w3c.www.mime.*;
import org.w3c.jigsaw.html.HtmlGenerator ;

/**
 * This class exports the state of an entry. For the time being it doesn't
 * do much, but it should act as a directory (container) for all revisions
 * of a document. 
 * <p>The lookup method of this entity should be able to turn a revision number
 * into an editable (or viewable) document.
 */

public class CvsEntryResource extends FramedResource {


  class CvsEntryFrame extends HTTPFrame {

    ResourceReference container = null;
    String            name      = null;

    protected Reply dolog (Request request)
      throws ProtocolException
    {
      String log = null;
      try {
	CvsFrame cvsframe = (CvsFrame) container.lock();
	log = cvsframe.getCvsManager().log(name);
      } catch (CvsException cvs_ex) {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
	HtmlGenerator g = new HtmlGenerator ("CVS log command failed") ;
	g.append ("<p>The CVS <strong>log</strong> command failed "
		  + " on " + name
		  + " with the following error message: "
		  + "<em>" + cvs_ex.getMessage() + "</em>"
		  + "<hr> from class: " + this.getClass().getName()) ;
	error.setStream (g) ;
	throw new HTTPException (error) ;
      } catch (InvalidResourceException ex) {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
	HtmlGenerator g = new HtmlGenerator ("CVS log command failed") ;
	g.append ("<p>The CVS <strong>log</strong> command failed "
		  + " on " + name
		  + " with the following error message: "
		  + "<em>" + ex.getMessage() + "</em>"
		  + "<hr> from class: " + this.getClass().getName()) ;
	error.setStream (g) ;
	throw new HTTPException (error) ;
      } finally {
	container.unlock();
      }
      Reply reply = request.makeReply(HTTP.OK) ;
      reply.setContentType (MimeType.TEXT_PLAIN) ;
      reply.setContent (log) ;
      return reply ;
    }

    protected Reply dodiff (Request request)
      throws HTTPException
    {
      String diff = null ;
      try {
	CvsFrame cvsframe = (CvsFrame) container.lock();
	diff = cvsframe.getCvsManager().diff(name);
      } catch (CvsException cvs_ex) {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
	HtmlGenerator g = new HtmlGenerator ("CVS diff command failed") ;
	g.append ("<p>The CVS <strong>diff</strong> command failed "
		  + " on " + name
		  + " with the following error message: "
		  + "<em>" + cvs_ex.getMessage() + "</em>"
		  + "<hr> from class: " + this.getClass().getName()) ;
	error.setStream (g) ;
	throw new HTTPException (error) ;
      } catch (InvalidResourceException ex) {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
	HtmlGenerator g = new HtmlGenerator ("CVS diff command failed") ;
	g.append ("<p>The CVS <strong>diff</strong> command failed "
		  + " on " + name
		  + " with the following error message: "
		  + "<em>" + ex.getMessage() + "</em>"
		  + "<hr> from class: " + this.getClass().getName()) ;
	error.setStream (g) ;
	throw new HTTPException (error) ;
      } finally {
	container.unlock();
      }
      // if there are no differences, generate a dummy report
      Reply         reply = request.makeReply(HTTP.OK) ;
      if((diff == null) || (diff.length() == 0)) {
	HtmlGenerator g = new HtmlGenerator("CVS diff command results");
	g.append("<P>No differences between " + name
		 + " and the repository</P>");
	reply.setStream(g);
      } else {
	reply.setContent(diff);
	reply.setContentType(MimeType.TEXT_PLAIN);
      }
      return reply ;
    }

    /**
     * Getting an entry entity start with dumping the log for this entity
     * which (should) act as a directory for all versions of it.
     */

    public Reply get (Request request)
      throws ProtocolException
    {
      if ( ! request.hasState("query") ) {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);
	error.setContent("Invalid query field.");
	throw new HTTPException (error) ;
      }
      String cmd = request.getQueryString() ;
      if ( cmd.equalsIgnoreCase("log") ) {
	return dolog(request) ;
      } else if ( cmd.equalsIgnoreCase ("diff")) {
	return dodiff(request) ;
      } else {
	Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
	error.setContent ("Unknown command: "+cmd) ;
	throw new HTTPException(error) ;
      }
    }

    public CvsEntryFrame (ResourceReference rr_cvsframe, String name) {
      this.container = rr_cvsframe;
      this.name      = name;
    }

  }
 
  private DummyResourceReference self = null;

  public ResourceReference lookup (String name) {
    return getResourceReference();
  }

  public ResourceReference getResourceReference() {
    if (self == null)
      self = new DummyResourceReference(this);
    return self;
  }

  CvsEntryResource (ResourceReference rr_cvsframe, String name) {
    Hashtable defs = new Hashtable(3);
    registerFrame( new CvsEntryFrame(rr_cvsframe, name), defs );
  }

}
