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                        (a[i-13] == 'g') &&
790                        (a[i-12] == 'e') &&
791                        (a[i-11] == 't') &&
792                        (a[i-10] == 'C') &&
793                        (a[i-9] == 'l') &&
794                        (a[i-8] == 'a') &&
795                        (a[i-7] == 's') &&
796                        (a[i-6] == 's') &&
797                        (a[i-5] == 'L') &&
798                        (a[i-4] == 'o') &&
799                        (a[i-3] == 'a') &&
800                        (a[i-2] == 'd') &&
801                        (a[i-1] == 'e') &&
802                        (a[i] == 'r')) {
803                 matchlen = 14;
804                 mask |= GetClassLoader;
805             } else if (i >= 12 && /* registerMBean */
806                        (a[i-12] == 'r') &&
807                        (a[i-11] == 'e') &&
808                        (a[i-10] == 'g') &&
809                        (a[i-9] == 'i') &&
810                        (a[i-8] == 's') &&
811                        (a[i-7] == 't') &&
812                        (a[i-6] == 'e') &&
813                        (a[i-5] == 'r') &&
814                        (a[i-4] == 'M') &&
815                        (a[i-3] == 'B') &&
816                        (a[i-2] == 'e') &&
817                        (a[i-1] == 'a') &&
818                        (a[i] == 'n')) {
819                 matchlen = 13;
820                 mask |= RegisterMBean;
821             } else if (i >= 11 && /* getAttribute */
822                        (a[i-11] == 'g') &&
823                        (a[i-10] == 'e') &&
824                        (a[i-9] == 't') &&
825                        (a[i-8] == 'A') &&
826                        (a[i-7] == 't') &&
827                        (a[i-6] == 't') &&
828                        (a[i-5] == 'r') &&
829                        (a[i-4] == 'i') &&
830                        (a[i-3] == 'b') &&
831                        (a[i-2] == 'u') &&
832                        (a[i-1] == 't') &&
833                        (a[i] == 'e')) {
834                 matchlen = 12;
835                 mask |= GetAttribute;
836             } else if (i >= 11 && /* getMBeanInfo */
837                        (a[i-11] == 'g') &&
838                        (a[i-10] == 'e') &&
839                        (a[i-9] == 't') &&
840                        (a[i-8] == 'M') &&
841                        (a[i-7] == 'B') &&
842                        (a[i-6] == 'e') &&
843                        (a[i-5] == 'a') &&
844                        (a[i-4] == 'n') &&
845                        (a[i-3] == 'I') &&
846                        (a[i-2] == 'n') &&
847                        (a[i-1] == 'f') &&
848                        (a[i] == 'o')) {
849                 matchlen = 12;
850                 mask |= GetMBeanInfo;
851             } else if (i >= 11 && /* isInstanceOf */
852                        (a[i-11] == 'i') &&
853                        (a[i-10] == 's') &&
854                        (a[i-9] == 'I') &&
855                        (a[i-8] == 'n') &&
856                        (a[i-7] == 's') &&
857                        (a[i-6] == 't') &&
858                        (a[i-5] == 'a') &&
859                        (a[i-4] == 'n') &&
860                        (a[i-3] == 'c') &&
861                        (a[i-2] == 'e') &&
862                        (a[i-1] == 'O') &&
863                        (a[i] == 'f')) {
864                 matchlen = 12;
865                 mask |= IsInstanceOf;
866             } else if (i >= 11 && /* setAttribute */
867                        (a[i-11] == 's') &&
868                        (a[i-10] == 'e') &&
869                        (a[i-9] == 't') &&
870                        (a[i-8] == 'A') &&
871                        (a[i-7] == 't') &&
872                        (a[i-6] == 't') &&
873                        (a[i-5] == 'r') &&
874                        (a[i-4] == 'i') &&
875                        (a[i-3] == 'b') &&
876                        (a[i-2] == 'u') &&
877                        (a[i-1] == 't') &&
878                        (a[i] == 'e')) {
879                 matchlen = 12;
880                 mask |= SetAttribute;
881             } else if (i >= 10 && /* instantiate */
882                        (a[i-10] == 'i') &&
883                        (a[i-9] == 'n') &&
884                        (a[i-8] == 's') &&
885                        (a[i-7] == 't') &&
886                        (a[i-6] == 'a') &&
887                        (a[i-5] == 'n') &&
888                        (a[i-4] == 't') &&
889                        (a[i-3] == 'i') &&
890                        (a[i-2] == 'a') &&
891                        (a[i-1] == 't') &&
892                        (a[i] == 'e')) {
893                 matchlen = 11;
894                 mask |= Instantiate;
895             } else if (i >= 10 && /* queryMBeans */
896                        (a[i-10] == 'q') &&
897                        (a[i-9] == 'u') &&
898                        (a[i-8] == 'e') &&
899                        (a[i-7] == 'r') &&
900                        (a[i-6] == 'y') &&
901                        (a[i-5] == 'M') &&
902                        (a[i-4] == 'B') &&
903                        (a[i-3] == 'e') &&
904                        (a[i-2] == 'a') &&
905                        (a[i-1] == 'n') &&
906                        (a[i] == 's')) {
907                 matchlen = 11;
908                 mask |= QueryMBeans;
909             } else if (i >= 9 && /* getDomains */
910                        (a[i-9] == 'g') &&
911                        (a[i-8] == 'e') &&
912                        (a[i-7] == 't') &&
913                        (a[i-6] == 'D') &&
914                        (a[i-5] == 'o') &&
915                        (a[i-4] == 'm') &&
916                        (a[i-3] == 'a') &&
917                        (a[i-2] == 'i') &&
918                        (a[i-1] == 'n') &&
919                        (a[i] == 's')) {
920                 matchlen = 10;
921                 mask |= GetDomains;
922             } else if (i >= 9 && /* queryNames */
923                        (a[i-9] == 'q') &&
924                        (a[i-8] == 'u') &&
925                        (a[i-7] == 'e') &&
926                        (a[i-6] == 'r') &&
927                        (a[i-5] == 'y') &&
928                        (a[i-4] == 'N') &&
929                        (a[i-3] == 'a') &&
930                        (a[i-2] == 'm') &&
931                        (a[i-1] == 'e') &&
932                        (a[i] == 's')) {
933                 matchlen = 10;
934                 mask |= QueryNames;
935             } else if (i >= 5 && /* invoke */
936                        (a[i-5] == 'i') &&
937                        (a[i-4] == 'n') &&
938                        (a[i-3] == 'v') &&
939                        (a[i-2] == 'o') &&
940                        (a[i-1] == 'k') &&
941                        (a[i] == 'e')) {
942                 matchlen = 6;
943                 mask |= Invoke;
944             } else {
945                 // parse error
946
throw new IllegalArgumentException JavaDoc("Invalid permission: " +
947                                                    action);
948             }
949
950             // make sure we didn't just match the tail of a word
951
// like "ackbarfaccept". Also, skip to the comma.
952
boolean seencomma = false;
953             while (i >= matchlen && !seencomma) {
954                 switch(a[i-matchlen]) {
955                 case ',':
956                     seencomma = true;
957                     /*FALLTHROUGH*/
958                 case ' ': case '\r': case '\n':
959                 case '\f': case '\t':
960                     break;
961                 default:
962                     throw new IllegalArgumentException JavaDoc("Invalid permission: " +
963                                                        action);
964                 }
965                 i--;
966             }
967
968             // point i at the location of the comma minus one (or -1).
969
i -= matchlen;
970         }
971
972         return mask;
973     }
974
975     /**
976      * <p>Checks if this MBeanPermission object "implies" the
977      * specified permission.</p>
978      *
979      * <p>More specifically, this method returns true if:</p>
980      *
981      * <ul>
982      *
983      * <li> <i>p</i> is an instance of MBeanPermission; and</li>
984      *
985      * <li> <i>p</i> has a null className or <i>p</i>'s className
986      * matches this object's className; and</li>
987      *
988      * <li> <i>p</i> has a null member or <i>p</i>'s member matches this
989      * object's member; and</li>
990      *
991      * <li> <i>p</i> has a null object name or <i>p</i>'s
992      * object name matches this object's object name; and</li>
993      *
994      * <li> <i>p</i>'s actions are a subset of this object's actions</li>
995      *
996      * </ul>
997      *
998      * <p>If this object's className is "<code>*</code>", <i>p</i>'s
999      * className always matches it. If it is "<code>a.*</code>", <i>p</i>'s
1000     * className matches it if it begins with "<code>a.</code>".</p>
1001     *
1002     * <p>If this object's member is "<code>*</code>", <i>p</i>'s
1003     * member always matches it.</p>
1004     *
1005     * <p>If this object's objectName <i>n1</i> is an object name pattern,
1006     * <i>p</i>'s objectName <i>n2</i> matches it if
1007     * {@link ObjectName#equals <i>n1</i>.equals(<i>n2</i>)} or if
1008     * {@link ObjectName#apply <i>n1</i>.apply(<i>n2</i>)}.</p>
1009     *
1010     * <p>A permission that includes the <code>queryMBeans</code> action
1011     * is considered to include <code>queryNames</code> as well.</p>
1012     *
1013     * @param p the permission to check against.
1014     * @return true if the specified permission is implied by this object,
1015     * false if not.
1016     */

1017    public boolean implies(Permission JavaDoc p) {
1018        if (!(p instanceof MBeanPermission JavaDoc))
1019            return false;
1020
1021        MBeanPermission JavaDoc that = (MBeanPermission JavaDoc) p;
1022
1023        // Actions
1024
//
1025
// The actions in 'this' permission must be a
1026
// superset of the actions in 'that' permission
1027
//
1028

1029    /* "queryMBeans" implies "queryNames" */
1030    if ((this.mask & QueryMBeans) == QueryMBeans) {
1031        if (((this.mask | QueryNames) & that.mask) != that.mask) {
1032        //System.out.println("action [with QueryNames] does not imply");
1033
return false;
1034        }
1035    } else {
1036        if ((this.mask & that.mask) != that.mask) {
1037        //System.out.println("action does not imply");
1038
return false;
1039        }
1040    }
1041
1042        // Target name
1043
//
1044
// The 'className' check is true iff:
1045
// 1) the className in 'this' permission is omitted or "*", or
1046
// 2) the className in 'that' permission is omitted or "*", or
1047
// 3) the className in 'this' permission does pattern
1048
// matching with the className in 'that' permission.
1049
//
1050
// The 'member' check is true iff:
1051
// 1) the member in 'this' permission is omitted or "*", or
1052
// 2) the member in 'that' permission is omitted or "*", or
1053
// 3) the member in 'this' permission equals the member in
1054
// 'that' permission.
1055
//
1056
// The 'object name' check is true iff:
1057
// 1) the object name in 'this' permission is omitted or "*:*", or
1058
// 2) the object name in 'that' permission is omitted or "*:*", or
1059
// 3) the object name in 'this' permission does pattern
1060
// matching with the object name in 'that' permission.
1061
//
1062

1063        /* Check if this.className implies that.className.
1064       
1065       If that.classNamePrefix is empty that means the className is
1066       irrelevant for this permission check. Otherwise, we do not
1067       expect that "that" contains a wildcard, since it is a
1068       needed permission. So we assume that.classNameExactMatch. */

1069
1070    if (that.classNamePrefix == null) {
1071        // bottom is implied
1072
} else if (this.classNamePrefix == null) {
1073        // bottom implies nothing but itself
1074
return false;
1075    } else if (this.classNameExactMatch) {
1076        if (!that.classNameExactMatch)
1077        return false; // exact never implies wildcard
1078
if (!that.classNamePrefix.equals(this.classNamePrefix))
1079        return false; // exact match fails
1080
} else {
1081        // prefix match, works even if "that" is also a wildcard
1082
// e.g. a.* implies a.* and a.b.*
1083
if (!that.classNamePrefix.startsWith(this.classNamePrefix))
1084        return false;
1085    }
1086
1087        /* Check if this.member implies that.member */
1088
1089    if (that.member == null) {
1090        // bottom is implied
1091
} else if (this.member == null) {
1092        // bottom implies nothing but itself
1093
return false;
1094    } else if (this.member.equals("*")) {
1095        // wildcard implies everything (including itself)
1096
} else if (!this.member.equals(that.member)) {
1097        return false;
1098    }
1099
1100        /* Check if this.objectName implies that.objectName */
1101
1102    if (that.objectName == null) {
1103        // bottom is implied
1104
} else if (this.objectName == null) {
1105        // bottom implies nothing but itself
1106
return false;
1107    } else if (!this.objectName.apply(that.objectName)) {
1108        /* ObjectName.apply returns false if that.objectName is a
1109           wildcard so we also allow equals for that case. This
1110           never happens during real permission checks, but means
1111           the implies relation is reflexive. */

1112        if (!this.objectName.equals(that.objectName))
1113        return false;
1114        }
1115
1116        return true;
1117    }
1118
1119    /**
1120     * Checks two MBeanPermission objects for equality. Checks
1121     * that <i>obj</i> is an MBeanPermission, and has the same
1122     * name and actions as this object.
1123     * <P>
1124     * @param obj the object we are testing for equality with this object.
1125     * @return true if obj is an MBeanPermission, and has the
1126     * same name and actions as this MBeanPermission object.
1127     */

1128    public boolean equals(Object JavaDoc obj) {
1129        if (obj == this)
1130            return true;
1131
1132        if (! (obj instanceof MBeanPermission JavaDoc))
1133            return false;
1134
1135        MBeanPermission JavaDoc that = (MBeanPermission JavaDoc) obj;
1136
1137        return (this.mask == that.mask) &&
1138            (this.getName().equals(that.getName()));
1139    }
1140
1141    /**
1142     * Deserialize this object based on its name and actions.
1143     */

1144    private void readObject(ObjectInputStream JavaDoc in)
1145        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1146    in.defaultReadObject();
1147    parseName();
1148    parseActions();
1149    }
1150}
1151
Popular Tags