Save This Page
Home » openjdk-7 » javax » management » [javadoc | source]
    1   /*
    2    * Copyright 2002-2007 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.management;
   27   
   28   import java.io.IOException;
   29   import java.io.ObjectInputStream;
   30   import java.security.Permission;
   31   
   32   /**
   33    * <p>Permission controlling access to MBeanServer operations.  If a
   34    * security manager has been set using {@link
   35    * System#setSecurityManager}, most operations on the MBean Server
   36    * require that the caller's permissions imply an MBeanPermission
   37    * appropriate for the operation.  This is described in detail in the
   38    * documentation for the {@link MBeanServer} interface.</p>
   39    *
   40    * <p>As with other {@link Permission} objects, an MBeanPermission can
   41    * represent either a permission that you <em>have</em> or a
   42    * permission that you <em>need</em>.  When a sensitive operation is
   43    * being checked for permission, an MBeanPermission is constructed
   44    * representing the permission you need.  The operation is only
   45    * allowed if the permissions you have {@link #implies imply} the
   46    * permission you need.</p>
   47    *
   48    * <p>An MBeanPermission contains four items of information:</p>
   49    *
   50    * <ul>
   51    *
   52    * <li><p>The <em>action</em>.  For a permission you need,
   53    * this is one of the actions in the list <a
   54    * href="#action-list">below</a>.  For a permission you have, this is
   55    * a comma-separated list of those actions, or <code>*</code>,
   56    * representing all actions.</p>
   57    *
   58    * <p>The action is returned by {@link #getActions()}.</p>
   59    *
   60    * <li><p>The <em>class name</em>.</p>
   61    *
   62    * <p>For a permission you need, this is the class name of an MBean
   63    * you are accessing, as returned by {@link
   64    * MBeanServer#getMBeanInfo(ObjectName)
   65    * MBeanServer.getMBeanInfo(name)}.{@link MBeanInfo#getClassName()
   66    * getClassName()}.  Certain operations do not reference a class name,
   67    * in which case the class name is null.</p>
   68    *
   69    * <p>For a permission you have, this is either empty or a <em>class
   70    * name pattern</em>.  A class name pattern is a string following the
   71    * Java conventions for dot-separated class names.  It may end with
   72    * "<code>.*</code>" meaning that the permission grants access to any
   73    * class that begins with the string preceding "<code>.*</code>".  For
   74    * instance, "<code>javax.management.*</code>" grants access to
   75    * <code>javax.management.MBeanServerDelegate</code> and
   76    * <code>javax.management.timer.Timer</code>, among other classes.</p>
   77    *
   78    * <p>A class name pattern can also be empty or the single character
   79    * "<code>*</code>", both of which grant access to any class.</p>
   80    *
   81    * <li><p>The <em>member</em>.</p>
   82    *
   83    * <p>For a permission you need, this is the name of the attribute or
   84    * operation you are accessing.  For operations that do not reference
   85    * an attribute or operation, the member is null.</p>
   86    *
   87    * <p>For a permission you have, this is either the name of an attribute
   88    * or operation you can access, or it is empty or the single character
   89    * "<code>*</code>", both of which grant access to any member.</p>
   90    *
   91    * <li><p>The <em>object name</em>.</p>
   92    *
   93    * <p>For a permission you need, this is the {@link ObjectName} of the
   94    * MBean you are accessing.  For operations that do not reference a
   95    * single MBean, it is null.  It is never an object name pattern.</p>
   96    *
   97    * <p>For a permission you have, this is the {@link ObjectName} of the
   98    * MBean or MBeans you can access.  It may be an object name pattern
   99    * to grant access to all MBeans whose names match the pattern.  It
  100    * may also be empty, which grants access to all MBeans whatever their
  101    * name.</p>
  102    *
  103    * </ul>
  104    *
  105    * <p>If you have an MBeanPermission, it allows operations only if all
  106    * four of the items match.</p>
  107    *
  108    * <p>The class name, member, and object name can be written together
  109    * as a single string, which is the <em>name</em> of this permission.
  110    * The name of the permission is the string returned by {@link
  111    * Permission#getName() getName()}.  The format of the string is:</p>
  112    *
  113    * <blockquote>
  114    * <code>className#member[objectName]</code>
  115    * </blockquote>
  116    *
  117    * <p>The object name is written using the usual syntax for {@link
  118    * ObjectName}.  It may contain any legal characters, including
  119    * <code>]</code>.  It is terminated by a <code>]</code> character
  120    * that is the last character in the string.</p>
  121    *
  122    * <p>One or more of the <code>className</code>, <code>member</code>,
  123    * or <code>objectName</code> may be omitted.  If the
  124    * <code>member</code> is omitted, the <code>#</code> may be too (but
  125    * does not have to be).  If the <code>objectName</code> is omitted,
  126    * the <code>[]</code> may be too (but does not have to be).  It is
  127    * not legal to omit all three items, that is to have a <em>name</em>
  128    * that is the empty string.</p>
  129    *
  130    * <p>One or more of the <code>className</code>, <code>member</code>,
  131    * or <code>objectName</code> may be the character "<code>-</code>",
  132    * which is equivalent to a null value.  A null value is implied by
  133    * any value (including another null value) but does not imply any
  134    * other value.</p>
  135    *
  136    * <p><a name="action-list">The possible actions are these:</a></p>
  137    *
  138    * <ul>
  139    * <li>addNotificationListener</li>
  140    * <li>getAttribute</li>
  141    * <li>getClassLoader</li>
  142    * <li>getClassLoaderFor</li>
  143    * <li>getClassLoaderRepository</li>
  144    * <li>getDomains</li>
  145    * <li>getMBeanInfo</li>
  146    * <li>getObjectInstance</li>
  147    * <li>instantiate</li>
  148    * <li>invoke</li>
  149    * <li>isInstanceOf</li>
  150    * <li>queryMBeans</li>
  151    * <li>queryNames</li>
  152    * <li>registerMBean</li>
  153    * <li>removeNotificationListener</li>
  154    * <li>setAttribute</li>
  155    * <li>unregisterMBean</li>
  156    * </ul>
  157    *
  158    * <p>In a comma-separated list of actions, spaces are allowed before
  159    * and after each action.</p>
  160    *
  161    * @since 1.5
  162    */
  163   public class MBeanPermission extends Permission {
  164   
  165       private static final long serialVersionUID = -2416928705275160661L;
  166   
  167       /**
  168        * Actions list.
  169        */
  170       private static final int AddNotificationListener    = 0x00001;
  171       private static final int GetAttribute               = 0x00002;
  172       private static final int GetClassLoader             = 0x00004;
  173       private static final int GetClassLoaderFor          = 0x00008;
  174       private static final int GetClassLoaderRepository   = 0x00010;
  175       private static final int GetDomains                 = 0x00020;
  176       private static final int GetMBeanInfo               = 0x00040;
  177       private static final int GetObjectInstance          = 0x00080;
  178       private static final int Instantiate                = 0x00100;
  179       private static final int Invoke                     = 0x00200;
  180       private static final int IsInstanceOf               = 0x00400;
  181       private static final int QueryMBeans                = 0x00800;
  182       private static final int QueryNames                 = 0x01000;
  183       private static final int RegisterMBean              = 0x02000;
  184       private static final int RemoveNotificationListener = 0x04000;
  185       private static final int SetAttribute               = 0x08000;
  186       private static final int UnregisterMBean            = 0x10000;
  187   
  188       /**
  189        * No actions.
  190        */
  191       private static final int NONE = 0x00000;
  192   
  193       /**
  194        * All actions.
  195        */
  196       private static final int ALL =
  197           AddNotificationListener    |
  198           GetAttribute               |
  199           GetClassLoader             |
  200           GetClassLoaderFor          |
  201           GetClassLoaderRepository   |
  202           GetDomains                 |
  203           GetMBeanInfo               |
  204           GetObjectInstance          |
  205           Instantiate                |
  206           Invoke                     |
  207           IsInstanceOf               |
  208           QueryMBeans                |
  209           QueryNames                 |
  210           RegisterMBean              |
  211           RemoveNotificationListener |
  212           SetAttribute               |
  213           UnregisterMBean;
  214   
  215       /**
  216        * The actions string.
  217        */
  218       private String actions;
  219   
  220       /**
  221        * The actions mask.
  222        */
  223       private transient int mask;
  224   
  225       /**
  226        * The classname prefix that must match.  If null, is implied by any
  227        * classNamePrefix but does not imply any non-null classNamePrefix.
  228        */
  229       private transient String classNamePrefix;
  230   
  231       /**
  232        * True if classNamePrefix must match exactly.  Otherwise, the
  233        * className being matched must start with classNamePrefix.
  234        */
  235       private transient boolean classNameExactMatch;
  236   
  237       /**
  238        * The member that must match.  If null, is implied by any member
  239        * but does not imply any non-null member.
  240        */
  241       private transient String member;
  242   
  243       /**
  244        * The objectName that must match.  If null, is implied by any
  245        * objectName but does not imply any non-null objectName.
  246        */
  247       private transient ObjectName objectName;
  248   
  249       /**
  250        * Parse <code>actions</code> parameter.
  251        */
  252       private void parseActions() {
  253   
  254           int mask;
  255   
  256           if (actions == null)
  257               throw new IllegalArgumentException("MBeanPermission: " +
  258                                                  "actions can't be null");
  259           if (actions.equals(""))
  260               throw new IllegalArgumentException("MBeanPermission: " +
  261                                                  "actions can't be empty");
  262   
  263           mask = getMask(actions);
  264   
  265           if ((mask & ALL) != mask)
  266               throw new IllegalArgumentException("Invalid actions mask");
  267           if (mask == NONE)
  268               throw new IllegalArgumentException("Invalid actions mask");
  269           this.mask = mask;
  270       }
  271   
  272       /**
  273        * Parse <code>name</code> parameter.
  274        */
  275       private void parseName() {
  276           String name = getName();
  277   
  278           if (name == null)
  279               throw new IllegalArgumentException("MBeanPermission name " +
  280                                                  "cannot be null");
  281   
  282           if (name.equals(""))
  283               throw new IllegalArgumentException("MBeanPermission name " +
  284                                                  "cannot be empty");
  285   
  286           /* The name looks like "class#member[objectname]".  We subtract
  287              elements from the right as we parse, so after parsing the
  288              objectname we have "class#member" and after parsing the
  289              member we have "class".  Each element is optional.  */
  290   
  291           // Parse ObjectName
  292   
  293           int openingBracket = name.indexOf("[");
  294           if (openingBracket == -1) {
  295               // If "[on]" missing then ObjectName("*:*")
  296               //
  297               objectName = ObjectName.WILDCARD;
  298           } else {
  299               if (!name.endsWith("]")) {
  300                   throw new IllegalArgumentException("MBeanPermission: " +
  301                                                      "The ObjectName in the " +
  302                                                      "target name must be " +
  303                                                      "included in square " +
  304                                                      "brackets");
  305               } else {
  306                   // Create ObjectName
  307                   //
  308                   try {
  309                       // If "[]" then ObjectName("*:*")
  310                       //
  311                       String on = name.substring(openingBracket + 1,
  312                                                  name.length() - 1);
  313                       if (on.equals(""))
  314                           objectName = ObjectName.WILDCARD;
  315                       else if (on.equals("-"))
  316                           objectName = null;
  317                       else
  318                           objectName = new ObjectName(on);
  319                   } catch (MalformedObjectNameException e) {
  320                       throw new IllegalArgumentException("MBeanPermission: " +
  321                                                          "The target name does " +
  322                                                          "not specify a valid " +
  323                                                          "ObjectName");
  324                   }
  325               }
  326   
  327               name = name.substring(0, openingBracket);
  328           }
  329   
  330           // Parse member
  331   
  332           int poundSign = name.indexOf("#");
  333   
  334           if (poundSign == -1)
  335               setMember("*");
  336           else {
  337               String memberName = name.substring(poundSign + 1);
  338               setMember(memberName);
  339               name = name.substring(0, poundSign);
  340           }
  341   
  342           // Parse className
  343   
  344           setClassName(name);
  345       }
  346   
  347       /**
  348        * Assign fields based on className, member, and objectName
  349        * parameters.
  350        */
  351       private void initName(String className, String member,
  352                             ObjectName objectName) {
  353           setClassName(className);
  354           setMember(member);
  355           this.objectName = objectName;
  356       }
  357   
  358       private void setClassName(String className) {
  359           if (className == null || className.equals("-")) {
  360               classNamePrefix = null;
  361               classNameExactMatch = false;
  362           } else if (className.equals("") || className.equals("*")) {
  363               classNamePrefix = "";
  364               classNameExactMatch = false;
  365           } else if (className.endsWith(".*")) {
  366               // Note that we include the "." in the required prefix
  367               classNamePrefix = className.substring(0, className.length() - 1);
  368               classNameExactMatch = false;
  369           } else {
  370               classNamePrefix = className;
  371               classNameExactMatch = true;
  372           }
  373       }
  374   
  375       private void setMember(String member) {
  376           if (member == null || member.equals("-"))
  377               this.member = null;
  378           else if (member.equals(""))
  379               this.member = "*";
  380           else
  381               this.member = member;
  382       }
  383   
  384       /**
  385        * <p>Create a new MBeanPermission object with the specified target name
  386        * and actions.</p>
  387        *
  388        * <p>The target name is of the form
  389        * "<code>className#member[objectName]</code>" where each part is
  390        * optional.  It must not be empty or null.</p>
  391        *
  392        * <p>The actions parameter contains a comma-separated list of the
  393        * desired actions granted on the target name.  It must not be
  394        * empty or null.</p>
  395        *
  396        * @param name the triplet "className#member[objectName]".
  397        * @param actions the action string.
  398        *
  399        * @exception IllegalArgumentException if the <code>name</code> or
  400        * <code>actions</code> is invalid.
  401        */
  402       public MBeanPermission(String name, String actions) {
  403           super(name);
  404   
  405           parseName();
  406   
  407           this.actions = actions;
  408           parseActions();
  409       }
  410   
  411       /**
  412        * <p>Create a new MBeanPermission object with the specified target name
  413        * (class name, member, object name) and actions.</p>
  414        *
  415        * <p>The class name, member and object name parameters define a
  416        * target name of the form
  417        * "<code>className#member[objectName]</code>" where each part is
  418        * optional.  This will be the result of {@link #getName()} on the
  419        * resultant MBeanPermission.</p>
  420        *
  421        * <p>The actions parameter contains a comma-separated list of the
  422        * desired actions granted on the target name.  It must not be
  423        * empty or null.</p>
  424        *
  425        * @param className the class name to which this permission applies.
  426        * May be null or <code>"-"</code>, which represents a class name
  427        * that is implied by any class name but does not imply any other
  428        * class name.
  429        * @param member the member to which this permission applies.  May
  430        * be null or <code>"-"</code>, which represents a member that is
  431        * implied by any member but does not imply any other member.
  432        * @param objectName the object name to which this permission
  433        * applies.  May be null, which represents an object name that is
  434        * implied by any object name but does not imply any other object
  435        * name.
  436        * @param actions the action string.
  437        */
  438       public MBeanPermission(String className,
  439                              String member,
  440                              ObjectName objectName,
  441                              String actions) {
  442   
  443           super(makeName(className, member, objectName));
  444           initName(className, member, objectName);
  445   
  446           this.actions = actions;
  447           parseActions();
  448       }
  449   
  450       private static String makeName(String className, String member,
  451                                      ObjectName objectName) {
  452           final StringBuilder name = new StringBuilder();
  453           if (className == null)
  454               className = "-";
  455           name.append(className);
  456           if (member == null)
  457               member = "-";
  458           name.append("#" + member);
  459           if (objectName == null)
  460               name.append("[-]");
  461           else
  462               name.append("[").append(objectName.getCanonicalName()).append("]");
  463   
  464           /* In the interests of legibility for Permission.toString(), we
  465              transform the empty string into "*".  */
  466           if (name.length() == 0)
  467               return "*";
  468           else
  469               return name.toString();
  470       }
  471   
  472       /**
  473        * Returns the "canonical string representation" of the actions. That is,
  474        * this method always returns present actions in alphabetical order.
  475        *
  476        * @return the canonical string representation of the actions.
  477        */
  478       public String getActions() {
  479   
  480           if (actions == null)
  481               actions = getActions(this.mask);
  482   
  483           return actions;
  484       }
  485   
  486       /**
  487        * Returns the "canonical string representation"
  488        * of the actions from the mask.
  489        */
  490       private static String getActions(int mask) {
  491           final StringBuilder sb = new StringBuilder();
  492           boolean comma = false;
  493   
  494           if ((mask & AddNotificationListener) == AddNotificationListener) {
  495               comma = true;
  496               sb.append("addNotificationListener");
  497           }
  498   
  499           if ((mask & GetAttribute) == GetAttribute) {
  500               if (comma) sb.append(',');
  501               else comma = true;
  502               sb.append("getAttribute");
  503           }
  504   
  505           if ((mask & GetClassLoader) == GetClassLoader) {
  506               if (comma) sb.append(',');
  507               else comma = true;
  508               sb.append("getClassLoader");
  509           }
  510   
  511           if ((mask & GetClassLoaderFor) == GetClassLoaderFor) {
  512               if (comma) sb.append(',');
  513               else comma = true;
  514               sb.append("getClassLoaderFor");
  515           }
  516   
  517           if ((mask & GetClassLoaderRepository) == GetClassLoaderRepository) {
  518               if (comma) sb.append(',');
  519               else comma = true;
  520               sb.append("getClassLoaderRepository");
  521           }
  522   
  523           if ((mask & GetDomains) == GetDomains) {
  524               if (comma) sb.append(',');
  525               else comma = true;
  526               sb.append("getDomains");
  527           }
  528   
  529           if ((mask & GetMBeanInfo) == GetMBeanInfo) {
  530               if (comma) sb.append(',');
  531               else comma = true;
  532               sb.append("getMBeanInfo");
  533           }
  534   
  535           if ((mask & GetObjectInstance) == GetObjectInstance) {
  536               if (comma) sb.append(',');
  537               else comma = true;
  538               sb.append("getObjectInstance");
  539           }
  540   
  541           if ((mask & Instantiate) == Instantiate) {
  542               if (comma) sb.append(',');
  543               else comma = true;
  544               sb.append("instantiate");
  545           }
  546   
  547           if ((mask & Invoke) == Invoke) {
  548               if (comma) sb.append(',');
  549               else comma = true;
  550               sb.append("invoke");
  551           }
  552   
  553           if ((mask & IsInstanceOf) == IsInstanceOf) {
  554               if (comma) sb.append(',');
  555               else comma = true;
  556               sb.append("isInstanceOf");
  557           }
  558   
  559           if ((mask & QueryMBeans) == QueryMBeans) {
  560               if (comma) sb.append(',');
  561               else comma = true;
  562               sb.append("queryMBeans");
  563           }
  564   
  565           if ((mask & QueryNames) == QueryNames) {
  566               if (comma) sb.append(',');
  567               else comma = true;
  568               sb.append("queryNames");
  569           }
  570   
  571           if ((mask & RegisterMBean) == RegisterMBean) {
  572               if (comma) sb.append(',');
  573               else comma = true;
  574               sb.append("registerMBean");
  575           }
  576   
  577           if ((mask & RemoveNotificationListener) == RemoveNotificationListener) {
  578               if (comma) sb.append(',');
  579               else comma = true;
  580               sb.append("removeNotificationListener");
  581           }
  582   
  583           if ((mask & SetAttribute) == SetAttribute) {
  584               if (comma) sb.append(',');
  585               else comma = true;
  586               sb.append("setAttribute");
  587           }
  588   
  589           if ((mask & UnregisterMBean) == UnregisterMBean) {
  590               if (comma) sb.append(',');
  591               else comma = true;
  592               sb.append("unregisterMBean");
  593           }
  594   
  595           return sb.toString();
  596       }
  597   
  598       /**
  599        * Returns the hash code value for this object.
  600        *
  601        * @return a hash code value for this object.
  602        */
  603       public int hashCode() {
  604           return this.getName().hashCode() + this.getActions().hashCode();
  605       }
  606   
  607       /**
  608        * Converts an action String to an integer action mask.
  609        *
  610        * @param action the action string.
  611        * @return the action mask.
  612        */
  613       private static int getMask(String action) {
  614   
  615           /*
  616            * BE CAREFUL HERE! PARSING ORDER IS IMPORTANT IN THIS ALGORITHM.
  617            *
  618            * The 'string length' test must be performed for the lengthiest
  619            * strings first.
  620            *
  621            * In this permission if the "unregisterMBean" string length test is
  622            * performed after the "registerMBean" string length test the algorithm
  623            * considers the 'unregisterMBean' action as being the 'registerMBean'
  624            * action and a parsing error is returned.
  625            */
  626   
  627           int mask = NONE;
  628   
  629           if (action == null) {
  630               return mask;
  631           }
  632   
  633           if (action.equals("*")) {
  634               return ALL;
  635           }
  636   
  637           char[] a = action.toCharArray();
  638   
  639           int i = a.length - 1;
  640           if (i < 0)
  641               return mask;
  642   
  643           while (i != -1) {
  644               char c;
  645   
  646               // skip whitespace
  647               while ((i!=-1) && ((c = a[i]) == ' ' ||
  648                                  c == '\r' ||
  649                                  c == '\n' ||
  650                                  c == '\f' ||
  651                                  c == '\t'))
  652                   i--;
  653   
  654               // check for the known strings
  655               int matchlen;
  656   
  657               if (i >= 25 && /* removeNotificationListener */
  658                   (a[i-25] == 'r') &&
  659                   (a[i-24] == 'e') &&
  660                   (a[i-23] == 'm') &&
  661                   (a[i-22] == 'o') &&
  662                   (a[i-21] == 'v') &&
  663                   (a[i-20] == 'e') &&
  664                   (a[i-19] == 'N') &&
  665                   (a[i-18] == 'o') &&
  666                   (a[i-17] == 't') &&
  667                   (a[i-16] == 'i') &&
  668                   (a[i-15] == 'f') &&
  669                   (a[i-14] == 'i') &&
  670                   (a[i-13] == 'c') &&
  671                   (a[i-12] == 'a') &&
  672                   (a[i-11] == 't') &&
  673                   (a[i-10] == 'i') &&
  674                   (a[i-9] == 'o') &&
  675                   (a[i-8] == 'n') &&
  676                   (a[i-7] == 'L') &&
  677                   (a[i-6] == 'i') &&
  678                   (a[i-5] == 's') &&
  679                   (a[i-4] == 't') &&
  680                   (a[i-3] == 'e') &&
  681                   (a[i-2] == 'n') &&
  682                   (a[i-1] == 'e') &&
  683                   (a[i] == 'r')) {
  684                   matchlen = 26;
  685                   mask |= RemoveNotificationListener;
  686               } else if (i >= 23 && /* getClassLoaderRepository */
  687                          (a[i-23] == 'g') &&
  688                          (a[i-22] == 'e') &&
  689                          (a[i-21] == 't') &&
  690                          (a[i-20] == 'C') &&
  691                          (a[i-19] == 'l') &&
  692                          (a[i-18] == 'a') &&
  693                          (a[i-17] == 's') &&
  694                          (a[i-16] == 's') &&
  695                          (a[i-15] == 'L') &&
  696                          (a[i-14] == 'o') &&
  697                          (a[i-13] == 'a') &&
  698                          (a[i-12] == 'd') &&
  699                          (a[i-11] == 'e') &&
  700                          (a[i-10] == 'r') &&
  701                          (a[i-9] == 'R') &&
  702                          (a[i-8] == 'e') &&
  703                          (a[i-7] == 'p') &&
  704                          (a[i-6] == 'o') &&
  705                          (a[i-5] == 's') &&
  706                          (a[i-4] == 'i') &&
  707                          (a[i-3] == 't') &&
  708                          (a[i-2] == 'o') &&
  709                          (a[i-1] == 'r') &&
  710                          (a[i] == 'y')) {
  711                   matchlen = 24;
  712                   mask |= GetClassLoaderRepository;
  713               } else if (i >= 22 && /* addNotificationListener */
  714                          (a[i-22] == 'a') &&
  715                          (a[i-21] == 'd') &&
  716                          (a[i-20] == 'd') &&
  717                          (a[i-19] == 'N') &&
  718                          (a[i-18] == 'o') &&
  719                          (a[i-17] == 't') &&
  720                          (a[i-16] == 'i') &&
  721                          (a[i-15] == 'f') &&
  722                          (a[i-14] == 'i') &&
  723                          (a[i-13] == 'c') &&
  724                          (a[i-12] == 'a') &&
  725                          (a[i-11] == 't') &&
  726                          (a[i-10] == 'i') &&
  727                          (a[i-9] == 'o') &&
  728                          (a[i-8] == 'n') &&
  729                          (a[i-7] == 'L') &&
  730                          (a[i-6] == 'i') &&
  731                          (a[i-5] == 's') &&
  732                          (a[i-4] == 't') &&
  733                          (a[i-3] == 'e') &&
  734                          (a[i-2] == 'n') &&
  735                          (a[i-1] == 'e') &&
  736                          (a[i] == 'r')) {
  737                   matchlen = 23;
  738                   mask |= AddNotificationListener;
  739               } else if (i >= 16 && /* getClassLoaderFor */
  740                          (a[i-16] == 'g') &&
  741                          (a[i-15] == 'e') &&
  742                          (a[i-14] == 't') &&
  743                          (a[i-13] == 'C') &&
  744                          (a[i-12] == 'l') &&
  745                          (a[i-11] == 'a') &&
  746                          (a[i-10] == 's') &&
  747                          (a[i-9] == 's') &&
  748                          (a[i-8] == 'L') &&
  749                          (a[i-7] == 'o') &&
  750                          (a[i-6] == 'a') &&
  751                          (a[i-5] == 'd') &&
  752                          (a[i-4] == 'e') &&
  753                          (a[i-3] == 'r') &&
  754                          (a[i-2] == 'F') &&
  755                          (a[i-1] == 'o') &&
  756                          (a[i] == 'r')) {
  757                   matchlen = 17;
  758                   mask |= GetClassLoaderFor;
  759               } else if (i >= 16 && /* getObjectInstance */
  760                          (a[i-16] == 'g') &&
  761                          (a[i-15] == 'e') &&
  762                          (a[i-14] == 't') &&
  763                          (a[i-13] == 'O') &&
  764                          (a[i-12] == 'b') &&
  765                          (a[i-11] == 'j') &&
  766                          (a[i-10] == 'e') &&
  767                          (a[i-9] == 'c') &&
  768                          (a[i-8] == 't') &&
  769                          (a[i-7] == 'I') &&
  770                          (a[i-6] == 'n') &&
  771                          (a[i-5] == 's') &&
  772                          (a[i-4] == 't') &&
  773                          (a[i-3] == 'a') &&
  774                          (a[i-2] == 'n') &&
  775                          (a[i-1] == 'c') &&
  776                          (a[i] == 'e')) {
  777                   matchlen = 17;
  778                   mask |= GetObjectInstance;
  779               } else if (i >= 14 && /* unregisterMBean */
  780                          (a[i-14] == 'u') &&
  781                          (a[i-13] == 'n') &&
  782                          (a[i-12] == 'r') &&
  783                          (a[i-11] == 'e') &&
  784                          (a[i-10] == 'g') &&
  785                          (a[i-9] == 'i') &&
  786                          (a[i-8] == 's') &&
  787                          (a[i-7] == 't') &&
  788                          (a[i-6] == 'e') &&
  789                          (a[i-5] == 'r') &&
  790                          (a[i-4] == 'M') &&
  791                          (a[i-3] == 'B') &&
  792                          (a[i-2] == 'e') &&
  793                          (a[i-1] == 'a') &&
  794                          (a[i] == 'n')) {
  795                   matchlen = 15;
  796                   mask |= UnregisterMBean;
  797               } else if (i >= 13 && /* getClassLoader */
  798                          (a[i-13] == 'g') &&
  799                          (a[i-12] == 'e') &&
  800                          (a[i-11] == 't') &&
  801                          (a[i-10] == 'C') &&
  802                          (a[i-9] == 'l') &&
  803                          (a[i-8] == 'a') &&
  804                          (a[i-7] == 's') &&
  805                          (a[i-6] == 's') &&
  806                          (a[i-5] == 'L') &&
  807                          (a[i-4] == 'o') &&
  808                          (a[i-3] == 'a') &&
  809                          (a[i-2] == 'd') &&
  810                          (a[i-1] == 'e') &&
  811                          (a[i] == 'r')) {
  812                   matchlen = 14;
  813                   mask |= GetClassLoader;
  814               } else if (i >= 12 && /* registerMBean */
  815                          (a[i-12] == 'r') &&
  816                          (a[i-11] == 'e') &&
  817                          (a[i-10] == 'g') &&
  818                          (a[i-9] == 'i') &&
  819                          (a[i-8] == 's') &&
  820                          (a[i-7] == 't') &&
  821                          (a[i-6] == 'e') &&
  822                          (a[i-5] == 'r') &&
  823                          (a[i-4] == 'M') &&
  824                          (a[i-3] == 'B') &&
  825                          (a[i-2] == 'e') &&
  826                          (a[i-1] == 'a') &&
  827                          (a[i] == 'n')) {
  828                   matchlen = 13;
  829                   mask |= RegisterMBean;
  830               } else if (i >= 11 && /* getAttribute */
  831                          (a[i-11] == 'g') &&
  832                          (a[i-10] == 'e') &&
  833                          (a[i-9] == 't') &&
  834                          (a[i-8] == 'A') &&
  835                          (a[i-7] == 't') &&
  836                          (a[i-6] == 't') &&
  837                          (a[i-5] == 'r') &&
  838                          (a[i-4] == 'i') &&
  839                          (a[i-3] == 'b') &&
  840                          (a[i-2] == 'u') &&
  841                          (a[i-1] == 't') &&
  842                          (a[i] == 'e')) {
  843                   matchlen = 12;
  844                   mask |= GetAttribute;
  845               } else if (i >= 11 && /* getMBeanInfo */
  846                          (a[i-11] == 'g') &&
  847                          (a[i-10] == 'e') &&
  848                          (a[i-9] == 't') &&
  849                          (a[i-8] == 'M') &&
  850                          (a[i-7] == 'B') &&
  851                          (a[i-6] == 'e') &&
  852                          (a[i-5] == 'a') &&
  853                          (a[i-4] == 'n') &&
  854                          (a[i-3] == 'I') &&
  855                          (a[i-2] == 'n') &&
  856                          (a[i-1] == 'f') &&
  857                          (a[i] == 'o')) {
  858                   matchlen = 12;
  859                   mask |= GetMBeanInfo;
  860               } else if (i >= 11 && /* isInstanceOf */
  861                          (a[i-11] == 'i') &&
  862                          (a[i-10] == 's') &&
  863                          (a[i-9] == 'I') &&
  864                          (a[i-8] == 'n') &&
  865                          (a[i-7] == 's') &&
  866                          (a[i-6] == 't') &&
  867                          (a[i-5] == 'a') &&
  868                          (a[i-4] == 'n') &&
  869                          (a[i-3] == 'c') &&
  870                          (a[i-2] == 'e') &&
  871                          (a[i-1] == 'O') &&
  872                          (a[i] == 'f')) {
  873                   matchlen = 12;
  874                   mask |= IsInstanceOf;
  875               } else if (i >= 11 && /* setAttribute */
  876                          (a[i-11] == 's') &&
  877                          (a[i-10] == 'e') &&
  878                          (a[i-9] == 't') &&
  879                          (a[i-8] == 'A') &&
  880                          (a[i-7] == 't') &&
  881                          (a[i-6] == 't') &&
  882                          (a[i-5] == 'r') &&
  883                          (a[i-4] == 'i') &&
  884                          (a[i-3] == 'b') &&
  885                          (a[i-2] == 'u') &&
  886                          (a[i-1] == 't') &&
  887                          (a[i] == 'e')) {
  888                   matchlen = 12;
  889                   mask |= SetAttribute;
  890               } else if (i >= 10 && /* instantiate */
  891                          (a[i-10] == 'i') &&
  892                          (a[i-9] == 'n') &&
  893                          (a[i-8] == 's') &&
  894                          (a[i-7] == 't') &&
  895                          (a[i-6] == 'a') &&
  896                          (a[i-5] == 'n') &&
  897                          (a[i-4] == 't') &&
  898                          (a[i-3] == 'i') &&
  899                          (a[i-2] == 'a') &&
  900                          (a[i-1] == 't') &&
  901                          (a[i] == 'e')) {
  902                   matchlen = 11;
  903                   mask |= Instantiate;
  904               } else if (i >= 10 && /* queryMBeans */
  905                          (a[i-10] == 'q') &&
  906                          (a[i-9] == 'u') &&
  907                          (a[i-8] == 'e') &&
  908                          (a[i-7] == 'r') &&
  909                          (a[i-6] == 'y') &&
  910                          (a[i-5] == 'M') &&
  911                          (a[i-4] == 'B') &&
  912                          (a[i-3] == 'e') &&
  913                          (a[i-2] == 'a') &&
  914                          (a[i-1] == 'n') &&
  915                          (a[i] == 's')) {
  916                   matchlen = 11;
  917                   mask |= QueryMBeans;
  918               } else if (i >= 9 && /* getDomains */
  919                          (a[i-9] == 'g') &&
  920                          (a[i-8] == 'e') &&
  921                          (a[i-7] == 't') &&
  922                          (a[i-6] == 'D') &&
  923                          (a[i-5] == 'o') &&
  924                          (a[i-4] == 'm') &&
  925                          (a[i-3] == 'a') &&
  926                          (a[i-2] == 'i') &&
  927                          (a[i-1] == 'n') &&
  928                          (a[i] == 's')) {
  929                   matchlen = 10;
  930                   mask |= GetDomains;
  931               } else if (i >= 9 && /* queryNames */
  932                          (a[i-9] == 'q') &&
  933                          (a[i-8] == 'u') &&
  934                          (a[i-7] == 'e') &&
  935                          (a[i-6] == 'r') &&
  936                          (a[i-5] == 'y') &&
  937                          (a[i-4] == 'N') &&
  938                          (a[i-3] == 'a') &&
  939                          (a[i-2] == 'm') &&
  940                          (a[i-1] == 'e') &&
  941                          (a[i] == 's')) {
  942                   matchlen = 10;
  943                   mask |= QueryNames;
  944               } else if (i >= 5 && /* invoke */
  945                          (a[i-5] == 'i') &&
  946                          (a[i-4] == 'n') &&
  947                          (a[i-3] == 'v') &&
  948                          (a[i-2] == 'o') &&
  949                          (a[i-1] == 'k') &&
  950                          (a[i] == 'e')) {
  951                   matchlen = 6;
  952                   mask |= Invoke;
  953               } else {
  954                   // parse error
  955                   throw new IllegalArgumentException("Invalid permission: " +
  956                                                      action);
  957               }
  958   
  959               // make sure we didn't just match the tail of a word
  960               // like "ackbarfaccept".  Also, skip to the comma.
  961               boolean seencomma = false;
  962               while (i >= matchlen && !seencomma) {
  963                   switch(a[i-matchlen]) {
  964                   case ',':
  965                       seencomma = true;
  966                       break;
  967                   case ' ': case '\r': case '\n':
  968                   case '\f': case '\t':
  969                       break;
  970                   default:
  971                       throw new IllegalArgumentException("Invalid permission: " +
  972                                                          action);
  973                   }
  974                   i--;
  975               }
  976   
  977               // point i at the location of the comma minus one (or -1).
  978               i -= matchlen;
  979           }
  980   
  981           return mask;
  982       }
  983   
  984       /**
  985        * <p>Checks if this MBeanPermission object "implies" the
  986        * specified permission.</p>
  987        *
  988        * <p>More specifically, this method returns true if:</p>
  989        *
  990        * <ul>
  991        *
  992        * <li> <i>p</i> is an instance of MBeanPermission; and</li>
  993        *
  994        * <li> <i>p</i> has a null className or <i>p</i>'s className
  995        * matches this object's className; and</li>
  996        *
  997        * <li> <i>p</i> has a null member or <i>p</i>'s member matches this
  998        * object's member; and</li>
  999        *
 1000        * <li> <i>p</i> has a null object name or <i>p</i>'s
 1001        * object name matches this object's object name; and</li>
 1002        *
 1003        * <li> <i>p</i>'s actions are a subset of this object's actions</li>
 1004        *
 1005        * </ul>
 1006        *
 1007        * <p>If this object's className is "<code>*</code>", <i>p</i>'s
 1008        * className always matches it.  If it is "<code>a.*</code>", <i>p</i>'s
 1009        * className matches it if it begins with "<code>a.</code>".</p>
 1010        *
 1011        * <p>If this object's member is "<code>*</code>", <i>p</i>'s
 1012        * member always matches it.</p>
 1013        *
 1014        * <p>If this object's objectName <i>n1</i> is an object name pattern,
 1015        * <i>p</i>'s objectName <i>n2</i> matches it if
 1016        * {@link ObjectName#equals <i>n1</i>.equals(<i>n2</i>)} or if
 1017        * {@link ObjectName#apply <i>n1</i>.apply(<i>n2</i>)}.</p>
 1018        *
 1019        * <p>A permission that includes the <code>queryMBeans</code> action
 1020        * is considered to include <code>queryNames</code> as well.</p>
 1021        *
 1022        * @param p the permission to check against.
 1023        * @return true if the specified permission is implied by this object,
 1024        * false if not.
 1025        */
 1026       public boolean implies(Permission p) {
 1027           if (!(p instanceof MBeanPermission))
 1028               return false;
 1029   
 1030           MBeanPermission that = (MBeanPermission) p;
 1031   
 1032           // Actions
 1033           //
 1034           // The actions in 'this' permission must be a
 1035           // superset of the actions in 'that' permission
 1036           //
 1037   
 1038           /* "queryMBeans" implies "queryNames" */
 1039           if ((this.mask & QueryMBeans) == QueryMBeans) {
 1040               if (((this.mask | QueryNames) & that.mask) != that.mask) {
 1041                   //System.out.println("action [with QueryNames] does not imply");
 1042                   return false;
 1043               }
 1044           } else {
 1045               if ((this.mask & that.mask) != that.mask) {
 1046                   //System.out.println("action does not imply");
 1047                   return false;
 1048               }
 1049           }
 1050   
 1051           // Target name
 1052           //
 1053           // The 'className' check is true iff:
 1054           // 1) the className in 'this' permission is omitted or "*", or
 1055           // 2) the className in 'that' permission is omitted or "*", or
 1056           // 3) the className in 'this' permission does pattern
 1057           //    matching with the className in 'that' permission.
 1058           //
 1059           // The 'member' check is true iff:
 1060           // 1) the member in 'this' permission is omitted or "*", or
 1061           // 2) the member in 'that' permission is omitted or "*", or
 1062           // 3) the member in 'this' permission equals the member in
 1063           //    'that' permission.
 1064           //
 1065           // The 'object name' check is true iff:
 1066           // 1) the object name in 'this' permission is omitted or "*:*", or
 1067           // 2) the object name in 'that' permission is omitted or "*:*", or
 1068           // 3) the object name in 'this' permission does pattern
 1069           //    matching with the object name in 'that' permission.
 1070           //
 1071   
 1072           /* Check if this.className implies that.className.
 1073   
 1074              If that.classNamePrefix is empty that means the className is
 1075              irrelevant for this permission check.  Otherwise, we do not
 1076              expect that "that" contains a wildcard, since it is a
 1077              needed permission.  So we assume that.classNameExactMatch.  */
 1078   
 1079           if (that.classNamePrefix == null) {
 1080               // bottom is implied
 1081           } else if (this.classNamePrefix == null) {
 1082               // bottom implies nothing but itself
 1083               return false;
 1084           } else if (this.classNameExactMatch) {
 1085               if (!that.classNameExactMatch)
 1086                   return false; // exact never implies wildcard
 1087               if (!that.classNamePrefix.equals(this.classNamePrefix))
 1088                   return false; // exact match fails
 1089           } else {
 1090               // prefix match, works even if "that" is also a wildcard
 1091               // e.g. a.* implies a.* and a.b.*
 1092               if (!that.classNamePrefix.startsWith(this.classNamePrefix))
 1093                   return false;
 1094           }
 1095   
 1096           /* Check if this.member implies that.member */
 1097   
 1098           if (that.member == null) {
 1099               // bottom is implied
 1100           } else if (this.member == null) {
 1101               // bottom implies nothing but itself
 1102               return false;
 1103           } else if (this.member.equals("*")) {
 1104               // wildcard implies everything (including itself)
 1105           } else if (!this.member.equals(that.member)) {
 1106               return false;
 1107           }
 1108   
 1109           /* Check if this.objectName implies that.objectName */
 1110   
 1111           if (that.objectName == null) {
 1112               // bottom is implied
 1113           } else if (this.objectName == null) {
 1114               // bottom implies nothing but itself
 1115               return false;
 1116           } else if (!this.objectName.apply(that.objectName)) {
 1117               /* ObjectName.apply returns false if that.objectName is a
 1118                  wildcard so we also allow equals for that case.  This
 1119                  never happens during real permission checks, but means
 1120                  the implies relation is reflexive.  */
 1121               if (!this.objectName.equals(that.objectName))
 1122                   return false;
 1123           }
 1124   
 1125           return true;
 1126       }
 1127   
 1128       /**
 1129        * Checks two MBeanPermission objects for equality. Checks
 1130        * that <i>obj</i> is an MBeanPermission, and has the same
 1131        * name and actions as this object.
 1132        * <P>
 1133        * @param obj the object we are testing for equality with this object.
 1134        * @return true if obj is an MBeanPermission, and has the
 1135        * same name and actions as this MBeanPermission object.
 1136        */
 1137       public boolean equals(Object obj) {
 1138           if (obj == this)
 1139               return true;
 1140   
 1141           if (! (obj instanceof MBeanPermission))
 1142               return false;
 1143   
 1144           MBeanPermission that = (MBeanPermission) obj;
 1145   
 1146           return (this.mask == that.mask) &&
 1147               (this.getName().equals(that.getName()));
 1148       }
 1149   
 1150       /**
 1151        * Deserialize this object based on its name and actions.
 1152        */
 1153       private void readObject(ObjectInputStream in)
 1154               throws IOException, ClassNotFoundException {
 1155           in.defaultReadObject();
 1156           parseName();
 1157           parseActions();
 1158       }
 1159   }

Save This Page
Home » openjdk-7 » javax » management » [javadoc | source]