1 21 package org.apache.webdav.ant.taskdefs; 22 import java.io.ByteArrayInputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.IOException ; 27 import java.io.InputStreamReader ; 28 import java.util.ArrayList ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 import java.util.Set ; 33 import java.util.zip.ZipEntry ; 34 import java.util.zip.ZipFile ; 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 60 public class Put extends WebdavTask { 61 private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; 62 63 private boolean lock = true; 64 65 private String locktoken = null; 66 67 private int lockTimeout = 3600; 68 private String lockOwnerInfo = null; 69 70 private List filesets = new ArrayList (); 71 private List zipfilesets = new ArrayList (); 72 73 private File file = null; 74 private boolean overwrite = false; 75 76 private FilterSetCollection filterSets = new FilterSetCollection(); 77 private String encoding = null; 78 79 private int countWrittenFiles = 0; 80 private int countOmittedFiles = 0; 81 82 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 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 enc) { 108 this.encoding = enc; 109 } 110 public void setFile(File 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 value) { 122 this.lockOwnerInfo = value; 123 } 124 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 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 if (Utils.collectionExists(getHttpClient(), getUrl())) { 157 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 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 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"; } 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 236 { 237 DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); 238 String basedir = scanner.getBasedir().getAbsolutePath(); 239 240 for(Iterator i = determineRequiredDirectories(scanner); i.hasNext();) { 242 String dir = (String )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 String [] files = scanner.getIncludedFiles(); 257 for (int i = 0; i < files.length; ++i) { 258 File file = getProject().resolveFile(basedir + File.separator + files[i]); 259 uploadFile(asDavPath(files[i]), file); 260 } 261 } 262 263 private Iterator determineRequiredDirectories(DirectoryScanner scanner) { 264 Set result = new HashSet (); 265 266 String [] files = scanner.getIncludedFiles(); 268 for (int i = 0; i < files.length; i++) { 269 String file = asDavPath(files[i]); 270 int slashPos = file.lastIndexOf('/'); 271 if (slashPos != -1) { 272 result.add(file.substring(0, slashPos)); 273 } 274 } 275 276 String [] 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 291 private void uploadFile(String relative, File file) 292 throws IOException 293 { 294 HttpURL url = Utils.createHttpURL(getUrl(), relative); 295 uploadFile(url, file, relative); 296 } 297 301 private void uploadFile(HttpURL url, File file, String relative) 302 throws IOException 303 { 304 305 boolean putit = false; 306 try { 307 if (this.overwrite) { 308 putit = true; 309 } else { 310 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 contentType = Mimetypes.getMimeType(file, DEFAULT_CONTENT_TYPE); 330 if (this.filterSets.hasFilters()) { 331 InputStreamReader reader = new InputStreamReader ( 333 new FileInputStream (file), this.encoding); 334 ByteArrayOutputStream out = new ByteArrayOutputStream (); 335 LineTokenizer tok = new LineTokenizer(); 336 tok.setIncludeDelims(true); 337 338 for (String 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 (out.toByteArray()), 343 contentType, this.locktoken); 344 } else { 345 Utils.putFile(getHttpClient(), url, 346 new FileInputStream (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 362 { 363 DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject()); 364 365 ZipFile zipFile = new ZipFile (fileSet.getSrc()); 366 367 for(Iterator i = determineRequiredDirectories(scanner); i.hasNext();) { 369 String dir = (String )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 String [] 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 name, ZipFile zipFile) 390 throws IOException 391 { 392 boolean putit = false; 393 ZipEntry entry = zipFile.getEntry(name); 394 395 try { 396 if (this.overwrite) { 397 putit = true; 398 } else { 399 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 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 asDavPath(String 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 src = null; 440 441 public void setSrc(File src) { 442 this.src = src; 443 } 444 445 File 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 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 |