3789983e89
Reviewed-by: darcy, ihse
359 lines
9.9 KiB
Java
359 lines
9.9 KiB
Java
/*
|
|
* 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);
|
|
}
|
|
|
|
}
|