| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.wayang.core.util.fs; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.MalformedURLException; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.stream.Collectors; |
| import org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.wayang.core.api.exception.WayangException; |
| |
| /** |
| * {@link FileSystem} implementation for the local file system. |
| */ |
| public class LocalFileSystem implements FileSystem { |
| |
| private static final Logger logger = LogManager.getLogger(LocalFileSystem.class); |
| |
| /** |
| * Retrieves a directory that can be used for temporary files. |
| * |
| * @return a {@link File} representing the directory |
| */ |
| public static File findTempDir() { |
| try { |
| final File tempFile = File.createTempFile("wayang", "probe"); |
| tempFile.deleteOnExit(); |
| return tempFile.getParentFile(); |
| } catch (IOException e) { |
| logger.warn("Could not determine local temp directory.", e); |
| return null; |
| } |
| } |
| |
| /** |
| * Converts a {@link File} object to a URL. |
| * |
| * @param file that should be converted |
| * @return the {@link String} representation of the URL |
| */ |
| public static String toURL(File file) { |
| try { |
| return file.toPath().toUri().toURL().toString(); |
| } catch (MalformedURLException e) { |
| throw new WayangException(String.format("Could not create URI for %s", file), e); |
| } |
| } |
| |
| /** |
| * Ensure that there is a directory represented by the given {@link File}. |
| * |
| * @param file the directory that should be ensured |
| */ |
| public static void ensureDir(File file) { |
| if (file.exists()) { |
| if (!file.isDirectory()) { |
| throw new WayangException(String.format("Could not ensure directory %s: It exists, but is not a directory.", file)); |
| } |
| } else if (!file.mkdirs()) { |
| throw new WayangException(String.format("Could not ensure directory %s: It does not exist, but could also not be created.", file)); |
| } |
| } |
| |
| /** |
| * Create an empty file. |
| * |
| * @param file that should be created |
| */ |
| public static void touch(File file) { |
| ensureDir(file.getParentFile()); |
| try (FileOutputStream fos = new FileOutputStream(file)) { |
| } catch (IOException e) { |
| throw new WayangException(String.format("Could not create %s.", file), e); |
| } |
| } |
| |
| private static File toFile(String fileUrl) throws URISyntaxException, MalformedURLException { |
| if (fileUrl.startsWith("file:")) { |
| return new File(new URL(fileUrl).toURI()); |
| } else { |
| logger.warn("Expect URLs, but got {}. Converting it to file:{}...", fileUrl, fileUrl); |
| return toFile("file:" + fileUrl); |
| } |
| } |
| |
| @Override |
| public long getFileSize(String fileUrl) throws FileNotFoundException { |
| try { |
| File file = toFile(fileUrl); |
| return file.length(); |
| } catch (MalformedURLException | URISyntaxException e) { |
| logger.error("Illegal URL: \"{}\"", fileUrl); |
| throw new FileNotFoundException("File not found, because the URL is not correct."); |
| } |
| } |
| |
| @Override |
| public boolean canHandle(String urlAsString) { |
| if (!urlAsString.startsWith("file:")) return false; |
| try { |
| URL url = new URL(urlAsString); |
| return url.getProtocol().equals("file") && |
| (url.getHost().equals("") || url.getHost().equals("localhost")); |
| } catch (MalformedURLException e) { |
| logger.error(String.format("Illegal URL: \"%s\"", urlAsString), e); |
| return false; |
| } |
| } |
| |
| @Override |
| public InputStream open(String url) throws IOException { |
| try { |
| File file = toFile(url); |
| return new FileInputStream(file); |
| } catch (URISyntaxException e) { |
| throw new IOException("Could not process the given URL.", e); |
| } |
| } |
| |
| @Override |
| public OutputStream create(String url) throws IOException { |
| return this.create(url, false); |
| } |
| |
| @Override |
| public OutputStream create(String url, Boolean forceCreateParentDirs) throws IOException { |
| File file = null; |
| try { |
| file = toFile(url); |
| if (forceCreateParentDirs && file.getParentFile()!=null) |
| file.getParentFile().mkdirs(); |
| return new FileOutputStream(file, false); |
| } catch (URISyntaxException e) { |
| throw new IOException("Could not process the given URL.", e); |
| } catch (IOException e) { |
| if (file != null) { |
| file.delete(); |
| } |
| throw e; |
| } |
| } |
| |
| @Override |
| public boolean isDirectory(String url) { |
| try { |
| return toFile(url).isDirectory(); |
| } catch (URISyntaxException | MalformedURLException e) { |
| logger.warn("Could not inspect directory.", e); |
| return false; |
| } |
| } |
| |
| @Override |
| public Collection<String> listChildren(String url) { |
| try { |
| final File[] files = toFile(url).listFiles(); |
| if (files == null) { |
| return Collections.emptyList(); |
| } |
| return Arrays.stream(files).map(File::toURI).map(Object::toString).collect(Collectors.toList()); |
| } catch (URISyntaxException | MalformedURLException e) { |
| logger.warn("Could not inspect directory.", e); |
| return Collections.emptyList(); |
| } |
| } |
| |
| @Override |
| public boolean delete(String url, boolean isRecursiveDelete) throws IOException { |
| try { |
| final File file = toFile(url); |
| if (!isRecursiveDelete && file.isDirectory()) return false; |
| return this.delete(file); |
| } catch (URISyntaxException e) { |
| throw new IOException("Cannot access file.", e); |
| } |
| } |
| |
| private boolean delete(File file) { |
| boolean canDelete = !file.isDirectory() || Arrays.stream(file.listFiles()).allMatch(this::delete); |
| return canDelete && file.delete(); |
| |
| } |
| |
| } |