Date: 2004-11-04T15:24:19
   Editor: BrianLee <[EMAIL PROTECTED]>
   Wiki: Jakarta-Slide Wiki
   Page: WebDavConstructionKit
   URL: http://wiki.apache.org/jakarta-slide/WebDavConstructionKit

   no comment

Change Log:

------------------------------------------------------------------------------
@@ -8,7 +8,9 @@
 Currently, WCK is only available from CVS. For more information on accessing Slide 
from CVS, check http://jakarta.apache.org/site/cvsindex.html
 
 
-==== Build Details ====
+==== Build Notes ====
+
+The easiest way to get everything done on any platform (downloading from CVS, 
buidling from ant, etc...) is to use [http://www.eclipse.org Eclipse] IDE.
 
 ===== Full Working build.properties Example =====
 
@@ -93,9 +95,568 @@
 commons-transaction-20041031.jar with the version you find in the
 2.1b2 lib directory"
 
-==== Example Store ====
+==== Store Implementation ====
+
+Any concrete store must implement the 
[http://jakarta.apache.org/slide/wck/javadoc/org/apache/slide/simple/store/BasicWebdavStore.html
 org.apache.slide.simple.store.BasicWebdavStore] interface.
+
+===== Call Back Methods List =====
+
+The following functions are basically all Slide and WCK need to make basic WebDAV 
operations work.
+
+ 1.begin, commit, rollback: begins, commits, aborts a request / transaction
+
+ 2.objectExists, isFolder, isResource: existence checks, collection vs. content checks
+
+ 3.createFolder, createResource: creation of a collection or a content resource
+
+ 4.removeObject: deletion of a collection or a content resource
+
+ 5.setResourceContent, getResourceContent: storing and retrieval of a content resource
 
-Any concrete store must implement the 
[http://jakarta.apache.org/slide/wck/javadoc/org/apache/slide/simple/store/BasicWebdavStore.html
 org.apache.slide.simple.store.BasicWebdavStore]
+ 6.getLastModified, getCreationDate, getResourceLength: retrieval of basic meta data
 
+ 7.getChildrenNames: retrieval of the children of a collection
+
+===== WebdavFileStore Example =====
+[http://jakarta.apache.org/slide/wck/javadoc/org/apache/slide/simple/reference/WebdavFileStore.html
 org.apache.slide.simple.reference.WebdavFileStore] is the reference implementation 
(example) that you want to look at. The source is listed below - 
+
+{{{
+public class WebdavFileStore implements BasicWebdavStore, WebdavStoreLockExtension, 
WebdavStoreBulkPropertyExtension,
+        WebdavStoreMacroCopyExtension, WebdavStoreMacroMoveExtension, 
WebdavStoreMacroDeleteExtension {
+
+    private static final String ROOTPATH_PARAMETER = "rootpath";
+
+    private static final String LOCK_FILE_EXTENSION = ".lck";
+
+    private static final String PROPERTY_FILE_PREFIX = ".";
+
+    private static void save(InputStream is, File file) throws IOException {
+        OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
+        try {
+            FileHelper.copy(is, os);
+        } finally {
+            try {
+                is.close();
+            } finally {
+                os.close();
+            }
+        }
+    }
+
+    private static File root = null;
+
+    private static Service service = null;
+
+    private static LoggerFacade logger = null;
+
+    public synchronized void begin(Service service, Principal principal, Object 
connection, LoggerFacade logger,
+            Hashtable parameters) throws ServiceAccessException, 
ServiceParameterErrorException,
+            ServiceParameterMissingException {
+        // set parameters only once...
+        if (WebdavFileStore.root == null) {
+            WebdavFileStore.service = service;
+            WebdavFileStore.logger = logger;
+            String rootPath = (String) parameters.get(ROOTPATH_PARAMETER);
+            if (rootPath == null)
+                throw new ServiceParameterMissingException(service, 
ROOTPATH_PARAMETER);
+
+            WebdavFileStore.root = new File(rootPath);
+            if (!WebdavFileStore.root.exists()) {
+                if (!WebdavFileStore.root.mkdirs()) {
+                    throw new ServiceParameterErrorException(service, 
ROOTPATH_PARAMETER + ": " + WebdavFileStore.root
+                            + " does not exist and could not be created");
+                } else {
+                    logger.logInfo("Created root folder at: " + rootPath);
+                }
+            }
+        }
+    }
+
+    public void commit() throws ServiceAccessException {
+    }
+
+    public void rollback() throws ServiceAccessException {
+    }
+
+    public void macroCopy(String sourceUri, String targetUri, boolean overwrite, 
boolean recursive) throws ServiceAccessException, AccessDeniedException,
+            ObjectNotFoundException, ObjectAlreadyExistsException {
+        try {
+            File fromFile = getFile(sourceUri);
+            File toFile = getFile(targetUri);
+            if (toFile.exists() && !overwrite) {
+                throw new ObjectAlreadyExistsException(targetUri);
+            }
+            if (!toFile.getParentFile().exists()) {
+                throw new ObjectNotFoundException(toFile.getParentFile().toString());
+            }
+            if (fromFile.isDirectory() && !recursive) {
+                //  copy directory only, which means create dir and copy properties
+                if (!toFile.exists()) {
+                    toFile.mkdirs();
+                }
+            } else {
+                FileHelper.copyRec(fromFile, toFile);
+            }
+            File propertyFile = getPropertyFile(sourceUri);
+            File destPropertyFile = getPropertyFile(targetUri);
+            if (propertyFile.exists()) FileHelper.copy(propertyFile, 
destPropertyFile);
+            // XXX is it correct not to take over locking information on copy? I 
guess so (OZ)
+//            File lockFile = getLockFile(sourceUri);
+//            File destLockFile = getLockFile(targetUri);
+//            if (lockFile.exists()) FileHelper.copy(propertyFile, destPropertyFile);
+        } catch (FileNotFoundException e) {
+            throw new ObjectNotFoundException(targetUri);
+        } catch (IOException e) {
+            throw new ServiceAccessException(service, e);
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(targetUri, e.getMessage(), 
"/actions/write");
+        }
+    }
+
+    public void macroMove(String sourceUri, String targetUri, boolean overwrite) 
throws ServiceAccessException, AccessDeniedException,
+            ObjectNotFoundException, ObjectAlreadyExistsException {
+        try {
+            File fromFile = getFile(sourceUri);
+            File toFile = getFile(targetUri);
+            if (toFile.exists() && !overwrite) {
+                throw new ObjectAlreadyExistsException(targetUri);
+            }
+            if (!toFile.getParentFile().exists()) {
+                throw new ObjectNotFoundException(toFile.getParentFile().toString());
+            }
+            renameOrMove(fromFile, toFile);
+            File propertyFile = getPropertyFile(sourceUri);
+            File destPropertyFile = getPropertyFile(targetUri);
+            renameOrMove(propertyFile, destPropertyFile);
+            File lockFile = getLockFile(sourceUri);
+            File destLockFile = getLockFile(targetUri);
+            renameOrMove(lockFile, destLockFile);
+        } catch (FileNotFoundException e) {
+            throw new ObjectNotFoundException(targetUri);
+        } catch (IOException e) {
+            throw new ServiceAccessException(service, e);
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(targetUri, e.getMessage(), 
"/actions/write");
+        }
+    }
+
+    protected void renameOrMove(File from, File to) throws IOException,
+            ObjectAlreadyExistsException {
+        if (from.exists()) {
+            if (to.exists()) {
+                boolean success = to.delete();
+                if (!success) {
+                    new ObjectAlreadyExistsException(to.toString());
+                }
+            }
+            boolean success = from.renameTo(to);
+            if (!success) {
+                FileHelper.moveRec(from, to);
+            }
+        }
+    }
+    
+    public void macroDelete(String targetUri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectNotFoundException {
+        try {
+            File file = getFile(targetUri);
+            FileHelper.removeRec(file);
+            File propertyFile = getPropertyFile(targetUri);
+            if (propertyFile.exists()) propertyFile.delete();    
+            File lockFile = getLockFile(targetUri);
+            if (lockFile.exists()) lockFile.delete();    
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(targetUri, e.getMessage(), 
"/actions/write");
+        }
+    }
+
+    public boolean objectExists(String uri) throws ServiceAccessException, 
AccessDeniedException {
+        try {
+            return getFile(uri).exists();
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(uri, e.getMessage(), "read");
+        }
+    }
+
+    public boolean isFolder(String uri) throws ServiceAccessException, 
AccessDeniedException {
+        try {
+            return (getFile(uri).exists() && getFile(uri).isDirectory());
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(uri, e.getMessage(), "read");
+        }
+
+    }
+
+    public boolean isResource(String uri) throws ServiceAccessException, 
AccessDeniedException {
+        try {
+            return (getFile(uri).exists() && !getFile(uri).isDirectory());
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(uri, e.getMessage(), "read");
+        }
+    }
+
+    public void createFolder(String folderUri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectAlreadyExistsException {
+        try {
+            if (!getFile(folderUri).mkdir())
+                throw new ServiceAccessException(service, "Can not create directory " 
+ folderUri);
+
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(folderUri, e.getMessage(), "create");
+        }
+    }
+
+    public String[] getChildrenNames(String folderUri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectNotFoundException {
+        try {
+
+            File file = getFile(folderUri);
+            if (file.isDirectory()) {
+
+                File[] children = file.listFiles();
+                List childList = new ArrayList();
+                for (int i = 0; i < children.length; i++) {
+                    String name = children[i].getName();
+                    // locking and property information should not be displayed
+                    // as a resource
+                    if (!isLockFilename(name) && !isPropertyFilename(name)) {
+                        childList.add(name);
+                    }
+                }
+                String[] childrenNames = new String[childList.size()];
+                childrenNames = (String[]) childList.toArray(childrenNames);
+                return childrenNames;
+            } else {
+                return null;
+            }
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(folderUri, e.getMessage(), "read");
+        }
+    }
+
+    public void createResource(String resourceUri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectAlreadyExistsException {
+        try {
+            File file = getFile(resourceUri);
+            if (file.exists())
+                throw new ObjectAlreadyExistsException(resourceUri);
+            if (!file.createNewFile())
+                throw new ServiceAccessException(service, "Can not create file " + 
resourceUri);
+        } catch (IOException e) {
+            throw new ServiceAccessException(service, e);
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(resourceUri, e.getMessage(), "create");
+        }
+    }
+
+    public void setResourceContent(String resourceUri, InputStream content, String 
contentType, String characterEncoding) throws ServiceAccessException,
+            AccessDeniedException, ObjectNotFoundException {
+        try {
+
+            File file = getFile(resourceUri);
+            if (!file.exists())
+                throw new ObjectNotFoundException(resourceUri);
+            try {
+                save(content, file);
+            } catch (FileNotFoundException e) {
+                // XXX this really indicates a denied access
+                throw new AccessDeniedException(resourceUri, e.getMessage(), "store");
+            } catch (IOException e) {
+                throw new ServiceAccessException(service, e);
+            }
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(resourceUri, e.getMessage(), "store");
+        }
+    }
+
+    public long getResourceLength(String resourceUri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectNotFoundException {
+        try {
+            File file = getFile(resourceUri);
+            if (!file.exists())
+                throw new ObjectNotFoundException(resourceUri);
+            return file.length();
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(resourceUri, e.getMessage(), "read");
+        }
+
+    }
+
+    public InputStream getResourceContent(String resourceUri) throws 
ServiceAccessException, AccessDeniedException,
+            ObjectNotFoundException {
+        try {
+            File file = getFile(resourceUri);
+            if (!file.exists())
+                throw new ObjectNotFoundException(resourceUri);
+            InputStream in;
+            try {
+                in = new BufferedInputStream(new FileInputStream(file));
+                return in;
+            } catch (FileNotFoundException e) {
+                throw new ObjectNotFoundException(resourceUri);
+            }
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(resourceUri, e.getMessage(), "read");
+        }
+    }
+
+    public void removeObject(String uri) throws ServiceAccessException, 
AccessDeniedException, ObjectNotFoundException {
+        try {
+            File file = getFile(uri);
+            if (!file.exists())
+                throw new ObjectNotFoundException(uri);
+
+            if (!file.delete())
+                throw new ServiceAccessException(service, "Unable to delete " + uri);
+            getPropertyFile(uri).delete();
+            getLockFile(uri).delete();
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(uri, e.getMessage(), "delete");
+        }
+    }
+
+    public Date getLastModified(String uri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectNotFoundException {
+        try {
+            File file = getFile(uri);
+            if (!file.exists())
+                throw new ObjectNotFoundException(uri);
+            long lastModified = file.lastModified();
+            return new Date(lastModified);
+        } catch (SecurityException e) {
+            throw new AccessDeniedException(uri, e.getMessage(), "read");
+        }
+    }
+
+    public Date getCreationDate(String uri) throws ServiceAccessException, 
AccessDeniedException,
+            ObjectNotFoundException {
+        // XXX we do not have this information
+        return getLastModified(uri);
+    }
+
+    public Map getProperties(String uri) throws ServiceAccessException, 
AccessDeniedException {
+        File file = getPropertyFile(uri);
+        if (!file.exists()) {
+            return null;
+        }
+        return readProperties(file);
+    }
+
+    public void setProperties(String uri, Map properties) throws 
ServiceAccessException, AccessDeniedException {
+        File file = getPropertyFile(uri);
+        assureCreated(file, uri);
+        Properties props = new Properties();
+        props.putAll(properties);
+        saveProperties(file, props, "WebDAV properties");
+    }
+
+    public void addOrUpdateProperty(String uri, String name, String value) throws 
ServiceAccessException,
+            AccessDeniedException, ObjectNotFoundException {
+    }
+
+    public void removeProperty(String uri, String name) throws 
ServiceAccessException, AccessDeniedException,
+            ObjectNotFoundException {
+    }
+
+    public void lockObject(String uri, String lockId, String subject, Date 
expiration, boolean exclusive,
+            boolean inheritable) throws ServiceAccessException, AccessDeniedException 
{
+        File file = getLockFile(uri);
+        assureCreated(file, uri);
+        Properties properties = readProperties(file);
+        String lockString = expiration.getTime() + "|" + String.valueOf(exclusive) + 
"|" + String.valueOf(inheritable)
+                + "|" + subject;
+        properties.setProperty(lockId, lockString);
+        saveProperties(file, properties, "WebDAV locks");
+    }
+
+    public void unlockObject(String uri, String lockId) throws 
ServiceAccessException, AccessDeniedException {
+        File file = getLockFile(uri);
+        if (!file.exists()) {
+            throw new ServiceAccessException(service, "There nothing to unlock for " 
+ uri);
+        }
+        Properties properties = readProperties(file);
+        properties.remove(lockId);
+        // do a special trick and remove the lock file when there are no more
+        // locks
+        if (properties.size() != 0) {
+            saveProperties(file, properties, "WebDAV locks");
+        } else {
+            if (!file.delete())
+                throw new ServiceAccessException(service, "Could not delete lock file 
for " + uri);
+        }
+    }
+
+    public Lock[] getLockInfo(String uri) throws ServiceAccessException, 
AccessDeniedException {
+        File file = getLockFile(uri);
+        if (!file.exists()) {
+            return null;
+        }
+        Properties properties = readProperties(file);
+        List locks = new ArrayList();
+        Enumeration enum = properties.propertyNames();
+        while (enum.hasMoreElements()) {
+            String id = (String) enum.nextElement();
+            String value = properties.getProperty(id);
+            if (value == null) {
+                throw new ServiceAccessException(service, "Invalid lockId " + id);
+            }
+            StringTokenizer tokenizer = new StringTokenizer(value, "|");
+            int tokens = tokenizer.countTokens();
+            if (tokens != 4) {
+                throw new ServiceAccessException(service, "Invalid lock information 
for lockId " + id);
+            }
+            String dateString = tokenizer.nextToken();
+            String exclusiveString = tokenizer.nextToken();
+            String inheritableString = tokenizer.nextToken();
+            String subject = tokenizer.nextToken();
+            Date date = new Date(Long.valueOf(dateString).longValue());
+            boolean exclusive = Boolean.valueOf(exclusiveString).booleanValue();
+            boolean inheritable = Boolean.valueOf(inheritableString).booleanValue();
+            Lock lock = new SimpleLock(id, exclusive, inheritable, date, subject);
+            locks.add(lock);
+        }
+        Lock[] lockArray = new Lock[locks.size()];
+        lockArray = (Lock[]) locks.toArray(lockArray);
+        return lockArray;
+    }
+
+    protected File getFile(String uri) {
+        File file = new File(root, uri);
+        return file;
+    }
+
+    protected File getPropertyFile(String uri) {
+        String dir;
+        String name;
+        int lastSlash = uri.lastIndexOf('/');
+        if (lastSlash != -1) {
+            dir = uri.substring(0, lastSlash + 1);
+            name = uri.substring(lastSlash + 1);
+        } else {
+            dir = "";
+            name = uri;
+        }
+        String path = dir + PROPERTY_FILE_PREFIX + name;
+        File file = new File(root, path);
+        return file;
+    }
+
+    protected boolean isPropertyFilename(String uri) {
+        return uri.startsWith(PROPERTY_FILE_PREFIX);
+    }
+
+    protected File getLockFile(String uri) {
+        File file = new File(root, uri + LOCK_FILE_EXTENSION);
+        return file;
+    }
+
+    protected boolean isLockFilename(String uri) {
+        return uri.endsWith(LOCK_FILE_EXTENSION);
+    }
+
+    protected void assureCreated(File file, String uri) throws ServiceAccessException 
{
+        if (!file.exists()) {
+            try {
+                if (!file.createNewFile())
+                    throw new ServiceAccessException(service, "Can not create file " 
+ uri);
+            } catch (IOException e) {
+                throw new ServiceAccessException(service, e);
+            }
+        }
+    }
+
+    protected String getLockEntry(String uri, String lockId) throws 
ServiceAccessException, ObjectNotFoundException {
+        File file = getLockFile(uri);
+        if (!file.exists()) {
+            throw new ObjectNotFoundException(uri);
+        }
+        Properties properties = readProperties(file);
+        String value = properties.getProperty(lockId);
+        if (value == null) {
+            throw new ServiceAccessException(service, "Invalid lockId " + lockId);
+        }
+        return value;
+    }
+
+    protected void saveProperties(File file, Properties properties, String header) 
throws ServiceAccessException {
+        OutputStream os = null;
+        try {
+            os = new BufferedOutputStream(new FileOutputStream(file));
+            properties.store(os, header);
+        } catch (FileNotFoundException e) {
+            throw new ServiceAccessException(service, e);
+        } catch (IOException e) {
+            throw new ServiceAccessException(service, e);
+        } finally {
+            if (os != null)
+                try {
+                    os.close();
+                } catch (IOException e) {
+                }
+        }
+    }
+
+    protected Properties readProperties(File file) throws ServiceAccessException {
+        InputStream is = null;
+        try {
+            is = new BufferedInputStream(new FileInputStream(file));
+            Properties properties = new Properties();
+            properties.load(is);
+            return properties;
+        } catch (FileNotFoundException e) {
+            throw new ServiceAccessException(service, e);
+        } catch (IOException e) {
+            throw new ServiceAccessException(service, e);
+        } finally {
+            if (is != null)
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+        }
+    }
+
+    private static class SimpleLock implements Lock {
+
+        public String id;
+
+        public boolean exclusive;
+
+        public boolean inheritable;
+
+        public Date expirationDate;
+
+        public String subject;
+
+        public SimpleLock(String id, boolean exclusive, boolean inheritable, Date 
expirationDate, String subject) {
+            this.id = id;
+            this.exclusive = exclusive;
+            this.inheritable = inheritable;
+            this.expirationDate = expirationDate;
+            this.subject = subject;
+        }
+
+        public boolean isExclusive() {
+            return exclusive;
+        }
+
+        public Date getExpirationDate() {
+            return expirationDate;
+        }
+
+        public String getId() {
+            return id;
+        }
+
+        public boolean isInheritable() {
+            return inheritable;
+        }
+
+        public String getSubject() {
+            return subject;
+        }
+
+    }
+}
+}}}
 
-[http://jakarta.apache.org/slide/wck/javadoc/org/apache/slide/simple/reference/WebdavFileStore.html
 org.apache.slide.simple.reference.WebdavFileStore] is the reference implementation 
(example) that you want to look at.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to