1/* 2 * Copyright (c) 1999, 2015, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package TVJar; 24 25import java.security.Permission; 26import java.security.PermissionCollection; 27import java.util.ArrayList; 28import java.util.Collections; 29import java.util.Enumeration; 30import java.util.Iterator; 31import java.util.StringJoiner; 32import java.util.StringTokenizer; 33 34public class TVPermission extends Permission { 35 36 /** 37 * Watch 38 */ 39 private final static int WATCH = 0x1; 40 41 /** 42 * Preview 43 */ 44 private final static int PREVIEW = 0x2; 45 46 /** 47 * No actions 48 */ 49 private final static int NONE = 0x0; 50 51 /** 52 * All actions 53 */ 54 private final static int ALL = WATCH | PREVIEW; 55 56 // the actions mask 57 private int mask; 58 59 // the actions string 60 private String actions; 61 62 // the canonical name of the channel 63 private String cname; 64 65 // true if the channelname is a wildcard 66 private boolean wildcard; 67 68 // num range on channel 69 private int[] numrange; 70 71 // various num constants 72 private final static int NUM_MIN = 1; 73 private final static int NUM_MAX = 128; 74 75 public TVPermission(String channel, String action) { 76 this(channel, getMask(action)); 77 } 78 79 TVPermission(String channel, int mask) { 80 super(channel); 81 init(channel, mask); 82 } 83 84 private synchronized int[] parseNum(String num) 85 throws Exception { 86 87 if (num == null || num.equals("") || num.equals("*")) { 88 wildcard = true; 89 return new int[]{NUM_MIN, NUM_MAX}; 90 } 91 92 int dash = num.indexOf('-'); 93 94 if (dash == -1) { 95 int p = 0; 96 try { 97 p = Integer.parseInt(num); 98 } catch (NumberFormatException nfe) { 99 throw new IllegalArgumentException("invalid input" + num); 100 } 101 return new int[]{p, p}; 102 } else { 103 String low = num.substring(0, dash); 104 String high = num.substring(dash + 1); 105 int l, h; 106 107 if (low.equals("")) { 108 l = NUM_MIN; 109 } else { 110 try { 111 l = Integer.parseInt(low); 112 } catch (NumberFormatException nfe) { 113 throw new IllegalArgumentException("invalid input" + num); 114 } 115 } 116 117 if (high.equals("")) { 118 h = NUM_MAX; 119 } else { 120 try { 121 h = Integer.parseInt(high); 122 } catch (NumberFormatException nfe) { 123 throw new IllegalArgumentException("invalid input" + num); 124 } 125 } 126 if (h < l || l < NUM_MIN || h > NUM_MAX) { 127 throw new IllegalArgumentException("invalid num range"); 128 } 129 130 return new int[]{l, h}; 131 } 132 } 133 134 /** 135 * Initialize the TVPermission object. 136 */ 137 private synchronized void init(String channel, int mask) { 138 139 // Parse the channel name. 140 int sep = channel.indexOf(':'); 141 142 if (sep != -1) { 143 String num = channel.substring(sep + 1); 144 cname = channel.substring(0, sep); 145 try { 146 numrange = parseNum(num); 147 } catch (Exception e) { 148 throw new IllegalArgumentException("invalid num range: " + num); 149 } 150 } else { 151 numrange = new int[]{NUM_MIN, NUM_MAX}; 152 } 153 } 154 155 /** 156 * Convert an action string to an integer actions mask. 157 * 158 * @param action the action string 159 * @return the action mask 160 */ 161 private synchronized static int getMask(String action) { 162 int mask = NONE; 163 164 if (action == null) { 165 return mask; 166 } 167 168 StringTokenizer st = new StringTokenizer(action.toLowerCase(), ","); 169 while (st.hasMoreTokens()) { 170 String token = st.nextToken(); 171 if (token.equals("watch")) { 172 mask |= WATCH; 173 } else if (token.equals("preview")) { 174 mask |= PREVIEW; 175 } else { 176 throw new IllegalArgumentException("invalid TV permission: " + token); 177 } 178 } 179 return mask; 180 } 181 182 @Override 183 public boolean implies(Permission p) { 184 if (!(p instanceof TVPermission)) { 185 return false; 186 } 187 188 if (this.wildcard) { 189 return true; 190 } 191 192 TVPermission that = (TVPermission) p; 193 194 if ((this.mask & that.mask) != that.mask) { 195 System.out.println("Masks are not ok this = " 196 + this.mask + "THat = " + that.mask); 197 return false; 198 } 199 200 if ((this.numrange[0] > that.numrange[0]) 201 || (this.numrange[1] < that.numrange[1])) { 202 203 System.out.println("This 0= " + this.numrange[0] 204 + " 1 = " + this.numrange[1]); 205 System.out.println("That 0= " + that.numrange[0] 206 + " 1 = " + that.numrange[1]); 207 return false; 208 } 209 return true; 210 } 211 212 /** 213 * Checks two TVPermission objects for equality. 214 * <p> 215 * @param obj the object we are testing for equality. 216 * @return true if obj is a TVPermission, and has the same channelname and 217 * action mask as this TVPermission object. 218 */ 219 @Override 220 public boolean equals(Object obj) { 221 if (obj == this) { 222 return true; 223 } 224 225 if (!(obj instanceof TVPermission)) { 226 return false; 227 } 228 229 TVPermission that = (TVPermission) obj; 230 231 // check the mask first 232 if (this.mask != that.mask) { 233 return false; 234 } 235 236 // now check the num range... 237 if ((this.numrange[0] != that.numrange[0]) 238 || (this.numrange[1] != that.numrange[1])) { 239 return false; 240 } 241 242 return this.getName().equals(that.getName()); 243 } 244 245 /** 246 * Returns the hash code value for this object. 247 * 248 * @return a hash code value for this object. 249 */ 250 @Override 251 public int hashCode() { 252 return this.getName().hashCode(); 253 } 254 255 /** 256 * Return the canonical string representation of the actions. Always returns 257 * actions in the following order: watch,preview. 258 * 259 * @param mask a specific integer action mask to translate into a string 260 * @return the canonical string representation of the actions 261 */ 262 private synchronized static String getActions(int mask) { 263 StringJoiner sj = new StringJoiner(","); 264 if ((mask & WATCH) == WATCH) { 265 sj.add("watch"); 266 } 267 if ((mask & PREVIEW) == PREVIEW) { 268 sj.add("preview"); 269 } 270 return sj.toString(); 271 } 272 273 /** 274 * Return the canonical string representation of the actions. Always returns 275 * actions in the following order: watch,preview. 276 * 277 * @return the canonical string representation of the actions. 278 */ 279 @Override 280 public String getActions() { 281 if (actions == null) { 282 actions = getActions(this.mask); 283 } 284 285 return actions; 286 } 287 288 @Override 289 public String toString() { 290 return super.toString() + "\n" 291 + "cname = " + cname + "\n" 292 + "wildcard = " + wildcard + "\n" 293 + "numrange = " + numrange[0] + "," + numrange[1] + "\n"; 294 295 } 296 297 @Override 298 public PermissionCollection newPermissionCollection() { 299 return new TVPermissionCollection(); 300 } 301} 302 303final class TVPermissionCollection extends PermissionCollection { 304 305 /** 306 * The TVPermissions for this set. 307 */ 308 private final ArrayList<TVPermission> permissions = new ArrayList<>(); 309 310 /** 311 * Adds a permission to the TVPermissions. The key for the hash is the name 312 * in the case of wildcards, or all the IP addresses. 313 * 314 * @param permission the Permission object to add. 315 */ 316 @Override 317 public void add(Permission permission) { 318 if (!(permission instanceof TVPermission)) { 319 throw new IllegalArgumentException("invalid permission: " + permission); 320 } 321 permissions.add((TVPermission) permission); 322 } 323 324 /** 325 * Check and see if this collection of permissions implies the permissions 326 * expressed in "permission". 327 * 328 * @param p the Permission object to compare 329 * 330 * @return true if "permission" is a proper subset of a permission in the 331 * collection, false if not. 332 */ 333 @Override 334 public boolean implies(Permission p) { 335 if (!(p instanceof TVPermission)) { 336 return false; 337 } 338 339 Iterator<TVPermission> i = permissions.iterator(); 340 while (i.hasNext()) { 341 if (((TVPermission) i.next()).implies(p)) { 342 return true; 343 } 344 } 345 return false; 346 } 347 348 /** 349 * Returns an enumeration of all the TVPermission objects in the container. 350 * 351 * @return an enumeration of all the TVPermission objects. 352 */ 353 @Override 354 public Enumeration elements() { 355 return Collections.enumeration(permissions); 356 } 357 358} 359