| /* |
| * Copyright 2004-2005 The Apache Software Foundation or its licensors, |
| * as applicable. |
| * |
| * Licensed 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.jackrabbit.core.fs.vfs; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collection; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.commons.vfs.AllFileSelector; |
| import org.apache.commons.vfs.FileObject; |
| import org.apache.commons.vfs.FileSelector; |
| import org.apache.commons.vfs.FileSystemException; |
| import org.apache.commons.vfs.FileType; |
| import org.apache.commons.vfs.FileUtil; |
| import org.apache.commons.vfs.RandomAccessContent; |
| import org.apache.commons.vfs.cache.SoftRefFilesCache; |
| import org.apache.commons.vfs.impl.StandardFileSystemManager; |
| import org.apache.commons.vfs.util.RandomAccessMode; |
| import org.apache.jackrabbit.core.fs.FileSystem; |
| import org.apache.jackrabbit.core.fs.RandomAccessOutputStream; |
| |
| /** |
| * FileSystem backed by Commons VFS |
| * |
| * @author <a href="mailto:edgarpoce@gmail.com">Edgar Poce </a> |
| */ |
| public class VFSFileSystem implements FileSystem |
| { |
| /** |
| * Logger |
| */ |
| private Log log = LogFactory.getLog(VFSFileSystem.class); |
| |
| /** |
| * File selector |
| */ |
| public final static FileSelector ALL = new AllFileSelector() ; |
| |
| /** |
| * VFS manager |
| */ |
| StandardFileSystemManager fsManager; |
| |
| /** |
| * Scheme |
| */ |
| private String prefix; |
| |
| /** |
| * Path |
| */ |
| private String path; |
| |
| /** |
| * The config file |
| */ |
| private String config; |
| |
| /** |
| * |
| */ |
| public VFSFileSystem() |
| { |
| super(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#init() |
| */ |
| public void init() throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| |
| if (this.path == null) |
| { |
| String msg = "Path is not set"; |
| log.error(msg); |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(msg); |
| } |
| |
| if (this.config == null) |
| { |
| String msg = "Configuration file name is not set (\"config\" parameter )."; |
| log.error(msg); |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(msg); |
| } |
| |
| try |
| { |
| // Init file system |
| fsManager = new StandardFileSystemManager(); |
| |
| // Set class loader for resource retrieval |
| fsManager.setClassLoader(this.getClass().getClassLoader()); |
| |
| // Configuration file name |
| fsManager.setConfiguration(this.getClass().getClassLoader() |
| .getResource(this.config).toExternalForm()); |
| |
| // Set the logger |
| fsManager.setLogger(log); |
| |
| // Cache strategy |
| // FIXME: set through configuration |
| fsManager.setFilesCache(new SoftRefFilesCache()); |
| fsManager.init(); |
| |
| // Set the base folder |
| FileObject fo = fsManager |
| .resolveFile(this.prefix + ":" + this.path); |
| fsManager.setBaseFile(fo); |
| |
| } catch (FileSystemException e) |
| { |
| String msg = "Unable to init VFS FileSystem"; |
| log.error(msg, e); |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(msg, e); |
| } |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#close() |
| */ |
| public void close() |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| this.fsManager.close() ; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#getInputStream(java.lang.String) |
| */ |
| public InputStream getInputStream(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| this.validateFile(file); |
| return file.getContent().getInputStream(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#getOutputStream(java.lang.String) |
| */ |
| public OutputStream getOutputStream(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| if (!file.exists()) |
| { |
| file.createFile(); |
| } |
| this.validateFile(file); |
| return file.getContent().getOutputStream(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#getRandomAccessOutputStream(java.lang.String) |
| */ |
| public RandomAccessOutputStream getRandomAccessOutputStream(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| this.validateFile(file); |
| RandomAccessContent raf = file.getContent().getRandomAccessContent( |
| RandomAccessMode.READWRITE); |
| return new VFSRAFOutputStream(raf); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#createFolder(java.lang.String) |
| */ |
| public void createFolder(String folderPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject folder = this.getFile(folderPath); |
| folder.createFolder(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#exists(java.lang.String) |
| */ |
| public boolean exists(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| return this.getFile(path).exists(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#isFile(java.lang.String) |
| */ |
| public boolean isFile(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| return this.getFile(path).getType().equals(FileType.FILE); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#isFolder(java.lang.String) |
| */ |
| public boolean isFolder(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| return this.getFile(path).getType().equals(FileType.FOLDER); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#hasChildren(java.lang.String) |
| */ |
| public boolean hasChildren(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| return this.getFile(path).getChildren().length > 0; |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#length(java.lang.String) |
| */ |
| public long length(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| this.validateFile(file); |
| return file.getContent().getSize(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#lastModified(java.lang.String) |
| */ |
| public long lastModified(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| return this.getFile(path).getContent().getLastModifiedTime(); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#touch(java.lang.String) |
| */ |
| public void touch(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| this.validateFile(file); |
| file.getContent().setLastModifiedTime( |
| Calendar.getInstance().getTimeInMillis()); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#list(java.lang.String) |
| */ |
| public String[] list(String folderPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| return this.list(this.getFile(folderPath), null); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#listFiles(java.lang.String) |
| */ |
| public String[] listFiles(String folderPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| return this.list(this.getFile(folderPath), FileType.FILE); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#listFolders(java.lang.String) |
| */ |
| public String[] listFolders(String folderPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| return this.list(this.getFile(folderPath), FileType.FOLDER); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#deleteFile(java.lang.String) |
| */ |
| public void deleteFile(String filePath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject file = this.getFile(filePath); |
| this.validateFile(file); |
| this.delete(file); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#deleteFolder(java.lang.String) |
| */ |
| public void deleteFolder(String folderPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject folder = this.getFile(folderPath); |
| this.validateFolder(folder); |
| this.delete(folder); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#move(java.lang.String, |
| * java.lang.String) |
| */ |
| public void move(String srcPath, String destPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject src = this.getFile(srcPath); |
| FileObject dest = this.getFile(destPath); |
| src.moveTo(dest); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.jackrabbit.core.fs.FileSystem#copy(java.lang.String, |
| * java.lang.String) |
| */ |
| public void copy(String srcPath, String destPath) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| FileObject src = this.getFile(srcPath); |
| FileObject dest = this.getFile(destPath); |
| FileUtil.copyContent(src, dest); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } catch (IOException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /** |
| * Gets the FileObject for the given path |
| * |
| * @param path |
| * @return FileSystem |
| * @throws FileSystemException |
| */ |
| private FileObject getFile(String path) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| if (path.startsWith("/")) { |
| path = path.substring(1, path.length()) ; |
| } |
| return fsManager.resolveFile(path); |
| } catch (FileSystemException e) |
| { |
| String msg = "Unable to get file " + path; |
| log.error(msg, e); |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(msg, e); |
| } |
| } |
| |
| /** |
| * Validates Folder Type |
| * |
| * @param folder |
| * @throws FileSystemException |
| */ |
| private void validateFolder(FileObject folder) throws FileSystemException |
| { |
| if (!folder.getType().equals(FileType.FOLDER)) |
| { |
| String msg = folder.getName().getPath() |
| + " does not denote a folder"; |
| log.error(msg); |
| throw new FileSystemException(msg); |
| } |
| } |
| |
| /** |
| * Validates File Type |
| * |
| * @param folder |
| * @throws FileSystemException |
| */ |
| private void validateFile(FileObject file) throws FileSystemException |
| { |
| if (!file.getType().equals(FileType.FILE)) |
| { |
| String msg = file.getName().getPath() + " does not denote a file"; |
| log.error(msg); |
| throw new FileSystemException(msg); |
| } |
| } |
| |
| /** |
| * List the children for the given Type. |
| * |
| * @param path |
| * @param type |
| * @return |
| * @throws org.apache.jackrabbit.core.fs.FileSystemException |
| */ |
| private String[] list(FileObject folder, FileType type) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| this.validateFolder(folder); |
| FileObject[] fo = folder.getChildren(); |
| Collection c = new ArrayList(); |
| for (int i = 0; i < fo.length; i++) |
| { |
| if (type == null) |
| { |
| c.add(fo[i].getName().getBaseName()); |
| } else |
| { |
| if (fo[i].getType().equals(type)) |
| { |
| c.add(fo[i].getName().getBaseName()); |
| } |
| } |
| } |
| return (String[]) c.toArray(new String[c.size()]); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| /** |
| * Deletes the given File |
| */ |
| private void delete(FileObject file) |
| throws org.apache.jackrabbit.core.fs.FileSystemException |
| { |
| try |
| { |
| file.delete(ALL); |
| } catch (FileSystemException e) |
| { |
| throw new org.apache.jackrabbit.core.fs.FileSystemException(e); |
| } |
| } |
| |
| public String getPath() |
| { |
| return path; |
| } |
| |
| public void setPath(String path) |
| { |
| this.path = path; |
| } |
| |
| /** |
| * Makes a file canonical |
| */ |
| public static File getCanonicalFile(final File file) |
| { |
| try |
| { |
| return file.getCanonicalFile(); |
| } catch (IOException e) |
| { |
| return file.getAbsoluteFile(); |
| } |
| } |
| |
| public String getConfig() |
| { |
| return config; |
| } |
| |
| public void setConfig(String config) |
| { |
| this.config = config; |
| } |
| |
| /** |
| * @return Returns the scheme. |
| */ |
| public String getPrefix() |
| { |
| return prefix; |
| } |
| |
| /** |
| * @param scheme |
| * The scheme to set. |
| */ |
| public void setPrefix(String prefix) |
| { |
| this.prefix = prefix; |
| } |
| } |