Author: ecki
Date: Wed Sep 23 19:18:20 2015
New Revision: 1704920

URL: http://svn.apache.org/viewvc?rev=1704920&view=rev
Log:
[VFS-577] Fix and test FileOperationsProvider lifecycle.

Added:
    
commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/
    
commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTestCase.java
Modified:
    
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
    
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/operations/DefaultFileOperations.java
    commons/proper/vfs/trunk/src/changes/changes.xml

Modified: 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
URL: 
http://svn.apache.org/viewvc/commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java?rev=1704920&r1=1704919&r2=1704920&view=diff
==============================================================================
--- 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
 (original)
+++ 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
 Wed Sep 23 19:18:20 2015
@@ -575,8 +575,8 @@ public class DefaultFileSystemManager im
      * Closes the manager.
      * <p>
      * This will close all providers (all files), it will also close
-     * all managed components including temporary files, replicators
-     * and cache.
+     * all managed components including temporary files, replicator,
+     * file cache and file operations.
      * <p>
      * The manager is in uninitialized state after this method.
      */
@@ -587,12 +587,16 @@ public class DefaultFileSystemManager im
             return;
         }
 
-        // Close the providers.
-        for (final Object provider : providers.values())
+        // make sure all discovered components in
+        // 
org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(Element)
+        // are closed here
+
+        // Close the file system providers.
+        for (final FileProvider provider : providers.values())
         {
             closeComponent(provider);
         }
-        // just to be sure
+        // unregister all
         providers.clear();
 
         // Close the other components
@@ -602,9 +606,19 @@ public class DefaultFileSystemManager im
         closeComponent(filesCache);
         closeComponent(defaultProvider);
 
+        // FileOperations are components, too
+        for (final List<FileOperationProvider> opproviders : 
operationProviders.values())
+        {
+            for (final FileOperationProvider p : opproviders)
+            {
+                closeComponent(p);
+            }
+        }
+        // unregister all
+        operationProviders.clear();
+
         // collections with add()
         typeMap.clear();
-        operationProviders.clear();
 
         // should not happen, but make debugging easier:
         if (!components.isEmpty())

Modified: 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/operations/DefaultFileOperations.java
URL: 
http://svn.apache.org/viewvc/commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/operations/DefaultFileOperations.java?rev=1704920&r1=1704919&r2=1704920&view=diff
==============================================================================
--- 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/operations/DefaultFileOperations.java
 (original)
+++ 
commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/operations/DefaultFileOperations.java
 Wed Sep 23 19:18:20 2015
@@ -96,7 +96,7 @@ public class DefaultFileOperations imple
         if (providers == null)
         {
             throw new FileSystemException(
-                    "vfs.provider/operation-not-supported.error", 
operationClass);
+                    "vfs.operation/operation-not-supported.error", 
operationClass);
         }
 
         FileOperation resultOperation = null;
@@ -114,7 +114,7 @@ public class DefaultFileOperations imple
         if (resultOperation == null)
         {
             throw new FileSystemException(
-                    "vfs.provider/operation-not-supported.error", 
operationClass);
+                    "vfs.operation/operation-not-supported.error", 
operationClass);
         }
 
         return resultOperation;

Added: 
commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTestCase.java?rev=1704920&view=auto
==============================================================================
--- 
commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTestCase.java
 (added)
+++ 
commons/proper/vfs/trunk/core/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTestCase.java
 Wed Sep 23 19:18:20 2015
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ */
+package org.apache.commons.vfs2.operations;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.util.Collection;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs2.operations.vcs.VcsLog;
+import org.apache.commons.vfs2.provider.FileProvider;
+import org.apache.commons.vfs2.provider.VfsComponent;
+import org.apache.commons.vfs2.provider.VfsComponentContext;
+import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Basic Tests for the FileOperations and FileOperationsProvider API.
+ */
+public class BasicOperationsTestCase
+{
+    /** This FileOperationsProvider is a VfsComponent and records invocations. 
*/
+    static class MyFileOperationProviderComp
+        extends MyFileOprationProviderBase
+        implements VfsComponent
+    {
+        @Override
+        public void setLogger(Log logger)
+        {
+            assertNotNull("setLogger", logger);
+            ops |= 1;
+        }
+
+        @Override
+        public void setContext(VfsComponentContext context)
+        {
+            assertNotNull("setContext", context);
+            ops |= 2;
+        }
+
+        @Override
+        public void init()
+            throws FileSystemException
+        {
+            ops |= 4;
+        }
+
+        @Override
+        public void close()
+        {
+            ops |= 8;
+        }
+    }
+
+    /** This FileOperationsProvider is no VfsComponent. */
+    static class MyFileOperationProviderNoncomp
+        extends MyFileOprationProviderBase
+    {
+    }
+
+    /**
+     * Base class for different Test Providers. This is also a compile test
+     * to ensure interface stability.
+     */
+    static class MyFileOprationProviderBase implements FileOperationProvider
+    {
+        int ops = 0; // bit array to record invocations (poor mans mock)
+
+        @Override
+        public void collectOperations(Collection<Class< ? extends 
FileOperation>> operationsList,
+                                      FileObject file)
+                                          throws FileSystemException
+        {
+            assertNotNull("collect operationsList", operationsList);
+            assertNotNull("collect file", file);
+            ops |= 16;
+        }
+
+        @Override
+        public FileOperation getOperation(FileObject file, Class< ? extends 
FileOperation> operationClass)
+            throws FileSystemException
+        {
+            assertNotNull("file object", file);
+            assertNotNull("operationclass", operationClass);
+            ops |= 32;
+            return null;
+        }
+    }
+
+    /** FSM to work with, maintained by JUnit Fixture. */
+    private DefaultFileSystemManager manager;
+
+    /**
+     * JUnit Fixture: Prepare a simple FSM.
+     * @throws FileSystemException for runtime problems
+     */
+    @Before
+    public void setUp() throws FileSystemException
+    {
+        manager = new DefaultFileSystemManager();
+        FileProvider fp = new DefaultLocalFileProvider();
+        manager.addProvider("file", fp);
+        manager.init();
+    }
+
+    /**
+     * Ensure FileOperationProviders which are VfsComponents are
+     * set up and teared down.
+     * @throws FileSystemException for runtime problems
+     */
+    @Test
+    public void testLifecycleComp() throws FileSystemException
+    {
+        final MyFileOprationProviderBase myop = new 
MyFileOperationProviderComp();
+        assertEquals(0,  myop.ops);
+        manager.addOperationProvider("file", myop);
+        assertEquals(7, myop.ops);
+        manager.close();
+        assertEquals("close() not called", 15, myop.ops); // VFS-577
+
+        //fixture will close again
+   }
+
+    /**
+     * Ensure you can use FileOperationProvider which is not a VfsComponnt.
+     * @throws FileSystemException for runtime problems
+     */
+    @Test
+    public void testLifecycleNoncomp() throws FileSystemException
+    {
+        final MyFileOprationProviderBase myop = new 
MyFileOperationProviderNoncomp();
+        manager.addOperationProvider("file", myop);
+        FileOperationProvider[] ops = manager.getOperationProviders("file");
+        assertSame("exactly one provider registered", 1, ops.length);
+        assertSame(myop, ops[0]);
+        assertEquals(0, myop.ops); // collect not invoked
+    }
+
+    /**
+     * Ensures getOperations calls collect and allows empty response.
+     * @throws FileSystemException for runtime problems
+     */
+    @Test
+    public void testNotFoundAny() throws FileSystemException
+    {
+        final MyFileOprationProviderBase myop = new 
MyFileOperationProviderNoncomp();
+        manager.addOperationProvider("file", myop);
+        FileObject fo = manager.toFileObject(new File("."));
+
+        FileOperations ops = fo.getFileOperations();
+        assertNotNull(ops);
+
+        Class< ? extends FileOperation>[] oparray = ops.getOperations();
+        assertSame("no ops should be found", 0, oparray.length);
+        assertSame(16, myop.ops); // collect
+    }
+
+    /**
+     * Ensure proper response for not found FileOperation.
+     * @throws FileSystemException for runtime problems
+     */
+    @Test
+    public void testNotFoundOperation() throws FileSystemException
+    {
+        final MyFileOprationProviderBase myop = new 
MyFileOperationProviderNoncomp();
+        manager.addOperationProvider("file", myop);
+        FileObject fo = manager.toFileObject(new File("."));
+
+        FileOperations ops = fo.getFileOperations();
+        assertNotNull(ops);
+
+        try
+        {
+            FileOperation logop = ops.getOperation(VcsLog.class);
+            fail("Must throw but returned " + logop);
+        }
+        catch (FileSystemException e)
+        {
+            assertEquals("vfs.operation/operation-not-supported.error", 
e.getCode());
+        }
+        assertSame(32, myop.ops); // getOperation was called
+    }
+
+    /**
+     * JUnit Fixture: Tear Down the FSM.
+     * @throws FileSystemException for runtime problems
+     */
+    @After
+    public void tearDown() throws FileSystemException
+    {
+        if (manager != null)
+        {
+            manager.close();
+            manager = null;
+        }
+    }
+}

Modified: commons/proper/vfs/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/vfs/trunk/src/changes/changes.xml?rev=1704920&r1=1704919&r2=1704920&view=diff
==============================================================================
--- commons/proper/vfs/trunk/src/changes/changes.xml (original)
+++ commons/proper/vfs/trunk/src/changes/changes.xml Wed Sep 23 19:18:20 2015
@@ -26,6 +26,10 @@
 <!--       <action issue="VFS-443" dev="ggregory" type="update" 
due-to="nickallen"> -->
 <!--        [Local] Need an easy way to convert from a FileObject to a File. 
-->
 <!--       </action> -->
+      <action issue="VFS-577" dev="ecki" type="fix">
+        Ensure FileOpertionProviders are closed. Adds some testcases.
+        The error code for missing operations exceptions corrected: 
vfs.operation/operation-not-supported.error
+     </action>
       <action issue="VFS-279" dev="ecki" type="fix" due-to="Didier Earith, 
Simon Legner">
         [local] Avoid ClassCastException when replicating local files while 
OnCall caching is active.
       </action>


Reply via email to