1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.security; 19 20import java.io.IOException; 21import java.io.Serializable; 22 23import org.apache.harmony.security.internal.nls.Messages; 24 25/** 26 * {@code BasicPermission} is the common base class of all permissions which 27 * have a name but no action lists. A {@code BasicPermission} is granted or it 28 * is not. 29 * <p> 30 * Names of a BasicPermission follow the dot separated, hierarchical property 31 * naming convention. Asterisk '*' can be used as wildcards. Either by itself, 32 * matching anything, or at the end of the name, immediately preceded by a '.'. 33 * For example: 34 * 35 * <pre> 36 * java.io.* grants all permissions under the java.io permission hierarchy 37 * * grants all permissions 38 * </pre> 39 * <p> 40 * While this class ignores the action list in the 41 * {@link #BasicPermission(String, String)} constructor, subclasses may 42 * implement actions on top of this class. 43 */ 44public abstract class BasicPermission extends Permission implements 45 Serializable { 46 47 private static final long serialVersionUID = 6279438298436773498L; 48 49 /** 50 * Constructs a new instance of {@code BasicPermission} with the specified 51 * name. 52 * 53 * @param name 54 * the name of the permission. 55 * @throws NullPointerException if {@code name} is {@code null}. 56 * @throws IllegalArgumentException if {@code name.length() == 0}. 57 */ 58 public BasicPermission(String name) { 59 super(name); 60 checkName(name); 61 } 62 63 /** 64 * Constructs a new instance of {@code BasicPermission} with the specified 65 * name. The {@code action} parameter is ignored. 66 * 67 * @param name 68 * the name of the permission. 69 * @param action 70 * is ignored. 71 * @throws NullPointerException 72 * if {@code name} is {@code null}. 73 * @throws IllegalArgumentException 74 * if {@code name.length() == 0}. 75 */ 76 public BasicPermission(String name, String action) { 77 super(name); 78 checkName(name); 79 } 80 81 /** 82 * Checks name parameter 83 */ 84 private final void checkName(String name) { 85 if (name == null) { 86 throw new NullPointerException(Messages.getString("security.28")); //$NON-NLS-1$ 87 } 88 if (name.length() == 0) { 89 throw new IllegalArgumentException(Messages.getString("security.29")); //$NON-NLS-1$ 90 } 91 } 92 93 /** 94 * Compares the specified object with this {@code BasicPermission} for 95 * equality. Returns {@code true} if the specified object has the same class 96 * and the two {@code Permissions}s have the same name. 97 * <p> 98 * The {@link #implies(Permission)} method should be used for making access 99 * control checks. 100 * 101 * @param obj 102 * object to be compared for equality with this {@code 103 * BasicPermission}. 104 * @return {@code true} if the specified object is equal to this {@code 105 * BasicPermission}, otherwise {@code false}. 106 */ 107 @Override 108 public boolean equals(Object obj) { 109 if (obj == this) { 110 return true; 111 } 112 113 if (obj != null && obj.getClass() == this.getClass()) { 114 return this.getName().equals(((Permission)obj).getName()); 115 } 116 return false; 117 } 118 119 /** 120 * Returns the hash code value for this {@code BasicPermission}. Returns the 121 * same hash code for {@code BasicPermission}s that are equal to each other 122 * as required by the general contract of {@link Object#hashCode}. 123 * 124 * @return the hash code value for this {@code BasicPermission}. 125 * @see Object#equals(Object) 126 * @see BasicPermission#equals(Object) 127 */ 128 @Override 129 public int hashCode() { 130 return getName().hashCode(); 131 } 132 133 /** 134 * Returns the actions associated with this permission. Since {@code 135 * BasicPermission} instances have no actions, an empty string is returned. 136 * 137 * @return an empty string. 138 */ 139 @Override 140 public String getActions() { 141 return ""; //$NON-NLS-1$ 142 } 143 144 /** 145 * Indicates whether the specified permission is implied by this permission. 146 * 147 * @param permission 148 * the permission to check against this permission. 149 * @return {@code true} if the specified permission is implied by this 150 * permission, {@code false} otherwise. 151 */ 152 @Override 153 public boolean implies(Permission permission) { 154 if (permission != null && permission.getClass() == this.getClass()) { 155 return nameImplies(getName(), permission.getName()); 156 } 157 return false; 158 } 159 160 /** 161 * Checks if {@code thisName} implies {@code thatName}, 162 * accordingly to hierarchical property naming convention. 163 * It is assumed that names cannot be {@code null} or empty. 164 */ 165 static boolean nameImplies(String thisName, String thatName) { 166 if (thisName == thatName) { 167 return true; 168 } 169 int end = thisName.length(); 170 if (end > thatName.length()) { 171 return false; 172 } 173 if (thisName.charAt(--end) == '*' 174 && (end == 0 || thisName.charAt(end - 1) == '.')) { 175 //wildcard found 176 end--; 177 } else if (end != (thatName.length()-1)) { 178 //names are not equal 179 return false; 180 } 181 for (int i = end; i >= 0; i--) { 182 if (thisName.charAt(i) != thatName.charAt(i)) { 183 return false; 184 } 185 } 186 return true; 187 } 188 189 /** 190 * Returns an empty {@link PermissionCollection} for holding permissions. 191 * <p> 192 * For {@code PermissionCollection} (and subclasses which do not override 193 * this method), the collection which is returned does <em>not</em> invoke 194 * the {@link #implies(Permission)} method of the permissions which are 195 * stored in it when checking if the collection implies a permission. 196 * Instead, it assumes that if the type of the permission is correct, and 197 * the name of the permission is correct, there is a match. 198 * 199 * @return an empty {@link PermissionCollection} for holding permissions. 200 * @see BasicPermissionCollection 201 */ 202 @Override 203 public PermissionCollection newPermissionCollection() { 204 return new BasicPermissionCollection(); 205 } 206 207 /** 208 * Checks name after default deserialization. 209 */ 210 private void readObject(java.io.ObjectInputStream in) throws IOException, 211 ClassNotFoundException { 212 in.defaultReadObject(); 213 checkName(this.getName()); 214 } 215} 216