1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.nio.file.attribute; 27 28 import static java.nio.file.attribute.PosixFilePermission.*; 29 import java.util.*; 30 31 /** 32 * This class consists exclusively of static methods that operate on sets of 33 * {@link PosixFilePermission} objects. 34 * 35 * @since 1.7 36 */ 37 38 public final class PosixFilePermissions { PosixFilePermissions()39 private PosixFilePermissions() { } 40 41 // Write string representation of permission bits to {@code sb}. writeBits(StringBuilder sb, boolean r, boolean w, boolean x)42 private static void writeBits(StringBuilder sb, boolean r, boolean w, boolean x) { 43 if (r) { 44 sb.append('r'); 45 } else { 46 sb.append('-'); 47 } 48 if (w) { 49 sb.append('w'); 50 } else { 51 sb.append('-'); 52 } 53 if (x) { 54 sb.append('x'); 55 } else { 56 sb.append('-'); 57 } 58 } 59 60 /** 61 * Returns the {@code String} representation of a set of permissions. It 62 * is guaranteed that the returned {@code String} can be parsed by the 63 * {@link #fromString} method. 64 * 65 * <p> If the set contains {@code null} or elements that are not of type 66 * {@code PosixFilePermission} then these elements are ignored. 67 * 68 * @param perms 69 * the set of permissions 70 * 71 * @return the string representation of the permission set 72 */ toString(Set<PosixFilePermission> perms)73 public static String toString(Set<PosixFilePermission> perms) { 74 StringBuilder sb = new StringBuilder(9); 75 writeBits(sb, perms.contains(OWNER_READ), perms.contains(OWNER_WRITE), 76 perms.contains(OWNER_EXECUTE)); 77 writeBits(sb, perms.contains(GROUP_READ), perms.contains(GROUP_WRITE), 78 perms.contains(GROUP_EXECUTE)); 79 writeBits(sb, perms.contains(OTHERS_READ), perms.contains(OTHERS_WRITE), 80 perms.contains(OTHERS_EXECUTE)); 81 return sb.toString(); 82 } 83 isSet(char c, char setValue)84 private static boolean isSet(char c, char setValue) { 85 if (c == setValue) 86 return true; 87 if (c == '-') 88 return false; 89 throw new IllegalArgumentException("Invalid mode"); 90 } isR(char c)91 private static boolean isR(char c) { return isSet(c, 'r'); } isW(char c)92 private static boolean isW(char c) { return isSet(c, 'w'); } isX(char c)93 private static boolean isX(char c) { return isSet(c, 'x'); } 94 95 /** 96 * Returns the set of permissions corresponding to a given {@code String} 97 * representation. 98 * 99 * <p> The {@code perms} parameter is a {@code String} representing the 100 * permissions. It has 9 characters that are interpreted as three sets of 101 * three. The first set refers to the owner's permissions; the next to the 102 * group permissions and the last to others. Within each set, the first 103 * character is {@code 'r'} to indicate permission to read, the second 104 * character is {@code 'w'} to indicate permission to write, and the third 105 * character is {@code 'x'} for execute permission. Where a permission is 106 * not set then the corresponding character is set to {@code '-'}. 107 * 108 * <p> <b>Usage Example:</b> 109 * Suppose we require the set of permissions that indicate the owner has read, 110 * write, and execute permissions, the group has read and execute permissions 111 * and others have none. 112 * <pre> 113 * Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---"); 114 * </pre> 115 * 116 * @param perms 117 * string representing a set of permissions 118 * 119 * @return the resulting set of permissions 120 * 121 * @throws IllegalArgumentException 122 * if the string cannot be converted to a set of permissions 123 * 124 * @see #toString(Set) 125 */ fromString(String perms)126 public static Set<PosixFilePermission> fromString(String perms) { 127 if (perms.length() != 9) 128 throw new IllegalArgumentException("Invalid mode"); 129 Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class); 130 if (isR(perms.charAt(0))) result.add(OWNER_READ); 131 if (isW(perms.charAt(1))) result.add(OWNER_WRITE); 132 if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE); 133 if (isR(perms.charAt(3))) result.add(GROUP_READ); 134 if (isW(perms.charAt(4))) result.add(GROUP_WRITE); 135 if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE); 136 if (isR(perms.charAt(6))) result.add(OTHERS_READ); 137 if (isW(perms.charAt(7))) result.add(OTHERS_WRITE); 138 if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE); 139 return result; 140 } 141 142 /** 143 * Creates a {@link FileAttribute}, encapsulating a copy of the given file 144 * permissions, suitable for passing to the {@link java.nio.file.Files#createFile 145 * createFile} or {@link java.nio.file.Files#createDirectory createDirectory} 146 * methods. 147 * 148 * @param perms 149 * the set of permissions 150 * 151 * @return an attribute encapsulating the given file permissions with 152 * {@link FileAttribute#name name} {@code "posix:permissions"} 153 * 154 * @throws ClassCastException 155 * if the set contains elements that are not of type {@code 156 * PosixFilePermission} 157 */ 158 public static FileAttribute<Set<PosixFilePermission>> asFileAttribute(Set<PosixFilePermission> perms)159 asFileAttribute(Set<PosixFilePermission> perms) 160 { 161 // copy set and check for nulls (CCE will be thrown if an element is not 162 // a PosixFilePermission) 163 perms = new HashSet<PosixFilePermission>(perms); 164 for (PosixFilePermission p: perms) { 165 if (p == null) 166 throw new NullPointerException(); 167 } 168 final Set<PosixFilePermission> value = perms; 169 return new FileAttribute<Set<PosixFilePermission>>() { 170 @Override 171 public String name() { 172 return "posix:permissions"; 173 } 174 @Override 175 public Set<PosixFilePermission> value() { 176 return Collections.unmodifiableSet(value); 177 } 178 }; 179 } 180 } 181