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  import java.util.Iterator;
22  
23  import org.apache.commons.vfs2.FileObject;
24  import org.apache.commons.vfs2.FileSystemException;
25  
26  /**
27   *
28   * @since 0.1
29   */
30  public abstract class AbstractFileOperationProvider implements FileOperationProvider {
31  
32      /**
33       * Available operations. Operations could be registered for different schemes. Some operations can work only for
34       * "file" scheme, other - for "svnhttp(s)", "svn", "svnssh", but not for "file", etc. The Map has scheme as a key
35       * and Collection of operations that are available for that scheme.
36       */
37      private final Collection<Class<? extends FileOperation>> operations = new ArrayList<>();
38  
39      /**
40       * Gather available operations for the specified FileObject and put them into specified operationsList.
41       *
42       * @param operationsList the list of available operations for the specified FileObject. The operationList contains
43       *            classes of available operations, e.g. Class objects.
44       * @param file the FileObject for which we want to get the list of available operations.
45       * @throws FileSystemException if list of operations cannot be retrieved.
46       */
47      @Override
48      public final void collectOperations(final Collection<Class<? extends FileOperation>> operationsList,
49              final FileObject file) throws FileSystemException {
50          doCollectOperations(operations, operationsList, file);
51      }
52  
53      /**
54       * Gather available operations for the specified FileObject and put them into specified operationsList.
55       *
56       * @param availableOperations the list of available operations for the specified FileObject.
57       * @param resultList List to be filled with applicable operations.
58       * @param file the FileObject for which we want to get the list of available operations.
59       * @throws FileSystemException if list of operations cannot be retrieved.
60       * @see #collectOperations(Collection operationsList, FileObject file)
61       */
62      protected abstract void doCollectOperations(final Collection<Class<? extends FileOperation>> availableOperations,
63              final Collection<Class<? extends FileOperation>> resultList, final FileObject file)
64              throws FileSystemException;
65  
66      /**
67       * @param file the FileObject for which we need a operation.
68       * @param operationClass the Class which instance we are needed.
69       * @return the required operation instance.
70       * @throws FileSystemException if operation cannot be retrieved.
71       */
72      @Override
73      public final FileOperation getOperation(final FileObject file, final Class<? extends FileOperation> operationClass)
74              throws FileSystemException {
75          final Class<? extends FileOperation> implementation = lookupOperation(operationClass);
76  
77          final FileOperation operationInstance = instantiateOperation(file, implementation);
78  
79          return operationInstance;
80      }
81  
82      /**
83       * Get operation instance for specified FileOperation subclass.
84       *
85       * @param file the file this operation should act on.
86       * @param operationClass the class of an file operation interface to instantiate.
87       * @return a new file operation
88       * @throws FileSystemException if operation cannot be instantiated.
89       */
90      protected abstract FileOperation instantiateOperation(final FileObject file,
91              final Class<? extends FileOperation> operationClass) throws FileSystemException;
92  
93      /**
94       * Find class implementing a specific operation interface.
95       *
96       * @param operationClass the interface which is requested.
97       * @return never returns null
98       * @throws FileSystemException if operationClass is not a known FileOperation interface.
99       */
100     protected final Class<? extends FileOperation> lookupOperation(final Class<? extends FileOperation> operationClass)
101             throws FileSystemException {
102         // check validity of passed class
103         if (!FileOperation.class.isAssignableFrom(operationClass)) {
104             throw new FileSystemException("vfs.operation/wrong-type.error", operationClass);
105         }
106 
107         // find appropriate class
108         Class<? extends FileOperation> foundClass = null;
109         final Iterator<Class<? extends FileOperation>> iterator = operations.iterator();
110         while (iterator.hasNext()) {
111             final Class<? extends FileOperation> operation = iterator.next();
112             if (operationClass.isAssignableFrom(operation)) {
113                 foundClass = operation;
114                 break;
115             }
116         }
117 
118         if (foundClass == null) {
119             throw new FileSystemException("vfs.operation/not-found.error", operationClass);
120         }
121 
122         return foundClass;
123     }
124 
125     /**
126      * Add new FileOperation to list of known operations.
127      *
128      * @param operationClass a class implementing FileOperation.
129      * @throws FileSystemException if instances of the class cannot be assigned to FileOperation.
130      */
131     protected final void addOperation(final Class<? extends FileOperation> operationClass) throws FileSystemException {
132         // check validity of passed class
133         if (!FileOperation.class.isAssignableFrom(operationClass)) {
134             throw new FileSystemException("vfs.operation/cant-register.error", operationClass);
135         }
136 
137         // ok, lets add it to the list
138         operations.add(operationClass);
139     }
140 }