Package org.w3c.jigedit.filters

Source Code of org.w3c.jigedit.filters.PutListResource

// PutListResource.java
// $Id: PutListResource.java,v 1.14 2007/02/09 21:20:12 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigedit.filters;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import java.net.URL;

import org.w3c.util.IO;
import org.w3c.util.ObservableProperties;

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.FileAttribute;
import org.w3c.tools.resources.FileResource;
import org.w3c.tools.resources.FramedResource;
import org.w3c.tools.resources.IntegerAttribute;
import org.w3c.tools.resources.InvalidResourceException;
import org.w3c.tools.resources.Resource;
import org.w3c.tools.resources.ResourceReference;
import org.w3c.tools.resources.ServerInterface;

import org.w3c.tools.resources.serialization.Serializer;
import org.w3c.tools.resources.ProtocolException;

import org.w3c.cvs.CVS;
import org.w3c.cvs.CvsDirectory;
import org.w3c.cvs.CvsException;
import org.w3c.cvs.UncheckedOutException;

import org.w3c.jigsaw.auth.AuthFilter;

import org.w3c.jigsaw.http.Request;

import org.w3c.www.http.HttpRequestMessage;

public class PutListResource extends FramedResource {

    protected static final boolean debug = true;

    /**
     * status: File published
     */
    public static final int FILE_PB = 1;

    /**
     * status: File unchanged
     */
    public static final int FILE_UC = 2;

    /**
     * status: File merged
     */
    public static final int FILE_MG = 3;

    /**
     * status: conflict
     */
    public static final int FILE_CF = 4;

    /**
     * status: deleted
     */
    public static final int FILE_DEL = 5;

    /**
     * Attribute index - The file used to store the modification list.
     */
    protected static int ATTR_FILE = -1;
    /**
     * Attribute index - The user's local space.
     */
    protected static int ATTR_SPACE = -1;
    /**
     * Attribute index - The web server public space.
     */
    protected static int ATTR_ROOT = -1;
    /**
     * Attribute index - The auto publish flag
     */   
    protected static int ATTR_AUTO_PUBLISH = -1;
    /**
     * Attribute index - The auto delete flag
     */   
    protected static int ATTR_AUTO_DELETE = -1;
    /**
     * Attribute index - The max number of published entries stored
     */
    protected static int ATTR_MAX_PUBLISHED = -1;

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

  try {
      c = Class.forName("org.w3c.jigedit.filters.PutListResource");
  } catch (Exception ex) {
      ex.printStackTrace();
      System.exit(1);
  }
  // Register the file attribute:
  a = new FileAttribute("file"
            , null
            , Attribute.EDITABLE|Attribute.MANDATORY);
  ATTR_FILE = AttributeRegistry.registerAttribute(c, a);
  // Register the space attribute:
  a = new FileAttribute("space"
            , null
            , Attribute.EDITABLE|Attribute.MANDATORY);
  ATTR_SPACE = AttributeRegistry.registerAttribute(c, a);
  // Register the server root:
  a = new FileAttribute("root"
            , null
            , Attribute.EDITABLE| Attribute.MANDATORY);
  ATTR_ROOT = AttributeRegistry.registerAttribute(c, a);
  // Register the auto publish flag
  a = new BooleanAttribute("auto-publish",
         Boolean.FALSE,
         Attribute.EDITABLE);
  ATTR_AUTO_PUBLISH = AttributeRegistry.registerAttribute(c, a);
  // Register the auto delete flag
  a = new BooleanAttribute("auto-delete",
         Boolean.FALSE,
         Attribute.EDITABLE);
  ATTR_AUTO_DELETE = AttributeRegistry.registerAttribute(c, a);
  // Register the max number of published entries stored
  a = new IntegerAttribute("max-published",
         new Integer(10),
         Attribute.EDITABLE);
  ATTR_MAX_PUBLISHED = AttributeRegistry.registerAttribute(c, a);
    }

    protected static Serializer serializer = null;

    static {
  serializer =
      new org.w3c.tools.resources.serialization.xml.XMLSerializer();
    }

    /**
     * Get our auto publish flag.
     * @return a boolean.
     */
    public boolean getAutoPublishFlag() {
  return getBoolean(ATTR_AUTO_PUBLISH, false);
    }

    /**
     * Enable or disable the auto publish feature.
     * @param onoff if onoff is true auto publish is enable.
     */
    protected void setAutoPublish(boolean onoff) {
  setValue(ATTR_AUTO_PUBLISH, new Boolean(onoff));
    }

    /**
     * Get our auto delete flag.
     * @return a boolean.
     */
    public boolean getAutoDeleteFlag() {
  return getBoolean(ATTR_AUTO_DELETE, false);
    }

    /**
     * Enable or disable the auto delete feature.
     * @param onoff if onoff is true auto publish is enable.
     */
    protected void setAutoDelete(boolean onoff) {
  setValue(ATTR_AUTO_DELETE, new Boolean(onoff));
    }

    /**
     * Get the max number of published entries stored in the putlist.
     * @return an int.
     */
    public int getMaxPublishedEntryStored() {
  return getInt(ATTR_MAX_PUBLISHED, 10);
    }

    /**
     * Set the max number of published entries stored in the putlist.
     * @param max This number.
     */
    protected void setMaxPublishedEntryStored(int max) {
  setValue(ATTR_MAX_PUBLISHED, new Integer(max));
    }

    /**
     * Known entries.
     */
    private Hashtable entries = null;

    /**
     * Known "todelete" entries.
     */
    private Hashtable dentries = null;

    /**
     * Published
     */
    private Hashtable published = null;

    /**
     * Our server context properties.
     */
    ObservableProperties props = null;

    /**
     * Get the modified entries.
     * @return an enumeration of PutedEntry
     * @see PutedEntry
     */
    protected Enumeration getEntries() {
  return entries.elements();
    }

    /**
     * Get the modified entries keys
     * @return an enumeration of String
     */
    protected Enumeration getEntriesKeys() {
  return entries.keys();
    }

    /**
     * Get the modified entry relative to the given key.
     * @param key The key relative to the PutedEntry
     * @return a PutedEntry
     * @see PutedEntry
     */
    protected PutedEntry getEntry(String key) {
  return (PutedEntry) entries.get(key);
    }

    /**
     * Add an entry into the putlist
     * @param e the entry to add
     */
    protected void addEntry(PutedEntry e) {
  entries.put(e.getKey(), e);
    }

    /**
     * Remove a modified entry from the putlist
     * @param key the key of the entry to remove
     */
    protected void removeEntry(String key) {
  entries.remove(key);
    }

    /**
     * Get the deleted entries.
     * @return an enumeration of DeletedEntry
     * @see DeletedEntry
     */
    protected Enumeration getDelEntries() {
  return dentries.elements();
    }

    /**
     * Get the deleted entries keys
     * @return an enumeration of String
     */
    protected Enumeration getDelEntriesKeys() {
  return dentries.keys();
    }

    /**
     * Get the deleted entry relative to the given key.
     * @param key The key relative to the DeletedEntry
     * @return a DeletedEntry
     * @see DeletedEntry
     */
    protected DeletedEntry getDelEntry(String key) {
  return (DeletedEntry) dentries.get(key);
    }

    /**
     * Add an entry into the putlist
     * @param e the entry to add
     */
    protected void addDelEntry(DeletedEntry e) {
  dentries.put(e.getKey(), e);
    }

    /**
     * Remove a deleted entry from the putlist
     * @param key the key of the entry to remove
     */
    protected void removeDelEntry(String key) {
  dentries.remove(key);
    }

    //---

    /**
     * Get the published entries.
     * @return an enumeration of PutedEntry
     * @see PutedEntry
     */
    protected Enumeration getPublishedEntries() {
  return published.elements();
    }

    /**
     * Remove the oldest published entry from the putlist.
     */
    protected void removeOldestPublishedEntry() {
  //Could be optimized, but it is significant?
  Enumeration penum = published.elements();
  PutedEntry oldest = null;
  PutedEntry current = null;

  if (!penum.hasMoreElements()) {
      return;
  }
  oldest = (PutedEntry) penum.nextElement();
  while (penum.hasMoreElements()) {
      current = (PutedEntry) penum.nextElement();
      if (current.getTime() < oldest.getTime())
    oldest = current;
  }
  published.remove(oldest.getKey());
    }

    /**
     * Add a published entry into the putlist.
     * @param e The published entry to add.
     * @see PutedEntry
     */
    protected synchronized void addPubEntry(PutedEntry e) {
  while (published.size() >= getMaxPublishedEntryStored())
      removeOldestPublishedEntry();
  published.put(e.getKey(), e);
    }

    /**
     * Remove a published entry from the putlist
     * @param key the key of the entry to remove
     */
    protected synchronized void removePubEntry(String key) {
  published.remove(key);
    }

    /**
     * Compute the path of the public file for the given local file.
     * This method uses the <em>space</em> and <em>root</em> attributes
     * to translate the path of the given file from the user's local space
     * to the public (server) space.
     * @return A File instance, or <strong>null</strong>.
     */
    protected File getServerFile(File file) {
  String fpath  = file.getAbsolutePath();
  String fspace = getCvsSpace().getAbsolutePath();
  if ( ! fpath.startsWith(fspace) )
      return null;
  return new File(getRoot(), fpath.substring(fspace.length()));
    }

    /**
     * Get the file to use to store the edited list of files.
     * @return The file.
     */
    public File getFile() {
  return (File) getValue(ATTR_FILE, null);
    }

    /**
     * Get the file to use to store the edited list of published files.
     * @return The file.
     */
    public File getPubFile() {
        File file = getFile();
  if (file != null)
        return new File(file+".pub");
  else
    return null;
    }

    /**
     * Get the file to use to store the edited list of deleted files.
     * @return The file.
     */
    public File getDelFile() {
        File file = getFile();
  if (file != null)
        return new File(file+".del");
  else
    return null;
    }

    /**
     * Get the root directory of the public server to update.
     * @return The root directory of the public server space, supposed to
     * be controled by CVS.
     */
    public File getRoot() {
  return (File) getValue(ATTR_ROOT, null);
    }

    /**
     * Get this user's local CVS space root directory.
     * @return The usre's root of the CVS local space, assumed to be
     * under CVS control.
     */
    public File getCvsSpace() {
  return (File) getValue(ATTR_SPACE, null);
    }

    protected synchronized void write(File file, Enumeration genum) {
  if (file == null)
      return;
  File backup = null;
  // Save old version if available:
  if ( file.exists() ) {
      backup = new File(file+".bak");
      if ( backup.exists() )
    backup.delete();
      file.renameTo(backup);
  }
  try {
      Vector v = new Vector(10);
      while (genum.hasMoreElements()) {
    v.addElement(genum.nextElement());
      }
      AttributeHolder holders[] = new AttributeHolder[v.size()];
      v.copyInto(holders);
      Writer writer = new BufferedWriter(new FileWriter(file));
      serializer.writeResources(holders, writer);
  } catch (Exception ex) {
      ex.printStackTrace();
      if ( backup != null )
    backup.renameTo(file);
  }
    }

    /**
     * Dump the current list of edited files back to disk.
     */
    protected synchronized void writeList() {
  write(getFile(), entries.elements());
    }

    /**
     * Dump the current list of published files back to disk.
     */
    protected synchronized void writePubList() {
  write(getPubFile(), published.elements());
    }

    /**
     * Dump the current list of [ublished files back to disk.
     */
    protected synchronized void writeDelList() {
  write(getDelFile(), getDelEntries());
    }

    protected synchronized void removeUnconfirmedDelEntries() {
  Enumeration denum = getDelEntries();
  while (denum.hasMoreElements()) {
      DeletedEntry e = (DeletedEntry) denum.nextElement();
      if (! e.isConfirmed()) {
    removeDelEntry(e.getKey());
      }
  }
    }

    /**
     * Restore the list from the file.
     */
    protected synchronized void readList() {
  File file = getFile();
  try {
      Reader reader = new BufferedReader(new FileReader(file));
      AttributeHolder holders[] =
    serializer.readAttributeHolders(reader);
      for (int i = 0 ; i < holders.length ; i++)
    addEntry((PutedEntry)holders[i]);
  } catch (Exception ex) {
      // FIXME
      ex.printStackTrace();
  }
    }

    /**
     * Restore the published list from the file.
     */
    protected synchronized void readPubList() {
  File file = getPubFile();
  try {
      Reader reader = new BufferedReader(new FileReader(file));
      AttributeHolder holders[] =
    serializer.readAttributeHolders(reader);
      for (int i = 0 ; i < holders.length ; i++)
    addPubEntry((PutedEntry)holders[i]);
  } catch (Exception ex) {
      // FIXME
      ex.printStackTrace();
  }
    }

    /**
     * Restore the deleted list from the file.
     */
    protected synchronized void readDelList() {
  File file = getDelFile();
  try {
      Reader reader = new BufferedReader(new FileReader(file));
      AttributeHolder holders[] =
    serializer.readAttributeHolders(reader);
      for (int i = 0 ; i < holders.length ; i++) {
    DeletedEntry e = (DeletedEntry) holders[i];
    e.confirm();
    addDelEntry(e);
      }
  } catch (Exception ex) {
      // FIXME
      ex.printStackTrace();
  }
    }

    protected PutedEntry lookupEntry(Request request) {
  ResourceReference rr = request.getTargetResource();
  String            k  = request.getURL().toExternalForm();
  Resource          r  = null;
  if (rr != null) {
    try {
      r = rr.lock();
      if ( r instanceof FileResource )
        k = ((FileResource) r).getFile().getAbsolutePath().toString();
    } catch (InvalidResourceException ex) {
      // continue
    } finally {
      rr.unlock();
    }
  }
  return (PutedEntry) entries.get(k);
    }

    protected DeletedEntry lookupDelEntry(Request request) {
  ResourceReference rr = request.getTargetResource();
  String            k  = request.getURL().toExternalForm();
  Resource          r  = null;
  if (rr != null) {
    try {
      r = rr.lock();
      if ( r instanceof FileResource )
        k = ((FileResource) r).getFile().getAbsolutePath().toString();
    } catch (InvalidResourceException ex) {
      // continue
    } finally {
      rr.unlock();
    }
  }
  return (DeletedEntry) dentries.get(k);
    }

    /**
     * Register the given request, which must has a PUT method.
     * @param file The modified file.
     */
    public synchronized int registerRequest(Request request) {
  PutedEntry e = lookupEntry(request);
  if ( e == null ) {
      e = PutedEntry.makeEntry(request);
      addEntry(e);
  } else {
      e.update(request);
  }
  if (getAutoPublishFlag()) {
      return publish(e);
  } else {
      return FILE_UC;
  }
    }

    public synchronized void registerDeleteRequest(Request request) {
  DeletedEntry e = (DeletedEntry) DeletedEntry.makeEntry(request);
  addDelEntry(e);
    }

    public synchronized int confirmDelete(Request request) {
  DeletedEntry e = lookupDelEntry(request);
  if (e != null) {
      e.confirm();
      if (getAutoDeleteFlag())
    return delete(e);
  }
  return FILE_UC;
    }

    /**
     * Delete the file relative to the given entry.
     * @param entry The DeletedEntry.
     * @return FILE_UC, FILE_DEL
     */
    protected int delete(DeletedEntry de) {
  File file  = new File(de.getFilename());
  File sfile = getServerFile(file);
  if (sfile.exists()) {
      if (debug)
    System.out.println("Deleting : "+sfile);
      sfile.delete();
      removeDelEntry(de.getKey());
      return FILE_DEL;
  } else {
      if (debug)
    System.out.println("Nothing to delete : "+sfile);
      removeDelEntry(de.getKey());
      return FILE_UC;
  }
    }

    /**
     * Publish the file relative to the given entry.
     * @param entry The PutedEntry.
     * @return FILE_UC, FILE_CF, FILE_PB, FILE_MG
     */
    protected int publish(PutedEntry pe) {
  File file  = new File(pe.getFilename());
  File sfile = getServerFile(file);
  int status = FILE_UC;

  try {
      // First step: does the private version needs commit ?
      File         d  = new File(file.getParent());
      CvsDirectory c  = CvsDirectory.getManager(d, props);
      if ( c.status(file.getName()) == CVS.FILE_M ) {
    String author = pe.getAuthor();
    String env [] = { "USER="+author ,
          "LOGNAME="+author };
    String msg    = ((author != null)
         ? "Published by "+author+" through Jigsaw"
         : "Published through Jigsaw");
    c.commit(file.getName(), msg, env);
      } else if ( debug ) {
    System.out.println("PutList: no commit needed on "+
           file.getAbsolutePath()+
           " st="+c.status(file.getName()));
      }
      // Second step: publish
      File sd = new File(sfile.getParent());
      try {
    CvsDirectory sc =
        CvsDirectory.getManager(sd, props);
    String filename = sfile.getName();
    int cvs_status = sc.status(filename);
    if (debug) {
        System.out.println("publishing "+
               CvsDirectory.statusToString(cvs_status)+
               " file : "+filename);
    }
    if (cvs_status == CVS.FILE_C) {
        //conflict! we try to merge
        //create a backup file
        File backup = new File(sfile.getParent(), filename+".bak");
        try {
      org.w3c.util.IO.copy(sfile, backup);
      //try to merge
      sc.update(filename);
      cvs_status = sc.status(filename);
      if (cvs_status == CVS.FILE_M) {
          //merge done, so commit.
          String author = pe.getAuthor();
          String env [] = { "USER="+author ,
                "LOGNAME="+author };
          String msg    = ((author != null)
               ? "Merged by "+author+
               " through Jigsaw"
               : "Merged through Jigsaw");
          sc.commit(filename, msg, env);
          //done so delete backup file
          backup.delete();
          status = FILE_MG;
      } else if (cvs_status == CVS.FILE_C) {
          //merge failed
          sfile.delete();
          backup.renameTo(sfile);
          status = FILE_CF;
      }
        } catch (IOException ex) {
      ex.printStackTrace();
      status = FILE_CF;
        }
    } else if (cvs_status != CVS.FILE_OK) {
        sc.update(filename);
        status = FILE_PB;
    } else if ( debug ) {
        System.out.println("PutList: no update needed on "+
              sfile.getAbsolutePath()+
              " st="+
              CvsDirectory.statusToString(cvs_status));
    }
      } catch (UncheckedOutException ex) {
    // perform a get from root
    File root = new File(getRoot().getAbsolutePath());
    CvsDirectory sc = CvsDirectory.getManager(root, props);
    String fpath  = file.getAbsolutePath();
    String fspace = getCvsSpace().getAbsolutePath();
    String path   = fpath.substring(fspace.length()+1);
    sc.get(path);
    status = FILE_PB;
      }
      // Last step: remove published entries:
      entries.remove(pe.getKey());
      // publication time
      pe.setValue(PutedEntry.ATTR_TIME,
      new Long(System.currentTimeMillis()));
      addPubEntry(pe);
  } catch (CvsException ex) {
      ex.printStackTrace();
  }
  return status;
    }

    public synchronized void notifyUnload() {
  writeList();
  writePubList();
  writeDelList();
  super.notifyUnload();
    }

    public void initialize(Object values[]) {
  super.initialize(values);
  // Prepare empty entry list:
  File file = getFile();
  if ((file != null) && file.exists())
      readList();
  File pub = getPubFile();
  if ((pub != null) && pub.exists())
      readPubList();
  File del = getDelFile();
  if ((del != null) && del.exists())
      readDelList();
  // Get the server properties:
  this.props = getServer().getProperties();
  try {
    registerFrameIfNone("org.w3c.jigedit.filters.PutListFrame",
            "putlist-frame");
  } catch (Exception ex) {
    ex.printStackTrace();
  }
    }

    public PutListResource() {
  super();
  this.entries = new Hashtable(11);
  this.dentries = new Hashtable(11);
  this.published = new Hashtable(11);
    }

}
TOP

Related Classes of org.w3c.jigedit.filters.PutListResource

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.