/* * 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.solr.hadoop; import java.io.IOException; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.permission.FsAction; /** * ArgumentType subclass for HDFS Path type, using fluent style API. */ public class PathArgumentType implements ArgumentType<Path> { private final Configuration conf; private FileSystem fs; private boolean acceptSystemIn = false; private boolean verifyExists = false; private boolean verifyNotExists = false; private boolean verifyIsFile = false; private boolean verifyIsDirectory = false; private boolean verifyCanRead = false; private boolean verifyCanWrite = false; private boolean verifyCanWriteParent = false; private boolean verifyCanExecute = false; private boolean verifyIsAbsolute = false; private boolean verifyHasScheme = false; private String verifyScheme = null; public PathArgumentType(Configuration conf) { this.conf = conf; } public PathArgumentType acceptSystemIn() { acceptSystemIn = true; return this; } public PathArgumentType verifyExists() { verifyExists = true; return this; } public PathArgumentType verifyNotExists() { verifyNotExists = true; return this; } public PathArgumentType verifyIsFile() { verifyIsFile = true; return this; } public PathArgumentType verifyIsDirectory() { verifyIsDirectory = true; return this; } public PathArgumentType verifyCanRead() { verifyCanRead = true; return this; } public PathArgumentType verifyCanWrite() { verifyCanWrite = true; return this; } public PathArgumentType verifyCanWriteParent() { verifyCanWriteParent = true; return this; } public PathArgumentType verifyCanExecute() { verifyCanExecute = true; return this; } public PathArgumentType verifyIsAbsolute() { verifyIsAbsolute = true; return this; } public PathArgumentType verifyHasScheme() { verifyHasScheme = true; return this; } public PathArgumentType verifyScheme(String scheme) { verifyScheme = scheme; return this; } @Override public Path convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { Path file = new Path(value); try { fs = file.getFileSystem(conf); if (verifyHasScheme && !isSystemIn(file)) { verifyHasScheme(parser, file); } if (verifyScheme != null && !isSystemIn(file)) { verifyScheme(parser, file); } if (verifyIsAbsolute && !isSystemIn(file)) { verifyIsAbsolute(parser, file); } if (verifyExists && !isSystemIn(file)) { verifyExists(parser, file); } if (verifyNotExists && !isSystemIn(file)) { verifyNotExists(parser, file); } if (verifyIsFile && !isSystemIn(file)) { verifyIsFile(parser, file); } if (verifyIsDirectory && !isSystemIn(file)) { verifyIsDirectory(parser, file); } if (verifyCanRead && !isSystemIn(file)) { verifyCanRead(parser, file); } if (verifyCanWrite && !isSystemIn(file)) { verifyCanWrite(parser, file); } if (verifyCanWriteParent && !isSystemIn(file)) { verifyCanWriteParent(parser, file); } if (verifyCanExecute && !isSystemIn(file)) { verifyCanExecute(parser, file); } } catch (IOException e) { throw new ArgumentParserException(e, parser); } return file; } private void verifyExists(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { if (!fs.exists(file)) { throw new ArgumentParserException("File not found: " + file, parser); } } private void verifyNotExists(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { if (fs.exists(file)) { throw new ArgumentParserException("File found: " + file, parser); } } private void verifyIsFile(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { if (!fs.isFile(file)) { throw new ArgumentParserException("Not a file: " + file, parser); } } private void verifyIsDirectory(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { if (!fs.isDirectory(file)) { throw new ArgumentParserException("Not a directory: " + file, parser); } } private void verifyCanRead(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { verifyExists(parser, file); if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.READ)) { throw new ArgumentParserException("Insufficient permissions to read file: " + file, parser); } } private void verifyCanWrite(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { verifyExists(parser, file); if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.WRITE)) { throw new ArgumentParserException("Insufficient permissions to write file: " + file, parser); } } private void verifyCanWriteParent(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { Path parent = file.getParent(); if (parent == null || !fs.exists(parent) || !fs.getFileStatus(parent).getPermission().getUserAction().implies(FsAction.WRITE)) { throw new ArgumentParserException("Cannot write parent of file: " + file, parser); } } private void verifyCanExecute(ArgumentParser parser, Path file) throws ArgumentParserException, IOException { verifyExists(parser, file); if (!fs.getFileStatus(file).getPermission().getUserAction().implies(FsAction.EXECUTE)) { throw new ArgumentParserException("Insufficient permissions to execute file: " + file, parser); } } private void verifyIsAbsolute(ArgumentParser parser, Path file) throws ArgumentParserException { if (!file.isAbsolute()) { throw new ArgumentParserException("Not an absolute file: " + file, parser); } } private void verifyHasScheme(ArgumentParser parser, Path file) throws ArgumentParserException { if (file.toUri().getScheme() == null) { throw new ArgumentParserException("URI scheme is missing in path: " + file, parser); } } private void verifyScheme(ArgumentParser parser, Path file) throws ArgumentParserException { if (!verifyScheme.equals(file.toUri().getScheme())) { throw new ArgumentParserException("Scheme of path: " + file + " must be: " + verifyScheme, parser); } } private boolean isSystemIn(Path file) { return acceptSystemIn && file.toString().equals("-"); } }