You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by jd...@apache.org on 2008/05/30 06:01:37 UTC

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/

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 <a href="mailto:james@atlassian.com">James William Dumay</a>
@@ -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);      
+    }
+}