KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > webman > stager > SitePacker


1 package webman.stager;
2
3 import java.util.*;
4 import java.io.*;
5 import com.ringlord.archive.*;
6
7 /**
8  * geht durch die generierte Site, nimmt Informationen aus
9  *
10  * SiteStructureConfigReader: Nutzerkonfiguration (welche Dateien/Verzeichnisse sollen übertragen werden)
11  *
12  * SiteDocumentsListing: Informationen über den letzten Stand der Site
13  * (Dateiliste mit Datum, Größe und Zielverzeichnis) --> welche Dateien sind neu/geändert
14  *
15  * schreibt den neuen Stand der Site wieder ins SiteDocumentsListing
16  *
17  * Endinformation:
18  * neuer Status der Site
19  * die zu übertragenden Dateien
20  *
21  * Extendet von webman.stager.SiteDocumentsListing für leichten Transfer der Dateiliste zum SiteReceiver (Serialisierung)
22  *
23  * @author $Author: torsten $
24  * @version $Revision: 1.22 $
25  */

26 class SitePacker extends SiteDocumentsListing
27 {
28
29     /**Interne Version, entspricht CVS-Revision*/
30     private final static String JavaDoc INTERNAL_VERSION = "1.15";
31     /**Umschreibung für System.out*/
32     private static PrintStream sysout;
33     /**IO-Puffergröße in Bytes für Kopieren von Dateien*/
34     private final static int BUFSIZE = 2048;
35     /**Verzeichnistrennzeichen*/
36     private final static String JavaDoc FS = File.separator;
37     /**das Verzeichnis, von dem aus alle Dateien/Vezeichnisse abgearbeitet werden*/
38     private String JavaDoc documentRoot;
39     /**Name der Datei in der die alte Dateiliste gespeichert ist*/
40     private SiteDocumentsListing oldListing;
41  
42     /**
43      * @param docRoot Wurzelverzeichnis für den Dateisammelprozess; alle Unterverzeichnisse werden besucht
44      * @param configFile Nutzerkonfiguration der Site-Struktur (z.B. conf/sitedocuments.conf)
45      * @param targetDir optional kann statt configFile auch nur ein Zielverzeichnis für den OnlineServer benannt werden
46      * dann wird die gesamte documentRoot übertragen; sind beide Parameter vorhanden, wird configFile bevorzugt
47      * @param documentListing Name der Datei in der die alte Dateiliste gespeichert ist und die neue auch gespeichert wird
48      * @param filterFiles bei false wird nicht beachtet, was die Nutzerkonfiguration aussagt in Bezug darauf
49      * ob Dateien/Verzeichnisse übertragen werden sollen oder nicht
50      * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
51      */

52     SitePacker(String JavaDoc docRoot, String JavaDoc configFile, String JavaDoc targetDir, SiteDocumentsListing documentListing,
53                         boolean filterFiles) throws IOException
54     {
55         super();
56         sysout = System.out; //Work-around für Jtest (wenn man statisch inititalisiert, erkennt jtest system.out!!
57
documentRoot = docRoot;
58         oldListing = documentListing;
59         SiteStructureConfigReader sscr = new SiteStructureConfigReader(configFile,targetDir);
60         sysout.println("SitePacker-Version: " + INTERNAL_VERSION);
61         try
62         {
63             processDirectory(".", sscr, filterFiles);
64         }
65         catch ( IOException e )
66         {
67             if ( e.getMessage().endsWith(documentRoot + FS + "." + FS + " is no directory or cannot be read.") )
68             {
69                 throw new IOException("DocumentRoot " + documentRoot + " cannot be read. Check that it's really a readable directory!");
70             }
71         }
72     }
73
74     /**
75      * packt die zu übertragende Site in ein Zip
76      * egal, wo das Zip gespeichert wird, die interne Dateistruktur entpricht der DocumentRoot
77      * @param filename Name des zu erstellenden Zips
78      * @param tempDir Name des temporären Verzeichnisses, in dem die Site für das Zip zusammengestellt wird
79      * @param onlyChangedDocuments wenn true werden nur seit der letzten Übertragung neue/geänderte Dateien übertragen
80      * @return Referenz auf das fertige Zipfile
81      * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
82      */

83     public File zipSite(String JavaDoc filename, String JavaDoc tempDir, boolean onlyChangedDocuments) throws IOException
84     {
85         //making tempdir if dont exist
86
File f = new File(tempDir);
87         createDir(f);
88         // copy files to temp dir
89
if ( !tempDir.endsWith(FS) && !tempDir.endsWith("/") )
90         //Windows-Pfadnamen können in Java auch mit / gebildet werden. Wenn allerdings tempDir auf /
91
//endet und ich normalerweise deswegen den FS anhängen würde, käme ein falscher Pfadname zu Stande
92
//(den Dateien im Zip würde dann immer der erste Buchstabe fehlen!!). Deswegen muss ich auch auf / testen
93
{
94             tempDir = tempDir + FS;
95         }
96         if ( !documentRoot.endsWith(FS) && !tempDir.endsWith("/") ) //Begründung s.o.
97
{
98             documentRoot = documentRoot + FS;
99         }
100         // get list of dirs
101
String JavaDoc[] dirs = getDirectories();
102         for ( int k = 0; k < dirs.length; k++ )
103         {
104             // create targetDirs
105
createDir(new File(tempDir, dirs[k]));
106             // sysout.println("copy contents of directory " + dirs[k] + "<br>");
107
// get list of documents
108
String JavaDoc[] files;
109             if ( onlyChangedDocuments )
110             {
111                 files = getChangedAndNewDocumentNames(dirs[k], oldListing);
112             }
113             else
114             {
115                 files = getDocumentNames(dirs[k]);
116             }
117             // copy files
118
String JavaDoc aDir = dirs[k] + File.separator;
119             for ( int i = 0; i < files.length; i++ )
120             {
121                 String JavaDoc fname = aDir + files[i];
122                 //sysout.println("copy file " + fname + " from " + documentRoot + " to " + tempDir + "<br>");
123
copyFile(new File(documentRoot, fname), new File(tempDir, fname));
124             }
125         }
126     
127         Archive archive = null;
128         File archiveFile = new File(filename);
129         try
130         {
131             archive = new ArchiveFactory().create(archiveFile);
132             if ( archive == null )
133             {
134                 throw new IOException("archive could not be created.");
135             }
136             archive.addDir("",new File(tempDir), true);
137             archive.close();
138         }
139         catch (Exception JavaDoc e)
140         {
141             if ( e.getMessage().indexOf("ZIP file must have at least one entry") > -1 )
142             {
143                 sysout.println("Note: zipfile contains no data.");
144                 archiveFile.createNewFile(); //neue, leere Datei erstellen (sonst gibz die Datei nich!)
145
}
146             else
147             {
148                 sysout.println(e);
149                 e.printStackTrace();
150             }
151         }
152         return archiveFile;
153     }
154
155     /**
156      * Arbeitet Verzeichnis der DocumentRoot ab und sammelt entsprechend der Konfiguration Dateien/Unterverzeichnisse für die Übertragung
157      * @param subDir das aktuell zu bearbeitende Verzeichnis
158      * @param sscr die Konfiguration (u.U. aus targetDir hergeleitet, s. Konstruktor)
159      * @param filterFiles bei false wird nicht beachtet, was die Nutzerkonfiguration aussagt in Bezug darauf
160      * ob Dateien/Verzeichnisse übertragen werden sollen oder nicht
161      * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
162      */

163     void processDirectory(String JavaDoc subDir, SiteStructureConfigReader sscr, boolean filterFiles) throws IOException
164     {
165         String JavaDoc curDir = new File(documentRoot + FS + subDir + FS).getCanonicalPath() + FS;
166         //jtest duldet keine System.out.println!!
167
sysout.println("site assembler: processing directory " + curDir + "<br>");
168         String JavaDoc target = sscr.getTargetDirectory(subDir + FS);
169         // get contents of current dir
170
String JavaDoc[] list = (new File(curDir)).list();
171         //Abfrage wichtig, wenn ich mit DocRoot beginne und die falsch gesetzt war (käme sonst zu NullPointeException)
172
if ( list == null )
173         {
174             throw new IOException(curDir + " is no directory or cannot be read.");
175         }
176         // look at every entry
177
for ( int i = 0; i < list.length; i++ )
178         {
179             //System.out.println("packer: " + subDir + FS + list[i] + " ?");
180
File f = new File(curDir + list[i]);
181             if ( f.isDirectory() )
182             {
183                 // test if dir belongs to site
184
if ( !filterFiles || sscr.belongsToSite(subDir + FS + list[i] + FS) )
185                 {
186                     // recursive call
187
processDirectory(subDir + FS + list[i], sscr, filterFiles);
188                 }
189             }
190             else
191             {
192                 // test if document belongs to site
193
if ( !filterFiles || sscr.belongsToSite(subDir + FS + list[i]) )
194                 {
195                     addDocument(subDir, list[i], f.lastModified(), f.length(), target);
196                     //System.out.println("packer: added doc " + subDir + FS + list[i] + "<br>");
197
}
198             }
199         }
200     }
201
202     /**
203      * Kopiert Dateien/Verzeichnisse
204      * @param source Quelldatei/-verzeichnis
205      * @param target Zieldatei/-verzeichnis
206      * @throws IOException wenn beim Kopieren was schiefgeht
207      */

208     static void copyFile(File source, File target) throws IOException
209     {
210         if ( source.isDirectory() ) //kann Directories als solche nicht kopieren
211
{
212             if ( !target.mkdir() )
213             {
214                 throw new IOException("could not create temporary directory " + target.getPath());
215             }
216             return; //mehr ist nicht zu tun
217
}
218         FileInputStream fis = null;
219         FileOutputStream fos = null;
220         try
221         {
222             fis = new FileInputStream(source);
223             fos = new FileOutputStream(target);
224             byte[] buf = new byte[BUFSIZE];
225             //int offs = 0;
226
int read;
227
228             while ( (read = fis.read(buf, 0, BUFSIZE)) != -1)
229             {
230                 fos.write(buf, 0, read);
231             }
232             fos.flush();
233         }
234         catch (IOException e)
235         {
236             throw new IOException("unable to copy file " + source + " to " + target + " (" + e + ")");
237         }
238         finally
239         {
240             if ( fis != null )
241             {
242                 fis.close();
243             }
244             if ( fos != null )
245             {
246                 fos.close();
247             }
248         }
249     }
250
251     /**
252      * Erstellt ein Verzeichnis, falls es noch nicht vorhanden ist (und auch keine gleichnamige Datei existiert)
253      * @param f zu erstellendes Verzeichnis
254      * @throws IOException wenn beim Zusammentragen der Dateien was schiefgeht
255      */

256     static void createDir(File f) throws IOException
257     {
258         if ( !f.exists() )
259         {
260             if ( !f.mkdirs() )
261             {
262                 throw new IOException("unable to create directory: " + f);
263             }
264         }
265         else
266         {
267             // must be a directory
268
if ( !f.isDirectory() )
269             {
270                 throw new IOException("unable to create directory: " + f + " - a file with that name exist");
271             }
272         }
273     }
274 }
Popular Tags