]> source.dussan.org Git - archiva.git/commitdiff
MRM-781 - Removal of Archiva-Webdav implementation in favor of Jackrabbit-webdav
authorJames William Dumay <jdumay@apache.org>
Fri, 30 May 2008 04:01:37 +0000 (04:01 +0000)
committerJames William Dumay <jdumay@apache.org>
Fri, 30 May 2008 04:01:37 +0000 (04:01 +0000)
* Adding LockManager to DavResourceFactory
* Adding locking support to DavResource
* General cleanup inside of the dav resource
* Adding DavSession attachement inside of DavSessionProvider
* Tests

NOTE: We should have a complete Class 2 locking implementation (Exclusive only) so OS X dav client should work

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@661563 13f79535-47bb-0310-9956-ffa450edef68

archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java [new file with mode: 0644]

index f98940ea47d893346c71f571986a4bac9f65fdcb..7d0efa9f487542183110d54637a094b2ae0193a8 100644 (file)
@@ -56,23 +56,27 @@ public class ArchivaDavResource
 
     private final String logicalResource;
 
-    private static final String METHODS =
-        "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, PUT, DELETE, MOVE";
-
-    private static final String COMPLIANCE_CLASS = "1";
-
     private DavPropertySet properties;
 
     private boolean propsInitialized = false;
-
-    public ArchivaDavResource( String localResource, String logicalResource, MimeTypes mimeTypes,
-                               ArchivaDavResourceLocator locator, DavResourceFactory factory )
+    
+    private LockManager lockManager;
+    
+    private final DavSession session;
+
+    public ArchivaDavResource( String localResource, 
+                               String logicalResource,
+                               MimeTypes mimeTypes,
+                               DavSession session,
+                               ArchivaDavResourceLocator locator, 
+                               DavResourceFactory factory )
     {
         this.mimeTypes = mimeTypes;
         this.localResource = new File( localResource );
         this.logicalResource = logicalResource;
         this.locator = locator;
         this.factory = factory;
+        this.session = session;
         this.properties = new DavPropertySet();
     }
 
@@ -218,7 +222,7 @@ public class ArchivaDavResource
             DavResourceLocator parentloc = locator.getFactory().createResourceLocator( locator.getPrefix(), parentPath );
             try
             {
-                parent = factory.createResource( parentloc, null );
+                parent = factory.createResource( parentloc, session );
             }
             catch ( DavException e )
             {
@@ -285,7 +289,7 @@ public class ArchivaDavResource
                         String path = locator.getResourcePath() + '/' + item;
                         DavResourceLocator resourceLocator =
                             locator.getFactory().createResourceLocator( locator.getPrefix(), path );
-                        DavResource resource = factory.createResource( resourceLocator, null );
+                        DavResource resource = factory.createResource( resourceLocator, session );
                         if ( resource != null )
                             list.add( resource );
                     }
@@ -302,20 +306,20 @@ public class ArchivaDavResource
     public void removeMember( DavResource member )
         throws DavException
     {
-        File localResource = checkDavResourceIsArchivaDavResource( member ).getLocalResource();
+        File resource = checkDavResourceIsArchivaDavResource( member ).getLocalResource();
 
-        if ( !localResource.exists() )
+        if ( !resource.exists() )
         {
             throw new DavException( HttpServletResponse.SC_NOT_FOUND, member.getResourcePath() );
         }
 
         boolean suceeded = false;
 
-        if ( localResource.isDirectory() )
+        if ( resource.isDirectory() )
         {
             try
             {
-                FileUtils.deleteDirectory( localResource );
+                FileUtils.deleteDirectory( resource );
                 suceeded = true;
             }
             catch ( IOException e )
@@ -324,9 +328,9 @@ public class ArchivaDavResource
             }
         }
 
-        if ( !suceeded && localResource.isFile() )
+        if ( !suceeded && resource.isFile() )
         {
-            suceeded = localResource.delete();
+            suceeded = resource.delete();
         }
 
         if ( !suceeded )
@@ -346,14 +350,14 @@ public class ArchivaDavResource
 
         try
         {
-            ArchivaDavResource localResource = checkDavResourceIsArchivaDavResource( destination );
+            ArchivaDavResource resource = checkDavResourceIsArchivaDavResource( destination );
             if ( isCollection() )
             {
-                FileUtils.moveDirectory( getLocalResource(), localResource.getLocalResource() );
+                FileUtils.moveDirectory( getLocalResource(), resource.getLocalResource() );
             }
             else
             {
-                FileUtils.moveFile( getLocalResource(), localResource.getLocalResource() );
+                FileUtils.moveFile( getLocalResource(), resource.getLocalResource() );
             }
         }
         catch ( IOException e )
@@ -377,14 +381,14 @@ public class ArchivaDavResource
 
         try
         {
-            ArchivaDavResource localResource = checkDavResourceIsArchivaDavResource( destination );
+            ArchivaDavResource resource = checkDavResourceIsArchivaDavResource( destination );
             if ( isCollection() )
             {
-                FileUtils.copyDirectory( getLocalResource(), localResource.getLocalResource() );
+                FileUtils.copyDirectory( getLocalResource(), resource.getLocalResource() );
             }
             else
             {
-                FileUtils.copyFile( getLocalResource(), localResource.getLocalResource() );
+                FileUtils.copyFile( getLocalResource(), resource.getLocalResource() );
             }
         }
         catch ( IOException e )
@@ -395,43 +399,82 @@ public class ArchivaDavResource
 
     public boolean isLockable( Type type, Scope scope )
     {
-        return false;
+        return Type.WRITE.equals(type) && Scope.EXCLUSIVE.equals(scope);
     }
 
     public boolean hasLock( Type type, Scope scope )
     {
-        return false;
+        return getLock(type, scope) != null;
     }
 
     public ActiveLock getLock( Type type, Scope scope )
     {
-        return null;
+        ActiveLock lock = null;
+        if (exists() && Type.WRITE.equals(type) && Scope.EXCLUSIVE.equals(scope)) 
+        {
+            lock = lockManager.getLock(type, scope, this);
+        }
+        return lock;
     }
 
     public ActiveLock[] getLocks()
     {
-        return new ActiveLock[0];
+        ActiveLock writeLock = getLock(Type.WRITE, Scope.EXCLUSIVE);
+        return (writeLock != null) ? new ActiveLock[]{writeLock} : new ActiveLock[0];
     }
 
-    public ActiveLock lock( LockInfo reqLockInfo )
+    public ActiveLock lock( LockInfo lockInfo )
         throws DavException
     {
-        return null;
+        ActiveLock lock = null;
+        if (isLockable(lockInfo.getType(), lockInfo.getScope())) 
+        {
+            lock = lockManager.createLock(lockInfo, this);
+        }
+        else 
+        {
+            throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "Unsupported lock type or scope.");
+        }
+        return lock;
     }
 
-    public ActiveLock refreshLock( LockInfo reqLockInfo, String lockToken )
+    public ActiveLock refreshLock( LockInfo lockInfo, String lockToken )
         throws DavException
     {
-        return null;
+        if (!exists()) {
+            throw new DavException(DavServletResponse.SC_NOT_FOUND);
+        }
+        ActiveLock lock = getLock(lockInfo.getType(), lockInfo.getScope());
+        if (lock == null) {
+            throw new DavException(DavServletResponse.SC_PRECONDITION_FAILED, "No lock with the given type/scope present on resource " + getResourcePath());
+        }
+
+        lock = lockManager.refreshLock(lockInfo, lockToken, this);
+
+        return lock;
     }
 
     public void unlock( String lockToken )
         throws DavException
     {
+        ActiveLock lock = getLock(Type.WRITE, Scope.EXCLUSIVE);
+        if (lock == null)
+        {
+            throw new DavException(HttpServletResponse.SC_PRECONDITION_FAILED);
+        }
+        else if (lock.isLockedByToken(lockToken))
+        {
+            lockManager.releaseLock(lockToken, this);
+        }
+        else
+        {
+            throw new DavException(DavServletResponse.SC_LOCKED);
+        }
     }
 
-    public void addLockManager( LockManager lockmgr )
+    public void addLockManager( LockManager lockManager )
     {
+        this.lockManager = lockManager;
     }
 
     public DavResourceFactory getFactory()
@@ -441,7 +484,7 @@ public class ArchivaDavResource
 
     public DavSession getSession()
     {
-        return null;
+        return session;
     }
 
     /**
index 8e67ff68cdee590b82d79c7ab2b461ecfd07c934..71ae2c27c93d58ca637b9fbb773f17ea88044a44 100644 (file)
@@ -68,6 +68,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.io.*;
+import org.apache.jackrabbit.webdav.lock.LockManager;
+import org.apache.jackrabbit.webdav.lock.SimpleLockManager;
 
 /**
  * @author <a href="mailto:james@atlassian.com">James William Dumay</a>
@@ -123,6 +125,12 @@ public class ArchivaDavResourceFactory
      */
     private HttpAuthenticator httpAuth;
     
+    
+    /**
+     * Lock Manager - use simple implementation from JackRabbit
+     */
+    private final LockManager lockManager = new SimpleLockManager();
+    
     public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
                                        final DavServletResponse response )
         throws DavException
@@ -216,7 +224,7 @@ public class ArchivaDavResourceFactory
                         {
                             throw new BrowserRedirectException( resource.getHref() );
                         }
-
+                        resource.addLockManager(lockManager);
                         return resource;
                     }
                 }
@@ -243,9 +251,10 @@ public class ArchivaDavResourceFactory
             String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
             File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource );
             resource =
-                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource, mimeTypes, archivaLocator,
+                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource, mimeTypes, davSession, archivaLocator,
                                         this );
         }
+        resource.addLockManager(lockManager);
         return resource;
     }
 
@@ -255,7 +264,7 @@ public class ArchivaDavResourceFactory
     {
         File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
         ArchivaDavResource resource =
-            new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator, this );
+            new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, request.getDavSession(), locator, this );
 
         if ( !resource.isCollection() )
         {
@@ -289,7 +298,7 @@ public class ArchivaDavResourceFactory
                                     resourceFile, " (proxied)" );
             }
             resource =
-                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator,
+                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, request.getDavSession(), locator,
                                         this );
 
             if ( !resourceFile.exists() )
@@ -326,7 +335,7 @@ public class ArchivaDavResourceFactory
         processAuditEvents( request, locator.getRepositoryId(), logicalResource.getPath(), previouslyExisted,
                             resourceFile, null );
 
-        return new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator,
+        return new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, request.getDavSession(), locator,
                                        this );
     }
 
index ba1e3316bee37284c520afef80b74bc6f48111b3..b712adbb525d5a76938ac46bba0b37ea20e73e90 100644 (file)
@@ -46,6 +46,11 @@ public class ArchivaDavResourceLocator
         this.repositoryId = repositoryId;
         this.davLocatorFactory = davLocatorFactory;
         this.resourcePath = resourcePath;
+        
+        if (!resourcePath.startsWith("/"))
+        {
+            this.resourcePath = "/" + resourcePath;
+        }
 
         String escapedPath = Text.escapePath( resourcePath );
         String hrefPrefix = prefix;
index d5265323f697a91550a92a7d7f9b77438206be40..b2200aac69a9126a349c7a709ab9c7d1ea0cb43d 100644 (file)
@@ -65,6 +65,9 @@ public class ArchivaDavSessionProvider
         {
             AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );
             
+            //Create a dav session
+            request.setDavSession(new ArchivaDavSession());
+            
             return servletAuth.isAuthenticated( request, result );
         }
         catch ( AuthenticationException e )
@@ -81,9 +84,13 @@ public class ArchivaDavSessionProvider
         }        
     }
 
-    public void releaseSession( WebdavRequest webdavRequest )
+    public void releaseSession( WebdavRequest request )
     {
-
+        //Remove DavSession
+        if (request.getDavSession() != null)
+        {
+            request.setDavSession(null);
+        }
     }
     
     private String removeContextPath( final DavServletRequest request )
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java
new file mode 100644 (file)
index 0000000..9291601
--- /dev/null
@@ -0,0 +1,238 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import java.io.File;
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavSession;
+import org.apache.jackrabbit.webdav.lock.ActiveLock;
+import org.apache.jackrabbit.webdav.lock.LockInfo;
+import org.apache.jackrabbit.webdav.lock.LockManager;
+import org.apache.jackrabbit.webdav.lock.Scope;
+import org.apache.jackrabbit.webdav.lock.SimpleLockManager;
+import org.apache.jackrabbit.webdav.lock.Type;
+import org.apache.maven.archiva.webdav.util.MimeTypes;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.codehaus.plexus.spring.PlexusToSpringUtils;
+import quicktime.std.qtcomponents.SCInfo;
+
+
+public class DavResourceTest extends PlexusInSpringTestCase
+{
+    private DavSession session;
+    
+    private MimeTypes mimeTypes;
+    
+    private ArchivaDavResourceLocator resourceLocator;
+    
+    private ArchivaDavResourceFactory factory;
+    
+    private File baseDir;
+    
+    private final String REPOPATH = "/myresource.jar";
+    
+    private final File myResource = new File(baseDir, REPOPATH);
+    
+    private DavResource resource;
+    
+    private LockManager lockManager;
+    
+    @Override
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+        session = new ArchivaDavSession();
+        mimeTypes = (MimeTypes)getApplicationContext().getBean(PlexusToSpringUtils.buildSpringId(MimeTypes.class));
+        baseDir = new File("target/DavResourceTest");
+        baseDir.mkdirs();
+        myResource.createNewFile();
+        resourceLocator = (ArchivaDavResourceLocator)new ArchivaDavLocatorFactory().createResourceLocator("/", REPOPATH);
+        resource = getDavResource(REPOPATH, myResource);
+        lockManager = new SimpleLockManager();
+        resource.addLockManager(lockManager);
+    }
+
+    @Override
+    protected void tearDown()
+        throws Exception
+    {
+        super.tearDown();
+        release(mimeTypes);
+        FileUtils.deleteDirectory(baseDir);
+    }
+    
+    private DavResource getDavResource(String logicalPath, File file)
+    {
+        return new ArchivaDavResource(logicalPath, file.getAbsolutePath(), mimeTypes, session, resourceLocator, null);
+    }
+    
+    public void testIsLockable()
+    {
+        assertTrue(resource.isLockable(Type.WRITE, Scope.EXCLUSIVE));
+        assertFalse(resource.isLockable(Type.WRITE, Scope.SHARED));
+    }
+    
+    public void testLock()
+        throws Exception
+    {
+        assertEquals(0, resource.getLocks().length);
+       
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        lockManager.createLock(info, resource);
+        
+        assertEquals(1, resource.getLocks().length);
+    }
+    
+    public void testLockIfResourceUnlockable()
+        throws Exception
+    {
+        assertEquals(0, resource.getLocks().length);
+       
+        LockInfo info = new LockInfo(Scope.SHARED, Type.WRITE, "/", 0, false);
+        try
+        {
+            lockManager.createLock(info, resource);
+            fail("Did not throw dav exception");
+        }
+        catch (Exception e)
+        {
+            //Simple lock manager will die
+        }
+        assertEquals(0, resource.getLocks().length); 
+    }
+    
+    public void testGetLock()
+        throws Exception
+    {
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        lockManager.createLock(info, resource);
+        
+        assertEquals(1, resource.getLocks().length);
+        
+        //Lock should exist
+        assertNotNull(resource.getLock(Type.WRITE, Scope.EXCLUSIVE));
+        
+        //Lock should not exist
+        assertNull(resource.getLock(Type.WRITE, Scope.SHARED));
+    }
+    
+    
+    public void testRefreshLockThrowsExceptionIfNoLockIsPresent()
+        throws Exception
+    {
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        
+        assertEquals(0, resource.getLocks().length);       
+        
+        try
+        {
+            lockManager.refreshLock(info, "notoken", resource);
+            fail("Did not throw dav exception");
+        }
+        catch (DavException e)
+        {
+            assertEquals(DavServletResponse.SC_PRECONDITION_FAILED, e.getErrorCode());
+        }
+        
+        assertEquals(0, resource.getLocks().length);
+    }
+    
+    public void testRefreshLock()
+        throws Exception
+    {
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        
+        assertEquals(0, resource.getLocks().length);
+        
+        lockManager.createLock(info, resource);
+        
+        assertEquals(1, resource.getLocks().length);
+        
+        ActiveLock lock = resource.getLocks()[0];
+
+        lockManager.refreshLock(info, lock.getToken(), resource);
+        
+        assertEquals(1, resource.getLocks().length);
+    }
+    
+    public void testUnlock()
+        throws Exception
+    {
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        
+        assertEquals(0, resource.getLocks().length);
+        
+        lockManager.createLock(info, resource);
+        
+        assertEquals(1, resource.getLocks().length);
+        
+        ActiveLock lock = resource.getLocks()[0];
+
+        lockManager.releaseLock(lock.getToken(), resource);
+        
+        assertEquals(0, resource.getLocks().length);
+    }    
+    
+    public void testUnlockThrowsDavExceptionIfNotLocked()
+        throws Exception
+    {
+        LockInfo info = new LockInfo(Scope.EXCLUSIVE, Type.WRITE, "/", 0, false);
+        
+        assertEquals(0, resource.getLocks().length);
+        
+        lockManager.createLock(info, resource);
+        
+        assertEquals(1, resource.getLocks().length);
+
+        try
+        {
+            lockManager.releaseLock("BLAH", resource);
+            fail("Did not throw DavException");
+        }
+        catch (DavException e)
+        {
+            assertEquals(DavServletResponse.SC_LOCKED, e.getErrorCode());
+        }
+        
+        assertEquals(1, resource.getLocks().length);      
+    }
+    
+    public void testUnlockThrowsDavExceptionIfResourceNotLocked()
+        throws Exception
+    {        
+        assertEquals(0, resource.getLocks().length);
+
+        try
+        {
+            lockManager.releaseLock("BLAH", resource);
+            fail("Did not throw DavException");
+        }
+        catch (DavException e)
+        {
+            assertEquals(DavServletResponse.SC_PRECONDITION_FAILED, e.getErrorCode());
+        }
+        
+        assertEquals(0, resource.getLocks().length);      
+    }
+}