package com.idega.slide.util;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpURL;
import org.apache.commons.httpclient.HttpsURL;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.webdav.lib.methods.LockMethod;
import org.apache.webdav.lib.Property;
import org.apache.webdav.lib.WebdavResource;
import org.apache.webdav.lib.WebdavResources;
import org.apache.webdav.lib.methods.DepthSupport;
import com.idega.util.CoreConstants;
/**
*
* This class is an extended version Slide's WebdavResource. <br>
* It has been extended in order to retrieve the basic list of properties
* (listBasic in WebdavResource) along <br>
* with additional (versioncontrol) DeltaV properties. <br>
* The new list method is listWithDeltaV() (to get the children with their
* version info).
*
* @author <a href="eiki@idega.is>Eirikur S. Hrafnsson </a> with a little help
* from Billy Joe McCue the author of the SwingDaver webdav client.
*
*/
public class WebdavExtendedResource extends WebdavResource {
private String path;
private String checkedIn;
private String checkedOut;
private String versionName;
private String comment;
private String parentPath;
private String creationDate;
public WebdavExtendedResource(String urlStr, Credentials cred, boolean followRedirects) throws IOException {
super(urlStr, cred, followRedirects);
}
public WebdavExtendedResource(HttpClient client) {
super(client);
}
public WebdavExtendedResource(HttpURL url) throws HttpException, IOException {
super(url);
}
public String getParentPath() {
if (this.parentPath == null) {
if (this.path != null) {
int index = this.path.lastIndexOf(CoreConstants.SLASH);
if (index == 0) {
this.parentPath = CoreConstants.EMPTY;
} else {
this.parentPath = this.path.substring(0, index);
}
} else {
return null;
}
}
return this.parentPath;
}
/**
*
* Create a new WebdavResource object (as a seperate method so that it can
* be overridden by subclasses.
* @param client HttpClient to be used by this webdavresource.
* @return A new WebdavResource object.
*/
@Override
protected WebdavResource createWebdavResource(HttpClient client) {
WebdavResource resource = new WebdavExtendedResource(client);
resource.setCredentials(this.hostCredentials);
return resource;
}
/**
* Create an updated version of itself
*/
public WebdavExtendedResource createUpdatedResource() {
WebdavExtendedResource resource = (WebdavExtendedResource) createWebdavResource(this.client);
try {
resource.setFinalHttpURL(getHttpURL());
}
catch (IOException e) {
e.printStackTrace();
}
return resource;
}
/**
*
* Initial purpose of overiding this method is because
* the WebdavResources addResource(WebdavResource) method
* calls this method to use the return value as a key
* in it's hashtable called hreftable which in turn is
* used for retrieving all of it's child resources.
* This being said, the original getName method seems to return
* duplicate names of siblings for some resources, thus, overwriting
* it's sibling's key in the href table.
* We should probably try to return something unique, yet relavent
* to the name.
* Get the name of this WebdavResource.
* If the decoding of the name fails, this method will not throw an
* exception but return the escaped name instead.
*
* @return the name of this WebdavResource.
* @see org.apache.commons.httpclient.HttpURL#getName()
*
*/
@Override
public String getName() {
return this.path;
}
public void setFinalHttpURL(HttpURL url) throws IOException {
//eiki not sure this is needed String scheme = url.getScheme();
if (url instanceof HttpsURL) {
this.httpURL = new HttpsURL((HttpsURL) url, this.path);
}
else {
this.httpURL = new HttpURL(url, getPath());
}
}
public void putMethod(String path, File file, String comment) throws IOException {
super.putMethod(file);
/*
* super.putMethod(path, file); // now we do all this to set a fricken
* comment // on the new version created (if any) setCheckedIn(null);
* Vector vProps = new Vector(1); vProps.addElement(CHECKED_IN);
* Enumeration responses = propfindMethod(DepthSupport.DEPTH_0, vProps);
* if(responses.hasMoreElements()) { ResponseEntity response =
* (ResponseEntity) responses.nextElement();
* // Process the resource's properties Enumeration properties =
* response.getProperties(); while (properties.hasMoreElements()) {
*
* Property property = (Property) properties.nextElement();
* // ------------------------------ Checking WebDAV properties
* processProperty(property); } } String cIn = getCheckedIn(); if(cIn !=
* null) { proppatchMethod(cIn, COMMENT,comment,true); }
*/
}
/**
* Process a property, setting various member variables depending on what the property is.
* @param property The property to process.
*/
@Override
protected void processProperty(Property property) {
String propName = property.getLocalName();
String strVal = property.getPropertyAsString();
// Take the first property we get to
// properly set the path.
if (this.path == null) {
// we'll have to use this when our
// setFinalHttpURL is called.
this.path = property.getOwningURL();
}
if (propName.equals(VersionHelper.PROPERTY_CHECKED_IN)) {
setCheckedIn(strVal);
}
else if (propName.equals(VersionHelper.PROPERTY_CHECKED_OUT)) {
setCheckedOut(strVal);
}
else if (propName.equals(VersionHelper.PROPERTY_VERSION_NAME)) {
setVersionName(strVal);
if (strVal != null && strVal.length() > 0) {
// We're in the history section, looking
// at a version of a resource
// So we're interested in showing the version-name
// as the display-name
setDisplayName(strVal);
}
}
else if(propName.equals(VersionHelper.PROPERTY_COMMENT)){
setComment(strVal);
}
else if (propName.equals(VersionHelper.PROPERTY_CREATION_DATE)) {
strVal = strVal.replaceFirst("T", " ");
strVal = strVal.replaceFirst("Z", "");
setCreationDateString(strVal);
}
else {
super.processProperty(property);
}
}
protected void setCreationDateString(String value) {
this.creationDate = value;
}
public String getCreationDateString() {
return this.creationDate;
}
protected void setCheckedIn(String value) {
this.checkedIn = value;
}
public String getCheckedIn() {
return this.checkedIn;
}
protected void setCheckedOut(String value) {
this.checkedOut = value;
}
public String getCheckedOut() {
return this.checkedOut;
}
protected void setVersionName(String value) {
this.versionName = value;
}
public String getVersionName() {
return this.versionName;
}
/**
*
* Sets the basic properties and DeltaV properties
* on a resource by indirectly issuing a PROPFIND
* on the resource.<p>
* Properties retrieved include:
* <ul>
* <li>displayname</li>
* <li>getcontentlength</li>
* <li>getcontenttype</li>
* <li>resourcetype</li>
* <li>getlastmodified</li>
* <li>lockdiscovery</li>
* // DeltaV support
* <li>checked-in</li>
* <li>checked-out</li>
* <li>version-name</li>
* <li>creationdate</li>
* </ul>
*/
public WebdavResources listWithDeltaV() throws IOException {
Vector properties = new Vector();
properties.addElement(DISPLAYNAME);
properties.addElement(GETCONTENTLENGTH);
properties.addElement(GETCONTENTTYPE);
properties.addElement(RESOURCETYPE);
properties.addElement(GETLASTMODIFIED);
properties.addElement(CREATIONDATE);
properties.addElement(LOCKDISCOVERY);
// DeltaV support
properties.addElement(VersionHelper.PROPERTY_CHECKED_IN);
properties.addElement(VersionHelper.PROPERTY_CHECKED_OUT);
properties.addElement(VersionHelper.PROPERTY_VERSION_NAME);
properties.addElement(VersionHelper.PROPERTY_COMMENT);
properties.addElement(VersionHelper.PROPERTY_CREATION_DATE);
// The following call should in turn, call
// Enumeration responses = super.propfindMethod(DEPTH_1, properies)
// super.setWebdavProperties(reponses)
// in turn, calls
// this.createWebdavResource(client); (see above)
// in turn, calls a series of
// processProperty(property)
setNamedProp(DepthSupport.DEPTH_1, properties);
// Here we use childResources directly, because
// getChildResources() calls another setProperties
// call before returning childResources, which we
// don't really want to do, since we've
// already called a setNamedProp above.
return this.childResources;
}
/**
*
* Sets the basic properties and DeltaV properties
* on a resource by indirectly issuing a PROPFIND
* on the resource.<p>
* Properties retrieved include:
* <ul>
* <li>displayname</li>
* <li>getcontentlength</li>
* <li>getcontenttype</li>
* <li>resourcetype</li>
* <li>getlastmodified</li>
* <li>lockdiscovery</li>
* // DeltaV support
* <li>checked-in</li>
* <li>checked-out</li>
* <li>version-name</li>
* <li>creationdate</li>
* </ul>
*/
public void setProperties() throws IOException {
Vector properties = new Vector();
properties.addElement(DISPLAYNAME);
properties.addElement(GETCONTENTLENGTH);
properties.addElement(GETCONTENTTYPE);
properties.addElement(RESOURCETYPE);
properties.addElement(GETLASTMODIFIED);
properties.addElement(LOCKDISCOVERY);
// DeltaV support
properties.addElement(VersionHelper.PROPERTY_CHECKED_IN);
properties.addElement(VersionHelper.PROPERTY_CHECKED_OUT);
properties.addElement(VersionHelper.PROPERTY_VERSION_NAME);
properties.addElement(VersionHelper.PROPERTY_COMMENT);
properties.addElement(VersionHelper.PROPERTY_CREATION_DATE);
// The following call should in turn, call
// Enumeration responses = super.propfindMethod(DEPTH_1, properies)
// super.setWebdavProperties(reponses)
// in turn, calls
// this.createWebdavResource(client); (see above)
// in turn, calls a series of
// processProperty(property)
setNamedProp(DepthSupport.DEPTH_0, properties);
}
public String getDecodedPath() {
try {
return URIUtil.decode(getPath());
}
catch (URIException e) {
e.printStackTrace();
return getPath();
}
}
public String getEncodedPath() {
try {
return URIUtil.encodePath(getPath());
}
catch (URIException e) {
e.printStackTrace();
return getPath();
}
}
/**
* @return Returns the comment.
*/
public String getComment() {
return this.comment;
}
/**
* @param comment The comment to set.
*/
public void setComment(String comment) {
this.comment = comment;
}
public boolean lockMethodNoTimeout() throws HttpException, IOException {
String owner = httpURL.getUser() == null ? "Slide" : httpURL.getUser();
boolean result = lockMethod(httpURL.getPath(), owner, LockMethod.TIMEOUT_INFINITY);
if (result)
refresh();
return result;
}
}