biz.taoconsulting.dominodav.resource.DAVAbstractResource.java Source code

Java tutorial

Introduction

Here is the source code for biz.taoconsulting.dominodav.resource.DAVAbstractResource.java

Source

/** ========================================================================= *
 * Copyright (C) 2006, 2007 TAO Consulting Pte <http://www.taoconsulting.sg/> *
 *                            All rights reserved.                            *
 * ========================================================================== *
 *                                                                            *
 * Licensed under the  Apache License, Version 2.0  (the "License").  You may *
 * not use this file except in compliance with the License.  You may obtain a *
 * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>.       *
 *                                                                            *
 * Unless  required  by applicable  law or  agreed  to  in writing,  software *
 * distributed under the License is distributed on an  "AS IS" BASIS, WITHOUT *
 * WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied.  See the *
 * License for the  specific language  governing permissions  and limitations *
 * under the License.                                                         *
 *                                                                            *
 * ========================================================================== */
package biz.taoconsulting.dominodav.resource;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import biz.taoconsulting.dominodav.DAVProperties;
import biz.taoconsulting.dominodav.LockManager;
import biz.taoconsulting.dominodav.interfaces.IDAVAddressInformation;
import biz.taoconsulting.dominodav.interfaces.IDAVRepository;
import biz.taoconsulting.dominodav.interfaces.IDAVResource;

import com.ibm.xsp.webdav.WebDavManager;
import com.ibm.xsp.webdav.interfaces.IDAVXMLResponse;

/**
 * DAVAbstractResource represents an entry in a WebDAV Repository. It can be a
 * collection (a.k.a a directory) containing other Resources or it can be a
 * "file" which is something that returns a stream or can be written to as a
 * stream. A resource has 3 identifiers The href = access to the resource
 * relative to the repository as seen from the browser The path = access to the
 * resource as seen from it's internal mechanism like (the absolute) path in a
 * file system or url or query statement The uri = access to the resource from
 * the browser including servlet and repository
 * 
 * @author Stephan H. Wissel
 * 
 */
public abstract class DAVAbstractResource implements IDAVResource, IDAVAddressInformation {

    /**
     * Logger for Errors
     */
    private static final Log LOGGER = LogFactory.getLog(DAVAbstractResource.class);

    /**
     * Length of the content expressed in bytes as a Long
     */
    protected Long contentLenght = null;

    /**
     * Creation date -- not supported in Java for files, but other members could
     */
    private Date creationDate;

    /**
     * The path to the resource = access to the resource from the repository as
     * seen from it's internal mechanism if the browser types
     * http://www.myserver.com/dav/special/jan/report.xls and the repository is
     * "special", wich is located c:\test and the file is
     * c:\test\jan\reports.xls then the path is = "\jan\reports.xls" In Domino
     * or RDBMS this would be the query expression!
     */
    private String internalAddress;

    /**
     * Is the resource Read Only, we assume it is read write
     */
    private boolean readOnly = false;

    /**
     * Is this a directory yes/no
     */
    private boolean isCollection;

    /**
     * is it a member: Needed when a collection is parsed. To avoid endless
     * recursion We set isMember when adding a resource inside a collection
     */
    private boolean isMember;

    /**
     * Last modified date
     */
    private Date lastModifiedDate;

    /**
     * List of members (for directory/collection only)
     */
    private Vector<IDAVResource> members;

    /**
     * Name of the resource --- used for display typically the filename without
     * any path
     */
    private String name;

    /**
     * Who owns the resource
     */
    private IDAVRepository owner;

    /**
     * Properties of the resource
     */
    private DAVProperties properties;

    /**
     * The URL of the resource = access to the resource from the repository as
     * seen from the browser if the browser types
     * http://www.myserver.com/dav/special/jan/report.xls and the repository is
     * "special", then the URL = "/jan/reports.xls"
     */
    private String publicHref;

    /**
     * The internal type of resource we are dealing with
     */
    private String resourceType = null;

    /**
     * Name of the current file extension
     */
    private String fileExtension;

    /**
     * addToKXml adds reponseparts to the XML output
     * 
     * @param dxr
     *            - DAV XML Resonse
     * @throws IOException
     *             for XML Errors
     */

    /**
     * The unique eTag
     */
    protected String eTag = null;

    /**
     * The MimeType for this resource
     */
    private String mimeType = null;

    /**
     * Adds informatoin about locking to a resource output
     * 
     * @param dxr
     */
    private void addLockStatus(IDAVXMLResponse dxr) {
        // Special for locked properties
        LockManager lm = LockManager.getLockManager();

        if (lm.isLocked(this)) {
            /*
             * <D:lockdiscovery> <D:activelock>
             * <D:locktype><D:write/></D:locktype>
             * <D:lockscope><D:exclusive/></D:lockscope> <D:depth>0</D:depth>
             * <D:owner>James Smith</D:owner> --- We don't reveal token and
             * timeout --- <D:timeout>Infinite</D:timeout> <D:locktoken>
             * <D:href>
             * opaquelocktoken:f81de2ad-7f3d-a1b3-4f3c-00a0c91a9d76</D:href>
             * </D:locktoken> </D:activelock> </D:lockdiscovery>
             */
            String owner = lm.getLockOwner(this);
            dxr.openTag("lockdiscovery");
            dxr.openTag("activelock");
            dxr.openTag("locktype");
            dxr.emptyTag("write");
            dxr.closeTag(1);
            dxr.openTag("lockscope");
            dxr.emptyTag("exclusive");
            dxr.closeTag(1);
            dxr.simpleTag("depth", "0");
            dxr.simpleTag("owner", owner);
            dxr.closeTag(2); // activelock lockdiscovery
        }
    }

    /**
     * Adds the XML needed for proper locking support
     * 
     * @param dxr
     */
    private void addLockType(IDAVXMLResponse dxr) {
        /*
         * the structure of the lock information: <supportedlock> <lockentry>
         * <lockscope> <exclusive/> </lockscope> <locktype> <write/> </locktype>
         * </lockentry> <lockentry> <lockscope> <shared/> </lockscope>
         * <locktype> <write/> </locktype> </lockentry> </supportedlock>
         */
        dxr.openTag("supportedlock");
        dxr.openTag("lockentry");
        dxr.openTag("lockscope");
        dxr.emptyTag("exclusive");
        dxr.closeTag(1);
        dxr.openTag("locktype");
        dxr.emptyTag("write");
        dxr.closeTag(2);
        // And the share one
        dxr.openTag("lockentry");
        dxr.openTag("lockscope");
        dxr.emptyTag("shared");
        dxr.closeTag(1);
        dxr.openTag("locktype");
        dxr.emptyTag("write");
        dxr.closeTag(3); // close until supportedlock
    }

    public void addToDavXMLResponse(IDAVXMLResponse dxr) throws IOException {

        // Format expected as result. multistatus is already set in PROPFIND
        /*
         * <?xml version="1.0" encoding="utf-8" ?> <D:multistatus
         * xmlns:D="DAV:"> <D:response> <D:href>/webdav/Demo/</D:href>
         * <D:propstat> <D:prop>
         * <D:creationdate>2011-06-28T09:36:29Z</D:creationdate>
         * <D:displayname><![CDATA[Demo]]></D:displayname> <D:resourcetype>
         * <D:collection/> </D:resourcetype> <D:source/> <D:supportedlock>
         * <D:lockentry> <D:lockscope> <D:exclusive/> </D:lockscope>
         * <D:locktype> <D:write/> </D:locktype> </D:lockentry> <D:lockentry>
         * <D:lockscope> <D:shared/> </D:lockscope> <D:locktype> <D:write/>
         * </D:locktype> </D:lockentry> </D:supportedlock> </D:prop>
         * <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response>
         * <D:response> <D:href>/webdav/Demo/Test1.doc</D:href> <D:propstat>
         * <D:prop> <D:creationdate>2011-06-26T11:53:49Z</D:creationdate>
         * <D:displayname><![CDATA[Test1.doc]]></D:displayname>
         * <D:getlastmodified>Sun, 26 Jun 2011 11:53:49 GMT</D:getlastmodified>
         * <D:getcontentlength>19968</D:getcontentlength>
         * <D:getcontenttype>application/msword</D:getcontenttype>
         * <D:getetag>W/"19968-1309089229626"</D:getetag> <D:resourcetype/>
         * <D:source/> <D:supportedlock> <D:lockentry> <D:lockscope>
         * <D:exclusive/> </D:lockscope> <D:locktype> <D:write/> </D:locktype>
         * </D:lockentry> <D:lockentry> <D:lockscope> <D:shared/> </D:lockscope>
         * <D:locktype> <D:write/> </D:locktype> </D:lockentry>
         * </D:supportedlock> </D:prop> <D:status>HTTP/1.1 200 OK</D:status>
         * </D:propstat> </D:response> </D:multistatus>
         */

        // Step 1: Get all variables
        // Intercept if the Href is missing - shouldn't happen
        String curHref = this.getPublicHref(); // .properties.getVal("href");
        String hrefToWrite = (curHref == null) ? "null" : curHref;
        // If it is a collection/directory it must end with /
        if (this.isCollection && !hrefToWrite.endsWith("/")) {
            hrefToWrite += "/";
        }

        String displayName = this.getName();
        Date creaDate = this.getCreationDate();
        Date modiDate = this.getLastModified();
        String contentLString = String.valueOf(this.getContentLength());
        String mimeString = this.getMimeType();
        String eTagString = this.getETag();

        // Step 2: Write out the result -- to better distinguish between files
        // and directories
        // the code below separates them

        if (this.isCollection) {
            // Step 2a: Write a collection
            dxr.openTag("response"); // <D:response>
            dxr.simpleTag("href", hrefToWrite); // <D:href>/webdav/Demo/</D:href>
            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.dateTagForCreateDate("creationdate", new Date()); // <D:creationdate>2011-06-28T09:36:29Z</D:creationdate>
            dxr.cdataTag("displayname", displayName); // <D:displayname><![CDATA[Demo]]></D:displayname>
            dxr.openTag("resourcetype"); // <D:resourcetype>
            dxr.emptyTag("collection"); // <D:collection/>
            dxr.closeTag(1); // </D:resourcetype>
            dxr.emptyTag("source"); // <D:source/>
            if (this.isReadOnly()) {
                dxr.simpleTag("isreadonly", "true"); // Readonly Status
            }
            this.addLockType(dxr); // <D:supportedlock> ... </D:supportedlock>
            dxr.closeTag(1); // </D:prop>
            dxr.simpleTag("status", "HTTP/1.1 200 OK"); // <D:status>HTTP/1.1
            // 200 OK</D:status>
            dxr.closeTag(2); // </D:propstat></D:response>

            // Once a collection has been written eventually the members
            // need to be written. In HTTP that's the header depth=1
            // Here we indicate that with !isMember()
            // If this resource is directory we are interested in the members
            if (!this.isMember && this.members != null) {
                LOGGER.debug("Now writing XML child entries for " + curHref);
                for (int i = 0; i < this.members.size(); i++) {
                    ((DAVAbstractResource) (this.members.get(i))).addToDavXMLResponse(dxr);
                }
                LOGGER.debug("XML child entries written for " + curHref);
            }
        } else {
            // Step 2b: Write a file
            // LOGGER.info("DAV Locale="+Locale.getDefault().toString());
            dxr.openTag("response"); // <D:response>
            dxr.simpleTag("href", hrefToWrite); // <D:href>/webdav/Demo/Test1.doc</D:href>
            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.dateTagForCreateDate("creationdate", creaDate); // <D:creationdate>2011-06-26T11:53:49Z</D:creationdate>
            dxr.cdataTag("displayname", displayName); // <D:displayname><![CDATA[Test1.doc]]></D:displayname>
            dxr.dateTag("getlastmodified", modiDate); // <D:getlastmodified>Sun,
            // 26 Jun 2011 11:53:49
            // GMT</D:getlastmodified>"
            dxr.simpleTag("getcontentlength", contentLString); // <D:getcontentlength>19968</D:getcontentlength>
            dxr.simpleTag("getcontenttype", mimeString); // <D:getcontenttype>application/msword</D:getcontenttype>
            dxr.simpleTag("getetag", eTagString); // <D:getetag>W/"19968-1309089229626"</D:getetag>
            // dxr.auxTag("Subject", "Subject Eugen Cretu "+displayName);
            // dxr.auxTag("Title", "Title Eugen Cretu "+displayName);
            dxr.emptyTag("resourcetype"); // <D:resourcetype/>
            dxr.emptyTag("source"); // <D:source/>
            if (this.isReadOnly()) {
                dxr.simpleTag("isreadonly", "true"); // Readonly Status
            }
            this.addLockType(dxr); // <D:supportedlock> ... </D:supportedlock>
            this.addLockStatus(dxr); // <D:lockdiscovery> ... </D:lockdiscovery>
            dxr.closeTag(1); // </D:prop>
            dxr.simpleTag("status", "HTTP/1.1 200 OK"); // <D:status>HTTP/1.1
            // 200 OK</D:status>
            dxr.closeTag(2); // </D:propstat></D:response>
        }

        LOGGER.debug("XML written for " + curHref);
    }

    public void addToDavXMLResponsePROPPATCH(IDAVXMLResponse dxr) throws IOException {

        // Format expected as result. multistatus is already set in PROPFIND
        /*
         * <?xml version="1.0" encoding="utf-8" ?> <D:multistatus
         * xmlns:D="DAV:"> <D:response> <D:href>/webdav/Demo/</D:href>
         * <D:propstat> <D:prop>
         * <D:creationdate>2011-06-28T09:36:29Z</D:creationdate>
         * <D:displayname><![CDATA[Demo]]></D:displayname> <D:resourcetype>
         * <D:collection/> </D:resourcetype> <D:source/> <D:supportedlock>
         * <D:lockentry> <D:lockscope> <D:exclusive/> </D:lockscope>
         * <D:locktype> <D:write/> </D:locktype> </D:lockentry> <D:lockentry>
         * <D:lockscope> <D:shared/> </D:lockscope> <D:locktype> <D:write/>
         * </D:locktype> </D:lockentry> </D:supportedlock> </D:prop>
         * <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response>
         * <D:response> <D:href>/webdav/Demo/Test1.doc</D:href> <D:propstat>
         * <D:prop> <D:creationdate>2011-06-26T11:53:49Z</D:creationdate>
         * <D:displayname><![CDATA[Test1.doc]]></D:displayname>
         * <D:getlastmodified>Sun, 26 Jun 2011 11:53:49 GMT</D:getlastmodified>
         * <D:getcontentlength>19968</D:getcontentlength>
         * <D:getcontenttype>application/msword</D:getcontenttype>
         * <D:getetag>W/"19968-1309089229626"</D:getetag> <D:resourcetype/>
         * <D:source/> <D:supportedlock> <D:lockentry> <D:lockscope>
         * <D:exclusive/> </D:lockscope> <D:locktype> <D:write/> </D:locktype>
         * </D:lockentry> <D:lockentry> <D:lockscope> <D:shared/> </D:lockscope>
         * <D:locktype> <D:write/> </D:locktype> </D:lockentry>
         * </D:supportedlock> </D:prop> <D:status>HTTP/1.1 200 OK</D:status>
         * </D:propstat> </D:response> </D:multistatus>
         */

        // Step 1: Get all variables
        // Intercept if the Href is missing - shouldn't happen
        String curHref = this.getPublicHref(); // .properties.getVal("href");
        String hrefToWrite = (curHref == null) ? "null" : curHref;
        // If it is a collection/directory it must end with /
        if (this.isCollection && !hrefToWrite.endsWith("/")) {
            hrefToWrite += "/";
        }

        String displayName = this.getName();

        // Step 2: Write out the result -- to better distinguish between files
        // and directories
        // the code below separates them

        if (this.isCollection) {
            // Step 2a: Write a collection
            dxr.openTag("response"); // <D:response>
            dxr.simpleTag("href", hrefToWrite); // <D:href>/webdav/Demo/</D:href>
            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.dateTagForCreateDate("creationdate", new Date()); // <D:creationdate>2011-06-28T09:36:29Z</D:creationdate>
            dxr.cdataTag("displayname", displayName); // <D:displayname><![CDATA[Demo]]></D:displayname>
            dxr.openTag("resourcetype"); // <D:resourcetype>
            dxr.emptyTag("collection"); // <D:collection/>
            dxr.closeTag(1); // </D:resourcetype>
            dxr.emptyTag("source"); // <D:source/>
            this.addLockType(dxr); // <D:supportedlock> ... </D:supportedlock>
            dxr.closeTag(1); // </D:prop>
            dxr.simpleTag("status", "HTTP/1.1 200 OK"); // <D:status>HTTP/1.1
            // 200 OK</D:status>
            dxr.closeTag(2); // </D:propstat></D:response>

            // Once a collection has been written eventually the members
            // need to be written. In HTTP that's the header depth=1
            // Here we indicate that with !isMember()
            // If this resource is directory we are interested in the members
            if (!this.isMember && this.members != null) {
                LOGGER.debug("Now writing XML child entries for " + curHref);
                for (int i = 0; i < this.members.size(); i++) {
                    ((DAVAbstractResource) (this.members.get(i))).addToDavXMLResponse(dxr);
                }
                LOGGER.debug("XML child entries written for " + curHref);
            }
        } else {
            // Step 2b: Write a file
            dxr.openTag("response"); // <D:response>
            dxr.simpleTag("href", hrefToWrite); // <D:href>/webdav/Demo/Test1.doc</D:href>
            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.emptyTag("creationdate");
            dxr.closeTag(1);
            dxr.simpleTag("status", "HTTP/1.1 200 OK");
            dxr.closeTag(1);

            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.emptyTag("lastaccessed");
            dxr.closeTag(1);
            dxr.simpleTag("status", "HTTP/1.1 200 OK");
            dxr.closeTag(1);

            dxr.openTag("propstat"); // <D:propstat>
            dxr.openTag("prop"); // <D:prop>
            dxr.emptyTag("getlastmodified");
            dxr.closeTag(1);
            dxr.simpleTag("status", "HTTP/1.1 200 OK");
            dxr.closeTag(1); // close propstat
            dxr.closeTag(1); // close response

        }

        LOGGER.debug("XML written for " + curHref);
    }

    /**
     * 
     * @return true/false - Success of delete operation
     */
    public abstract boolean delete();

    /**
     * 
     * @return Length of content
     */
    public Long getContentLength() {
        return this.contentLenght;
    }

    /**
     * 
     * @return Date CreationDate (not supported in Java)
     */
    public Date getCreationDate() {

        return this.creationDate;

    }

    /**
     * eTags are used to indicate if a resource has been overwritten
     */
    public String getETag() {
        // If an eTag has been created however we return that one
        if (this.eTag != null && this.eTag.equals("")) {
            return this.eTag;
        }
        Date lm = (this.getLastModified() == null) ? this.getCreationDate() : this.getLastModified();
        if (lm == null) {
            lm = new Date();
            // here
            // LOGGER.info("No creation and modified date for "+this.getInternalAddress()+" found");
        }
        // Otherwise we take a weak eTag which is lastModified + content length
        String weakTag = "W/\"" + String.valueOf(this.getContentLength()) + "-" + String.valueOf(lm.getTime())
                + "\"";
        // Here
        this.setCreationDate(new Date());
        //
        return weakTag;
    }

    /**
     * 
     * @return String the file extension
     */
    public String getExtension() {
        return this.fileExtension;
    }

    /**
     * @return Returns the uri.
     */
    public String getInternalAddress() {
        return this.internalAddress;
    }

    /**
     * 
     * @return Date LastModified Date
     */
    public Date getLastModified() {
        return this.lastModifiedDate;
    }

    /**
     * @param dateString
     *            a String that looks like a date
     * @return date the newly found date
     */
    private Date getLocaleDate(String dateString) {
        // TODO Check if implementation is clean
        String creatFormat = "dd'/'mm'/'yyyy' 'H':'m':'s"; // "02/02/2006 09:34:20";
        SimpleDateFormat fmt = new SimpleDateFormat(creatFormat, Locale.UK);
        Date tmpDate;
        try {
            tmpDate = fmt.parse(dateString);
        } catch (ParseException e) {
            LOGGER.error(e);
            tmpDate = new Date(); // Default value just in case
        }
        return tmpDate;
    }

    /**
     * 
     * @return Vector with DAVResourceObjects
     */
    protected Vector<IDAVResource> getMembers() {
        return this.members;
    }

    /**
     * 
     * @param context
     *            ServletContext for mime conversion
     * @return mime type of file
     */
    public String getMimeType() {

        if (this.mimeType != null && !this.mimeType.equals("")) {
            return this.mimeType;
        }

        String curName = this.getName();
        String returnType = WebDavManager.getManager(null).getMimeType(curName);
        if (returnType == null) {
            returnType = "application/octet-stream";
        }
        LOGGER.debug("Mime type for [" + curName + "] is: \"" + returnType + "\"");

        this.mimeType = returnType;
        return returnType;
    }

    /**
     * 
     * @return String Name of the resource - no path included
     */
    public String getName() {
        return this.name;
    }

    /**
     * 
     * @return Outputstream to update resource
     */
    public abstract OutputStream getOutputStream();

    /**
     * 
     * @return Owner of this resource
     */
    public IDAVRepository getOwner() {
        return this.owner;
    }

    /**
     * 
     * @return DAVProperties: all properties of the resource
     */
    @Deprecated
    public DAVProperties getxxxProperties() {
        return this.properties;
    }

    /**
     * 
     * @return href URL of the resource
     */
    public String getPublicHref() {
        // A huge headache is the possibility to
        // open directories with and without a trailing /
        // so we make sure that we only return the one without
        String result;
        if (this.publicHref == null) {
            this.publicHref = "";
        }
        if (this.publicHref.equals("/")) {
            result = "/"; // Special case for the root
        } else if (this.publicHref.endsWith("/")) {
            int hreflen = this.publicHref.length();
            result = this.publicHref.substring(0, hreflen - 1);
        } else {
            result = this.publicHref;
        }
        return result;
    }

    /**
     * 
     * @return repository - the owning repository
     */
    public IDAVRepository getRepository() {
        return this.getOwner();
    }

    public String getResourceType() {
        return this.resourceType;
    }

    /**
     * 
     * @return InputStream - Stream Object to read resource
     */
    public abstract InputStream getStream();

    /**
     * 
     * @return boolean: is it a collection/directory
     */
    public boolean isCollection() {
        return this.isCollection;
    }

    /**
     * @return is it a member, so there won't be any sub elements in it
     */
    public boolean isMember() {
        return this.isMember;
    }

    /**
     * @return Returns the readOnly.
     */
    public boolean isReadOnly() {
        return this.readOnly;
    }

    /**
     * 
     * @param isCollection
     *            declare it a collection with true
     */
    public void setCollection(boolean isCollection) {
        this.isCollection = isCollection;
    }

    /**
     * 
     * @param newLength
     *            Length of content
     */
    protected void setContentLength(Long newLength) {
        this.contentLenght = newLength;

    }

    /**
     * 
     * @param newLengthString
     *            Length of content
     */
    protected void setContentLength(String newLengthString) {
        this.contentLenght = new Long(newLengthString);

    }

    /**
     * 
     * @param date
     *            the CreationDate (not supported in Java)
     */
    public void setCreationDate(Date date) {
        this.creationDate = date;
    }

    /**
     * 
     * @param dateString
     *            String that looks like a CreationDate
     */
    protected void setCreationDate(String dateString) {
        this.creationDate = this.getLocaleDate(dateString);
    }

    /**
     * 
     * @param newExtension
     *            String the file extension
     */
    protected void setExtension(String newExtension) {
        this.fileExtension = newExtension;
    }

    public boolean setInternalAddress(String uri) {
        this.internalAddress = uri;
        return true;
    }

    /**
     * 
     * @param date
     *            Date LastModified Date
     */
    public void setLastModified(Date date) {
        this.lastModifiedDate = date;
    }

    /**
     * 
     * @param dateString
     *            String - Something that looks like a Date
     */
    protected void setLastModified(String dateString) {
        this.lastModifiedDate = this.getLocaleDate(dateString);
    }

    /**
     * 
     * @param isMember
     *            Make it a member
     */
    public void setMember(boolean isMember) {
        this.isMember = isMember;
    }

    /**
     * (non-Javadoc)
     * 
     * @see biz.taoconsulting.dominodav.interfaces.IDAVResource#setMembers(java.util.Vector)
     */
    public void setMembers(Vector<IDAVResource> members) {
        this.members = members;
    }

    public void setMimeType(String newMimeType) {
        this.mimeType = newMimeType;
    }

    /**
     * 
     * @param name
     *            name of the resource
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 
     * @param owner
     *            Owner of this resource
     */
    public void setOwner(IDAVRepository owner) {
        this.owner = owner;
    }

    /**
     * 
     * @param properties
     *            all properties of the resource
     */
    @Deprecated
    protected void setxxxProperties(DAVProperties properties) {
        this.properties = properties;
    }

    /**
     * 
     * @param href
     *            URL of the resource
     */
    public void setPublicHref(String href) {
        this.publicHref = href;
    }

    /**
     * @param readOnly
     *            The readOnly to set.
     */
    protected void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    public void setResourceType(String type) {
        this.resourceType = type;

    }

    // public void embed(){}
}