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>