All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jdk.dio.DeviceMgmtPermission Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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 jdk.dio;

import java.security.Permission;
import java.security.PermissionCollection;
import java.util.Objects;
import java.util.Vector;

import com.oracle.dio.utils.Utils;
import com.oracle.dio.utils.Utils;
import com.oracle.dio.utils.ExceptionMessage;

/**
 * The {@code DeviceMgmtPermission} class defines permissions for registering and unregistering devices as
 * well as opening devices using their registered configurations.
 * 

* Device management permissions have a target name and actions. *

* The target name is a combination of a device name and of a device ID or range of device IDs. * It takes the following form:

*
* {device-name-spec} [ ":"{device-id-spec} ] *
* where {device-name-spec} and {device-id-spec} are defined as follows: *
*
*
{device-name-spec}
*
* The {device-name-spec} string takes the following form: *
* {device-name} | "*" | "" *
* The {device-name}string is a device name as may be returned by a call to {@link DeviceDescriptor#getName() DeviceDescriptor.getName}. * Occurrences of the semicolon character ({@code ":"}) must be escaped with a backslash ({@code "\"}). *
* A {device-name-spec} specification consisting of the asterisk ("*") matches all device names. * A {device-name-spec} specification consisting of the empty string ("") designates an undefined device name * that may only be matched by an empty string or an asterisk. *
*
{device-id-spec}
*
* The {device-id-spec} string takes the following form: *
* {device-id} | "-"{device-id} | {device-id}"-"[{device-id}] | "*" *
* The {device-id} string is a device ID as may be returned by a call to {@link DeviceDescriptor#getID() DeviceDescriptor.getID}. * The characters in the string must all be decimal digits. *
* A {device-id-spec} specification of the form "N-M" (where N and M are device IDs) designates * a range of device IDs from N (inclusive) to M (inclusive), where M is greater or equal to N. * A {device-id-spec} specification of the form "N-" (where N is a device ID) signifies all device IDs * numbered N and above, while a specification of the form "-N" indicates all device IDs numbered N and below. * A single asterisk in the place of the {device-id-spec} field matches all device IDs. *
* The target name {@code "*:*"} matches all device names and all device IDs as is the target name {@code "*"}. *
*
*
*

* The actions to be granted are passed to the constructor in a string containing a list of one or more comma-separated * keywords. The supported actions are {@code open}, {@code register} and {@code unregister}. Their * meaning is defined as follows:

*
*
*
{@code open}
*
open a device using its device ID or name (see {@link DeviceManager#open(int) DeviceManager.open(id, ...)} * and {@link DeviceManager#open(java.lang.String, java.lang.Class, java.lang.String[]) DeviceManager.open(name, ...)} methods)
*
{@code register}
*
register a new device (see {@link DeviceManager#register DeviceManager.register})
*
{@code unregister}
*
unregister a device (see {@link DeviceManager#unregister DeviceManager.unregister})
*
*
* * @see DeviceManager#open DeviceManager.open * @see DeviceManager#register DeviceManager.register * @see DeviceManager#unregister DeviceManager.unregister * @since 1.0 */ @apimarker.API("device-io_1.1") public class DeviceMgmtPermission extends Permission { /** * The {@code register} action. */ public static final String REGISTER = "register"; /** * The {@code unregister} action. */ public static final String UNREGISTER = "unregister"; /** * The {@code open} action. */ public static final String OPEN = "open"; /** Comma-separated ordered action list */ private String myActions; private String thisName; private int lowID = -1; private int highID = -1; /** * Constructs a new {@code DeviceMgmtPermission} instance with the specified target name and action list. * The target name is normalized so that leading and trailing spaces are removed * and each occurrence of {device-id} is represented in its canonical * decimal representation form (no leading zeros). * * * @param name * the target name (as defined above). * @param actions * comma-separated list of device management operations: {@code register} * {@code unregister} or {@code open}. * @throws NullPointerException * if {@code name} is {@code null}. * @throws IllegalArgumentException *
    *
  • if {@code actions} is {@code null}, empty or contains an action other than the * specified possible actions,
  • *
  • if {@code name} is not properly formatted.
  • *
*/ public DeviceMgmtPermission(String name, String actions) { // null check super(name.toString()); if (null == actions) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.DEVICE_NULL_ACTIONS) ); } checkTargetNameFormat(name); myActions = Utils.verifyAndOrderActions(actions, REGISTER+","+UNREGISTER+","+OPEN); } private void checkTargetNameFormat(String name) { Objects.requireNonNull(name, ExceptionMessage.format(ExceptionMessage.DEVICE_NULL_NAME)); String id; int idx = -1; while (-1 != (idx = name.indexOf(':', idx + 1))) { if (idx == 0 || '\\' != name.charAt(idx - 1) ) { break; } } if (-1 == idx) { thisName = name; id = ""; } else { thisName = name.substring(0, idx); id = name.substring(idx + 1); if ("".equals(id)) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.DEVICE_INVALID_PERMISSION)); } } if ("*".equals(id) || "".equals(id)) { lowID = 0; highID = Integer.MAX_VALUE; } else { idx = -1; boolean foundDash = false; for (int i = 0; i < id.length(); i++) { char c = id.charAt(i); if (!Character.isDigit(c)) { if ('-' == c && !foundDash) { foundDash = true; break; } } } lowID = 0; highID = Integer.MAX_VALUE; try { if (foundDash) { idx = id.indexOf('-'); if (idx > 0) { lowID = Integer.parseInt(id.substring(0, idx)); } if (idx < id.length() - 1) { highID = Integer.parseInt(id.substring(idx + 1)); } if (lowID > highID) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.DEVICE_INVALID_PERMISSION)); } } else { lowID = Integer.parseInt(id); highID = Integer.parseInt(id); } } catch (NumberFormatException e) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.DEVICE_INVALID_PERMISSION)); } } return; } /** * Checks two {@code DeviceMgmtPermission} objects for equality. * Checks that {@code obj}'s class is the same as this object's class and has the * same name (as returned by {@link Permission#getName Permission.getName}) and same actions (sorted as per {@link #getActions getActions}) as this object. * * @param obj * the object to test for equality with this object. * @return {@code true} if {@code obj}'s class is the same as this object's class and has the same target * name and actions as this object; {@code false} otherwise. */ @Override public boolean equals(Object obj) { return DevicePermission.equals(this, obj); } /** * Returns the list of possible actions in the following order: {@code register}, * {@code unregister} or {@code open}. * * @return comma-separated list of possible actions. */ @Override public String getActions() { return myActions; } /** * Returns the hash code value for this object. The hash code is calculated * from this permission's name (as returned by {@link Permission#getName Permission.getName}) and actions (sorted as per {@link #getActions getActions}) * in a way that ensures that {@code permission1.equals(permission2)} implies * that {@code permission1.hashCode()==permission2.hashCode()} for any two permissions, * {@code permission1} and {@code permission2}, as required by the general contract of {@link Object#hashCode Object.hashCode} * and the contract of {@link Permission#hashCode Permission.hashCode}. * * @return a hash code value for this object. */ @Override public int hashCode() { return (getName() + myActions).hashCode(); } /** * Checks if this object "implies" the specified permission. *

* More specifically, this method returns {@code true} if:

*
    *
  • {@code permission}'s class is the same as this object's class, and
  • *
  • {@code permission}'s actions (as returned by {@link #getActions getActions}) are a proper subset of this object's action list, and
  • *
  • {@code permission}'s device name, ID or range thereof * is included in this device name or ID range, whichever is defined. *
* * @param permission * the permission to check against. * * @return {@code true} if the specified permission is not {@code null} and is implied by this * object, {@code false} otherwise. */ @Override public boolean implies(Permission permission) { if ((permission == null) || (permission.getClass() != getClass())) return false; if (!Utils.implies(myActions, permission.getActions())) return false; String thatName = ((DeviceMgmtPermission)permission).thisName; if (!"*".equals(thisName)) { // the empty string ("") designates an undefined peripheral name // that may only be matched by an empty string or an asterisk. // the same condition is for full name. if (!thisName.equals(thatName)) { return false; } } int thatLowID = ((DeviceMgmtPermission)permission).lowID; int thatHightID = ((DeviceMgmtPermission)permission).highID; return (thatLowID >= lowID && thatLowID <= highID && thatHightID >= lowID && thatHightID <= highID); } /** * Returns a new {@code PermissionCollection} for storing {@code DeviceMgmtPermission} objects. *

* {@code DeviceMgmtPermission} objects must be stored in a manner that allows them to be inserted into the * collection in any order, but that also enables the {@link PermissionCollection#implies PermissionCollection.implies} method to be implemented * in an efficient (and consistent) manner. * * @return a new {@code PermissionCollection} suitable for storing {@code DeviceMgmtPermission} objects. */ @Override public PermissionCollection newPermissionCollection() { return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy