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 * Abstracts implementations of {@link FileOperationProvider}.
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 * Constructs a new instance for subclasses.
41 */
42 public AbstractFileOperationProvider() {
43 // empty
44 }
45
46 /**
47 * Add new FileOperation to list of known operations.
48 *
49 * @param operationClass a class implementing FileOperation.
50 * @throws FileSystemException if instances of the class cannot be assigned to FileOperation.
51 */
52 protected final void addOperation(final Class<? extends FileOperation> operationClass) throws FileSystemException {
53 // check validity of passed class
54 if (!FileOperation.class.isAssignableFrom(operationClass)) {
55 throw new FileSystemException("vfs.operation/cant-register.error", operationClass);
56 }
57
58 // ok, lets add it to the list
59 operations.add(operationClass);
60 }
61
62 /**
63 * Gather available operations for the specified FileObject and put them into specified operationsList.
64 *
65 * @param operationsList the list of available operations for the specified FileObject. The operationList contains
66 * classes of available operations, e.g. Class objects.
67 * @param file the FileObject for which we want to get the list of available operations.
68 * @throws FileSystemException if list of operations cannot be retrieved.
69 */
70 @Override
71 public final void collectOperations(final Collection<Class<? extends FileOperation>> operationsList,
72 final FileObject file) throws FileSystemException {
73 doCollectOperations(operations, operationsList, file);
74 }
75
76 /**
77 * Gather available operations for the specified FileObject and put them into specified operationsList.
78 *
79 * @param availableOperations the list of available operations for the specified FileObject.
80 * @param resultList List to be filled with applicable operations.
81 * @param file the FileObject for which we want to get the list of available operations.
82 * @throws FileSystemException if list of operations cannot be retrieved.
83 * @see #collectOperations(Collection operationsList, FileObject file)
84 */
85 protected abstract void doCollectOperations(Collection<Class<? extends FileOperation>> availableOperations,
86 Collection<Class<? extends FileOperation>> resultList, FileObject file) throws FileSystemException;
87
88 /**
89 * @param file the FileObject for which we need an operation.
90 * @param operationClass the Class which instance we are needed.
91 * @return the required operation instance.
92 * @throws FileSystemException if operation cannot be retrieved.
93 */
94 @Override
95 public final FileOperation getOperation(final FileObject file, final Class<? extends FileOperation> operationClass)
96 throws FileSystemException {
97 return instantiateOperation(file, lookupOperation(operationClass));
98 }
99
100 /**
101 * Gets operation instance for specified FileOperation subclass.
102 *
103 * @param file the file this operation should act on.
104 * @param operationClass the class of a file operation interface to instantiate.
105 * @return a new file operation
106 * @throws FileSystemException if operation cannot be instantiated.
107 */
108 protected abstract FileOperation instantiateOperation(FileObject file, Class<? extends FileOperation> operationClass) throws FileSystemException;
109
110 /**
111 * Find class implementing a specific operation interface.
112 *
113 * @param operationClass the interface which is requested.
114 * @return never returns null
115 * @throws FileSystemException if operationClass is not a known FileOperation interface.
116 */
117 protected final Class<? extends FileOperation> lookupOperation(final Class<? extends FileOperation> operationClass)
118 throws FileSystemException {
119 // check validity of passed class
120 if (!FileOperation.class.isAssignableFrom(operationClass)) {
121 throw new FileSystemException("vfs.operation/wrong-type.error", operationClass);
122 }
123
124 // find appropriate class
125 Class<? extends FileOperation> foundClass = null;
126 for (final Class<? extends FileOperation> operation : operations) {
127 if (operationClass.isAssignableFrom(operation)) {
128 foundClass = operation;
129 break;
130 }
131 }
132
133 if (foundClass == null) {
134 throw new FileSystemException("vfs.operation/not-found.error", operationClass);
135 }
136
137 return foundClass;
138 }
139 }