Java tutorial
/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2019 by Hitachi Vantara : http://www.pentaho.com * ******************************************************************************* * * 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.pentaho.di.plugins.fileopensave.providers.vfs; import org.apache.commons.io.IOUtils; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.Selectors; import org.pentaho.di.connections.ConnectionDetails; import org.pentaho.di.connections.ConnectionManager; import org.pentaho.di.connections.ConnectionProvider; import org.pentaho.di.connections.vfs.VFSConnectionDetails; import org.pentaho.di.connections.vfs.VFSConnectionProvider; import org.pentaho.di.connections.vfs.VFSHelper; import org.pentaho.di.connections.vfs.VFSRoot; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleFileException; import org.pentaho.di.core.variables.Variables; import org.pentaho.di.core.vfs.KettleVFS; import org.pentaho.di.plugins.fileopensave.api.providers.BaseFileProvider; import org.pentaho.di.plugins.fileopensave.api.providers.Utils; import org.pentaho.di.plugins.fileopensave.api.providers.exception.FileException; import org.pentaho.di.plugins.fileopensave.providers.vfs.model.VFSDirectory; import org.pentaho.di.plugins.fileopensave.providers.vfs.model.VFSFile; import org.pentaho.di.plugins.fileopensave.providers.vfs.model.VFSLocation; import org.pentaho.di.plugins.fileopensave.providers.vfs.model.VFSTree; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; /** * Created by bmorrise on 2/14/19. */ public class VFSFileProvider extends BaseFileProvider<VFSFile> { public static final String NAME = "VFS Connections"; public static final String TYPE = "vfs"; private Supplier<ConnectionManager> connectionManagerSupplier = ConnectionManager::getInstance; private Map<String, List<VFSFile>> roots = new HashMap<>(); @Override public Class<VFSFile> getFileClass() { return VFSFile.class; } @Override public String getName() { return NAME; } @Override public String getType() { return TYPE; } /** * @return */ public boolean isAvailable() { return true; } /** * @return */ @Override public VFSTree getTree() { VFSTree vfsTree = new VFSTree(NAME); List<ConnectionProvider<? extends ConnectionDetails>> providers = connectionManagerSupplier.get() .getProvidersByType(VFSConnectionProvider.class); for (ConnectionProvider<? extends ConnectionDetails> provider : providers) { for (ConnectionDetails connectionDetails : provider.getConnectionDetails()) { VFSLocation vfsLocation = new VFSLocation(); vfsLocation.setName(connectionDetails.getName()); vfsLocation.setRoot(NAME); vfsLocation.setHasChildren(true); vfsLocation.setCanDelete(true); vfsLocation.setConnection(connectionDetails.getName()); vfsTree.addChild(vfsLocation); } } return vfsTree; } /** * @param file * @return */ private List<VFSFile> getRoot(VFSFile file) { if (this.roots.containsKey(file.getConnection())) { return this.roots.get(file.getConnection()); } List<VFSFile> files = new ArrayList<>(); VFSConnectionDetails vfsConnectionDetails = (VFSConnectionDetails) ConnectionManager.getInstance() .getConnectionDetails(file.getConnection()); @SuppressWarnings("unchecked") VFSConnectionProvider<VFSConnectionDetails> vfsConnectionProvider = (VFSConnectionProvider<VFSConnectionDetails>) ConnectionManager .getInstance().getConnectionProvider(vfsConnectionDetails.getType()); List<VFSRoot> roots = vfsConnectionProvider.getLocations(vfsConnectionDetails); for (VFSRoot root : roots) { VFSDirectory vfsDirectory = new VFSDirectory(); vfsDirectory.setName(root.getName()); vfsDirectory.setDate(root.getModifiedDate()); vfsDirectory.setHasChildren(true); vfsDirectory.setCanAddChildren(true); vfsDirectory.setConnection(vfsConnectionDetails.getName()); vfsDirectory.setPath(vfsConnectionProvider.getProtocol(vfsConnectionDetails) + "://" + root.getName()); vfsDirectory.setRoot(NAME); files.add(vfsDirectory); } this.roots.put(file.getConnection(), files); return files; } /** * @param file * @param filters * @return */ @Override public List<VFSFile> getFiles(VFSFile file, String filters) { if (file.getPath() == null) { return getRoot(file); } List<VFSFile> files = new ArrayList<>(); try { FileObject fileObject = KettleVFS.getFileObject(file.getPath(), new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); FileType fileType = fileObject.getType(); if (fileType.hasChildren()) { FileObject[] children = fileObject.getChildren(); for (FileObject child : children) { FileType fileType1 = child.getType(); if (fileType1.hasChildren()) { files.add(VFSDirectory.create(file.getPath(), child, file.getConnection())); } else { if (Utils.matches(child.getName().getBaseName(), filters)) { files.add(VFSFile.create(file.getPath(), child, file.getConnection())); } } } } } catch (KettleFileException | FileSystemException ignored) { // File does not exist } return files; } /** * @param files * @return */ public List<VFSFile> delete(List<VFSFile> files) { List<VFSFile> deletedFiles = new ArrayList<>(); for (VFSFile file : files) { try { FileObject fileObject = KettleVFS.getFileObject(file.getPath(), new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); if (fileObject.delete()) { deletedFiles.add(file); } } catch (KettleFileException | FileSystemException kfe) { // Ignore don't add } } return deletedFiles; } /** * @param folder * @return */ @Override public VFSFile add(VFSFile folder) { try { FileObject fileObject = KettleVFS.getFileObject(folder.getPath(), new Variables(), VFSHelper.getOpts(folder.getPath(), folder.getConnection())); fileObject.createFolder(); String parent = folder.getPath().substring(0, folder.getPath().length() - 1); return VFSDirectory.create(parent, fileObject, folder.getConnection()); } catch (KettleFileException | FileSystemException kfe) { // TODO: Do something smart here } return null; } /** * @param file * @param newPath * @param overwrite * @return */ @Override public VFSFile rename(VFSFile file, String newPath, boolean overwrite) { return doMove(file, newPath, overwrite); } /** * @param file * @param toPath * @param overwrite * @return */ @Override public VFSFile move(VFSFile file, String toPath, boolean overwrite) { return doMove(file, toPath, overwrite); } /** * @param file * @param newPath * @param overwrite * @return */ private VFSFile doMove(VFSFile file, String newPath, Boolean overwrite) { try { FileObject fileObject = KettleVFS.getFileObject(file.getPath(), new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); FileObject renameObject = KettleVFS.getFileObject(newPath, new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); if (overwrite) { if (renameObject.exists()) { renameObject.delete(); } } fileObject.moveTo(renameObject); if (file instanceof VFSDirectory) { return VFSDirectory.create(renameObject.getParent().getPublicURIString(), renameObject, file.getConnection()); } else { return VFSFile.create(renameObject.getParent().getPublicURIString(), renameObject, file.getConnection()); } } catch (KettleFileException | FileSystemException e) { return null; } } /** * @param file * @param toPath * @param overwrite * @return * @throws FileException */ @Override public VFSFile copy(VFSFile file, String toPath, boolean overwrite) throws FileException { try { FileObject fileObject = KettleVFS.getFileObject(file.getPath(), new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); FileObject copyObject = KettleVFS.getFileObject(toPath, new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); copyObject.copyFrom(fileObject, Selectors.SELECT_SELF); if (file instanceof VFSDirectory) { return VFSDirectory.create(copyObject.getParent().getPublicURIString(), fileObject, file.getConnection()); } else { return VFSFile.create(copyObject.getParent().getPublicURIString(), fileObject, file.getConnection()); } } catch (KettleFileException | FileSystemException e) { throw new FileException(); } } /** * @param dir * @param path * @return * @throws FileException */ @Override public boolean fileExists(VFSFile dir, String path) throws FileException { path = sanitizeName(dir, path); try { FileObject fileObject = KettleVFS.getFileObject(path, new Variables(), VFSHelper.getOpts(path, dir.getConnection())); return fileObject.exists(); } catch (KettleFileException | FileSystemException e) { throw new FileException(); } } /** * @param file * @return */ public InputStream readFile(VFSFile file) { try { FileObject fileObject = KettleVFS.getFileObject(file.getPath(), new Variables(), VFSHelper.getOpts(file.getPath(), file.getConnection())); return fileObject.getContent().getInputStream(); } catch (KettleException | FileSystemException e) { return null; } } /** * @param inputStream * @param destDir * @param path * @param overwrite * @return * @throws FileException */ @Override public VFSFile writeFile(InputStream inputStream, VFSFile destDir, String path, boolean overwrite) throws FileException { FileObject fileObject = null; try { fileObject = KettleVFS.getFileObject(path, new Variables(), VFSHelper.getOpts(destDir.getPath(), destDir.getConnection())); } catch (KettleException ke) { throw new FileException(); } if (fileObject != null) { try (OutputStream outputStream = fileObject.getContent().getOutputStream();) { IOUtils.copy(inputStream, outputStream); outputStream.flush(); return VFSFile.create(destDir.getPath(), fileObject, destDir.getConnection()); } catch (IOException e) { return null; } } return null; } /** * @param file1 * @param file2 * @return */ @Override public boolean isSame(org.pentaho.di.plugins.fileopensave.api.providers.File file1, org.pentaho.di.plugins.fileopensave.api.providers.File file2) { if (file1 instanceof VFSFile && file2 instanceof VFSFile) { VFSFile vfsFile1 = (VFSFile) file1; VFSFile vfsFile2 = (VFSFile) file2; return vfsFile1.getConnection().equals(vfsFile2.getConnection()); } return false; } /** * @param destDir * @param newPath * @return * @throws FileException */ @Override public String getNewName(VFSFile destDir, String newPath) throws FileException { String extension = Utils.getExtension(newPath); String parent = Utils.getParent(newPath); String name = Utils.getName(newPath).replace("." + extension, ""); int i = 1; String testName = sanitizeName(destDir, newPath); try { while (KettleVFS .getFileObject(testName, new Variables(), VFSHelper.getOpts(testName, destDir.getConnection())) .exists()) { if (Utils.isValidExtension(extension)) { testName = sanitizeName(destDir, parent + name + " " + i + "." + extension); } else { testName = sanitizeName(destDir, newPath + " " + i); } i++; } } catch (KettleFileException | FileSystemException e) { return testName; } return testName; } /** * @param file * @return */ @Override public VFSFile getParent(VFSFile file) { VFSFile vfsFile = new VFSFile(); vfsFile.setConnection(file.getConnection()); vfsFile.setPath(file.getParent()); return vfsFile; } @Override public String sanitizeName(VFSFile destDir, String newPath) { return getConnectionProvider(newPath).sanitizeName(newPath); } private VFSConnectionProvider<VFSConnectionDetails> getConnectionProvider(String key) { @SuppressWarnings("unchecked") VFSConnectionProvider<VFSConnectionDetails> vfsConnectionProvider = (VFSConnectionProvider<VFSConnectionDetails>) ConnectionManager .getInstance().getConnectionProvider(key); return vfsConnectionProvider; } }