001: /**
002: * The XMOJO Project 5
003: * Copyright © 2003 XMOJO.org. All rights reserved.
004:
005: * NO WARRANTY
006:
007: * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
008: * THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
009: * OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
010: * PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
011: * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
012: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
013: * TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
014: * LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
015: * REPAIR OR CORRECTION.
016:
017: * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
018: * ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
019: * THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
020: * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
021: * USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
022: * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
023: * PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
024: * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
025: * SUCH DAMAGES.
026: **/package javax.management.relation;
027:
028: import java.lang.reflect.Constructor;
029: import java.lang.reflect.Modifier;
030: import java.io.Serializable;
031:
032: import javax.management.MBeanInfo;
033: import javax.management.MBeanConstructorInfo;
034: import javax.management.NotCompliantMBeanException;
035:
036: import com.adventnet.jmx.DefaultDynamicMBean;
037:
038: /**
039: * A RoleInfo object represents a role information in a relation type.
040: */
041: public class RoleInfo implements Serializable {
042: /**
043: * To specify an unlimited cardinality
044: */
045: public static int ROLE_CARDINALITY_INFINITY = 0;
046:
047: // Name of the role
048: String roleName = null;
049:
050: // Name of class of MBean(s) expected to be referenced in corresponding role
051: String refMBeanClassName = null;
052:
053: // Description of role
054: String description = null;
055:
056: // Read access mode: true if role is readable
057: boolean isReadable = true;
058:
059: // Write access mode: true if role is writable
060: boolean isWritable = true;
061:
062: // Minimum degree (i.e. minimum number of referenced MBeans in
063: // corresponding role)
064: int minDegree = 1;
065:
066: // Maximum degree (i.e. maximum number of referenced MBeans in
067: // corresponding role)
068: int maxDegree = 1;
069:
070: /**
071: * Copy constructor
072: *
073: * @exception java.lang.IllegalArgumentException - if null parameter
074: *
075: * @param theRoleInfo RoleInfo object
076: */
077: public RoleInfo(RoleInfo theRoleInfo)
078: throws IllegalArgumentException {
079: if (theRoleInfo == null)
080: throw new IllegalArgumentException(
081: "Cannot create RoleInfo for null values");
082:
083: if (!(theRoleInfo instanceof RoleInfo))
084: throw new IllegalArgumentException();
085:
086: this .roleName = theRoleInfo.getName();
087: this .refMBeanClassName = theRoleInfo.getRefMBeanClassName();
088: this .description = theRoleInfo.getDescription();
089: this .isReadable = theRoleInfo.isReadable();
090: this .isWritable = theRoleInfo.isWritable();
091: this .minDegree = theRoleInfo.getMinDegree();
092: this .maxDegree = theRoleInfo.getMaxDegree();
093: }
094:
095: /**
096: * Constructor to create RoleInfo
097: *
098: * @param theName - name of the role
099: *
100: * @param theRefMBeanClassName - name of the class of MBean(s) expected
101: * to be referenced in corresponding role Readable and
102: * IsWritable defaulted to true.
103: * Minimum and maximum degrees defaulted to 1.
104: * Description of role defaulted to null.
105: *
106: * @exception java.lang.IllegalArgumentException - if null parameter
107: *
108: * @exception java.lang.ClassNotFoundException - if the class
109: * theMBeanClassName does not exist.
110: *
111: * @exception NotCompliantMBeanException - if the class
112: * theRefMBeanClassName is not a MBean class.
113: */
114: public RoleInfo(String theName, String theRefMBeanClassName)
115: throws IllegalArgumentException, ClassNotFoundException,
116: NotCompliantMBeanException {
117: if (theName == null || theRefMBeanClassName == null)
118: throw new IllegalArgumentException(
119: "Cannot create a RoleInfo with null values ");
120:
121: this .roleName = theName;
122: this .refMBeanClassName = theRefMBeanClassName;
123:
124: this .isReadable = true;
125: this .isWritable = true;
126:
127: this .minDegree = 1;
128: this .maxDegree = 1;
129:
130: this .description = null;
131: Class cl = Class.forName(theRefMBeanClassName);
132: testForCompliance(theRefMBeanClassName);
133:
134: try {
135: Object obj = cl.newInstance();
136: DefaultDynamicMBean mbean = new DefaultDynamicMBean(obj);
137: if (obj == null) {
138: throw new NotCompliantMBeanException();
139: }
140: } catch (Exception e) {
141: if (e instanceof NotCompliantMBeanException) {
142: throw (NotCompliantMBeanException) e;
143: }
144: //e.printStackTrace();
145: }
146: }
147:
148: /**
149: * Constructor to create RoleInfo
150: *
151: * @param theName - name of the role
152: *
153: * @param theRefMBeanClassName - name of the class of MBean(s) expected to
154: * be referenced in corresponding role
155: *
156: * @param theIsReadable - flag to indicate if the corresponding role can be read
157: *
158: * @param theIsWritable - flag to indicate if the corresponding role can be set
159: * Minimum and maximum degrees defaulted to 1.
160: * Description of role defaulted to null.
161: *
162: * @exception java.lang.IllegalArgumentException - if null parameter
163: *
164: * @exception java.lang.ClassNotFoundException - if the class
165: * theMBeanClassName does not exist.
166: *
167: * @exception NotCompliantMBeanException - if the class
168: * theRefMBeanClassName is not a MBean class.
169: */
170: public RoleInfo(String theName, String theRefMBeanClassName,
171: boolean theIsReadable, boolean theIsWritable)
172: throws IllegalArgumentException, ClassNotFoundException,
173: NotCompliantMBeanException {
174: if (theName == null || theRefMBeanClassName == null)
175: throw new IllegalArgumentException(
176: "Cannot create a RoleInfo with null values ");
177:
178: this .roleName = theName;
179: this .refMBeanClassName = theRefMBeanClassName;
180:
181: this .isReadable = theIsReadable;
182: this .isWritable = theIsWritable;
183:
184: this .minDegree = 1;
185: this .maxDegree = 1;
186:
187: this .description = null;
188: Class cl = Class.forName(theRefMBeanClassName);
189: testForCompliance(theRefMBeanClassName);
190:
191: try {
192: Object obj = cl.newInstance();
193: DefaultDynamicMBean mbean = new DefaultDynamicMBean(obj);
194: if (obj == null) {
195: throw new NotCompliantMBeanException();
196: }
197: } catch (Exception e) {
198: if (e instanceof NotCompliantMBeanException) {
199: throw (NotCompliantMBeanException) e;
200: }
201: //e.printStackTrace();
202: }
203:
204: }
205:
206: /**
207: * Constructor to create RoleInfo
208: *
209: * @param theName - name of the role
210: *
211: * @param theRefMBeanClassName - name of the class of MBean(s) expected to
212: * be referenced in corresponding role
213: *
214: * @param theIsReadable - flag to indicate if the corresponding role can be read
215: *
216: * @param theIsWritable - flag to indicate if the corresponding role can be set
217: *
218: * @param theMinDegree - minimum degree for role, i.e. minimum number of
219: * MBeans to provide in corresponding role Must be less or
220: * equal than theMaxDegree.
221: * (ROLE_CARDINALITY_INFINITY for unlimited)
222: *
223: * @param theMaxDegree - maximum degree for role, i.e. maximum number of
224: * MBeans to provide in corresponding role Must be greater or
225: * equal than theMinDegree
226: * (ROLE_CARDINALITY_INFINITY for unlimited)
227: *
228: * @param theDescription - description of the role (can be null)
229: *
230: * @throws java.lang.IllegalArgumentException - if null parameter
231: *
232: * @throws InvalidRoleInfoException - if the minimum degree is greater than
233: * the maximum degree.
234: *
235: * @throws java.lang.ClassNotFoundException - if the class
236: * theRefMBeanClassName does not exist.
237: *
238: * @throws NotCompliantMBeanException - if the class
239: * theRefMBeanClassName is not a MBean class.
240: */
241: public RoleInfo(String theName, String theRefMBeanClassName,
242: boolean theIsReadable, boolean theIsWritable,
243: int theMinDegree, int theMaxDegree, String theDescription)
244: throws IllegalArgumentException, InvalidRoleInfoException,
245: ClassNotFoundException, NotCompliantMBeanException {
246: if (theName == null || theRefMBeanClassName == null)
247: throw new IllegalArgumentException(
248: "Cannot create a RoleInfo with null values ");
249:
250: if (theMaxDegree != -1
251: && ((theMinDegree == -1) || (theMinDegree > theMaxDegree))) {
252: throw new InvalidRoleInfoException(
253: "The MinDegree is greater than MaxDegree");
254: }
255:
256: if (theMaxDegree < -1 || theMinDegree < -1)
257: throw new InvalidRoleInfoException(
258: "The Degrees specified for the RoleInfo are not valid !!!!");
259:
260: this .roleName = theName;
261: this .refMBeanClassName = theRefMBeanClassName;
262:
263: this .isReadable = theIsReadable;
264: this .isWritable = theIsWritable;
265:
266: this .minDegree = theMinDegree;
267: this .maxDegree = theMaxDegree;
268:
269: this .description = theDescription;
270: Class cl = Class.forName(theRefMBeanClassName);
271: testForCompliance(theRefMBeanClassName);
272:
273: try {
274: Object obj = cl.newInstance();
275: DefaultDynamicMBean mbean = new DefaultDynamicMBean(obj);
276: if (obj == null) {
277: throw new NotCompliantMBeanException();
278: }
279: } catch (Exception e) {
280: if (e instanceof NotCompliantMBeanException) {
281: throw (NotCompliantMBeanException) e;
282: }
283: //e.printStackTrace();
284: }
285: }
286:
287: /**
288: * Returns a boolean to specify if given value is less or equal than
289: * expected maximum degree (true if yes)
290: *
291: * @param theValue - value
292: *
293: * @return true if less or equal than maximum degree, false else
294: */
295: public boolean checkMaxDegree(int theValue) {
296: /*
297: if(this.maxDegree != -1 && theValue <= this.maxDegree)
298: return true;
299: else
300: return false;
301: */
302:
303: return theValue >= -1
304: && (maxDegree == -1 || theValue != -1
305: && theValue <= maxDegree);
306: }
307:
308: /**
309: * Returns a boolean to specify if given value is greater or equal than
310: * expected minimum degree (true if yes)
311: *
312: * @param theValue - value
313: *
314: * @return true if greater or equal than minimum degree, false else
315: */
316: public boolean checkMinDegree(int theValue) {
317: /*
318: if(this.minDegree != -1 && theValue >= this.minDegree)
319: return true;
320: else
321: return false;
322: */
323:
324: return theValue >= -1
325: && (minDegree == -1 || theValue >= minDegree);
326: }
327:
328: /**
329: * Returns description text for the role
330: *
331: * @return Description text for the role
332: */
333: public String getDescription() {
334: return this .description;
335: }
336:
337: /**
338: * Returns maximum degree for corresponding role reference
339: *
340: * @return Maximum degree for corresponding role reference
341: */
342: public int getMaxDegree() {
343: return this .maxDegree;
344: }
345:
346: /**
347: * Returns minimum degree for corresponding role reference
348: *
349: * @return Minimum degree for corresponding role reference
350: */
351: public int getMinDegree() {
352: return this .minDegree;
353: }
354:
355: /**
356: * Returns the name of the role
357: *
358: * @return The name of the role
359: */
360: public String getName() {
361: return this .roleName;
362: }
363:
364: /**
365: * Returns name of class of MBean expected to be referenced in corresponding role
366: *
367: * @return The string representation of name of class of MBean expected to
368: * be referenced in corresponding role
369: */
370: public String getRefMBeanClassName() {
371: return this .refMBeanClassName;
372: }
373:
374: /**
375: * Returns read access mode for the role (true if it is readable)
376: *
377: * @return True if it is readable otherwise false
378: */
379: public boolean isReadable() {
380: return this .isReadable;
381: }
382:
383: /**
384: * Returns write access mode for the role (true if it is writable)
385: *
386: * @return True if it is writable otherwise false
387: */
388: public boolean isWritable() {
389: return this .isWritable;
390: }
391:
392: /**
393: * Prints a string describing the role info
394: *
395: * Overrides:
396: * toString in class java.lang.Object
397: *
398: * @return String representation of the role info
399: */
400: public String toString() {
401: StringBuffer str = new StringBuffer();
402:
403: str.append("RoleInfo Name:" + getName() + "; isReadable:"
404: + isReadable() + "; isWritable:" + isWritable()
405: + "; Description:" + getDescription()
406: + "; Minimum Degree:" + getMinDegree()
407: + "; Maximum Degree:" + getMaxDegree()
408: + "; MBean Class:" + getRefMBeanClassName());
409:
410: return str.toString();
411: }
412:
413: //--------------------------- Private methods --------------------------//
414:
415: private void testForCompliance(String className)
416: throws NotCompliantMBeanException {
417: Class cl = null;
418:
419: try {
420: cl = Class.forName(className);
421: int i = cl.getModifiers();
422:
423: if (Modifier.isAbstract(i))
424: throw new NotCompliantMBeanException(
425: "The MBean cannot be a abstract class");
426:
427: Constructor constructors[] = cl.getConstructors();
428:
429: if (constructors.length == 0)
430: throw new NotCompliantMBeanException(
431: "The MBean does not have a public constructor");
432: } catch (ClassNotFoundException ee) {
433: //ee.printStackTrace();
434: //log.warn("ClassNotFoundException",ee);
435: }
436:
437: Class super Class = null;
438: super Class = cl;
439: Class class1 = null;
440: Class class2 = null;
441: boolean flag = false;
442:
443: for (; super Class != null; super Class = super Class
444: .getSuperclass()) {
445: Class[] interfaces = super Class.getInterfaces();
446: boolean checkFlag = false;
447: for (int j = 0; j < interfaces.length; j++) {
448: Class tempClass = checkForMBeanInterface(interfaces[j],
449: super Class.getName());
450: if (tempClass != null) {
451: flag = true;
452: class1 = tempClass;
453: class2 = super Class;
454: }
455: if (checkForDynamicMBeanInterface(interfaces[j])) {
456: flag = true;
457: checkFlag = true;
458: }
459: if (class1 != null && super Class.equals(class2)
460: && checkFlag)
461: throw new NotCompliantMBeanException(
462: className
463: + " implements javax.management.DynamicMBean and MBean interface");
464: }
465: if (flag)
466: break;
467: }
468: if (!flag)
469: throw new NotCompliantMBeanException(className
470: + " does not implement the " + className + "MBean"
471: + " interface or the DynamicMBean interface");
472: }
473:
474: private Class checkForMBeanInterface(Class class1, String s) {
475: if (class1.getName().compareTo(s + "MBean") == 0)
476: return class1;
477:
478: Class aclass[] = class1.getInterfaces();
479:
480: for (int i = 0; i < aclass.length; i++) {
481: if (aclass[i].getName().compareTo(s + "MBean") == 0)
482: return aclass[i];
483: }
484:
485: return null;
486: }
487:
488: private boolean checkForDynamicMBeanInterface(Class class1) {
489: if (class1.getName().compareTo("javax.management.DynamicMBean") == 0)
490: return true;
491:
492: Class aclass[] = class1.getInterfaces();
493:
494: for (int i = 0; i < aclass.length; i++)
495: if (aclass[i].getName().compareTo(
496: "javax.management.DynamicMBean") == 0)
497: return true;
498:
499: return false;
500: }
501:
502: private boolean isValidMBeanInfo(MBeanInfo mbInfo) {
503: if (mbInfo.getClassName() == null) {
504: return false;
505: }
506:
507: MBeanConstructorInfo[] consInfo = mbInfo.getConstructors();
508: if (consInfo == null) {
509: return false;
510: } else if (consInfo.length == 0) {
511: return false;
512: }
513:
514: return true;
515: }
516: }
|