1 22 package org.apache.webdav.ant; 23 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.text.DateFormat ; 27 import java.text.ParseException ; 28 import java.text.SimpleDateFormat ; 29 import java.util.Date ; 30 import java.util.Enumeration ; 31 import java.util.Locale ; 32 import java.util.Stack ; 33 import java.util.Vector ; 34 35 import org.apache.commons.httpclient.Header; 36 import org.apache.commons.httpclient.HttpClient; 37 import org.apache.commons.httpclient.HttpException; 38 import org.apache.commons.httpclient.HttpMethod; 39 import org.apache.commons.httpclient.HttpStatus; 40 import org.apache.commons.httpclient.HttpURL; 41 import org.apache.commons.httpclient.HttpsURL; 42 import org.apache.commons.httpclient.URIException; 43 import org.apache.commons.httpclient.methods.GetMethod; 44 import org.apache.commons.httpclient.methods.HeadMethod; 45 import org.apache.commons.httpclient.methods.PutMethod; 46 47 import org.apache.tools.ant.BuildException; 48 import org.apache.webdav.lib.Property; 49 import org.apache.webdav.lib.PropertyName; 50 import org.apache.webdav.lib.ResponseEntity; 51 import org.apache.webdav.lib.WebdavException; 52 import org.apache.webdav.lib.methods.CopyMethod; 53 import org.apache.webdav.lib.methods.LockMethod; 54 import org.apache.webdav.lib.methods.MkcolMethod; 55 import org.apache.webdav.lib.methods.MoveMethod; 56 import org.apache.webdav.lib.methods.PropFindMethod; 57 import org.apache.webdav.lib.methods.UnlockMethod; 58 import org.apache.webdav.lib.properties.ResourceTypeProperty; 59 import org.apache.webdav.lib.util.WebdavStatus; 60 61 63 public class Utils { 64 public static final String DAV_NAMESPACE= "DAV:"; 65 66 public static final PropertyName DISPLAYNAME = new PropertyName( 67 DAV_NAMESPACE, "displayname"); 68 69 public static final PropertyName GETLASTMODIFIED = new PropertyName( 70 DAV_NAMESPACE, "getlastmodified"); 71 72 public static final DateFormat GETLASTMODIFIED_FORMAT = 73 new SimpleDateFormat ("EEE, d MMM yyyy kk:mm:ss z", Locale.US); 74 75 public static final PropertyName RESOURCETYPE = new PropertyName( 76 DAV_NAMESPACE, "resourcetype"); 77 78 85 public static Property findProperty(PropFindMethod propFind, 86 PropertyName name, 87 String path) 88 { 89 Enumeration e = propFind.getResponseProperties(path); 90 Property p = findProperty(e, name); 91 if (p == null && path.endsWith("/")) { 94 e = propFind.getResponseProperties(path.substring(0, path.length()-1)); 95 p = findProperty(e, name); 96 } 97 return p; 98 } 99 100 107 public static Property findProperty(Enumeration e, PropertyName name) { 108 while (e.hasMoreElements()) { 109 Property p = (Property)e.nextElement(); 110 111 if (p.getNamespaceURI().equals(name.getNamespaceURI()) && 112 p.getLocalName().equals(name.getLocalName())) 113 { 114 return p; 115 } 116 } 117 return null; 118 } 119 120 128 public static boolean resourceExists(HttpClient client, HttpURL httpURL) 129 throws IOException , HttpException 130 { 131 HeadMethod head = new HeadMethod(httpURL.getURI()); 132 head.setFollowRedirects(true); 133 int status = client.executeMethod(head); 134 135 switch (status) { 136 case WebdavStatus.SC_OK: 137 return true; 138 case WebdavStatus.SC_NOT_FOUND: 139 return false; 140 default: 141 HttpException ex = new HttpException(); 142 ex.setReasonCode(status); 143 ex.setReason(head.getStatusText()); 144 throw ex; 145 } 146 } 147 148 public static boolean collectionExists(HttpClient client, HttpURL httpURL) 149 throws IOException , HttpException 150 { 151 Vector props = new Vector (1); 152 props.add(RESOURCETYPE); 153 PropFindMethod propFind = new PropFindMethod(httpURL.getURI(), 154 0, PropFindMethod.BY_NAME); 155 propFind.setFollowRedirects(true); 156 propFind.setPropertyNames(props.elements()); 157 int status = client.executeMethod(propFind); 158 switch (status) { 159 case WebdavStatus.SC_MULTI_STATUS: 160 Property p = findProperty(propFind, RESOURCETYPE, httpURL.getPath()); 161 if (p instanceof ResourceTypeProperty) { 162 return ((ResourceTypeProperty)p).isCollection(); 163 } else { 164 throw new WebdavException("PROPFFIND does not return resourcetype"); 165 } 166 case WebdavStatus.SC_NOT_FOUND: 167 return false; 168 default: 169 HttpException ex = new HttpException(); 170 ex.setReasonCode(status); 171 ex.setReason(propFind.getStatusText()); 172 throw ex; 173 } 174 } 175 176 public static long getLastModified(HttpClient client, HttpURL url) 177 throws IOException , HttpException 178 { 179 Vector props = new Vector (1); 180 props.add(GETLASTMODIFIED); 181 PropFindMethod propFind = new PropFindMethod(url.getURI(), 0); 182 propFind.setPropertyNames(props.elements()); 183 propFind.setFollowRedirects(true); 184 185 int status = client.executeMethod(propFind); 186 switch (status) { 187 case WebdavStatus.SC_MULTI_STATUS: 188 Property p = findProperty(propFind, GETLASTMODIFIED, url.getPath()); 189 if (p != null) { 190 try { 191 Date d = GETLASTMODIFIED_FORMAT.parse(p.getPropertyAsString()); 192 return d.getTime(); 193 } 194 catch (ParseException e) { 195 throw new HttpException("Invalid lastmodified property: " + 196 p.getPropertyAsString()); 197 } 198 } 199 throw new HttpException("PROPFIND does not return lastmodified."); 200 default: 201 HttpException ex = new HttpException(); 202 ex.setReasonCode(status); 203 ex.setReason(propFind.getStatusText()); 204 throw ex; 205 } 206 } 207 208 217 public static boolean assureExistingCollection(HttpClient client, 218 HttpURL httpURL, 219 String lockToken) 220 throws IOException , HttpException 221 { 222 String path = httpURL.getPath(); 223 if (!path.endsWith("/")) { 224 path = path + "/"; 225 } 226 Stack toBeCreated = new Stack (); 227 228 while (!path.equals("/")) { 229 HttpURL parent = Utils.createHttpURL(httpURL, path); 230 if (!collectionExists(client, parent)) { 231 toBeCreated.push(path); 232 path = path.substring(0, path.lastIndexOf("/", path.length()-2)+1); 233 } else { 234 break; 235 } 236 } 237 238 boolean created = !toBeCreated.empty(); 239 while(!toBeCreated.empty()) { 240 HttpURL newColl = Utils.createHttpURL(httpURL, (String )toBeCreated.pop()); 241 MkcolMethod mkcol = new MkcolMethod(newColl.getURI()); 242 mkcol.setFollowRedirects(true); 243 generateIfHeader(mkcol, lockToken); 244 int status = client.executeMethod(mkcol); 245 if (status != WebdavStatus.SC_CREATED) { 246 HttpException ex = new HttpException("Can't create collection " + 247 newColl); 248 ex.setReasonCode(status); 249 ex.setReason(mkcol.getStatusText()); 250 throw ex; 251 } 252 } 253 return created; 254 } 255 256 public static void putFile(HttpClient client, 257 HttpURL url, 258 InputStream is, 259 String contentType, 260 String lockToken) 261 throws IOException , HttpException 262 { 263 PutMethod put = new PutMethod(url.getURI()); 264 generateIfHeader(put, lockToken); 265 put.setRequestHeader("Content-Type", contentType); 266 put.setRequestBody(is); 267 put.setFollowRedirects(true); 268 int status = client.executeMethod(put); 269 switch (status) { 270 case WebdavStatus.SC_OK: 271 case WebdavStatus.SC_CREATED: 272 case WebdavStatus.SC_NO_CONTENT: 273 return; 274 default: 275 HttpException ex = new HttpException(); 276 ex.setReason(put.getStatusText()); 277 ex.setReasonCode(status); 278 throw ex; 279 } 280 } 281 282 public static InputStream getFile(HttpClient client, HttpURL url) 283 throws IOException , HttpException 284 { 285 GetMethod get = new GetMethod(url.toString()); 286 get.setFollowRedirects(true); 287 int status = client.executeMethod(get); 288 289 switch (status) { 290 case WebdavStatus.SC_OK: 291 return get.getResponseBodyAsStream(); 292 default: 293 HttpException ex = new HttpException(); 294 ex.setReason(get.getStatusText()); 295 ex.setReasonCode(status); 296 throw ex; 297 } 298 299 } 300 301 public static void generateIfHeader(HttpMethod method, String lockToken) { 302 if (lockToken != null) { 303 Header ifHeader = new Header(); 304 ifHeader.setName("If"); 305 ifHeader.setValue("(<" + lockToken + ">)"); 306 method.addRequestHeader(ifHeader); 307 } 308 } 309 310 public static String lockResource(HttpClient client, HttpURL url, 311 String ownerInfo, int depth, int timeout) 312 throws IOException , HttpException 313 { 314 LockMethod lock = new LockMethod(url.getURI()); 315 lock.setDepth(depth); 316 lock.setTimeout(timeout); 317 lock.setOwner(ownerInfo); 318 lock.setFollowRedirects(true); 320 int status = client.executeMethod(lock); 321 if (status == WebdavStatus.SC_OK) { 322 Header header = lock.getResponseHeader("Lock-Token"); 323 if (header != null) { 324 String l = header.getValue(); 325 return l.substring(1, l.length()-1); 326 } else { 327 String l = lock.getLockToken(); 328 if (l != null) { 329 return l; 330 } 331 throw new WebdavException("LOCK does not provide a lock token."); 332 } 333 } else if (status == WebdavStatus.SC_MULTI_STATUS) { 334 throw Utils.makeBuildException("Can't lock", lock.getResponses()); 335 } else { 336 throw Utils.makeBuildException("Can't lock", status, lock.getStatusText()); 337 } 338 } 339 340 public static void unlockResource(HttpClient client, HttpURL url, 341 String lockToken) 342 throws IOException , HttpException 343 { 344 UnlockMethod unlock = new UnlockMethod(url.getURI(), lockToken); 345 unlock.setFollowRedirects(true); 346 int status = client.executeMethod(unlock); 347 348 switch (status) { 349 case WebdavStatus.SC_OK: 350 case WebdavStatus.SC_NO_CONTENT: 351 return; 352 353 default: 354 HttpException ex = new HttpException(); 355 ex.setReasonCode(status); 356 ex.setReason(unlock.getStatusText()); 357 throw ex; 358 } 359 } 360 361 public static void copyResource(HttpClient client, HttpURL url, 362 String destination, int depth, boolean overwrite) 363 throws IOException , HttpException 364 { 365 CopyMethod copy = new CopyMethod( 366 url.getURI(), 367 destination, 368 overwrite, 369 depth); 370 copy.setFollowRedirects(true); 371 int status = client.executeMethod(copy); 372 switch (status) { 373 case WebdavStatus.SC_OK: 374 case WebdavStatus.SC_CREATED: 375 case WebdavStatus.SC_NO_CONTENT: 376 return; 377 378 default: 379 HttpException ex = new HttpException(); 380 ex.setReasonCode(status); 381 ex.setReason(copy.getStatusText()); 382 throw ex; 383 } 384 } 385 386 public static void moveResource(HttpClient client, HttpURL url, 387 String destination, boolean overwrite) 388 throws IOException , HttpException 389 { 390 MoveMethod move = new MoveMethod(url.getURI(), destination, overwrite); 391 move.setFollowRedirects(true); 392 int status = client.executeMethod(move); 393 switch (status) { 394 case WebdavStatus.SC_OK: 395 case WebdavStatus.SC_CREATED: 396 case WebdavStatus.SC_NO_CONTENT: 397 return; 398 399 default: 400 HttpException ex = new HttpException(); 401 ex.setReasonCode(status); 402 ex.setReason(move.getStatusText()); 403 throw ex; 404 } 405 } 406 407 public static BuildException makeBuildException(String msg, Exception e) { 408 if (e instanceof HttpException) { 409 HttpException he = (HttpException)e; 410 return new BuildException( 411 msg + " " + e.getMessage() + " (" + 412 (he.getReason() != null 413 ? he.getReason() 414 : HttpStatus.getStatusText(he.getReasonCode())) + 415 ")"); 416 417 } else { 418 return new BuildException(msg + " (" + e.toString() + ")", e); 419 } 420 } 421 422 public static BuildException makeBuildException(String msg, int status) { 423 return new BuildException(msg + " (" + 424 HttpStatus.getStatusText(status) + 425 ")"); 426 } 427 public static BuildException makeBuildException(String msg, 428 int status, String statusText) 429 { 430 return new BuildException(msg + " (" + 431 status + ", " + statusText + ")"); 432 } 433 434 public static BuildException makeBuildException( 435 String msg, 436 Enumeration enumOfResponseEntities) 437 { 438 StringBuffer b = new StringBuffer (); 439 440 b.append(msg).append("\n"); 441 442 for(;enumOfResponseEntities.hasMoreElements();) { 443 ResponseEntity e = (ResponseEntity)enumOfResponseEntities.nextElement(); 444 445 b.append(e.getHref()) 446 .append(" ") 447 .append(HttpStatus.getStatusText(e.getStatusCode())) 448 .append("\n"); 449 } 450 451 return new BuildException(b.toString()); 452 } 453 454 455 public static HttpURL createHttpURL(HttpURL base, String relative) 456 throws URIException 457 { 458 if (base instanceof HttpsURL) { 459 return new HttpsURL((HttpsURL)base, relative); 460 } else { 461 return new HttpURL(base, relative); 462 } 463 } 464 465 public static HttpURL createHttpURL(String url) throws URIException 466 { 467 if (url.startsWith("https://")) { 468 return new HttpsURL(url); 469 } else { 470 return new HttpURL(url); 471 } 472 } 473 474 475 } 476 | Popular Tags |