com.aliyun.odps.volume.VolumeFSUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.aliyun.odps.volume.VolumeFSUtil.java

Source

/**
 * 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 com.aliyun.odps.volume;

import java.net.URI;

import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.StringUtils;

import com.aliyun.odps.VolumeException;
import com.aliyun.odps.VolumeFSFile;
import com.aliyun.odps.fs.VolumeFileSystemConfigKeys;
import com.aliyun.odps.tunnel.VolumeFSErrorCode;
import com.aliyun.odps.volume.protocol.VolumeFSConstants;

/**
 * Utility that wraps some Volume related utility methods
 * 
 * @author Emerson Zhao [mailto:zhenyi.zzy@alibaba-inc.com]
 *
 */
public class VolumeFSUtil {

    /**
     * Whether the pathname is valid. Currently prohibits relative paths, names which contain a ":" or
     * "//", or other non-canonical paths.
     */
    public static boolean isValidName(String src) {
        if (src == null)
            return false;

        // Path must be absolute.
        if (!src.startsWith(Path.SEPARATOR)) {
            return false;
        }

        // Check for "~" ".." "." ":" "/"
        String[] components = StringUtils.split(src, '/');
        for (int i = 0; i < components.length; i++) {
            String element = components[i];
            if (element.equals("~") || element.equals(".") || element.equals("..") || (element.indexOf(":") >= 0)
                    || (element.indexOf("/") >= 0) || (element.indexOf("\\") >= 0)
                    || (element.indexOf("\0") >= 0)) {
                return false;
            }
            // The string may start or end with a /, but not have
            // "//" in the middle.
            if (element.isEmpty() && i != components.length - 1 && i != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * Get volume name from a specific {@link Path}
     * 
     * @param path
     * @throws VolumeException
     */
    public static String getVolumeFromPath(Path path) throws VolumeException {
        path = Path.getPathWithoutSchemeAndAuthority(path);
        if (path.depth() == 0) {
            throw new VolumeException(VolumeFSErrorCode.VolumeMissing, "No volume found!");
        } else {
            String p = path.toUri().getPath();
            String volume = p.split(VolumeFSConstants.SEPARATOR)[1];
            return volume;
        }
    }

    /**
     * Get volume name from a specific path str
     * 
     * @param pathStr
     * @throws VolumeException
     */
    public static String getVolumeFromPath(String pathStr) throws VolumeException {
        Path path = new Path(pathStr);
        return getVolumeFromPath(path);
    }

    /**
     * Transfer {@link VolumeFSFile} to {@link FileStatus}
     * 
     * @param file
     */
    public static FileStatus transferFile(VolumeFSFile file) {
        if (file == null) {
            return null;
        }
        Path symlink = org.apache.commons.lang.StringUtils.isBlank(file.getSymlink()) ? null
                : new Path(file.getSymlink());
        FileStatus fileStatus = new FileStatus(file.getLength(), file.getIsdir(), file.getBlockReplications(),
                file.getBlockSize(), file.getModificationTime().getTime(), file.getAccessTime().getTime(),
                new FsPermission(Short.valueOf(file.getPermission(), 8)), file.getOwner(), file.getGroup(), symlink,
                new Path(VolumeFileSystemConfigKeys.VOLUME_URI_SCHEME + "://" + file.getProject(), file.getPath()));
        return fileStatus;
    }

    /**
     * Check if a path is just a volume
     * 
     * @param path
     */
    public static boolean checkPathIsJustVolume(String path) {
        if (org.apache.commons.lang.StringUtils.isBlank(path)) {
            return false;
        }
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }
        if (path.indexOf("/") == -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Check if a path is root
     * 
     * @param path
     */
    public static boolean checkPathIsRoot(String path) {
        if (org.apache.commons.lang.StringUtils.isBlank(path)) {
            return false;
        }
        path = path.replaceAll("//", "/");
        return path.trim().equals(VolumeFSConstants.ROOT_PATH);
    }

    /**
     * Batch transfer {@link VolumeFSFile} to {@link FileStatus}
     * 
     * @param files s
     */
    public static FileStatus[] transferFiles(VolumeFSFile[] files) {
        if (files == null)
            return null;
        FileStatus[] fileStatusArray = new FileStatus[files.length];
        for (int i = 0; i < files.length; i++) {
            fileStatusArray[i] = transferFile(files[i]);
        }
        return fileStatusArray;
    }

    /**
     * Probe for a path being a parent of another
     * 
     * @param parent parent path
     * @param child possible child path
     * @return true if the parent's path matches the start of the child's
     */
    public static boolean isParentOf(Path parent, Path child) {
        URI parentURI = parent.toUri();
        String parentPath = parentURI.getPath();
        if (!parentPath.endsWith("/")) {
            parentPath += "/";
        }
        URI childURI = child.toUri();
        String childPath = childURI.getPath();
        return childPath.startsWith(parentPath);
    }

    public static void checkPath(String path) throws VolumeException {
        if (checkPathIsRoot(path)) {
            throw new VolumeException(VolumeFSErrorCode.VolumeMissing,
                    "Root path is not supported this operation!");
        }
        if (checkPathIsJustVolume(path)) {
            throw new VolumeException(VolumeFSErrorCode.InvalidPath, "The path is just a volume!");
        }
        if (!isValidName(path)) {
            throw new VolumeException(VolumeFSErrorCode.InvalidPath, "The path contains illegal characters!");
        }
    }

}