View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.operations;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  
22  import org.apache.commons.vfs2.FileObject;
23  import org.apache.commons.vfs2.FileSystemException;
24  
25  /**
26   *
27   * @since 0.1
28   */
29  public abstract class AbstractFileOperationProvider implements FileOperationProvider {
30  
31      /**
32       * Available operations. Operations could be registered for different schemes. Some operations can work only for
33       * "file" scheme, other - for "svnhttp(s)", "svn", "svnssh", but not for "file", etc. The Map has scheme as a key
34       * and Collection of operations that are available for that scheme.
35       */
36      private final Collection<Class<? extends FileOperation>> operations = new ArrayList<>();
37  
38      /**
39       * Gather available operations for the specified FileObject and put them into specified operationsList.
40       *
41       * @param operationsList the list of available operations for the specified FileObject. The operationList contains
42       *            classes of available operations, e.g. Class objects.
43       * @param file the FileObject for which we want to get the list of available operations.
44       * @throws FileSystemException if list of operations cannot be retrieved.
45       */
46      @Override
47      public final void collectOperations(final Collection<Class<? extends FileOperation>> operationsList,
48              final FileObject file) throws FileSystemException {
49          doCollectOperations(operations, operationsList, file);
50      }
51  
52      /**
53       * Gather available operations for the specified FileObject and put them into specified operationsList.
54       *
55       * @param availableOperations the list of available operations for the specified FileObject.
56       * @param resultList List to be filled with applicable operations.
57       * @param file the FileObject for which we want to get the list of available operations.
58       * @throws FileSystemException if list of operations cannot be retrieved.
59       * @see #collectOperations(Collection operationsList, FileObject file)
60       */
61      protected abstract void doCollectOperations(final Collection<Class<? extends FileOperation>> availableOperations,
62              final Collection<Class<? extends FileOperation>> resultList, final FileObject file)
63              throws FileSystemException;
64  
65      /**
66       * @param file the FileObject for which we need a operation.
67       * @param operationClass the Class which instance we are needed.
68       * @return the required operation instance.
69       * @throws FileSystemException if operation cannot be retrieved.
70       */
71      @Override
72      public final FileOperation getOperation(final FileObject file, final Class<? extends FileOperation> operationClass)
73              throws FileSystemException {
74          return instantiateOperation(file, lookupOperation(operationClass));
75      }
76  
77      /**
78       * Get operation instance for specified FileOperation subclass.
79       *
80       * @param file the file this operation should act on.
81       * @param operationClass the class of an file operation interface to instantiate.
82       * @return a new file operation
83       * @throws FileSystemException if operation cannot be instantiated.
84       */
85      protected abstract FileOperation instantiateOperation(final FileObject file,
86              final Class<? extends FileOperation> operationClass) throws FileSystemException;
87  
88      /**
89       * Find class implementing a specific operation interface.
90       *
91       * @param operationClass the interface which is requested.
92       * @return never returns null
93       * @throws FileSystemException if operationClass is not a known FileOperation interface.
94       */
95      protected final Class<? extends FileOperation> lookupOperation(final Class<? extends FileOperation> operationClass)
96              throws FileSystemException {
97          // check validity of passed class
98          if (!FileOperation.class.isAssignableFrom(operationClass)) {
99              throw new FileSystemException("vfs.operation/wrong-type.error", operationClass);
100         }
101 
102         // find appropriate class
103         Class<? extends FileOperation> foundClass = null;
104         for (final Class<? extends FileOperation> operation : operations) {
105             if (operationClass.isAssignableFrom(operation)) {
106                 foundClass = operation;
107                 break;
108             }
109         }
110 
111         if (foundClass == null) {
112             throw new FileSystemException("vfs.operation/not-found.error", operationClass);
113         }
114 
115         return foundClass;
116     }
117 
118     /**
119      * Add new FileOperation to list of known operations.
120      *
121      * @param operationClass a class implementing FileOperation.
122      * @throws FileSystemException if instances of the class cannot be assigned to FileOperation.
123      */
124     protected final void addOperation(final Class<? extends FileOperation> operationClass) throws FileSystemException {
125         // check validity of passed class
126         if (!FileOperation.class.isAssignableFrom(operationClass)) {
127             throw new FileSystemException("vfs.operation/cant-register.error", operationClass);
128         }
129 
130         // ok, lets add it to the list
131         operations.add(operationClass);
132     }
133 }