Package org.w3c.jigedit.webdav.frames

Source Code of org.w3c.jigedit.webdav.frames.CvsDAVFileFrame

// CvsDAVFileFrame.java
// $Id: CvsDAVFileFrame.java,v 1.5 2007/02/11 10:52:15 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigedit.webdav.frames ;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

import org.w3c.tools.resources.Attribute;
import org.w3c.tools.resources.AttributeHolder;
import org.w3c.tools.resources.AttributeRegistry;
import org.w3c.tools.resources.BooleanAttribute;
import org.w3c.tools.resources.DirectoryResource;
import org.w3c.tools.resources.FileResource;
import org.w3c.tools.resources.FramedResource;
import org.w3c.tools.resources.InvalidResourceException;
import org.w3c.tools.resources.MultipleLockException;
import org.w3c.tools.resources.ProtocolException;
import org.w3c.tools.resources.ReplyInterface;
import org.w3c.tools.resources.RequestInterface;
import org.w3c.tools.resources.Resource;
import org.w3c.tools.resources.ResourceException;
import org.w3c.tools.resources.ResourceFrame;
import org.w3c.tools.resources.ResourceReference;
import org.w3c.tools.resources.ServerInterface;

import org.w3c.jigsaw.webdav.DAVFrame;
import org.w3c.jigsaw.webdav.DAVRequest;

import org.w3c.jigsaw.http.HTTPException;
import org.w3c.jigsaw.http.Reply;
import org.w3c.jigsaw.http.Request;

import org.w3c.jigsaw.auth.AuthFilter;

import org.w3c.www.http.HTTP;
import org.w3c.www.http.HttpEntityMessage;
import org.w3c.www.http.HttpMessage;
import org.w3c.www.http.HttpReplyMessage;
import org.w3c.www.http.HttpRequestMessage;

import org.w3c.www.mime.MimeType;

import org.w3c.jigsaw.html.HtmlGenerator;

import org.w3c.cvs.CVS;
import org.w3c.cvs.CvsAddException;
import org.w3c.cvs.CvsDirectory;
import org.w3c.cvs.CvsException;
import org.w3c.cvs.UpToDateCheckFailedException;

import org.w3c.jigedit.cvs.CvsFrame;
import org.w3c.jigedit.cvs.CvsModule;

/**
* This subclass of HTTPFrame check cvs before performing a PUT request.
* If a CVS directory exists<BR>
* <ul>
* If the resource file exists<BR>
* <ul>
* If resource file not up to date Fail.<BR>
* Else perform PUT and commit it into cvs.<BR>
* </ul>
* Else perform PUT, add and commit it into cvs.<BR>
* </ul>
* Else perform PUT.
* @author Benoit Mahe <bmahe@sophia.inria.fr>
*/

public class CvsDAVFileFrame extends DAVFrame {

    public static final boolean debug = true;

    private final Object monitor = new Object();

    /**
     * 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("org.w3c.jigedit.webdav.frames.CvsDAVFileFrame") ;
  } 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) ;
    }

    protected static Reply error(Request request,
         int status,
         String title,
         String msg)
    {
  Reply error = request.makeReply(status);
  HtmlGenerator g = CvsFrame.getHtmlGenerator(title);
  g.append("<span class=\"title\">",title,"</span>\n");
  g.append("<p>",msg);
  error.setStream(g);
  return error;
    }

    /**
     * tell if we must always do an update.
     */
    public boolean isAutoUpdatable() {
  return getBoolean(ATTR_AUTOUPDATE, false);
    }

    protected File resDirectory = null;

    protected synchronized File getResourceDirectory() {
  if (resDirectory == null) {
      ResourceReference rr = getFileResource().getParent();
      ResourceReference rrtemp = null;
      Resource p = null;
      while ( true ) {
    try {
        if (rr == null)
      return null;
        p = rr.lock();
        if (p instanceof DirectoryResource) {
      resDirectory = ((DirectoryResource)p).getDirectory();
      break;
        }
        rrtemp = p.getParent();
    } catch (InvalidResourceException ex) {
        return null;
    } finally {
        if (rr != null)
      rr.unlock();
    }
    rr = rrtemp;
      }
  }
  return resDirectory;
    }

    protected synchronized CvsDirectory getCvsManager()
  throws CvsException
    {
  return CvsModule.getCvsManager(getResourceDirectory(),
               getContext(),
               getServer().getProperties());
    }

    protected boolean checkCvsManager() {
  try {
      return (getCvsManager() != null);
  } catch (CvsException ex) {
      return false;
  }
    }

    /**
     * Get this resource Etag string, it will be computed using
     * FileETag MTime Size directive like in Apache, this will fit some
     * needs for our own server farm, it won't hurt anyway/
     * @return a string or null if not applicable
     */
    public String computeETag() {
  String etag_s = null;
  if (fresource != null) {
      long lstamp = fresource.getFileStamp();
      long lsize = (long) fresource.getFileLength();
      if ( lstamp >= 0L ) {
    etag_s = Long.toHexString(lsize) + "-"
        + Long.toHexString(lstamp);
      }
  }
  return etag_s;
    }

    /**
     * @exception CvsException if the CVS process failed
     */
    protected void add(Request request)
  throws CvsException
    {
  String u = (String)request.getState(AuthFilter.STATE_AUTHUSER);
  String env[] = {"USER="+u , "LOGNAME="+u };
  String names [] = null;
  MimeType mtype;
        mtype = request.getContentType();
  if (mtype != null &&
      (mtype.match(MimeType.TEXT) != MimeType.MATCH_SUBTYPE) &&
      (mtype.match(MimeType.APPLICATION_XHTML_XML) !=
                      MimeType.MATCH_SPECIFIC_SUBTYPE)) {
      names = new String[2];
      names[0] = "-kb";
      names[1] = getFileResource().getFile().getName();
  } else {
      names = new String[1];
      names[0] = getFileResource().getFile().getName();
  }
  CvsDirectory cvsdir = null;
  cvsdir = getCvsManager();
  cvsdir.add(names, env);
    }

    /**
     * @exception CvsException if the CVS process failed
     */
    protected void commit(Request request)
  throws CvsException
    {
  commit (request, "Changed through Jigsaw.");
    }

    /**
     * @exception CvsException if the CVS process failed
     */
    protected void commit(Request request, String msg)
  throws CvsException
    {
  String u = (String)request.getState(AuthFilter.STATE_AUTHUSER);
  String env[] = {"USER="+u , "LOGNAME="+u };
  String comment = "("+u+") "+msg;
  CvsDirectory cvsdir = null;
  cvsdir = getCvsManager();
  cvsdir.commit(getFileResource().getFile().getName(), comment, env);
    }

    /**
     * @exception CvsException if the CVS process failed
     */
    protected void update()
  throws CvsException
    {
  CvsDirectory cvsdir = getCvsManager();
  cvsdir.update(getFileResource().getFile().getName());
    }

    /**
     * @exception CvsException if the CVS process failed
     */
    protected int status()
  throws CvsException
    {
  CvsDirectory cvsdir = getCvsManager();
  return cvsdir.status(getFileResource().getFile().getName());
    }

    protected String statusToString(int status) {
  return CvsDirectory.statusToString(status);
    }

    protected File getBackupFile() {
  File file = getFileResource().getFile();
  return new File(file.getParent(), file.getName()+".bak");
    }

    /**
     * Change the content of the associated FileResource.
     * +cvs action (commit, update)
     * @param request The incomming request.
     * @exception org.w3c.tools.resources.ProtocolException
     * if a protocol error occurs
     * @exception org.w3c.tools.resources.ResourceException
     * if a server error occurs
     */
    protected Reply putFileResource(Request request)
  throws ProtocolException, ResourceException
    {
  if (debug)
      System.out.println("Put on "+getResource().getIdentifier()+"...");
  if (getResourceDirectory() != null) {
      if (checkCvsManager()) {
    File resfile = getFileResource().getFile();
    int cvs_status = -1;
    try {
        cvs_status = status();
    } catch (CvsException ex) {
        //file not on disk yet, let's try to add this file..
        cvs_status = CVS.FILE_Q;
    }
    if (debug)
        System.out.println("... with a cvs status equals to : "+
               statusToString(cvs_status));
    if (cvs_status == CVS.FILE_C) {
        String msg = "Conflict between working "+
      "revision and repository revision.<br> "+
      "Please update the file manually or use the CVS form.";
        return error( request,
          HTTP.CONFLICT,
          "Conflict",
          msg );
    } else if (cvs_status == CVS.FILE_NCO) {
        String msg = "File already in the repository "+
      "(added independently by second party).<br>"+
      "Please update the file manually or use the CVS form.";
        return error( request,
          HTTP.CONFLICT,
          "Conflict",
          msg );
    } else if (resfile.exists() && (cvs_status != CVS.FILE_Q)) {
        File backup = getBackupFile();
        try {
      if (cvs_status ==  CVS.FILE_OK) {
          // Write the file to web space
          //save the current file
          try {
        org.w3c.util.IO.copy(resfile, backup);
          } catch (IOException ex) {
        //not exactly what we want but, it ~works
        backup.delete();
        resfile.renameTo(backup);
          }
          //perform the put
          Reply r = super.putFileResource(request);
          int rstatus = r.getStatus();
          // if OK
          if ((rstatus / 100 ) == 2 ) {
        // Do a CVS commit with user name
        commit(request);
          }
          //well done, remove the backup file now
          backup.delete();
          // update the file attrs
          getFileResource().checkContent();
          //return the reply.
          if ((rstatus / 100 ) == 2 ) {
        return createDefaultReply(request,
                r.getStatus());
          } else {
        return r;
          }
      } else {
          // fail
          String msg =
        "File is not up to date, "+
        "please update the file manually "+
        "or use the CVS form.";
          return error( request,
            HTTP.CONFLICT,
            "Error",
            msg );
      }
        } catch (UpToDateCheckFailedException utd_ex) {
      resfile.delete();
      //restore the backup file
      backup.renameTo(resfile);
      //send error
      String msg =  utd_ex.getFilename()+
          " is not up to date, "+
          "please update the file manually "+
          "or use the CVS form.";
      return error( request,
              HTTP.CONFLICT,
              "Error",
              msg );
        } catch (CvsException ex) {
      backup.delete();
      // fail too
      String msg = "CvsException : "+ex.getMessage();
      getServer().errlog(getIdentifier()+" : "
             +ex.getMessage());
      return error( request,
              HTTP.SERVICE_UNAVAILABLE,
              "Error",
              msg );
        }
    } else {
        // Write the file to web space
        Reply r = super.putFileResource(request);
        try {
      //  Do a CVS add with user name
      add(request);
      //  Do a CVS commit with user name
      commit(request);
      getFileResource().checkContent();
        } catch (CvsAddException ex) {
      String msg = "Cvs add failed : <br>'"+
          ex.getMessage()+
          "'<br>please update the file manually "+
          "or use the CVS form";
      return error( request,
              HTTP.SERVICE_UNAVAILABLE,
              "Error",
              msg );
        } catch (CvsException ex) {
      ex.printStackTrace();
      String msg = "Problem during cvs process : "+
          ex.getMessage();
      getServer().errlog(getIdentifier()+" : "+msg);
      return error( request,
              HTTP.INTERNAL_SERVER_ERROR,
              "Internal Server Error",
              msg );
        }
        if (r.getStatus() == HTTP.CREATED) {
      Reply reply = request.makeReply(r.getStatus());
      reply.setContent("<P>Resource succesfully created");
      if (request.hasState(STATE_CONTENT_LOCATION))
          reply.setContentLocation(
        getURL(request).toExternalForm());
      r = createDefaultReply(request, HTTP.CREATED);
      reply.setETag(r.getETag());
      return reply;
        }
        return createDefaultReply(request, r.getStatus());
    }
      } else {
    return super.putFileResource(request);
      }
  } else {
      String msg = "Server misconfigured : "+
    "unable to find resource directory";
      getServer().errlog(getIdentifier()+" : "+msg);
      return error( request,
        HTTP.INTERNAL_SERVER_ERROR,
        "Internal Server Error",
        msg );
  }
    }

    /**
     * The DELETE method delete the file and perform a cvs remove.
     * @param request The request to handle.
     * @exception ProtocolException if a protocol error occurs
     * @exception ResourceException If the resource got a fatal error.
     */

    protected synchronized Reply deleteFileResource(Request request)
  throws ProtocolException, ResourceException
    {
  if (fresource == null) {
      String msg = "Can't delete resource: "+resource.getIdentifier()+
    " is not associated with a FILE. Try again later.";
      Reply error = error( request,
         HTTP.FORBIDDEN,
         "Error",
         msg );
      throw new HTTPException(error);
  }
  //Get the user name
  String u = (String)request.getState(AuthFilter.STATE_AUTHUSER);
  String env[] = {"USER="+u , "LOGNAME="+u };
  //delete the file
  fresource.getFile().delete();
  //cvs remove
  String names[] = new String[1];
 
  names[0] = fresource.getFilename();
  if (names[0] == null)
      names[0] = fresource.getIdentifier();
  try {
      if (getCvsManager().status(names[0]) != CVS.FILE_Q) {
    getCvsManager().remove(names,
               "Deleted via HTTP delete method.",
               env);
      }
  } catch (CvsException cvs_ex) {
      String msg="Cvs remove failed : "+cvs_ex.getMessage();
      getServer().errlog(this, msg);
  }
  try {
      //delete the FileResource
      fresource.delete();
  } catch (MultipleLockException ex) {
      String msg = "Can't delete resource: "+resource.getIdentifier()+
    " is locked. Try again later.";
      Reply error = error( request,
         HTTP.FORBIDDEN,
         "Error",
         msg );
      throw new HTTPException(error);
  }
  //well done
  return request.makeReply(HTTP.NO_CONTENT) ;
    }

    /**
     * The WEBDAV DELETE method, actually the resource (file, directory)
     * is moved into the trash directory which is not accessible via HTTP.
     * @param request The request to handle.
     * @exception ProtocolException If processsing the request failed.
     * @exception ResourceException If the resource got a fatal error.
     */

    public Reply delete(Request request)
  throws ProtocolException, ResourceException
    {
  synchronized (monitor) {
      return super.delete(request);
  }
    }

    /**
     * The WEBDAV PUT method.
     * @param request The request to handle.
     * @exception ProtocolException If processsing the request failed.
     * @exception ResourceException If the resource got a fatal error.
     */

    public Reply put(Request request)
  throws ProtocolException, ResourceException
    {
  synchronized (monitor) {
      return super.put(request);
  }
    }

    /**
     * Perform a cvs update before perform a GET,HEAD,POST request.
     * @param req The request to handle.
     * @exception ProtocolException If processsing the request failed.
     * @exception ResourceException If the resource got a fatal error.
     */

    public ReplyInterface perform(RequestInterface req)
  throws ProtocolException, ResourceException
    {
  if (! checkRequest(req))
      return null;

  String method = ((Request)req).getMethod () ;
  if (( method.equals("GET") ||  method.equals("HEAD") ||
        method.equals("POST") ||  method.equals("PUT")) &&
      isAutoUpdatable() && (fresource != null)) {
     
      try {
    update();
      } catch (CvsException ex) {
    String msg = "cvs update \""+
        getFileResource().getFile().getName()+
        "\" failed.";
    getServer().errlog(this, msg);
      }
  }
  return super.perform(req);
    }
}
TOP

Related Classes of org.w3c.jigedit.webdav.frames.CvsDAVFileFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.