1 /*
2 * JBoss, the OpenSource J2EE webOS
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */
7 package javax.management.relation;
8
9 import java.util.ArrayList;
10 import java.util.HashSet;
11 import java.util.Iterator;
12
13 import javax.management.MBeanServer;
14 import javax.management.MBeanException;
15 import javax.management.ObjectName;
16
17 /**
18 * This is a helper class for performing role validation. It is used by
19 * both the RelationSupport and RelationService classes.<p>
20 *
21 * It is package private and NOT part of the specification.
22 *
23 * <p><b>Revisions:</b>
24 * <p><b>20020311 Adrian Brock:</b>
25 * <ul>
26 * <li>ValidateRole always failed
27 * <li>Throws wrong exception when not writable
28 * </ul>
29 *
30 * @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
31 * @version $Revision: 1.3.6.1 $
32 *
33 */
34 class RoleValidator
35 {
36 // Constants ---------------------------------------------------
37
38 // Static ------------------------------------------------------
39
40 /**
41 * Check a role for a relation type
42 *
43 * @param relationService the relation service object name
44 * @param server the MBeanServer of the relation service
45 * @param relationTypeName the relation to validate against
46 * @param role the role to validate
47 * @param write pass to true to check for a writable role
48 * @return zero for success or a RoleStatus value for failure
49 * @exception RelationTypeNotFoundException when the relation type
50 * does not exist in the relation service
51 */
52 public static int checkRole(ObjectName relationService, MBeanServer server,
53 String relationTypeName, Role role, boolean write)
54 throws RelationTypeNotFoundException
55 {
56 // Get the role information
57 RoleInfo roleInfo = null;
58 try
59 {
60 roleInfo = (RoleInfo) server.invoke(relationService, "getRoleInfo",
61 new Object[] { relationTypeName, role.getRoleName() },
62 new String[] { "java.lang.String", "java.lang.String" });
63 }
64 catch (MBeanException mbe)
65 {
66 Exception e=mbe.getTargetException();
67 if (e instanceof RelationTypeNotFoundException)
68 throw (RelationTypeNotFoundException) e;
69 if (e instanceof RoleInfoNotFoundException)
70 return RoleStatus.NO_ROLE_WITH_NAME;
71 throw new RuntimeException(e.toString());
72 }
73 catch (Exception e)
74 {
75 throw new RuntimeException(e.toString());
76 }
77
78 // Check if the role is writable
79 if (write == true && roleInfo.isWritable() == false)
80 return RoleStatus.ROLE_NOT_WRITABLE;
81
82 // Check the cardinality of the role
83 ArrayList mbeans = (ArrayList) role.getRoleValue();
84 int beanCount = mbeans.size();
85 int minimum = roleInfo.getMinDegree();
86 if (minimum != RoleInfo.ROLE_CARDINALITY_INFINITY && minimum > beanCount)
87 return RoleStatus.LESS_THAN_MIN_ROLE_DEGREE;
88 int maximum = roleInfo.getMaxDegree();
89 if (maximum != RoleInfo.ROLE_CARDINALITY_INFINITY && maximum < beanCount)
90 return RoleStatus.MORE_THAN_MAX_ROLE_DEGREE;
91
92 // Check the MBeans
93 String className = roleInfo.getRefMBeanClassName();
94
95 for (int i = 0; i < mbeans.size(); i++)
96 {
97 try
98 {
99 ObjectName objectName = (ObjectName) mbeans.get(i);
100 if (server.isInstanceOf(objectName, className) == false)
101 return RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS;
102 }
103 catch (Exception e)
104 {
105 return RoleStatus.REF_MBEAN_NOT_REGISTERED;
106 }
107 }
108 // All done
109 return 0;
110 }
111
112 /**
113 * Check the Roles for a relation Type.
114 *
115 * @param relationService the relation service object name
116 * @param server the MBeanServer of the relation service
117 * @param relationTypeName the relation to validate against
118 * @param roleList the roles to validate
119 * @param write pass to true to check for a writable role
120 * @return a RoleResult containing resolved and unresolved roles
121 * @exception RelationTypeNotFoundException when the relation type
122 * does not exist in the relation service
123 */
124 public static RoleResult checkRoles(ObjectName relationService,
125 MBeanServer server, String relationTypeName, RoleList roleList,
126 boolean write)
127 throws RelationTypeNotFoundException
128 {
129 // Set up the return value
130 RoleList resolved = new RoleList();
131 RoleUnresolvedList unresolved = new RoleUnresolvedList();
132 RoleResult result = new RoleResult(resolved, unresolved);
133
134 // Check each role
135 Iterator iterator = roleList.iterator();
136 while (iterator.hasNext())
137 {
138 Role role = (Role) iterator.next();
139 int status = checkRole(relationService, server, relationTypeName, role,
140 write);
141 if (status == 0)
142 resolved.add(role);
143 else
144 unresolved.add(new RoleUnresolved(role.getRoleName(),
145 role.getRoleValue(), status));
146 }
147 // All Done
148 return result;
149 }
150
151 /**
152 * Validate a role for a relation Type.
153 *
154 * @param relationService the relation service object name
155 * @param server the MBeanServer of the relation service
156 * @param relationTypeName the relation to validate against
157 * @param role the role to validate
158 * @param write pass to true to check for a writable role
159 * @exception InvalidRoleValueException when a role does not match its
160 * definition in the relation type's roleinfos
161 * @exception RelationTypeNotFoundException when the relation type
162 * does not exist in the relation service
163 * @exception RoleNotFoundException when a role does not exist
164 * in the role
165 */
166 public static void validateRole(ObjectName relationService,
167 MBeanServer server, String relationTypeName, Role role, boolean write)
168 throws InvalidRoleValueException, RelationTypeNotFoundException,
169 RoleNotFoundException
170 {
171 int status = checkRole(relationService, server, relationTypeName, role,
172 write);
173
174 if (status == RoleStatus.NO_ROLE_WITH_NAME)
175 throw new RoleNotFoundException(role.getRoleName());
176 if (status == RoleStatus.ROLE_NOT_WRITABLE)
177 throw new RoleNotFoundException(role.getRoleName() + " not writable");
178 else if (status != 0)
179 throw new InvalidRoleValueException(role.getRoleName());
180 }
181
182 /**
183 * Validate the Roles for a relation Type.
184 *
185 * @param relationService the relation service object name
186 * @param server the MBeanServer of the relation service
187 * @param relationTypeName the relation to validate against
188 * @param roleList the roles to validate
189 * @param write pass to true to check for a writable role
190 * @exception InvalidRoleValueException when there is a duplicate role name
191 * or a role does not match its definition in the
192 * relation type's roleinfos
193 * @exception RelationTypeNotFoundException when the relation type
194 * does not exist in the relation service
195 * @exception RoleNotFoundException when a role does not exist
196 * in the role
197 */
198 public static void validateRoles(ObjectName relationService,
199 MBeanServer server, String relationTypeName, RoleList roleList,
200 boolean write)
201 throws InvalidRoleValueException, RelationTypeNotFoundException,
202 RoleNotFoundException
203 {
204 Iterator iterator;
205
206 // Check for duplicate roles
207 HashSet roleNames = new HashSet();
208 iterator = roleList.iterator();
209 while (iterator.hasNext())
210 {
211 Object roleName = iterator.next();
212 if (roleNames.contains(roleName))
213 throw new InvalidRoleValueException("Duplicate role " + roleName);
214 roleNames.add(roleName);
215 }
216
217 // Check the roles
218 RoleResult result = checkRoles(relationService, server, relationTypeName,
219 roleList, write);
220 RoleUnresolvedList errors = result.getRolesUnresolved();
221 iterator = errors.iterator();
222 if (iterator.hasNext())
223 {
224 RoleUnresolved unresolved = (RoleUnresolved) iterator.next();
225 int status = unresolved.getProblemType();
226 if (status == RoleStatus.NO_ROLE_WITH_NAME)
227 throw new RoleNotFoundException(unresolved.getRoleName());
228 if (status == RoleStatus.ROLE_NOT_WRITABLE)
229 throw new RoleNotFoundException(unresolved.getRoleName() + " not writable");
230 else
231 throw new InvalidRoleValueException(unresolved.getRoleName());
232 }
233 }
234 }