KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > MBeanPermission


1 /*
2  * @(#)MBeanPermission.java 1.22 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management;
9
10 import java.security.Permission JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.ObjectInputStream JavaDoc;
13
14 /**
15  * <p>Permission controlling access to MBeanServer operations. If a
16  * security manager has been set using {@link
17  * System#setSecurityManager}, most operations on the MBean Server
18  * require that the caller's permissions imply an MBeanPermission
19  * appropriate for the operation. This is described in detail in the
20  * documentation for the {@link MBeanServer} interface.</p>
21  *
22  * <p>As with other {@link Permission} objects, an MBeanPermission can
23  * represent either a permission that you <em>have</em> or a
24  * permission that you <em>need</em>. When a sensitive operation is
25  * being checked for permission, an MBeanPermission is constructed
26  * representing the permission you need. The operation is only
27  * allowed if the permissions you have {@link #implies imply} the
28  * permission you need.</p>
29  *
30  * <p>An MBeanPermission contains four items of information:</p>
31  *
32  * <ul>
33  *
34  * <li><p>The <em>action</em>. For a permission you need,
35  * this is one of the actions in the list <a
36  * HREF="#action-list">below</a>. For a permission you have, this is
37  * a comma-separated list of those actions, or <code>*</code>,
38  * representing all actions.</p>
39  *
40  * <p>The action is returned by {@link #getActions()}.</p>
41  *
42  * <li><p>The <em>class name</em>.</p>
43  *
44  * <p>For a permission you need, this is the class name of an MBean
45  * you are accessing, as returned by {@link
46  * MBeanServer#getMBeanInfo(ObjectName)
47  * MBeanServer.getMBeanInfo(name)}.{@link MBeanInfo#getClassName()
48  * getClassName()}. Certain operations do not reference a class name,
49  * in which case the class name is null.</p>
50  *
51  * <p>For a permission you have, this is either empty or a <em>class
52  * name pattern</em>. A class name pattern is a string following the
53  * Java conventions for dot-separated class names. It may end with
54  * "<code>.*</code>" meaning that the permission grants access to any
55  * class that begins with the string preceding "<code>.*</code>". For
56  * instance, "<code>javax.management.*</code>" grants access to
57  * <code>javax.management.MBeanServerDelegate</code> and
58  * <code>javax.management.timer.Timer</code>, among other classes.</p>
59  *
60  * <p>A class name pattern can also be empty or the single character
61  * "<code>*</code>", both of which grant access to any class.</p>
62  *
63  * <li><p>The <em>member</em>.</p>
64  *
65  * <p>For a permission you need, this is the name of the attribute or
66  * operation you are accessing. For operations that do not reference
67  * an attribute or operation, the member is null.</p>
68  *
69  * <p>For a permission you have, this is either the name of an attribute
70  * or operation you can access, or it is empty or the single character
71  * "<code>*</code>", both of which grant access to any member.</p>
72  *
73  * <li><p>The <em>object name</em>.</p>
74  *
75  * <p>For a permission you need, this is the {@link ObjectName} of the
76  * MBean you are accessing. For operations that do not reference a
77  * single MBean, it is null. It is never an object name pattern.</p>
78  *
79  * <p>For a permission you have, this is the {@link ObjectName} of the
80  * MBean or MBeans you can access. It may be an object name pattern
81  * to grant access to all MBeans whose names match the pattern. It
82  * may also be empty, which grants access to all MBeans whatever their
83  * name.</p>
84  *
85  * </ul>
86  *
87  * <p>If you have an MBeanPermission, it allows operations only if all
88  * four of the items match.</p>
89  *
90  * <p>The class name, member, and object name can be written together
91  * as a single string, which is the <em>name</em> of this permission.
92  * The name of the permission is the string returned by {@link
93  * Permission#getName() getName()}. The format of the string is:</p>
94  *
95  * <blockquote>
96  * <code>className#member[objectName]</code>
97  * </blockquote>
98  *
99  * <p>The object name is written using the usual syntax for {@link
100  * ObjectName}. It may contain any legal characters, including
101  * <code>]</code>. It is terminated by a <code>]</code> character
102  * that is the last character in the string.</p>
103  *
104  * <p>One or more of the <code>className</code>, <code>member</code>,
105  * or <code>objectName</code> may be omitted. If the
106  * <code>member</code> is omitted, the <code>#</code> may be too (but
107  * does not have to be). If the <code>objectName</code> is omitted,
108  * the <code>[]</code> may be too (but does not have to be). It is
109  * not legal to omit all three items, that is to have a <em>name</em>
110  * that is the empty string.</p>
111  *
112  * <p>One or more of the <code>className</code>, <code>member</code>,
113  * or <code>objectName</code> may be the character "<code>-</code>",
114  * which is equivalent to a null value. A null value is implied by
115  * any value (including another null value) but does not imply any
116  * other value.</p>
117  *
118  * <p><a name="action-list">The possible actions are these:</a></p>
119  *
120  * <ul>
121  * <li>addNotificationListener</li>
122  * <li>getAttribute</li>
123  * <li>getClassLoader</li>
124  * <li>getClassLoaderFor</li>
125  * <li>getClassLoaderRepository</li>
126  * <li>getDomains</li>
127  * <li>getMBeanInfo</li>
128  * <li>getObjectInstance</li>
129  * <li>instantiate</li>
130  * <li>invoke</li>
131  * <li>isInstanceOf</li>
132  * <li>queryMBeans</li>
133  * <li>queryNames</li>
134  * <li>registerMBean</li>
135  * <li>removeNotificationListener</li>
136  * <li>setAttribute</li>
137  * <li>unregisterMBean</li>
138  * </ul>
139  *
140  * <p>In a comma-separated list of actions, spaces are allowed before
141  * and after each action.</p>
142  *
143  * @since 1.5
144  * @since.unbundled JMX 1.2
145  */

146 public class MBeanPermission extends Permission JavaDoc {
147
148     private static final long serialVersionUID = -2416928705275160661L;
149
150     /**
151      * Actions list.
152      */

153     private static final int AddNotificationListener = 0x00001;
154     private static final int GetAttribute = 0x00002;
155     private static final int GetClassLoader = 0x00004;
156     private static final int GetClassLoaderFor = 0x00008;
157     private static final int GetClassLoaderRepository = 0x00010;
158     private static final int GetDomains = 0x00020;
159     private static final int GetMBeanInfo = 0x00040;
160     private static final int GetObjectInstance = 0x00080;
161     private static final int Instantiate = 0x00100;
162     private static final int Invoke = 0x00200;
163     private static final int IsInstanceOf = 0x00400;
164     private static final int QueryMBeans = 0x00800;
165     private static final int QueryNames = 0x01000;
166     private static final int RegisterMBean = 0x02000;
167     private static final int RemoveNotificationListener = 0x04000;
168     private static final int SetAttribute = 0x08000;
169     private static final int UnregisterMBean = 0x10000;
170
171     /**
172      * No actions.
173      */

174     private static final int NONE = 0x00000;
175
176     /**
177      * All actions.
178      */

179     private static final int ALL =
180         AddNotificationListener |
181         GetAttribute |
182         GetClassLoader |
183         GetClassLoaderFor |
184         GetClassLoaderRepository |
185         GetDomains |
186         GetMBeanInfo |
187         GetObjectInstance |
188         Instantiate |
189         Invoke |
190         IsInstanceOf |
191         QueryMBeans |
192         QueryNames |
193         RegisterMBean |
194         RemoveNotificationListener |
195         SetAttribute |
196         UnregisterMBean;
197
198     /**
199      * An ObjectName that matches any other.
200      */

201     private static final ObjectName JavaDoc allObjectNames;
202     static {
203     try {
204         allObjectNames = new ObjectName JavaDoc("*:*");
205     } catch (MalformedObjectNameException JavaDoc e) {
206         throw new IllegalArgumentException JavaDoc("can't happen");
207     }
208     }
209
210     /**
211      * The actions string.
212      */

213     private String JavaDoc actions;
214
215     /**
216      * The actions mask.
217      */

218     private transient int mask;
219
220     /**
221      * The classname prefix that must match. If null, is implied by any
222      * classNamePrefix but does not imply any non-null classNamePrefix.
223      */

224     private transient String JavaDoc classNamePrefix;
225
226     /**
227      * True if classNamePrefix must match exactly. Otherwise, the
228      * className being matched must start with classNamePrefix.
229      */

230     private transient boolean classNameExactMatch;
231
232     /**
233      * The member that must match. If null, is implied by any member
234      * but does not imply any non-null member.
235      */

236     private transient String JavaDoc member;
237
238     /**
239      * The objectName that must match. If null, is implied by any
240      * objectName but does not imply any non-null objectName.
241      */

242     private transient ObjectName JavaDoc objectName;
243
244     /**
245      * Parse <code>actions</code> parameter.
246      */

247     private void parseActions() {
248
249         int mask;
250
251         if (actions == null)
252             throw new IllegalArgumentException JavaDoc("MBeanPermission: " +
253                            "actions can't be null");
254         if (actions.equals(""))
255             throw new IllegalArgumentException JavaDoc("MBeanPermission: " +
256                            "actions can't be empty");
257
258         mask = getMask(actions);
259
260         if ((mask & ALL) != mask)
261             throw new IllegalArgumentException JavaDoc("Invalid actions mask");
262         if (mask == NONE)
263             throw new IllegalArgumentException JavaDoc("Invalid actions mask");
264         this.mask = mask;
265     }
266
267     /**
268      * Parse <code>name</code> parameter.
269      */

270     private void parseName() {
271     String JavaDoc name = getName();
272
273     if (name.equals(""))
274         throw new IllegalArgumentException JavaDoc("MBeanPermission name " +
275                            "cannot be empty");
276
277     /* The name looks like "class#member[objectname]". We subtract
278        elements from the right as we parse, so after parsing the
279        objectname we have "class#member" and after parsing the
280        member we have "class". Each element is optional. */

281
282         // Parse ObjectName
283

284         int openingBracket = name.indexOf("[");
285         if (openingBracket == -1) {
286             // If "[on]" missing then ObjectName("*:*")
287
//
288
objectName = allObjectNames;
289         } else {
290             if (!name.endsWith("]")) {
291                 throw new IllegalArgumentException JavaDoc("MBeanPermission: " +
292                                                    "The ObjectName in the " +
293                                                    "target name must be " +
294                                                    "included in square " +
295                                                    "brackets");
296             } else {
297                 // Create ObjectName
298
//
299
try {
300                     // If "[]" then ObjectName("*:*")
301
//
302
String JavaDoc on = name.substring(openingBracket + 1,
303                                                name.length() - 1);
304                     if (on.equals(""))
305             objectName = allObjectNames;
306             else if (on.equals("-"))
307             objectName = null;
308             else
309             objectName = new ObjectName JavaDoc(on);
310                 } catch (MalformedObjectNameException JavaDoc e) {
311                     throw new IllegalArgumentException JavaDoc("MBeanPermission: " +
312                                                        "The target name does " +
313                                                        "not specify a valid " +
314                                                        "ObjectName");
315                 }
316             }
317
318         name = name.substring(0, openingBracket);
319         }
320
321     // Parse member
322

323         int poundSign = name.indexOf("#");
324
325         if (poundSign == -1)
326         setMember("*");
327     else {
328             String JavaDoc memberName = name.substring(poundSign + 1);
329         setMember(memberName);
330         name = name.substring(0, poundSign);
331         }
332
333         // Parse className
334

335     setClassName(name);
336     }
337
338     /**
339      * Assign fields based on className, member, and objectName
340      * parameters.
341      */

342     private void initName(String JavaDoc className, String JavaDoc member,
343               ObjectName JavaDoc objectName) {
344     setClassName(className);
345     setMember(member);
346     this.objectName = objectName;
347     }
348
349     private void setClassName(String JavaDoc className) {
350     if (className == null || className.equals("-")) {
351         classNamePrefix = null;
352         classNameExactMatch = false;
353     } else if (className.equals("") || className.equals("*")) {
354         classNamePrefix = "";
355         classNameExactMatch = false;
356         } else if (className.endsWith(".*")) {
357         // Note that we include the "." in the required prefix
358
classNamePrefix = className.substring(0, className.length() - 1);
359         classNameExactMatch = false;
360         } else {
361         classNamePrefix = className;
362         classNameExactMatch = true;
363         }
364     }
365
366     private void setMember(String JavaDoc member) {
367     if (member == null || member.equals("-"))
368         this.member = null;
369     else if (member.equals(""))
370         this.member = "*";
371     else
372         this.member = member;
373     }
374
375     /**
376      * <p>Create a new MBeanPermission object with the specified target name
377      * and actions.</p>
378      *
379      * <p>The target name is of the form
380      * "<code>className#member[objectName]</code>" where each part is
381      * optional. It must not be empty or null.</p>
382      *
383      * <p>The actions parameter contains a comma-separated list of the
384      * desired actions granted on the target name. It must not be
385      * empty or null.</p>
386      *
387      * @param name the triplet "className#member[objectName]".
388      * @param actions the action string.
389      *
390      * @exception IllegalArgumentException if the <code>name</code> or
391      * <code>actions</code> is invalid.
392      */

393     public MBeanPermission(String JavaDoc name, String JavaDoc actions) {
394         super(name);
395
396     parseName();
397
398     this.actions = actions;
399     parseActions();
400     }
401
402     /**
403      * <p>Create a new MBeanPermission object with the specified target name
404      * (class name, member, object name) and actions.</p>
405      *
406      * <p>The class name, member and object name parameters define a
407      * target name of the form
408      * "<code>className#member[objectName]</code>" where each part is
409      * optional. This will be the result of {@link #getName()} on the
410      * resultant MBeanPermission.</p>
411      *
412      * <p>The actions parameter contains a comma-separated list of the
413      * desired actions granted on the target name. It must not be
414      * empty or null.</p>
415      *
416      * @param className the class name to which this permission applies.
417      * May be null or <code>"-"</code>, which represents a class name
418      * that is implied by any class name but does not imply any other
419      * class name.
420      * @param member the member to which this permission applies. May
421      * be null or <code>"-"</code>, which represents a member that is
422      * implied by any member but does not imply any other member.
423      * @param objectName the object name to which this permission
424      * applies. May be null, which represents an object name that is
425      * implied by any object name but does not imply any other object
426      * name.
427      * @param actions the action string.
428      */

429     public MBeanPermission(String JavaDoc className,
430                String JavaDoc member,
431                ObjectName JavaDoc objectName,
432                String JavaDoc actions) {
433
434         super(makeName(className, member, objectName));
435     initName(className, member, objectName);
436
437     this.actions = actions;
438     parseActions();
439     }
440
441     private static String JavaDoc makeName(String JavaDoc className, String JavaDoc member,
442                    ObjectName JavaDoc objectName) {
443     StringBuffer JavaDoc name = new StringBuffer JavaDoc();
444     if (className == null)
445         className = "-";
446     name.append(className);
447     if (member == null)
448         member = "-";
449     name.append("#" + member);
450     if (objectName == null)
451         name.append("[-]");
452     else
453         name.append("[").append(objectName.getCanonicalName()).append("]");
454
455     /* In the interests of legibility for Permission.toString(), we
456        transform the empty string into "*". */

457     if (name.length() == 0)
458         return "*";
459     else
460         return name.toString();
461     }
462
463     /**
464      * Returns the "canonical string representation" of the actions. That is,
465      * this method always returns present actions in alphabetical order.
466      *
467      * @return the canonical string representation of the actions.
468      */

469     public String JavaDoc getActions() {
470
471         if (actions == null)
472             actions = getActions(this.mask);
473
474         return actions;
475     }
476
477     /**
478      * Returns the "canonical string representation"
479      * of the actions from the mask.
480      */

481     private static String JavaDoc getActions(int mask) {
482         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
483         boolean comma = false;
484
485         if ((mask & AddNotificationListener) == AddNotificationListener) {
486             comma = true;
487             sb.append("addNotificationListener");
488         }
489
490         if ((mask & GetAttribute) == GetAttribute) {
491             if (comma) sb.append(',');
492             else comma = true;
493             sb.append("getAttribute");
494         }
495
496         if ((mask & GetClassLoader) == GetClassLoader) {
497             if (comma) sb.append(',');
498             else comma = true;
499             sb.append("getClassLoader");
500         }
501
502         if ((mask & GetClassLoaderFor) == GetClassLoaderFor) {
503             if (comma) sb.append(',');
504             else comma = true;
505             sb.append("getClassLoaderFor");
506         }
507
508         if ((mask & GetClassLoaderRepository) == GetClassLoaderRepository) {
509             if (comma) sb.append(',');
510             else comma = true;
511             sb.append("getClassLoaderRepository");
512         }
513
514         if ((mask & GetDomains) == GetDomains) {
515             if (comma) sb.append(',');
516             else comma = true;
517             sb.append("getDomains");
518         }
519
520         if ((mask & GetMBeanInfo) == GetMBeanInfo) {
521             if (comma) sb.append(',');
522             else comma = true;
523             sb.append("getMBeanInfo");
524         }
525
526         if ((mask & GetObjectInstance) == GetObjectInstance) {
527             if (comma) sb.append(',');
528             else comma = true;
529             sb.append("getObjectInstance");
530         }
531
532         if ((mask & Instantiate) == Instantiate) {
533             if (comma) sb.append(',');
534             else comma = true;
535             sb.append("instantiate");
536         }
537
538         if ((mask & Invoke) == Invoke) {
539             if (comma) sb.append(',');
540             else comma = true;
541             sb.append("invoke");
542         }
543
544         if ((mask & IsInstanceOf) == IsInstanceOf) {
545             if (comma) sb.append(',');
546             else comma = true;
547             sb.append("isInstanceOf");
548         }
549
550         if ((mask & QueryMBeans) == QueryMBeans) {
551             if (comma) sb.append(',');
552             else comma = true;
553             sb.append("queryMBeans");
554         }
555
556         if ((mask & QueryNames) == QueryNames) {
557             if (comma) sb.append(',');
558             else comma = true;
559             sb.append("queryNames");
560         }
561
562         if ((mask & RegisterMBean) == RegisterMBean) {
563             if (comma) sb.append(',');
564             else comma = true;
565             sb.append("registerMBean");
566         }
567
568         if ((mask & RemoveNotificationListener) == RemoveNotificationListener) {
569             if (comma) sb.append(',');
570             else comma = true;
571             sb.append("removeNotificationListener");
572         }
573
574         if ((mask & SetAttribute) == SetAttribute) {
575             if (comma) sb.append(',');
576             else comma = true;
577             sb.append("setAttribute");
578         }
579
580         if ((mask & UnregisterMBean) == UnregisterMBean) {
581             if (comma) sb.append(',');
582             else comma = true;
583             sb.append("unregisterMBean");
584         }
585
586         return sb.toString();
587     }
588
589     /**
590      * Returns the hash code value for this object.
591      *
592      * @return a hash code value for this object.
593      */

594     public int hashCode() {
595         return this.getName().hashCode() + this.getActions().hashCode();
596     }
597
598     /**
599      * Converts an action String to an integer action mask.
600      *
601      * @param action the action string.
602      * @return the action mask.
603      */

604     private static int getMask(String JavaDoc action) {
605
606         /*
607          * BE CAREFUL HERE! PARSING ORDER IS IMPORTANT IN THIS ALGORITHM.
608          *
609          * The 'string length' test must be performed for the lengthiest
610          * strings first.
611          *
612          * In this permission if the "unregisterMBean" string length test is
613          * performed after the "registerMBean" string length test the algorithm
614          * considers the 'unregisterMBean' action as being the 'registerMBean'
615          * action and a parsing error is returned.
616          */

617
618         int mask = NONE;
619
620         if (action == null) {
621             return mask;
622         }
623
624         if (action.equals("*")) {
625             return ALL;
626         }
627
628         char[] a = action.toCharArray();
629
630         int i = a.length - 1;
631         if (i < 0)
632             return mask;
633
634         while (i != -1) {
635             char c;
636
637             // skip whitespace
638
while ((i!=-1) && ((c = a[i]) == ' ' ||
639                                c == '\r' ||
640                                c == '\n' ||
641                                c == '\f' ||
642                                c == '\t'))
643                 i--;
644
645             // check for the known strings
646
int matchlen;
647
648             if (i >= 25 && /* removeNotificationListener */
649                 (a[i-25] == 'r') &&
650                 (a[i-24] == 'e') &&
651                 (a[i-23] == 'm') &&
652                 (a[i-22] == 'o') &&
653                 (a[i-21] == 'v') &&
654                 (a[i-20] == 'e') &&
655                 (a[i-19] == 'N') &&
656                 (a[i-18] == 'o') &&
657                 (a[i-17] == 't') &&
658                 (a[i-16] == 'i') &&
659                 (a[i-15] == 'f') &&
660                 (a[i-14] == 'i') &&
661                 (a[i-13] == 'c') &&
662                 (a[i-12] == 'a') &&
663                 (a[i-11] == 't') &&
664                 (a[i-10] == 'i') &&
665                 (a[i-9] == 'o') &&
666                 (a[i-8] == 'n') &&
667                 (a[i-7] == 'L') &&
668                 (a[i-6] == 'i') &&
669                 (a[i-5] == 's') &&
670                 (a[i-4] == 't') &&
671                 (a[i-3] == 'e') &&
672                 (a[i-2] == 'n') &&
673                 (a[i-1] == 'e') &&
674                 (a[i] == 'r')) {
675                 matchlen = 26;
676                 mask |= RemoveNotificationListener;
677             } else if (i >= 23 && /* getClassLoaderRepository */
678                        (a[i-23] == 'g') &&
679                        (a[i-22] == 'e') &&
680                        (a[i-21] == 't') &&
681                        (a[i-20] == 'C') &&
682                        (a[i-19] == 'l') &&
683                        (a[i-18] == 'a') &&
684                        (a[i-17] == 's') &&
685                        (a[i-16] == 's') &&
686                        (a[i-15] == 'L') &&
687                        (a[i-14] == 'o') &&
688                        (a[i-13] == 'a') &&
689                        (a[i-12] == 'd') &&
690                        (a[i-11] == 'e') &&
691                        (a[i-10] == 'r') &&
692                        (a[i-9] == 'R') &&
693                        (a[i-8] == 'e') &&
694                        (a[i-7] == 'p') &&
695                        (a[i-6] == 'o') &&
696                        (a[i-5] == 's') &&
697                        (a[i-4] == 'i') &&
698                        (a[i-3] == 't') &&
699                        (a[i-2] == 'o') &&
700                        (a[i-1] == 'r') &&
701                        (a[i] == 'y')) {
702                 matchlen = 24;
703                 mask |= GetClassLoaderRepository;
704             } else if (i >= 22 && /* addNotificationListener */
705                        (a[i-22] == 'a') &&
706                        (a[i-21] == 'd') &&
707                        (a[i-20] == 'd') &&
708                        (a[i-19] == 'N') &&
709                        (a[i-18] == 'o') &&
710                        (a[i-17] == 't') &&
711                        (a[i-16] == 'i') &&
712                        (a[i-15] == 'f') &&
713                        (a[i-14] == 'i') &&
714                        (a[i-13] == 'c') &&
715                        (a[i-12] == 'a') &&
716                        (a[i-11] == 't') &&
717                        (a[i-10] == 'i') &&
718                        (a[i-9] == 'o') &&
719                        (a[i-8] == 'n') &&
720                        (a[i-7] == 'L') &&
721                        (a[i-6] == 'i') &&
722                        (a[i-5] == 's') &&
723                        (a[i-4] == 't') &&
724                        (a[i-3] == 'e') &&
725                        (a[i-2] == 'n') &&
726                        (a[i-1] == 'e') &&
727                        (a[i] == 'r')) {
728                 matchlen = 23;
729                 mask |= AddNotificationListener;
730             } else if (i >= 16 && /* getClassLoaderFor */
731                        (a[i-16] == 'g') &&
732                        (a[i-15] == 'e') &&
733                        (a[i-14] == 't') &&
734                        (a[i-13] == 'C') &&
735                        (a[i-12] == 'l') &&
736                        (a[i-11] == 'a') &&
737                        (a[i-10] == 's') &&
738                        (a[i-9] == 's') &&
739                        (a[i-8] == 'L') &&
740                        (a[i-7] == 'o') &&
741                        (a[i-6] == 'a') &&
742                        (a[i-5] == 'd') &&
743                        (a[i-4] == 'e') &&
744                        (a[i-3] == 'r') &&
745                        (a[i-2] == 'F') &&
746                        (a[i-1] == 'o') &&
747                        (a[i] == 'r')) {
748                 matchlen = 17;
749                 mask |= GetClassLoaderFor;
750             } else if (i >= 16 && /* getObjectInstance */
751                        (a[i-16] == 'g') &&
752                        (a[i-15] == 'e') &&
753                        (a[i-14] == 't') &&
754                        (a[i-13] == 'O') &&
755                        (a[i-12] == 'b') &&
756                        (a[i-11] == 'j') &&
757                        (a[i-10] == 'e') &&
758                        (a[i-9] == 'c') &&
759                        (a[i-8] == 't') &&
760                        (a[i-7] == 'I') &&
761                        (a[i-6] == 'n') &&
762                        (a[i-5] == 's') &&
763                        (a[i-4] == 't') &&
764                        (a[i-3] == 'a') &&
765                        (a[i-2] == 'n') &&
766                        (a[i-1] == 'c') &&
767                        (a[i] == 'e')) {
768                 matchlen = 17;
769                 mask |= GetObjectInstance;
770             } else if (i >= 14 && /* unregisterMBean */
771                        (a[i-14] == 'u') &&
772                        (a[i-13] == 'n') &&
773                        (a[i-12] == 'r') &&
774                        (a[i-11] == 'e') &&
775                        (a[i-10] == 'g') &&
776                        (a[i-9] == 'i') &&
777                        (a[i-8] == 's') &&
778                        (a[i-7] == 't') &&
779                        (a[i-6] == 'e') &&
780                        (a[i-5] == 'r') &&
781                        (a[i-4] == 'M') &&
782                        (a[i-3] == 'B') &&
783                        (a[i-2] == 'e') &&
784                        (a[i-1] == 'a') &&
785                        (a[i] == 'n')) {
786                 matchlen = 15;
787                 mask |= UnregisterMBean;
788             } else if (i >= 13 && /* getClassLoader */
789               &