KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > webdav > ant > taskdefs > Put


1 /*
2  * $Header: /home/cvs/jakarta-slide/webdavclient/ant/src/java/org/apache/webdav/ant/taskdefs/Put.java,v 1.3.2.1 2004/08/15 13:01:15 luetzkendorf Exp $
3  * $Revision: 1.3.2.1 $
4  * $Date: 2004/08/15 13:01:15 $
5  * ========================================================================
6  * Copyright 2004 The Apache Software Foundation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ========================================================================
20  */

21 package org.apache.webdav.ant.taskdefs;
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.FileInputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33 import java.util.zip.ZipEntry JavaDoc;
34 import java.util.zip.ZipFile JavaDoc;
35
36 import org.apache.commons.httpclient.HttpException;
37 import org.apache.commons.httpclient.HttpStatus;
38 import org.apache.commons.httpclient.HttpURL;
39 import org.apache.commons.httpclient.URIException;
40
41 import org.apache.tools.ant.BuildException;
42 import org.apache.tools.ant.DirectoryScanner;
43 import org.apache.tools.ant.Project;
44 import org.apache.tools.ant.types.AbstractFileSet;
45 import org.apache.tools.ant.types.FileSet;
46 import org.apache.tools.ant.types.FilterSet;
47 import org.apache.tools.ant.types.FilterSetCollection;
48 import org.apache.tools.ant.types.ZipScanner;
49 import org.apache.tools.ant.util.LineTokenizer;
50 import org.apache.webdav.ant.Mimetypes;
51 import org.apache.webdav.ant.Utils;
52 import org.apache.webdav.lib.methods.DepthSupport;
53
54 /**
55  * WebDAV task for writing files to an WebDAV server.
56  *
57  * @see <a HREF="../doc-files/tasks.htm#davput">Tasks documentation</a>
58  * @version $Revision: 1.3.2.1 $
59  */

60 public class Put extends WebdavTask {
61    private static final String JavaDoc DEFAULT_CONTENT_TYPE = "application/octet-stream";
62    /** Should we try to lock the remote resource as we upload it? */
63    private boolean lock = true;
64    /** The locktoken provided or or self created when lock is true. */
65    private String JavaDoc locktoken = null;
66    /** The timeout to be used with locking. */
67    private int lockTimeout = 3600;
68    private String JavaDoc lockOwnerInfo = null;
69    /** The sets of files that will be sent to the web server. */
70    private List JavaDoc filesets = new ArrayList JavaDoc();
71    private List JavaDoc zipfilesets = new ArrayList JavaDoc();
72    /** Single file to be putted. */
73    private File JavaDoc file = null;
74    private boolean overwrite = false;
75    
76    private FilterSetCollection filterSets = new FilterSetCollection();
77    private String JavaDoc encoding = null;
78    
79    private int countWrittenFiles = 0;
80    private int countOmittedFiles = 0;
81    
82    // configuration methods
83
/**
84     * Adds a set of files (nested fileset attribute).
85     */

86    public void addFileset(FileSet set) {
87       filesets.add(set);
88    }
89    public void setLock(boolean lock) {
90       this.lock = lock;
91    }
92
93    public void setOverwrite(boolean value) {
94       this.overwrite = value;
95    }
96    public void setLocktoken(String JavaDoc token) {
97       this.locktoken = token;
98       if (!this.locktoken.startsWith("opaquelocktoken:")) {
99          throw new BuildException("Invalid locktoken: " + token);
100       }
101    }
102    public FilterSet createFilterSet() {
103       FilterSet filterSet = new FilterSet();
104       this.filterSets.addFilterSet(filterSet);
105       return filterSet;
106    }
107    public void setEncoding(String JavaDoc enc) {
108       this.encoding = enc;
109    }
110    public void setFile(File JavaDoc file) {
111       this.file = file;
112    }
113    public void setTimeout(int value) {
114       if (value > 0) {
115          this.lockTimeout = value;
116       } else {
117          throw new BuildException("Invalid timeout value (Must be " +
118                "positive integer)");
119       }
120    }
121    public void setOwnerinfo(String JavaDoc value) {
122       this.lockOwnerInfo = value;
123    }
124    /**
125     * Does the work.
126     *
127     * @exception BuildException Thrown in unrecoverable error.
128     */

129    public void execute() throws BuildException {
130       boolean selfCreatedLock = false;
131       
132       validate();
133
134       try {
135          log("Uploading to: " + getUrl(), ifVerbose());
136          
137          if (this.file == null) {
138             Utils.assureExistingCollection(getHttpClient(), getUrl(), this.locktoken);
139          }
140
141          // lock URL if requested and no locktoken explicitly provided
142
if (this.lock && this.locktoken == null) {
143             log("Locking " + getUrl(), ifVerbose());
144             this.locktoken = Utils.lockResource(
145                    getHttpClient(),
146                    getUrl(),
147                    this.lockOwnerInfo,
148                    DepthSupport.DEPTH_INFINITY,
149                    this.lockTimeout);
150             log("locktoken: " + this.locktoken, Project.MSG_DEBUG);
151             selfCreatedLock = true;
152          }
153          
154          if (this.file != null) {
155             // put a single file
156
if (Utils.collectionExists(getHttpClient(), getUrl())) {
157                // if the given URL is a collection put a file named as the given one
158
setUrl(assureCollectionUrl(getUrl()));
159                uploadFile(this.file.getName(), this.file);
160             } else {
161                if (getUrl().getURI().endsWith("/")) {
162                   Utils.assureExistingCollection(getHttpClient(), getUrl(), this.locktoken);
163                   uploadFile(this.file.getName(), this.file);
164                } else {
165                   HttpURL targetColl = Utils.createHttpURL(getUrl(), ".");
166                   Utils.assureExistingCollection(getHttpClient(), targetColl, this.locktoken);
167                   uploadFile(getUrl(), this.file, this.file.getName());
168                }
169             }
170          } else {
171             for (int i = 0; i < filesets.size(); i++) {
172                FileSet fileset = (FileSet) filesets.get(i);
173                uploadFileSet(fileset);
174             }
175             for (int i = 0; i < zipfilesets.size(); i++) {
176                ZipFileSet fileset = (ZipFileSet) zipfilesets.get(i);
177                uploadZipFileSet(fileset);
178             }
179          }
180          
181          log("Puted " + this.countWrittenFiles
182                + (this.countWrittenFiles == 1 ? " file" : " files")
183                + " to " + getUrl(),
184                this.countWrittenFiles > 0 ? Project.MSG_INFO : ifVerbose());
185
186       }
187       catch (IOException JavaDoc e) {
188          throw Utils.makeBuildException("Put error!", e);
189       }
190       finally {
191          try {
192             if (this.locktoken != null && selfCreatedLock) {
193                log("Unlocking " + getUrl(), ifVerbose());
194                Utils.unlockResource(getHttpClient(),
195                                     getUrl(),
196                                     this.locktoken);
197             }
198          }
199          catch (IOException JavaDoc e) {
200             throw Utils.makeBuildException("Can't unlock!", e);
201          }
202       }
203    }
204    
205    protected void validate() {
206       super.validate();
207       
208       if (this.encoding == null && this.filterSets.hasFilters()) {
209          log("If filterSets are used a file encoding should be specified!",
210                Project.MSG_WARN);
211          this.encoding = "ISO-8859-1"; // TODO what sould be the default
212
}
213       if (this.file != null &&
214             (this.filesets.size() > 0 || this.zipfilesets.size() > 0)) {
215          throw new BuildException("No filesets allowed if file is set.");
216       }
217       
218       if (this.file != null && !(this.file.isFile() && this.file.exists())) {
219          throw new BuildException("File attribute must point to en existing file");
220       }
221       
222       if (this.file == null) {
223          try {
224             setUrl(assureCollectionUrl(getUrl()));
225          } catch (URIException e) {
226             throw new BuildException("Problem with URI: " + getUrl(), e);
227          }
228       }
229       if (this.lockOwnerInfo == null) {
230          this.lockOwnerInfo = "ant-webdav " + getUserid();
231       }
232    }
233    
234    private void uploadFileSet(FileSet fileSet)
235       throws IOException JavaDoc
236    {
237       DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
238       String JavaDoc basedir = scanner.getBasedir().getAbsolutePath();
239
240       // assert that all required collections does exist
241
for(Iterator JavaDoc i = determineRequiredDirectories(scanner); i.hasNext();) {
242          String JavaDoc dir = (String JavaDoc)i.next();
243          if (dir.equals("")) {
244             Utils.assureExistingCollection(getHttpClient(),
245                                            getUrl(),
246                                            this.locktoken);
247          } else {
248             HttpURL collURL = Utils.createHttpURL(getUrl(), dir + "/");
249             Utils.assureExistingCollection(getHttpClient(),
250                                            collURL,
251                                            this.locktoken);
252          }
253       }
254       
255       // write all files
256
String JavaDoc[] files = scanner.getIncludedFiles();
257       for (int i = 0; i < files.length; ++i) {
258          File JavaDoc file = getProject().resolveFile(basedir + File.separator + files[i]);
259          uploadFile(asDavPath(files[i]), file);
260       }
261    }
262    
263    private Iterator JavaDoc determineRequiredDirectories(DirectoryScanner scanner) {
264       Set JavaDoc result = new HashSet JavaDoc();
265       
266       // determine all directories that contain included files
267
String JavaDoc[] files = scanner.getIncludedFiles();
268       for (int i = 0; i < files.length; i++) {
269          String JavaDoc file = asDavPath(files[i]);
270          int slashPos = file.lastIndexOf('/');
271          if (slashPos != -1) {
272             result.add(file.substring(0, slashPos));
273          }
274       }
275       
276       // determine all included directories
277
String JavaDoc[] dirs = scanner.getIncludedDirectories();
278       for(int i = 0; i < dirs.length; i++) {
279          result.add(asDavPath(dirs[i]));
280       }
281       
282       return result.iterator();
283    }
284    
285    /**
286     * Puts a file to a resource relative to the url attribute.
287     * @param relative path relative
288     * @param file file to be written
289     * @throws IOException
290     */

291    private void uploadFile(String JavaDoc relative, File JavaDoc file)
292       throws IOException JavaDoc
293    {
294       HttpURL url = Utils.createHttpURL(getUrl(), relative);
295       uploadFile(url, file, relative);
296    }
297    /**
298     * Puts a file to a given URL.
299     * @param relative for logging purposes only.
300     */

301    private void uploadFile(HttpURL url, File JavaDoc file, String JavaDoc relative)
302       throws IOException JavaDoc
303    {
304
305       boolean putit = false;
306       try {
307          if (this.overwrite) {
308             putit = true;
309          } else {
310             // check last modified date (both GMT)
311
long remoteLastMod = Utils.getLastModified(getHttpClient(), url);
312             long localLastMod = file.lastModified();
313             putit = localLastMod > remoteLastMod;
314          }
315       }
316       catch (HttpException e) {
317          switch (e.getReasonCode()) {
318             case HttpStatus.SC_NOT_FOUND:
319                putit = true;
320                break;
321             default:
322                throw Utils.makeBuildException("Can't get lastmodified!?", e);
323          }
324       }
325
326       if (putit) {
327          log("Uploading: " + relative, ifVerbose());
328          try {
329             String JavaDoc contentType = Mimetypes.getMimeType(file, DEFAULT_CONTENT_TYPE);
330             if (this.filterSets.hasFilters()) {
331                // TODO this part doesn't look nice
332
InputStreamReader JavaDoc reader = new InputStreamReader JavaDoc(
333                                           new FileInputStream JavaDoc(file), this.encoding);
334                ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc();
335                LineTokenizer tok = new LineTokenizer();
336                tok.setIncludeDelims(true);
337                
338                for (String JavaDoc l = tok.getToken(reader); l != null; l = tok.getToken(reader)) {
339                   out.write(this.filterSets.replaceTokens(l).getBytes(this.encoding));
340                }
341                Utils.putFile(getHttpClient(), url,
342                      new ByteArrayInputStream JavaDoc(out.toByteArray()),
343                      contentType, this.locktoken);
344             } else {
345                Utils.putFile(getHttpClient(), url,
346                      new FileInputStream JavaDoc(file),
347                      contentType, this.locktoken);
348             }
349             this.countWrittenFiles++;
350          }
351          catch (HttpException e) {
352             throw Utils.makeBuildException("Can't upload " + url, e);
353          }
354       } else {
355          countOmittedFiles++;
356          log("Omitted: " + relative + " (uptodate)", ifVerbose());
357       }
358    }
359    
360    private void uploadZipFileSet(ZipFileSet fileSet)
361       throws IOException JavaDoc
362    {
363       DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
364       
365       ZipFile JavaDoc zipFile = new ZipFile JavaDoc(fileSet.getSrc());
366    
367       // assert that all required collections does exist
368
for(Iterator JavaDoc i = determineRequiredDirectories(scanner); i.hasNext();) {
369          String JavaDoc dir = (String JavaDoc)i.next();
370          if (dir.equals("")) {
371             Utils.assureExistingCollection(getHttpClient(),
372                                            getUrl(),
373                                            this.locktoken);
374          } else {
375             HttpURL collURL = Utils.createHttpURL(getUrl(), dir + "/");
376             Utils.assureExistingCollection(getHttpClient(),
377                                            collURL,
378                                            this.locktoken);
379          }
380       }
381       
382       // write all files
383
String JavaDoc[] files = scanner.getIncludedFiles();
384       for (int i = 0; i < files.length; ++i) {
385          uploadZipEntry(Utils.createHttpURL(getUrl(), files[i]), files[i], zipFile);
386       }
387    }
388    
389    private void uploadZipEntry(HttpURL url, String JavaDoc name, ZipFile JavaDoc zipFile)
390       throws IOException JavaDoc
391    {
392       boolean putit = false;
393       ZipEntry JavaDoc entry = zipFile.getEntry(name);
394       
395       try {
396          if (this.overwrite) {
397             putit = true;
398          } else {
399             // check last modified date (both GMT)
400
long remoteLastMod = Utils.getLastModified(getHttpClient(), url);
401             long localLastMod = entry.getTime();
402             putit = localLastMod > remoteLastMod;
403          }
404       }
405       catch (HttpException e) {
406          switch (e.getReasonCode()) {
407             case HttpStatus.SC_NOT_FOUND:
408                putit = true;
409                break;
410             default:
411                throw Utils.makeBuildException("Can't get lastmodified!?", e);
412          }
413       }
414       
415       if (putit) {
416          log("Uploading: " + name, ifVerbose());
417          String JavaDoc contentType = Mimetypes.getMimeType(name, DEFAULT_CONTENT_TYPE);
418          Utils.putFile(getHttpClient(), url,
419                zipFile.getInputStream(entry),
420                contentType, this.locktoken);
421          this.countWrittenFiles++;
422       } else {
423          countOmittedFiles++;
424          log("Omitted: " + name + " (uptodate)", ifVerbose());
425       }
426    }
427    
428    private String JavaDoc asDavPath(String JavaDoc path) {
429       return path.replace('\\', '/');
430    }
431    
432    public ZipFileSet createZipfileset() {
433       ZipFileSet fileSet = new ZipFileSet();
434       this.zipfilesets.add(fileSet);
435       return fileSet;
436    }
437    
438    public static class ZipFileSet extends AbstractFileSet {
439       private File JavaDoc src = null;
440       
441       public void setSrc(File JavaDoc src) {
442          this.src = src;
443       }
444       
445       File JavaDoc getSrc() {
446          if (this.src != null) {
447             return this.src;
448          } else {
449             throw new BuildException("ZipFileSet requires a src attribute!");
450          }
451       }
452
453       /*
454        * @see org.apache.tools.ant.types.AbstractFileSet#getDirectoryScanner(org.apache.tools.ant.Project)
455        */

456       public DirectoryScanner getDirectoryScanner(Project p)
457       {
458          ZipScanner zs = new ZipScanner();
459          zs.setSrc(getSrc());
460          super.setDir(p.getBaseDir());
461          setupDirectoryScanner(zs, p);
462          zs.init();
463          return zs;
464       }
465    }
466 }
467
Popular Tags