| /* |
| * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package TVJar; |
| |
| import java.security.Permission; |
| import java.security.PermissionCollection; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.StringJoiner; |
| import java.util.StringTokenizer; |
| |
| public class TVPermission extends Permission { |
| |
| /** |
| * Watch |
| */ |
| private final static int WATCH = 0x1; |
| |
| /** |
| * Preview |
| */ |
| private final static int PREVIEW = 0x2; |
| |
| /** |
| * No actions |
| */ |
| private final static int NONE = 0x0; |
| |
| /** |
| * All actions |
| */ |
| private final static int ALL = WATCH | PREVIEW; |
| |
| // the actions mask |
| private int mask; |
| |
| // the actions string |
| private String actions; |
| |
| // the canonical name of the channel |
| private String cname; |
| |
| // true if the channelname is a wildcard |
| private boolean wildcard; |
| |
| // num range on channel |
| private int[] numrange; |
| |
| // various num constants |
| private final static int NUM_MIN = 1; |
| private final static int NUM_MAX = 128; |
| |
| public TVPermission(String channel, String action) { |
| this(channel, getMask(action)); |
| } |
| |
| TVPermission(String channel, int mask) { |
| super(channel); |
| init(channel, mask); |
| } |
| |
| private synchronized int[] parseNum(String num) |
| throws Exception { |
| |
| if (num == null || num.equals("") || num.equals("*")) { |
| wildcard = true; |
| return new int[]{NUM_MIN, NUM_MAX}; |
| } |
| |
| int dash = num.indexOf('-'); |
| |
| if (dash == -1) { |
| int p = 0; |
| try { |
| p = Integer.parseInt(num); |
| } catch (NumberFormatException nfe) { |
| throw new IllegalArgumentException("invalid input" + num); |
| } |
| return new int[]{p, p}; |
| } else { |
| String low = num.substring(0, dash); |
| String high = num.substring(dash + 1); |
| int l, h; |
| |
| if (low.equals("")) { |
| l = NUM_MIN; |
| } else { |
| try { |
| l = Integer.parseInt(low); |
| } catch (NumberFormatException nfe) { |
| throw new IllegalArgumentException("invalid input" + num); |
| } |
| } |
| |
| if (high.equals("")) { |
| h = NUM_MAX; |
| } else { |
| try { |
| h = Integer.parseInt(high); |
| } catch (NumberFormatException nfe) { |
| throw new IllegalArgumentException("invalid input" + num); |
| } |
| } |
| if (h < l || l < NUM_MIN || h > NUM_MAX) { |
| throw new IllegalArgumentException("invalid num range"); |
| } |
| |
| return new int[]{l, h}; |
| } |
| } |
| |
| /** |
| * Initialize the TVPermission object. |
| */ |
| private synchronized void init(String channel, int mask) { |
| |
| // Parse the channel name. |
| int sep = channel.indexOf(':'); |
| |
| if (sep != -1) { |
| String num = channel.substring(sep + 1); |
| cname = channel.substring(0, sep); |
| try { |
| numrange = parseNum(num); |
| } catch (Exception e) { |
| throw new IllegalArgumentException("invalid num range: " + num); |
| } |
| } else { |
| numrange = new int[]{NUM_MIN, NUM_MAX}; |
| } |
| } |
| |
| /** |
| * Convert an action string to an integer actions mask. |
| * |
| * @param action the action string |
| * @return the action mask |
| */ |
| private synchronized static int getMask(String action) { |
| int mask = NONE; |
| |
| if (action == null) { |
| return mask; |
| } |
| |
| StringTokenizer st = new StringTokenizer(action.toLowerCase(), ","); |
| while (st.hasMoreTokens()) { |
| String token = st.nextToken(); |
| if (token.equals("watch")) { |
| mask |= WATCH; |
| } else if (token.equals("preview")) { |
| mask |= PREVIEW; |
| } else { |
| throw new IllegalArgumentException("invalid TV permission: " + token); |
| } |
| } |
| return mask; |
| } |
| |
| @Override |
| public boolean implies(Permission p) { |
| if (!(p instanceof TVPermission)) { |
| return false; |
| } |
| |
| if (this.wildcard) { |
| return true; |
| } |
| |
| TVPermission that = (TVPermission) p; |
| |
| if ((this.mask & that.mask) != that.mask) { |
| System.out.println("Masks are not ok this = " |
| + this.mask + "THat = " + that.mask); |
| return false; |
| } |
| |
| if ((this.numrange[0] > that.numrange[0]) |
| || (this.numrange[1] < that.numrange[1])) { |
| |
| System.out.println("This 0= " + this.numrange[0] |
| + " 1 = " + this.numrange[1]); |
| System.out.println("That 0= " + that.numrange[0] |
| + " 1 = " + that.numrange[1]); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Checks two TVPermission objects for equality. |
| * <p> |
| * @param obj the object we are testing for equality. |
| * @return true if obj is a TVPermission, and has the same channelname and |
| * action mask as this TVPermission object. |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj == this) { |
| return true; |
| } |
| |
| if (!(obj instanceof TVPermission)) { |
| return false; |
| } |
| |
| TVPermission that = (TVPermission) obj; |
| |
| // check the mask first |
| if (this.mask != that.mask) { |
| return false; |
| } |
| |
| // now check the num range... |
| if ((this.numrange[0] != that.numrange[0]) |
| || (this.numrange[1] != that.numrange[1])) { |
| return false; |
| } |
| |
| return this.getName().equals(that.getName()); |
| } |
| |
| /** |
| * Returns the hash code value for this object. |
| * |
| * @return a hash code value for this object. |
| */ |
| @Override |
| public int hashCode() { |
| return this.getName().hashCode(); |
| } |
| |
| /** |
| * Return the canonical string representation of the actions. Always returns |
| * actions in the following order: watch,preview. |
| * |
| * @param mask a specific integer action mask to translate into a string |
| * @return the canonical string representation of the actions |
| */ |
| private synchronized static String getActions(int mask) { |
| StringJoiner sj = new StringJoiner(","); |
| if ((mask & WATCH) == WATCH) { |
| sj.add("watch"); |
| } |
| if ((mask & PREVIEW) == PREVIEW) { |
| sj.add("preview"); |
| } |
| return sj.toString(); |
| } |
| |
| /** |
| * Return the canonical string representation of the actions. Always returns |
| * actions in the following order: watch,preview. |
| * |
| * @return the canonical string representation of the actions. |
| */ |
| @Override |
| public String getActions() { |
| if (actions == null) { |
| actions = getActions(this.mask); |
| } |
| |
| return actions; |
| } |
| |
| @Override |
| public String toString() { |
| return super.toString() + "\n" |
| + "cname = " + cname + "\n" |
| + "wildcard = " + wildcard + "\n" |
| + "numrange = " + numrange[0] + "," + numrange[1] + "\n"; |
| |
| } |
| |
| @Override |
| public PermissionCollection newPermissionCollection() { |
| return new TVPermissionCollection(); |
| } |
| } |
| |
| final class TVPermissionCollection extends PermissionCollection { |
| |
| /** |
| * The TVPermissions for this set. |
| */ |
| private final ArrayList<TVPermission> permissions = new ArrayList<>(); |
| |
| /** |
| * Adds a permission to the TVPermissions. The key for the hash is the name |
| * in the case of wildcards, or all the IP addresses. |
| * |
| * @param permission the Permission object to add. |
| */ |
| @Override |
| public void add(Permission permission) { |
| if (!(permission instanceof TVPermission)) { |
| throw new IllegalArgumentException("invalid permission: " + permission); |
| } |
| permissions.add((TVPermission) permission); |
| } |
| |
| /** |
| * Check and see if this collection of permissions implies the permissions |
| * expressed in "permission". |
| * |
| * @param p the Permission object to compare |
| * |
| * @return true if "permission" is a proper subset of a permission in the |
| * collection, false if not. |
| */ |
| @Override |
| public boolean implies(Permission p) { |
| if (!(p instanceof TVPermission)) { |
| return false; |
| } |
| |
| Iterator<TVPermission> i = permissions.iterator(); |
| while (i.hasNext()) { |
| if (((TVPermission) i.next()).implies(p)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns an enumeration of all the TVPermission objects in the container. |
| * |
| * @return an enumeration of all the TVPermission objects. |
| */ |
| @Override |
| public Enumeration elements() { |
| return Collections.enumeration(permissions); |
| } |
| |
| } |