SitePacker.java :  » Content-Management-System » webman » webman » stager » Java Open Source

Java Open Source » Content Management System » webman 
webman » webman » stager » SitePacker.java
package webman.stager;

import java.util.*;
import java.io.*;
import com.ringlord.archive.*;

/**
 * geht durch die generierte Site, nimmt Informationen aus
 *
 * SiteStructureConfigReader: Nutzerkonfiguration (welche Dateien/Verzeichnisse sollen bertragen werden)
 *
 * SiteDocumentsListing: Informationen ber den letzten Stand der Site
 *   (Dateiliste mit Datum, Gre und Zielverzeichnis) --> welche Dateien sind neu/gendert
 * 
 * schreibt den neuen Stand der Site wieder ins SiteDocumentsListing
 *
 * Endinformation:
 *   neuer Status der Site
 *   die zu bertragenden Dateien
 * 
 * Extendet von webman.stager.SiteDocumentsListing fr leichten Transfer der Dateiliste zum SiteReceiver (Serialisierung)
 *
 * @author $Author: torsten $
 * @version $Revision: 1.22 $
 */
class SitePacker extends SiteDocumentsListing
{

  /**Interne Version, entspricht CVS-Revision*/
  private final static String INTERNAL_VERSION = "1.15";
  /**Umschreibung fr System.out*/
  private static PrintStream sysout;
    /**IO-Puffergre in Bytes fr Kopieren von Dateien*/
    private final static int BUFSIZE = 2048;
    /**Verzeichnistrennzeichen*/
    private final static String FS = File.separator;
    /**das Verzeichnis, von dem aus alle Dateien/Vezeichnisse abgearbeitet werden*/
  private String documentRoot;
    /**Name der Datei in der die alte Dateiliste gespeichert ist*/
    private SiteDocumentsListing oldListing;
 
    /**
     * @param docRoot Wurzelverzeichnis fr den Dateisammelprozess; alle Unterverzeichnisse werden besucht
     * @param configFile Nutzerkonfiguration der Site-Struktur (z.B. conf/sitedocuments.conf)
     * @param targetDir optional kann statt configFile auch nur ein Zielverzeichnis fr den OnlineServer benannt werden
     * dann wird die gesamte documentRoot bertragen; sind beide Parameter vorhanden, wird configFile bevorzugt
     * @param documentListing Name der Datei in der die alte Dateiliste gespeichert ist und die neue auch gespeichert wird
     * @param filterFiles bei false wird nicht beachtet, was die Nutzerkonfiguration aussagt in Bezug darauf 
     * ob Dateien/Verzeichnisse bertragen werden sollen oder nicht
     * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
     */
    SitePacker(String docRoot, String configFile, String targetDir, SiteDocumentsListing documentListing, 
                        boolean filterFiles) throws IOException
    {
        super();
        sysout = System.out; //Work-around fr Jtest (wenn man statisch inititalisiert, erkennt jtest system.out!!
        documentRoot = docRoot;
        oldListing = documentListing;
        SiteStructureConfigReader sscr = new SiteStructureConfigReader(configFile,targetDir);
        sysout.println("SitePacker-Version: " + INTERNAL_VERSION);
        try
        {
          processDirectory(".", sscr, filterFiles);
        }
        catch ( IOException e )
        {
          if ( e.getMessage().endsWith(documentRoot + FS + "." + FS + " is no directory or cannot be read.") )
          {
              throw new IOException("DocumentRoot " + documentRoot + " cannot be read. Check that it's really a readable directory!");
            }
        }    
    }

    /**
     * packt die zu bertragende Site in ein Zip
     * egal, wo das Zip gespeichert wird, die interne Dateistruktur entpricht der DocumentRoot
     * @param filename Name des zu erstellenden Zips
     * @param tempDir Name des temporren Verzeichnisses, in dem die Site fr das Zip zusammengestellt wird
     * @param onlyChangedDocuments wenn true werden nur seit der letzten bertragung neue/genderte Dateien bertragen
     * @return Referenz auf das fertige Zipfile
     * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
     */
    public File zipSite(String filename, String tempDir, boolean onlyChangedDocuments) throws IOException
    {    
        //making tempdir if dont exist
        File f = new File(tempDir);
        createDir(f);
        // copy files to temp dir
        if ( !tempDir.endsWith(FS) && !tempDir.endsWith("/") )  
        //Windows-Pfadnamen knnen in Java auch mit / gebildet werden. Wenn allerdings tempDir auf /
        //endet und ich normalerweise deswegen den FS anhngen wrde, kme ein falscher Pfadname zu Stande
        //(den Dateien im Zip wrde dann immer der erste Buchstabe fehlen!!). Deswegen muss ich auch auf / testen
        {
            tempDir = tempDir + FS;
        }
        if ( !documentRoot.endsWith(FS) && !tempDir.endsWith("/") )  //Begrndung s.o.
        {
            documentRoot = documentRoot + FS;
        }
        // get list of dirs
        String[] dirs = getDirectories();
        for ( int k = 0; k < dirs.length; k++ )
        {    
            // create targetDirs
            createDir(new File(tempDir, dirs[k]));
            // sysout.println("copy contents of directory " + dirs[k] + "<br>");
            // get list of documents
            String[] files;
            if ( onlyChangedDocuments )
            {
                files = getChangedAndNewDocumentNames(dirs[k], oldListing);
            }
            else
            {
                files = getDocumentNames(dirs[k]);
            }
            // copy files
            String aDir = dirs[k] + File.separator;
            for ( int i = 0; i < files.length; i++ )
            { 
                String fname = aDir + files[i];
        //sysout.println("copy file " + fname + " from " + documentRoot + " to " + tempDir + "<br>");
                copyFile(new File(documentRoot, fname), new File(tempDir, fname));
            }
        }
    
        Archive archive = null;
        File archiveFile = new File(filename);
      try
        {
      archive = new ArchiveFactory().create(archiveFile);
            if ( archive == null )
            {
              throw new IOException("archive could not be created.");
            }
            archive.addDir("",new File(tempDir), true);
            archive.close();
    }
      catch (Exception e)
      {
          if ( e.getMessage().indexOf("ZIP file must have at least one entry") > -1 )
            {
              sysout.println("Note: zipfile contains no data.");
                archiveFile.createNewFile(); //neue, leere Datei erstellen (sonst gibz die Datei nich!)
            }
            else
            {
            sysout.println(e);
             e.printStackTrace();
            }
      }
        return archiveFile;
    }

    /**
     * Arbeitet Verzeichnis der DocumentRoot ab und sammelt entsprechend der Konfiguration Dateien/Unterverzeichnisse fr die bertragung
     * @param subDir das aktuell zu bearbeitende Verzeichnis
     * @param sscr die Konfiguration (u.U. aus targetDir hergeleitet, s. Konstruktor)
     * @param filterFiles bei false wird nicht beachtet, was die Nutzerkonfiguration aussagt in Bezug darauf 
     * ob Dateien/Verzeichnisse bertragen werden sollen oder nicht
     * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht     
     */
    void processDirectory(String subDir, SiteStructureConfigReader sscr, boolean filterFiles) throws IOException
    {
        String curDir = new File(documentRoot + FS + subDir + FS).getCanonicalPath() + FS;
        //jtest duldet keine System.out.println!!
        sysout.println("site assembler: processing directory " + curDir  + "<br>");
        String target = sscr.getTargetDirectory(subDir + FS);    
        // get contents of current dir
        String[] list = (new File(curDir)).list();
    //Abfrage wichtig, wenn ich mit DocRoot beginne und die falsch gesetzt war (kme sonst zu NullPointeException)
        if ( list == null ) 
        {
          throw new IOException(curDir + " is no directory or cannot be read.");
        }
        // look at every entry
        for ( int i = 0; i < list.length; i++ )
        {
            //System.out.println("packer: " + subDir + FS + list[i] + " ?");
            File f = new File(curDir + list[i]);
            if ( f.isDirectory() )
            {
                // test if dir belongs to site
                if ( !filterFiles || sscr.belongsToSite(subDir + FS + list[i] + FS) )
                {
                    // recursive call
                    processDirectory(subDir + FS + list[i], sscr, filterFiles);
                }
            }
            else
            {
                // test if document belongs to site        
                if ( !filterFiles || sscr.belongsToSite(subDir + FS + list[i]) )
                {
                    addDocument(subDir, list[i], f.lastModified(), f.length(), target);
                    //System.out.println("packer: added doc " + subDir + FS + list[i] + "<br>");    
                }
            }
        }
    }

     /**
     * Kopiert Dateien/Verzeichnisse
     * @param source Quelldatei/-verzeichnis
     * @param target Zieldatei/-verzeichnis
     * @throws IOException wenn beim Kopieren was schiefgeht     
     */
    static void copyFile(File source, File target) throws IOException
    {
      if ( source.isDirectory() ) //kann Directories als solche nicht kopieren
        {
          if ( !target.mkdir() )
            {
              throw new IOException("could not create temporary directory " + target.getPath());
            }
            return; //mehr ist nicht zu tun
        }
      FileInputStream fis = null;
      FileOutputStream fos = null;
        try
        {
            fis = new FileInputStream(source);
            fos = new FileOutputStream(target);
            byte[] buf = new byte[BUFSIZE];
            //int offs = 0;
            int read;

            while ( (read = fis.read(buf, 0, BUFSIZE)) != -1)
            {
                fos.write(buf, 0, read);
            }
            fos.flush();
        }
        catch (IOException e)
        {
            throw new IOException("unable to copy file " + source + " to " + target  + " (" + e + ")"); 
        }    
        finally
        {
          if ( fis != null ) 
            {
              fis.close();
            }
            if ( fos != null )
            {
              fos.close(); 
            }
        }
    }

    /**
     * Erstellt ein Verzeichnis, falls es noch nicht vorhanden ist (und auch keine gleichnamige Datei existiert)
     * @param f zu erstellendes Verzeichnis
     * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht     
     */
    static void createDir(File f) throws IOException
    {
        if ( !f.exists() )
        {
            if ( !f.mkdirs() )
            {
                throw new IOException("unable to create directory: " + f);
            }
        }
        else
        {
            // must be a directory
            if ( !f.isDirectory() ) 
            {
                throw new IOException("unable to create directory: " + f + " - a file with that name exist");
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.