You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by oz...@apache.org on 2004/09/20 09:56:38 UTC

cvs commit: jakarta-slide/src/stores/org/apache/slide/store/file AbstractSimpleStore.java SimpleFileStoreTest.java CountdownStore.java SimpleFileStore.java

ozeigermann    2004/09/20 00:56:38

  Added:       src/stores/org/apache/slide/store/file
                        AbstractSimpleStore.java SimpleFileStoreTest.java
                        CountdownStore.java SimpleFileStore.java
  Log:
  Added new simple file store donated by Alon Salant in 
  http://issues.apache.org/bugzilla/show_bug.cgi?id=31177
  
  Revision  Changes    Path
  1.1                  jakarta-slide/src/stores/org/apache/slide/store/file/AbstractSimpleStore.java
  
  Index: AbstractSimpleStore.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/file/AbstractSimpleStore.java,v 1.1 2004/09/20 07:56:38 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 07:56:38 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 The Apache Software Foundation
   *
   * 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 org.apache.slide.store.file;
  
  import java.util.*;
  import javax.transaction.xa.*;
  import org.apache.slide.common.*;
  import org.apache.slide.store.*;
  import org.apache.slide.content.*;
  import org.apache.slide.structure.*;
  import org.apache.slide.util.logger.*;
  import org.apache.commons.logging.*;
  
  /**
   * AbstractSimpleStore provides a minimal implementation to support creating a Slide Store.
   * It no-ops most methods and leaves abstract those methods you must implement to support
   * basic create/retrieve/update/remove.
   * <p>
   * For locking and security your implementation should be paired with
   * org.apache.slide.store.mem.TransientSecurityStore and
   * org.apache.slide.store.mem.TransientLockStore.
   *
   * @see SimpleFileStore
   * @author Alon Salant
   */
  public abstract class AbstractSimpleStore
    extends AbstractServiceBase
    implements ContentStore, NodeStore, RevisionDescriptorStore, RevisionDescriptorsStore
  {
    private static final Log log = LogFactory.getLog(AbstractSimpleStore.class);
  
    // ==== Service Methods ================================
  
    public void setParameters(Hashtable parameters)
      throws ServiceParameterErrorException, ServiceParameterMissingException
    {
      log("setParameters(" + parameters + ")");
    }
  
    public void connect() throws ServiceConnectionFailedException
    {
    }
  
    public void reset() throws ServiceResetFailedException
    {
    }
  
    public void disconnect() throws ServiceDisconnectionFailedException
    {
    }
  
    public boolean isConnected() throws ServiceAccessException
    {
      return true;
    }
  
    public int getTransactionTimeout() throws XAException
    {
      return 0;
    }
  
    public boolean setTransactionTimeout(int seconds) throws XAException
    {
      return false;
    }
  
    public boolean isSameRM(XAResource rm) throws XAException
    {
      return false;
    }
  
    public Xid[] recover(int flag) throws XAException
    {
      return new Xid[0];
    }
  
    public int prepare(Xid txId) throws XAException
    {
      return XA_RDONLY;
    }
  
    public void forget(Xid txId) throws XAException
    {
    }
  
    public void rollback(Xid txId) throws XAException
    {
    }
  
    public void end(Xid txId, int flags) throws XAException
    {
    }
  
    public void start(Xid txId, int flags) throws XAException
    {
    }
  
    public void commit(Xid txId, boolean onePhase) throws XAException
    {
    }
  
    // ==== ContentStore Methods ================================
  
    public abstract NodeRevisionContent retrieveRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException, RevisionNotFoundException;
  
    public abstract void createRevisionContent(Uri uri,
                                               NodeRevisionDescriptor revisionDescriptor,
                                               NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionAlreadyExistException;
  
    public abstract void storeRevisionContent(Uri uri,
                                              NodeRevisionDescriptor revisionDescriptor,
                                              NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionNotFoundException;
  
    public void removeRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException
    {
      log("removeRevisionContent(" + uri + ")");
    }
  
    // ==== NodeStore Methods ================================
  
    public abstract void storeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException;
  
    public abstract void createObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectAlreadyExistsException;
  
    public abstract void removeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException;
  
    public abstract ObjectNode retrieveObject(Uri uri)
      throws ServiceAccessException, ObjectNotFoundException;
  
    // ==== RevisionDescriptorsStore Methods ================================
  
    public NodeRevisionDescriptors retrieveRevisionDescriptors(Uri uri)
      throws ServiceAccessException, RevisionDescriptorNotFoundException
    {
      log("retrieveRevisionDescriptors(" + uri + ")");
  
      NodeRevisionNumber rev = new NodeRevisionNumber(1, 0);
  
      Hashtable workingRevisions = new Hashtable();
      workingRevisions.put("1.0", rev);
  
      Hashtable latestRevisionNumbers = new Hashtable();
      latestRevisionNumbers.put("1.0", rev);
  
      Hashtable branches = new Hashtable();
      branches.put(rev, new Vector());
  
      return new NodeRevisionDescriptors(uri.toString(),
                                         rev,
                                         workingRevisions,
                                         latestRevisionNumbers,
                                         branches,
                                         false);
    }
  
    public void createRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
      throws ServiceAccessException
    {
      log("createRevisionDescriptors(" + uri + ")");
    }
  
    public void storeRevisionDescriptors(Uri uri, NodeRevisionDescriptors revisionDescriptors)
      throws ServiceAccessException, RevisionDescriptorNotFoundException
    {
      log("storeRevisionDescriptors(" + uri + ")");
    }
  
    public void removeRevisionDescriptors(Uri uri) throws ServiceAccessException
    {
      log("removeRevisionDescriptors(" + uri + ")");
    }
  
    // ==== RevisionDescriptorStore Methods ================================
  
    public void createRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException
    {
      log("createRevisionDescriptor(" + uri + ")");
    }
  
    public void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException, RevisionDescriptorNotFoundException
    {
      log("storeRevisionDescriptor(" + uri + ")");
    }
  
    public void removeRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
      throws ServiceAccessException
    {
      log("removeRevisionDescriptor(" + uri + ")");
    }
  
    public abstract NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri, NodeRevisionNumber revisionNumber)
      throws ServiceAccessException, RevisionDescriptorNotFoundException;
  
    protected void log(String msg)
    {
      if (getLogger() == null)
        System.out.println(this.getClass().getName() + ": " + msg);
      else
        getLogger().log(msg, this.getClass().getName(), Logger.DEBUG);
    }
  
  }
  
  
  
  1.1                  jakarta-slide/src/stores/org/apache/slide/store/file/SimpleFileStoreTest.java
  
  Index: SimpleFileStoreTest.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/file/SimpleFileStoreTest.java,v 1.1 2004/09/20 07:56:38 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 07:56:38 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 The Apache Software Foundation
   *
   * 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 org.apache.slide.store.file;
  
  import java.io.*;
  import org.apache.commons.logging.*;
  import org.apache.slide.common.*;
  import org.apache.slide.content.*;
  import org.apache.slide.structure.*;
  import org.apache.slide.authenticate.*;
  import junit.framework.*;
  
  /**
   * @author Alon Salant
   */
  public class SimpleFileStoreTest
        extends TestCase
  {
    private static final Log log = LogFactory.getLog(SimpleFileStoreTest.class);
  
    Domain domain;
    NamespaceAccessToken namespace;
  
    public SimpleFileStoreTest(String s)
    {
        super(s);
    }
  
    public void setUp() throws Exception
    {
      Domain.init(new FileInputStream("WEB-INF/properties/TestDomain.xml"));
      namespace = Domain.accessNamespace(null, "slide");
    }
  
    public void tearDown() throws Exception
    {
  
    }
  
    public void testCreateFile() throws Exception
    {
      String path = "/test.txt";
      File file = new File("files/test.txt");
      try
      {
        SlideToken token = new SlideTokenWrapper(new SlideTokenImpl());
        token.setForceSecurity(false);
        token.setForceLock(false);
        token.setCredentialsToken(new CredentialsToken(""));
  
        Content content = namespace.getContentHelper();
        Structure structure = namespace.getStructureHelper();
  
        structure.create(token, new SubjectNode(), path);
  
        assertTrue(file.exists());
        assertTrue(file.isDirectory());
  
        NodeRevisionContent newContent = new NodeRevisionContent();
        newContent.setContent("delete me, please".getBytes());
        content.create(token, path, new NodeRevisionDescriptor(), newContent);
  
        NodeRevisionContent createdContent = content.retrieve(token, path, new NodeRevisionDescriptor());
        assertNotNull(createdContent);
        assertEquals(new String(newContent.getContent()), new String(createdContent.getContent()));
      }
      finally
      {
        if (file.exists()) file.delete();
      }
    }
  }
  
  
  
  1.1                  jakarta-slide/src/stores/org/apache/slide/store/file/CountdownStore.java
  
  Index: CountdownStore.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/file/CountdownStore.java,v 1.1 2004/09/20 07:56:38 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 07:56:38 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 The Apache Software Foundation
   *
   * 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 org.apache.slide.store.file;
  
  import java.util.*;
  import javax.transaction.xa.*;
  import org.apache.slide.store.*;
  import org.apache.slide.store.file.*;
  import org.apache.slide.content.*;
  import org.apache.slide.common.*;
  import org.apache.slide.structure.*;
  import org.apache.slide.util.logger.*;
  
  /**
   * CountdownStore is an AbstractSimpleStore implementation that shows how
   * to support the Store APIs with a little bit of code.
   * <p>
   * It presents nested directories 10 .. 1 and a file 0.txt in
   * the directory 1. This structure is defined in code. You can get some
   * funky things to happen by trying to change this structure through a
   * webdav client since this implementation seems to support all
   * operations but does not preserve state.
   *
   * @author Alon Salant
   */
  public class CountdownStore
    extends AbstractSimpleStore
  {
  
    // ==== ContentStore Methods ================================
  
    public NodeRevisionContent retrieveRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException, RevisionNotFoundException
    {
      log("retrieveRevisionContent(" + uri + ")");
      NodeRevisionContent nrc = new NodeRevisionContent();
      nrc.setContent("blast off!!".getBytes());
      return nrc;
    }
  
    public void createRevisionContent(Uri uri,
                                      NodeRevisionDescriptor revisionDescriptor,
                                      NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionAlreadyExistException
    {
      log("createRevisionContent(" + uri + ")");
    }
  
    public void storeRevisionContent(Uri uri,
                                     NodeRevisionDescriptor revisionDescriptor,
                                     NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionNotFoundException
    {
      log("storeRevisionContent(" + uri + ")");
    }
  
    public void removeRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException
    {
      log("removeRevisionContent(" + uri + ")");
    }
  
    // ==== NodeStore Methods ================================
  
    public void storeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("storeObject(" + uri + ")");
    }
  
    public void createObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectAlreadyExistsException
    {
      log("createObject(" + uri + ")");
    }
  
    public void removeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("removeObject(" + uri + ")");
    }
  
    public ObjectNode retrieveObject(Uri uri)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("retrieveObject(" + uri + ")");
  
      SubjectNode subject = new SubjectNode(uri.toString());
      if (uri.toString().endsWith("0.txt")) return subject;
  
      if (uri.isStoreRoot())
      {
        subject.addChild(new SubjectNode("9"));
        return subject;
      }
      int count = Integer.parseInt(uri.toString().substring(uri.toString().length() - 1));
      if (count > 1)
      {
        subject.addChild(new SubjectNode(count - 1 + ""));
        return subject;
      }
      subject.addChild(new SubjectNode("0.txt"));
      return subject;
    }
  
    // ==== RevisionDescriptorStore Methods ================================
  
    public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri,
                                                             NodeRevisionNumber revisionNumber) throws ServiceAccessException,
      RevisionDescriptorNotFoundException
    {
      log("retrieveRevisionDescriptor(" + uri + ")");
  
      NodeRevisionDescriptor descriptor = new NodeRevisionDescriptor(new NodeRevisionNumber(1, 0),
                                                                     NodeRevisionDescriptors.MAIN_BRANCH,
                                                                     new Vector(),
                                                                     new Hashtable());
      descriptor.setCreationDate(new Date(0));
      descriptor.setLastModified(new Date(new Date().getTime() - 2000));
      descriptor.setModificationDate(descriptor.getLastModifiedAsDate());
      if (uri.toString().endsWith("0.txt"))
      {
        descriptor.setContentLength("blast off!!".getBytes().length);
      }
      else
      {
        descriptor.setResourceType("<collection/>");
      }
      return descriptor;
    }
  
  }
  
  
  1.1                  jakarta-slide/src/stores/org/apache/slide/store/file/SimpleFileStore.java
  
  Index: SimpleFileStore.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/store/file/SimpleFileStore.java,v 1.1 2004/09/20 07:56:38 ozeigermann Exp $
   * $Revision: 1.1 $
   * $Date: 2004/09/20 07:56:38 $
   *
   * ====================================================================
   *
   * Copyright 1999-2002 The Apache Software Foundation
   *
   * 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 org.apache.slide.store.file;
  
  import java.util.*;
  import java.io.*;
  import org.apache.slide.content.*;
  import org.apache.slide.common.*;
  import org.apache.slide.structure.*;
  import org.apache.slide.store.file.*;
  
  /**
   * SimpleFileStore implements ContentStore, NodeStore, RevisionDescriptorStore,
   * and RevisionDescriptorsStore backed by a file system. Unlike the
   * org.apache.slide.store.txfile.* implementations, SimpleFileStore does not support
   * transactions, locking, security or versioning. But it will work by pointing it an
   * existing directory on your file system and does not need to keep track of any other
   * information other than what it can find in the file system.
   * <p>
   * See <a href="http://www.mail-archive.com/slide-user@jakarta.apache.org/msg07390.html">this
   * slide-user thread</a> for some history on this implementation.
   * <p>
   * SimpleFileStore needs to be deployed with implementations of LockStore and SecurityStore.
   * A sample Domain.xml entry looks like:
   * <p>
   * <pre>
   *  &lt;store name="simple">
   *      &lt;nodestore classname="org.apache.slide.store.file.SimpleFileStore">
   *          &lt;parameter name="rootpath">webapps/slidespace/files&lt;/parameter>
   *      &lt;/nodestore>
   *      &lt;contentstore>
   *        &lt;reference store="nodestore"/>
   *      &lt;/contentstore>
   *      &lt;revisiondescriptorsstore>
   *        &lt;reference store="nodestore"/>
   *      &lt;/revisiondescriptorsstore>
   *      &lt;revisiondescriptorstore>
   *        &lt;reference store="nodestore"/>
   *      &lt;/revisiondescriptorstore>
   *      &lt;securitystore classname="org.apache.slide.store.mem.TransientSecurityStore"/>
   *      &lt;lockstore classname="org.apache.slide.store.mem.TransientLockStore"/>
   *  &lt;/store>
   *  &lt;scope match="/simple" store="simple"/>
   * </pre>
   *
   * @author Alon Salant
   */
  public class SimpleFileStore
    extends AbstractSimpleStore
  {
    private static final String ROOT_PARAM = "rootpath";
    private static final String COLLECTION_TYPE = "<collection/>";
  
    private File root;
  
    public void setParameters(Hashtable parameters)
      throws ServiceParameterErrorException, ServiceParameterMissingException
    {
      log("setParameters(" + parameters + ")");
  
      if (parameters.get(ROOT_PARAM) == null) throw new ServiceParameterErrorException(this, ROOT_PARAM);
      File root = new File((String) parameters.get(ROOT_PARAM));
      if (!root.exists()) throw new ServiceParameterErrorException(this, ROOT_PARAM + ": " + root + " does not exist");
      this.root = root;
      log("Initialized with file root " + root);
    }
  
    public NodeRevisionContent retrieveRevisionContent(Uri uri, NodeRevisionDescriptor revisionDescriptor)
      throws ServiceAccessException, RevisionNotFoundException
    {
      log("retrieveRevisionContent(" + uri + ")");
      
      File file = getFile(uri);
      InputStream in = null;
      try
      {
        in = new FileInputStream(file);
        NodeRevisionContent nrc = new NodeRevisionContent();
        nrc.setContent(new FileInputStream(file));
        return nrc;
      }
      catch (FileNotFoundException e)
      {
        throw new RevisionNotFoundException(uri.toString(), revisionDescriptor.getRevisionNumber());
      }
      finally
      {
        try
        {
          if (in != null) in.close();
        }
        catch (IOException e)
        {
          throw new ServiceAccessException(this, e);
        }
      }
    }
  
    public void createRevisionContent(Uri uri,
                                      NodeRevisionDescriptor revisionDescriptor,
                                      NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionAlreadyExistException
    {
      log("createRevisionContent(" + uri + ")");
      File file = getFile(uri);
      if (file.exists()) throw new RevisionAlreadyExistException(uri.toString(), revisionDescriptor.getRevisionNumber());
  
      try
      {
        write(revisionContent.streamContent(), new FileOutputStream(file));
      }
      catch (IOException e)
      {
        throw new ServiceAccessException(this, e);
      }
    }
  
    public void storeRevisionContent(Uri uri,
                                     NodeRevisionDescriptor revisionDescriptor,
                                     NodeRevisionContent revisionContent)
      throws ServiceAccessException, RevisionNotFoundException
    {
      log("storeRevisionContent(" + uri + ")");
      File file = getFile(uri);
      if (!file.exists()) throw new RevisionNotFoundException(uri.toString(), revisionDescriptor.getRevisionNumber());
  
      if (file.isDirectory())
      {
        if (!file.delete()) throw new ServiceAccessException(this, "unable to remove directory " + file +
                                                                   " in order to create a file with the same name");
        revisionDescriptor.removeProperty(NodeRevisionDescriptor.RESOURCE_TYPE);
      }
  
      try
      {
        write(revisionContent.streamContent(), new FileOutputStream(file));
      }
      catch (IOException e)
      {
        throw new ServiceAccessException(this, e);
      }
    }
  
    public void storeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("storeObject(" + uri + ")");
      File file = getFile(uri);
      if (!file.exists()) throw new ObjectNotFoundException(uri);
    }
  
    /**
     * Creates a new object as a directory. This will always create a directory, since there
     * appears to be no way to know the type of the resource being created.
     * <p>
     * storeRevisionContent() will be called after the object is created and will
     * remove the directory and create a file.
     */
    public void createObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectAlreadyExistsException
    {
      log("createObject(" + uri + ")");
      File file = getFile(uri);
      if (file.exists()) throw new ObjectAlreadyExistsException(uri.toString());
      if (!file.mkdir()) throw new ServiceAccessException(this, "Unable to create " + uri.toString());
    }
  
    public void removeObject(Uri uri, ObjectNode object)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("removeObject(" + uri + ")");
      File file = getFile(uri);
      if (!file.exists()) throw new ObjectNotFoundException(uri);
      if (file.isDirectory() && !(file.listFiles().length == 0))
        throw new ServiceAccessException(this, uri.toString() + " is not empty");
  
      if (!file.delete()) throw new ServiceAccessException(this, "Unable to delete " + uri.toString());
    }
  
    /**
     * Return SubjectNode for normal use. Create SubjectNode with Uri.toString().
     * For folders add children as SubjectNodes created with file/folder name.
     */
    public ObjectNode retrieveObject(Uri uri)
      throws ServiceAccessException, ObjectNotFoundException
    {
      log("retrieveObject(" + uri + ")");
      File file = getFile(uri);
      if (!file.exists()) throw new ObjectNotFoundException(uri);
  
      SubjectNode subject = new SubjectNode(uri.toString());
      if (file.isFile()) return subject;
  
      File[] children = file.listFiles();
      for (int i = 0; i < children.length; i++)
      {
        subject.addChild(new SubjectNode(children[i].getName()));
      }
      return subject;
    }
  
    /**
     * Set resourceType to "<collection/>" for folders and set the contentLength for files.
     * Also set created and modified dates.
     */
    public NodeRevisionDescriptor retrieveRevisionDescriptor(Uri uri,
                                                             NodeRevisionNumber revisionNumber)
      throws ServiceAccessException, RevisionDescriptorNotFoundException
    {
      log("retrieveRevisionDescriptor(" + uri + ")");
      File file = getFile(uri);
      if (!file.exists()) throw new RevisionDescriptorNotFoundException(uri.toString());
  
      NodeRevisionDescriptor descriptor = new NodeRevisionDescriptor(new NodeRevisionNumber(1, 0),
                                                                     NodeRevisionDescriptors.MAIN_BRANCH,
                                                                     new Vector(),
                                                                     new Hashtable());
      descriptor.setCreationDate(new Date(file.lastModified()));
      descriptor.setLastModified(descriptor.getCreationDateAsDate());
      descriptor.setModificationDate(descriptor.getCreationDateAsDate());
      if (file.isDirectory())
      {
        descriptor.setResourceType(COLLECTION_TYPE);
      }
      else
      {
        descriptor.setContentLength(file.length());
      }
      return descriptor;
    }
  
  
    private void write(InputStream in, OutputStream out) throws IOException
    {
      byte buffer[] = new byte[2048];
      int len = buffer.length;
  
      try
      {
        while (true)
        {
          len = in.read(buffer);
          if (len == -1) break;
          out.write(buffer, 0, len);
        }
      }
      finally
      {
        try     { in.close(); }
        finally { out.close(); }
      }
    }
  
    private File getFile(Uri uri)
    {
      File file = new File(root, uri.getRelative());
      return file;
    }
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org