Return-Path: Delivered-To: apmail-archiva-commits-archive@www.apache.org Received: (qmail 59329 invoked from network); 30 May 2008 04:02:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 30 May 2008 04:02:03 -0000 Received: (qmail 93206 invoked by uid 500); 30 May 2008 04:02:05 -0000 Delivered-To: apmail-archiva-commits-archive@archiva.apache.org Received: (qmail 93167 invoked by uid 500); 30 May 2008 04:02:05 -0000 Mailing-List: contact commits-help@archiva.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@archiva.apache.org Delivered-To: mailing list commits@archiva.apache.org Received: (qmail 93158 invoked by uid 99); 30 May 2008 04:02:05 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 29 May 2008 21:02:05 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 30 May 2008 04:01:17 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D715A2388A26; Thu, 29 May 2008 21:01:37 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r661563 - in /archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src: main/java/org/apache/maven/archiva/webdav/ test/java/org/apache/maven/archiva/webdav/ Date: Fri, 30 May 2008 04:01:37 -0000 To: commits@archiva.apache.org From: jdumay@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080530040137.D715A2388A26@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jdumay Date: Thu May 29 21:01:37 2008 New Revision: 661563 URL: http://svn.apache.org/viewvc?rev=661563&view=rev Log: MRM-781 - Removal of Archiva-Webdav implementation in favor of Jackrabbit-webdav * 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 Added: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java?rev=661563&r1=661562&r2=661563&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java Thu May 29 21:01:37 2008 @@ -56,23 +56,27 @@ 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 @@ 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 @@ 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 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 @@ } } - if ( !suceeded && localResource.isFile() ) + if ( !suceeded && resource.isFile() ) { - suceeded = localResource.delete(); + suceeded = resource.delete(); } if ( !suceeded ) @@ -346,14 +350,14 @@ 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 @@ 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 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 DavSession getSession() { - return null; + return session; } /** Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java?rev=661563&r1=661562&r2=661563&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java Thu May 29 21:01:37 2008 @@ -68,6 +68,8 @@ 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 James William Dumay @@ -123,6 +125,12 @@ */ 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 @@ { throw new BrowserRedirectException( resource.getHref() ); } - + resource.addLockManager(lockManager); return resource; } } @@ -243,9 +251,10 @@ 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 @@ { 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 @@ 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 @@ 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 ); } Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java?rev=661563&r1=661562&r2=661563&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java Thu May 29 21:01:37 2008 @@ -46,6 +46,11 @@ this.repositoryId = repositoryId; this.davLocatorFactory = davLocatorFactory; this.resourcePath = resourcePath; + + if (!resourcePath.startsWith("/")) + { + this.resourcePath = "/" + resourcePath; + } String escapedPath = Text.escapePath( resourcePath ); String hrefPrefix = prefix; Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java?rev=661563&r1=661562&r2=661563&view=diff ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java (original) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java Thu May 29 21:01:37 2008 @@ -65,6 +65,9 @@ { 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 void releaseSession( WebdavRequest webdavRequest ) + public void releaseSession( WebdavRequest request ) { - + //Remove DavSession + if (request.getDavSession() != null) + { + request.setDavSession(null); + } } private String removeContextPath( final DavServletRequest request ) Added: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java?rev=661563&view=auto ============================================================================== --- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java (added) +++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/DavResourceTest.java Thu May 29 21:01:37 2008 @@ -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); + } +}