/*
 *  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
 *
 *      https://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.tools.ant.util;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;

import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.resources.ArchiveResource;
import org.apache.tools.ant.types.resources.FileProvider;

Contains helper methods for dealing with PosixFilePermission or the traditional Unix mode representation of permissions.
Since:Ant 1.10.0
/** * Contains helper methods for dealing with {@link * PosixFilePermission} or the traditional Unix mode representation of * permissions. * * @since Ant 1.10.0 */
public class PermissionUtils { private PermissionUtils() { }
Translates a set of permissions into a Unix stat(2) st_mode result.
Params:
  • permissions – the permissions
  • type – the file type
Returns:the "mode"
/** * Translates a set of permissions into a Unix stat(2) {@code * st_mode} result. * @param permissions the permissions * @param type the file type * @return the "mode" */
public static int modeFromPermissions(Set<PosixFilePermission> permissions, FileType type) { int mode; switch (type) { case SYMLINK: mode = 012; break; case REGULAR_FILE: mode = 010; break; case DIR: mode = 004; break; default: // OTHER could be a character or block device, a socket or a FIFO - so don't set anything mode = 0; break; } mode <<= 3; mode <<= 3; // we don't support sticky, setuid, setgid mode |= modeFromPermissions(permissions, "OWNER"); mode <<= 3; mode |= modeFromPermissions(permissions, "GROUP"); mode <<= 3; mode |= modeFromPermissions(permissions, "OTHERS"); return mode; }
Translates a Unix stat(2) st_mode compatible value into a set of permissions.
Params:
  • mode – the "mode"
Returns:set of permissions
/** * Translates a Unix stat(2) {@code st_mode} compatible value into * a set of permissions. * @param mode the "mode" * @return set of permissions */
public static Set<PosixFilePermission> permissionsFromMode(int mode) { Set<PosixFilePermission> permissions = EnumSet.noneOf(PosixFilePermission.class); addPermissions(permissions, "OTHERS", mode); addPermissions(permissions, "GROUP", mode >> 3); addPermissions(permissions, "OWNER", mode >> 6); return permissions; }
Sets permissions on a Resource - doesn't do anything for unsupported resource types.

Supported types are:

Params:
  • r – the resource to set permissions for
  • permissions – the permissions
  • posixNotSupportedCallback – optional callback that is invoked for a file provider resource if the file-system holding the file doesn't support PosixFilePermissions. The Path corresponding to the file is passed to the callback.
Throws:
/** * Sets permissions on a {@link Resource} - doesn't do anything * for unsupported resource types. * * <p>Supported types are:</p> * <ul> * <li>any {@link FileProvider}</li> * <li>{@link ArchiveResource}</li> * </ul> * * @param r the resource to set permissions for * @param permissions the permissions * @param posixNotSupportedCallback optional callback that is * invoked for a file provider resource if the file-system holding * the file doesn't support PosixFilePermissions. The Path * corresponding to the file is passed to the callback. * @throws IOException if something goes wrong */
public static void setPermissions(Resource r, Set<PosixFilePermission> permissions, Consumer<Path> posixNotSupportedCallback) throws IOException { FileProvider f = r.as(FileProvider.class); if (f != null) { Path p = f.getFile().toPath(); PosixFileAttributeView view = Files.getFileAttributeView(p, PosixFileAttributeView.class); if (view != null) { view.setPermissions(permissions); } else if (posixNotSupportedCallback != null) { posixNotSupportedCallback.accept(p); } } else if (r instanceof ArchiveResource) { ((ArchiveResource) r).setMode(modeFromPermissions(permissions, FileType.of(r))); } }
Sets permissions of a Resource - returns an empty set for unsupported resource types or file systems that don't support PosixFilePermissions and no fallback has been provided..

Supported types are:

Params:
  • r – the resource to read permissions from
  • posixNotSupportedFallback – optional fallback function to provide permissions for file system that don't support PosixFilePermissions. The Path corresponding to the file is passed to the callback.
Throws:
Returns:the permissions
/** * Sets permissions of a {@link Resource} - returns an empty set * for unsupported resource types or file systems that don't * support PosixFilePermissions and no fallback has been * provided.. * * <p>Supported types are:</p> * <ul> * <li>any {@link FileProvider}</li> * <li>{@link ArchiveResource}</li> * </ul> * * @param r the resource to read permissions from * @param posixNotSupportedFallback optional fallback function to provide * permissions for file system that don't support * PosixFilePermissions. The Path corresponding to the file is * passed to the callback. * @return the permissions * @throws IOException if something goes wrong */
public static Set<PosixFilePermission> getPermissions(Resource r, Function<Path, Set<PosixFilePermission>> posixNotSupportedFallback) throws IOException { FileProvider f = r.as(FileProvider.class); if (f != null) { Path p = f.getFile().toPath(); PosixFileAttributeView view = Files.getFileAttributeView(p, PosixFileAttributeView.class); if (view != null) { return view.readAttributes().permissions(); } else if (posixNotSupportedFallback != null) { return posixNotSupportedFallback.apply(p); } } else if (r instanceof ArchiveResource) { return permissionsFromMode(((ArchiveResource) r).getMode()); } return EnumSet.noneOf(PosixFilePermission.class); } private static long modeFromPermissions(Set<PosixFilePermission> permissions, String prefix) { long mode = 0; if (permissions.contains(PosixFilePermission.valueOf(prefix + "_READ"))) { mode |= 4; } if (permissions.contains(PosixFilePermission.valueOf(prefix + "_WRITE"))) { mode |= 2; } if (permissions.contains(PosixFilePermission.valueOf(prefix + "_EXECUTE"))) { mode |= 1; } return mode; } private static void addPermissions(Set<PosixFilePermission> permissions, String prefix, long mode) { if ((mode & 1) == 1) { permissions.add(PosixFilePermission.valueOf(prefix + "_EXECUTE")); } if ((mode & 2) == 2) { permissions.add(PosixFilePermission.valueOf(prefix + "_WRITE")); } if ((mode & 4) == 4) { permissions.add(PosixFilePermission.valueOf(prefix + "_READ")); } }
The supported types of files, maps to the isFoo methods in BasicFileAttributes.
/** * The supported types of files, maps to the {@code isFoo} methods * in {@link java.nio.file.attribute.BasicFileAttributes}. */
public enum FileType {
A regular file.
/** A regular file. */
REGULAR_FILE,
A directory.
/** A directory. */
DIR,
A symbolic link.
/** A symbolic link. */
SYMLINK,
Something that is neither a regular file nor a directory nor a symbolic link.
/** Something that is neither a regular file nor a directory nor a symbolic link. */
OTHER;
Determines the file type of a Path.
Params:
  • p – Path
Throws:
Returns:FileType
/** * Determines the file type of a {@link Path}. * * @param p Path * @return FileType * @throws IOException if file attributes cannot be read */
public static FileType of(Path p) throws IOException { BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class); if (attrs.isRegularFile()) { return FileType.REGULAR_FILE; } else if (attrs.isDirectory()) { return FileType.DIR; } else if (attrs.isSymbolicLink()) { return FileType.SYMLINK; } return FileType.OTHER; }
Determines the file type of a Resource.
Params:
  • r – Resource
Returns:FileType
/** * Determines the file type of a {@link Resource}. * * @param r Resource * @return FileType */
public static FileType of(Resource r) { if (r.isDirectory()) { return FileType.DIR; } return FileType.REGULAR_FILE; } } }