/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive_grid_cloud_portal.dataspace; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Collections; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.ws.rs.core.HttpHeaders; import org.apache.commons.vfs2.*; import org.objectweb.proactive.extensions.dataspaces.vfs.VFSFactory; import org.ow2.proactive.scheduler.common.exception.NotConnectedException; import org.ow2.proactive.scheduler.common.exception.PermissionException; import org.ow2.proactive.scheduler.common.util.SchedulerProxyUserInterface; import org.ow2.proactive_grid_cloud_portal.dataspace.dto.ListFile; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.common.io.Closer; public class FileSystem { private FileSystemManager fsm; private String userspace; private String globalspace; private FileSystem(String userspace, String globalspace, FileSystemManager fsm) { this.userspace = userspace; this.globalspace = globalspace; this.fsm = fsm; } public FileObject resolveFileInUserspace(String pathname) throws FileSystemException { FileObject answer = fsm.resolveFile(fsm.resolveFile(userspace), pathname); answer.refresh(); return answer; } public FileObject resolveFileInGlobalspace(String pathname) throws FileSystemException { FileObject answer = fsm.resolveFile(fsm.resolveFile(globalspace), pathname); answer.refresh(); return answer; } public FileObject resolveFile(String dirPath, String pathname) throws FileSystemException { FileObject answer = fsm.resolveFile(dirPath + (dirPath.endsWith(File.separator) ? "" : File.separator) + pathname); answer.refresh(); return answer; } public FileObject createFile(String pathname) throws FileSystemException { FileObject fo = fsm.resolveFile(pathname); fo.refresh(); if (!fo.exists()) { fo.createFile(); } return fo; } public static ListFile list(FileObject fo, List<String> includes, List<String> excludes) throws FileSystemException { fo.refresh(); ListFile answer = new ListFile(); List<String> dirList = Lists.newArrayList(); List<String> fileList = Lists.newArrayList(); List<String> fullList = Lists.newArrayList(); List<FileObject> foundFileObjects = new LinkedList<>(); if (isNullOrEmpty(includes) && isNullOrEmpty(excludes)) { fo.findFiles(Selectors.SELECT_CHILDREN, false, foundFileObjects); } else { FileSelector selector = new org.objectweb.proactive.extensions.dataspaces.vfs.selector.FileSelector(includes, excludes); fo.findFiles(selector, false, foundFileObjects); } for (FileObject child : foundFileObjects) { FileType type = child.getType(); FileName childName = child.getName(); switch (type) { case FOLDER: if (!child.equals(fo)) { // exclude root directory from the list String relativePath = fo.getName().getRelativeName(childName); dirList.add(relativePath); fullList.add(relativePath); } break; case FILE: String relativePath = fo.getName().getRelativeName(childName); fileList.add(relativePath); fullList.add(relativePath); break; default: throw new RuntimeException("Unknown : " + type); } } Collections.sort(dirList); Collections.sort(fileList); Collections.sort(fullList); answer.setDirectoryListing(dirList); answer.setFileListing(fileList); answer.setFullListing(fullList); return answer; } public static Map<String, Object> metadata(FileObject fo) throws FileSystemException { Map<String, Object> props = Maps.newHashMap(); switch (fo.getType()) { case FOLDER: fillDirProps(fo, props); break; case FILE: fillFileProps(fo, props); break; default: throw new RuntimeException("Unknown location."); } return props; } private static void fillDirProps(FileObject fo, Map<String, Object> properties) throws FileSystemException { properties.put("x-proactive-ds-type", "DIRECTORY"); properties.put("Last-Modified", new Date(fo.getContent().getLastModifiedTime())); } private static void fillFileProps(FileObject fo, Map<String, Object> properties) throws FileSystemException { properties.put("x-proactive-ds-type", "FILE"); properties.put(HttpHeaders.LAST_MODIFIED, new Date(fo.getContent().getLastModifiedTime())); properties.put(HttpHeaders.CONTENT_TYPE, contentType(fo)); properties.put(HttpHeaders.CONTENT_LENGTH, fo.getContent().getSize()); } public static List<FileObject> findFiles(FileObject root, List<String> includes, List<String> excludes) throws FileSystemException { root.refresh(); List<FileObject> files = Lists.newArrayList(); FileSelector selector = (isNullOrEmpty(includes) && isNullOrEmpty(excludes)) ? new AllFilesSelector() : new org.objectweb.proactive.extensions.dataspaces.vfs.selector.FileSelector(includes, excludes); root.findFiles(selector, true, files); return files; } public static void copy(InputStream is, FileObject outFile) throws IOException { outFile.refresh(); Closer closer = Closer.create(); closer.register(is); try { OutputStream os = outFile.getContent().getOutputStream(); closer.register(os); ByteStreams.copy(is, os); } catch (IOException ioe) { throw closer.rethrow(ioe); } finally { closer.close(); } } public static void copy(FileObject fo, OutputStream os) throws IOException { fo.refresh(); Closer closer = Closer.create(); closer.register(os); try { InputStream is = fo.getContent().getInputStream(); closer.register(is); ByteStreams.copy(is, os); } catch (IOException ioe) { throw closer.rethrow(ioe); } finally { closer.close(); } } public static boolean isEmpty(FileObject fo) throws FileSystemException { fo.refresh(); FileObject[] children = fo.getChildren(); return children == null || children.length == 0; } private static String baseName(FileObject fo) throws FileSystemException { return fo.getName().getBaseName(); } private static String contentType(FileObject fo) throws FileSystemException { return fo.getContent().getContentInfo().getContentType(); } private static boolean isNullOrEmpty(List<?> list) { return list == null || list.isEmpty(); } static class Builder { public static FileSystem create(SchedulerProxyUserInterface schedulerProxy) throws FileSystemException, NotConnectedException, PermissionException { return new FileSystem(schedulerProxy.getUserSpaceURIs().get(0), schedulerProxy.getGlobalSpaceURIs().get(0), VFSFactory.createDefaultFileSystemManager()); } } private static final class AllFilesSelector implements FileSelector { @Override public boolean includeFile(FileSelectInfo selInfo) throws Exception { return FileType.FILE == selInfo.getFile().getName().getType(); } @Override public boolean traverseDescendents(FileSelectInfo arg0) throws Exception { return true; } } }