/** * Returns <code>true</code> if the specified file operation and corresponding method is supported by the * given <code>AbstractFile</code> implementation.<br> * See the {@link FileOperation} enum for a complete list of file operations and their corresponding * <code>AbstractFile</code> methods. * * @param op a file operation * @param c the file implementation to test * @return <code>true</code> if the specified file operation is supported by this filesystem. * @see FileOperation */ public static boolean isFileOperationSupported(FileOperation op, Class<? extends AbstractFile> c) { return !op.getCorrespondingMethod(c).isAnnotationPresent(UnsupportedFileOperation.class); }
/** * Tests the absence of {@link UnsupportedFileOperation} annotations in all methods corresponding to * {@link #getSupportedOperations() supported operations}, and the absence thereof for unsupported operations. * * @throws Exception should not happen */ @Test public void testUnsupportedFileOperationAnnotations() throws Exception { List<FileOperation> supportedOps = Arrays.asList(getSupportedOperations()); Class<? extends AbstractFile> fileClass = tempFile.getClass(); Method m; for(FileOperation op: FileOperation.values()) { m = op.getCorrespondingMethod(fileClass); assert supportedOps.contains(op) == !fileClass.getMethod(m.getName(), m.getParameterTypes()).isAnnotationPresent(UnsupportedFileOperation.class) :"File operation "+op+" does not match annotation of method "+m.getName(); } }
/** * Verifies that the given {@link UnsupportedFileOperationException} is not <code>null</code> and that its * associated file operation matches the given one. * * @param e the {@link UnsupportedFileOperationException} to check * @param expectedFileOperation the expected file operation */ protected void assertUnsupportedFileOperationException(UnsupportedFileOperationException e, FileOperation expectedFileOperation) { assert e != null; assert expectedFileOperation.equals(e.getFileOperation()); }
/** * Ensures that the return value of {@link AbstractFile#isFileOperationSupported(FileOperation)} is consistent * with {@link #getSupportedOperations() supported operations}. * * @throws Exception should not happen */ @Test public void testSupportedFileOperations() throws Exception { List<FileOperation> supportedOps = Arrays.asList(getSupportedOperations()); AbstractFile tempFile = getTemporaryFile(); Class<? extends AbstractFile> fileClass = tempFile.getClass(); for(FileOperation op: FileOperation.values()) { boolean opSupported = supportedOps.contains(op); assert opSupported == tempFile.isFileOperationSupported(op); assert opSupported == AbstractFile.isFileOperationSupported(op, fileClass); } }
@Override public final boolean isFileOperationSupported(FileOperation op) { Class<? extends AbstractFile> thisClass = getClass(); Method opMethod = op.getCorrespondingMethod(thisClass); // If the method corresponding to the file operation has been overridden by this class (a ProxyFile subclass), // check the presence of the UnsupportedFileOperation annotation in this class. try { if(!thisClass.getMethod(opMethod.getName(), opMethod.getParameterTypes()).getDeclaringClass().equals(ProxyFile.class)) return AbstractFile.isFileOperationSupported(op, thisClass); } catch(Exception e) { // Should never happen, unless AbstractFile method signatures have changed and FileOperation has not been updated LOGGER.warn("Exception caught, this should not have happened", e); } // Otherwise, check for the presence of the UnsupportedFileOperation annotation in the wrapped AbstractFile. return file.isFileOperationSupported(op); }