001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package javax.management.relation;
010:
011: import java.util.ArrayList;
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.List;
015: import java.util.Map;
016: import javax.management.MBeanRegistration;
017: import javax.management.MBeanServer;
018: import javax.management.MBeanServerInvocationHandler;
019: import javax.management.ObjectName;
020: import javax.management.RuntimeOperationsException;
021:
022: import mx4j.log.Log;
023: import mx4j.log.Logger;
024:
025: /**
026: * @version $Revision: 1.17 $
027: */
028: public class RelationSupport implements RelationSupportMBean,
029: MBeanRegistration {
030: private String m_relationId;
031: private String m_relationTypeName;
032: private ObjectName m_relationServiceObjectName;
033: private MBeanServer m_server;
034: private RelationServiceMBean m_proxy;
035: private Boolean m_isInRelationService = Boolean.FALSE;
036: private Map m_roleNameToRole = new HashMap();
037:
038: public RelationSupport(String relationId,
039: ObjectName relationServiceObjectName, MBeanServer server,
040: String relationTypeName, RoleList roleList)
041: throws InvalidRoleValueException, IllegalArgumentException {
042: init(relationId, relationServiceObjectName, relationTypeName,
043: roleList);
044: // note the server may at this stage be null;
045: m_server = server;
046: m_proxy = (RelationServiceMBean) MBeanServerInvocationHandler
047: .newProxyInstance(m_server,
048: m_relationServiceObjectName,
049: RelationServiceMBean.class, false);
050: }
051:
052: private void init(String relationId,
053: ObjectName relationServiceObjectName,
054: String relationTypeName, RoleList roleList)
055: throws InvalidRoleValueException {
056: if (relationId == null)
057: throw new IllegalArgumentException(
058: "Illegal Null RelationId");
059: if (relationServiceObjectName == null)
060: throw new IllegalArgumentException(
061: "Illegal Null RelationService ObjectName");
062: if (relationTypeName == null)
063: throw new IllegalArgumentException(
064: "Illegal Null RelationTypeName");
065: if (roleList == null)
066: roleList = new RoleList();
067:
068: m_relationId = relationId;
069: m_relationServiceObjectName = relationServiceObjectName;
070: m_relationTypeName = relationTypeName;
071: //checks if role are not already in Map if not add them
072: initializeRoleList(roleList);
073: }
074:
075: public RelationSupport(String relationId,
076: ObjectName relationServiceObjectName,
077: String relationTypeName, RoleList roleList)
078: throws InvalidRoleValueException, IllegalArgumentException {
079: init(relationId, relationServiceObjectName, relationTypeName,
080: roleList);
081: }
082:
083: public List getRole(String roleName)
084: throws IllegalArgumentException, RoleNotFoundException,
085: RelationServiceNotRegisteredException {
086: Logger logger = getLogger();
087: if (roleName == null)
088: throw new IllegalArgumentException(
089: "Role name cannot be null");
090: if (logger.isEnabledFor(Logger.WARN))
091: logger.warn("getting roles whith RoleName: " + roleName
092: + " from RelationSupport");
093: Role role = getRoleFromRoleName(roleName);
094: // check role reading
095: int problemType = getReadingProblemType(role, roleName,
096: m_relationTypeName);
097: // no clone read only role found can return the list
098: if (problemType == 0)
099: return (role.getRoleValue());
100: else {
101: if (problemType == RoleStatus.NO_ROLE_WITH_NAME) {
102: logger.warn("RoleName: " + roleName + " not found");
103: throw new RoleNotFoundException("RoleName: " + roleName
104: + " does not exist in the relation");
105: } else if (problemType == RoleStatus.ROLE_NOT_READABLE) {
106: logger.warn("Role with roleName: " + roleName
107: + " cannot be read.");
108: throw new RoleNotFoundException("RoleName: " + roleName
109: + " is not readable");
110: }
111: }
112: // need to return something to satisfy compiler, if we get here !!
113: return null;
114: }
115:
116: int getReadingProblemType(Role role, String roleName,
117: String relationTypeName)
118: throws RelationServiceNotRegisteredException,
119: IllegalArgumentException {
120: if (roleName == null)
121: throw new IllegalArgumentException("Null Role Name.");
122: Logger logger = getLogger();
123: if (logger.isEnabledFor(Logger.WARN))
124: logger.warn("Checking the Role reading...");
125: if (role == null)
126: return (RoleStatus.NO_ROLE_WITH_NAME);
127: try {
128: return (m_proxy
129: .checkRoleReading(roleName, relationTypeName))
130: .intValue();
131: } catch (RelationTypeNotFoundException ex) {
132: logger.warn("Unable to find the Relation Type with name "
133: + relationTypeName);
134: throw new RuntimeOperationsException(null,
135: "Relation Type with name: " + relationTypeName
136: + " was not found");
137: }
138: }
139:
140: public RoleResult getRoles(String[] roleNames)
141: throws IllegalArgumentException,
142: RelationServiceNotRegisteredException {
143: if (roleNames == null)
144: throw new IllegalArgumentException("Null RoleName Array.");
145: Logger logger = getLogger();
146: if (logger.isEnabledFor(Logger.WARN))
147: logger.warn("Getting roles");
148: RoleList roleList = new RoleList();
149: RoleUnresolvedList unresolvedList = new RoleUnresolvedList();
150: for (int i = 0; i < roleNames.length; i++) {
151: String currentRoleName = roleNames[i];
152: Role role = getRoleFromRoleName(currentRoleName);
153: // check role reading for each role
154: int problemType = getReadingProblemType(role,
155: currentRoleName, m_relationTypeName);
156: // no problems - the role can read add it to roleList
157: if (problemType == 0)
158: roleList.add((Role) (role.clone()));
159: // we have a problem add the role to roleUnresolvedList with the problemType
160: else
161: unresolvedList.add((new RoleUnresolved(currentRoleName,
162: null, problemType)));
163: }
164: return (new RoleResult(roleList, unresolvedList));
165: }
166:
167: // can do here is get the list create a String[] of roleNames pass this to getRole(String[] roleNames)
168: public RoleResult getAllRoles()
169: throws RelationServiceNotRegisteredException {
170: Logger logger = getLogger();
171: if (logger.isEnabledFor(Logger.WARN))
172: logger.warn("getting all roles");
173: List roleNameList = getAllRoleNamesList();
174: String[] roleNames = new String[roleNameList.size()];
175: int index = 0;
176: for (Iterator i = roleNameList.iterator(); i.hasNext();) {
177: roleNames[index] = (String) i.next();
178: index++;
179: }
180: return (getRoles(roleNames));
181: }
182:
183: public RoleList retrieveAllRoles() {
184: synchronized (m_roleNameToRole) {
185: return (new RoleList(new ArrayList(m_roleNameToRole
186: .values())));
187: }
188: }
189:
190: private ArrayList getAllRolesList() {
191: synchronized (m_roleNameToRole) {
192: return (new ArrayList(m_roleNameToRole.values()));
193: }
194: }
195:
196: public void setRole(Role role) throws IllegalArgumentException,
197: RoleNotFoundException, RelationTypeNotFoundException,
198: InvalidRoleValueException,
199: RelationServiceNotRegisteredException,
200: RelationNotFoundException {
201: if (role == null)
202: throw new IllegalArgumentException(
203: "RelationSupport setRole has recieved a null Role.");
204:
205: String roleName = role.getRoleName();
206: Role oldRole = getRoleFromRoleName(roleName);
207: List oldRoleValue;
208: Boolean toBeInitialized;
209: // no role found therefore we have a new role and a new List to hold it
210: if (oldRole == null) {
211: toBeInitialized = new Boolean(true);
212: oldRoleValue = new ArrayList();
213: } else {
214: // role found we do not need to initialize the role
215: toBeInitialized = new Boolean(false);
216: oldRoleValue = oldRole.getRoleValue();
217: }
218: // check if the role is writable
219: int problemType = getRoleWritingValue(role, m_relationTypeName,
220: toBeInitialized);
221: if (problemType == 0) {
222: if (!(toBeInitialized.booleanValue())) {
223: // new role send an update notification
224: sendUpdateRoleNotification(m_relationId, role,
225: oldRoleValue);
226: updateRelationServiceMap(m_relationId, role,
227: oldRoleValue);
228: }
229: addRolesToRoleMap(roleName, role);
230: } else {
231: RelationService.throwRoleProblemException(problemType,
232: roleName);
233: }
234: }
235:
236: // checks if the role is writable
237: int getRoleWritingValue(Role role, String relationTypeName,
238: Boolean toBeInitialized)
239: throws RelationTypeNotFoundException {
240: if (m_proxy == null)
241: throw new IllegalArgumentException(
242: "Please check the RelationService is running");
243: return (m_proxy.checkRoleWriting(role, relationTypeName,
244: toBeInitialized).intValue());
245: }
246:
247: public RoleResult setRoles(RoleList roleList)
248: throws IllegalArgumentException,
249: RelationServiceNotRegisteredException,
250: RelationTypeNotFoundException, RelationNotFoundException {
251: Logger logger = getLogger();
252: if (roleList == null)
253: throw new IllegalArgumentException(
254: "RoleList cannot be null");
255: if (logger.isEnabledFor(Logger.WARN))
256: logger.warn("setting roles");
257: RoleList newRoleList = new RoleList();
258: RoleUnresolvedList roleUnresolvedList = new RoleUnresolvedList();
259: List oldRoleValue;
260: Boolean needsInitializing;
261: for (Iterator i = roleList.iterator(); i.hasNext();) {
262: Role currentRole = (Role) i.next();
263: String roleName = currentRole.getRoleName();
264: Role oldRole = getRoleFromRoleName(roleName);
265: if (oldRole == null) {
266: needsInitializing = new Boolean(true);
267: oldRoleValue = new ArrayList();
268: } else {
269: needsInitializing = new Boolean(false);
270: oldRoleValue = oldRole.getRoleValue();
271: }
272: int problemType = getRoleWritingValue(currentRole,
273: m_relationTypeName, needsInitializing);
274: if (problemType == 0) {
275: if (!(needsInitializing.booleanValue())) {
276: // send notification update RelationService map
277: sendUpdateRoleNotification(m_relationId,
278: currentRole, oldRoleValue);
279: updateRelationServiceMap(m_relationId, currentRole,
280: oldRoleValue);
281: }
282: // add the roles
283: addRolesToRoleMap(roleName, currentRole);
284: newRoleList.add(currentRole);
285: } else {
286: if (logger.isEnabledFor(Logger.WARN))
287: logger
288: .warn("We have some unresolved roles adding them to RoleUnresolvedList");
289: roleUnresolvedList.add(new RoleUnresolved(roleName,
290: currentRole.getRoleValue(), problemType));
291: }
292: }
293: return (new RoleResult(newRoleList, roleUnresolvedList));
294: }
295:
296: // check role conforms to defined cardinality
297: public Integer getRoleCardinality(String roleName)
298: throws IllegalArgumentException, RoleNotFoundException {
299: Logger logger = getLogger();
300: if (logger.isEnabledFor(Logger.WARN))
301: logger.warn("checking role cardinality with role named: "
302: + roleName);
303: if (roleName == null)
304: throw new IllegalArgumentException(
305: "Role name should not be null.");
306: Role role = getRoleFromRoleName(roleName);
307: if (role == null) {
308: int problemType = RoleStatus.NO_ROLE_WITH_NAME;
309: try {
310: // send the role cardinality error to the RelationService
311: RelationService.throwRoleProblemException(problemType,
312: roleName);
313: } catch (InvalidRoleValueException ex) {
314: new RuntimeOperationsException(null,
315: "Invalid role value");
316: }
317: }
318: List roleValue = role.getRoleValue();
319: return new Integer(roleValue.size());
320: }
321:
322: public void handleMBeanUnregistration(ObjectName objectName,
323: String roleName) throws IllegalArgumentException,
324: RoleNotFoundException, InvalidRoleValueException,
325: RelationServiceNotRegisteredException,
326: RelationTypeNotFoundException, RelationNotFoundException {
327: Logger logger = getLogger();
328: if (objectName == null)
329: throw new IllegalArgumentException("ObjectName is null");
330: if (roleName == null)
331: throw new IllegalArgumentException("Null roleName");
332: if (logger.isEnabledFor(Logger.WARN)) {
333: logger.warn("MBean with ObjectName: "
334: + objectName.getCanonicalName()
335: + " has been unregistered from the"
336: + " MBeanServer. Setting new Role values");
337: }
338: Role newRole = createNewRole(roleName, objectName);
339: setRole(newRole);
340: }
341:
342: private Role createNewRole(String roleName, ObjectName objectName)
343: throws RoleNotFoundException {
344: // get role stored in the Map
345: Role role = getRoleFromRoleName(roleName);
346: if (role == null)
347: throw new RoleNotFoundException(
348: "No role found for role name: " + roleName);
349:
350: // needs to be cloned as will be modified, need to cast role.getRoleValue as list does not implement Cloneable
351: ArrayList newRoleValue = (ArrayList) ((ArrayList) role
352: .getRoleValue()).clone();
353: newRoleValue.remove(objectName);
354: Role newRole = new Role(roleName, newRoleValue);
355: return newRole;
356: }
357:
358: public Map getReferencedMBeans() {
359: Logger logger = getLogger();
360: if (logger.isEnabledFor(Logger.WARN))
361: logger.warn("getting mbeanReferenced in RelationService");
362: HashMap referencedMBeansMap = new HashMap();
363: for (Iterator i = (getAllRolesList()).iterator(); i.hasNext();) {
364: Role currentRole = (Role) i.next();
365: String currentRoleName = currentRole.getRoleName();
366: // get the roleValues for each Role
367: List mbeanList = currentRole.getRoleValue();
368: for (Iterator iter = mbeanList.iterator(); iter.hasNext();) {
369: ObjectName currentObjectName = (ObjectName) iter.next();
370: List mbeanRoleNameList = (List) (referencedMBeansMap
371: .get(currentObjectName));
372: boolean newReference = false;
373: if (mbeanRoleNameList == null) {
374: // we have new references
375: newReference = true;
376: mbeanRoleNameList = new ArrayList();
377: }
378: mbeanRoleNameList.add(currentRoleName);
379: // we have a new reference add it to our map.
380: if (newReference)
381: referencedMBeansMap.put(currentObjectName,
382: mbeanRoleNameList);
383: }
384: }
385: return referencedMBeansMap;
386: }
387:
388: private Role getRoleFromRoleName(String roleName) {
389: synchronized (m_roleNameToRole) {
390: return ((Role) m_roleNameToRole.get(roleName));
391: }
392: }
393:
394: public String getRelationTypeName() {
395: return m_relationTypeName;
396: }
397:
398: public ObjectName getRelationServiceName() {
399: return m_relationServiceObjectName;
400: }
401:
402: public String getRelationId() {
403: return m_relationId;
404: }
405:
406: public Boolean isInRelationService() {
407: return m_isInRelationService;
408: }
409:
410: public void setRelationServiceManagementFlag(
411: Boolean isHandledByRelationService)
412: throws IllegalArgumentException {
413: if (isHandledByRelationService == null)
414: throw new IllegalArgumentException("Null flag");
415: m_isInRelationService = isHandledByRelationService;
416: }
417:
418: public ObjectName preRegister(MBeanServer server, ObjectName name)
419: throws Exception {
420: if (server == null)
421: throw new IllegalArgumentException(
422: "MBean Server is null cannot pre-register.");
423: if (name == null)
424: throw new IllegalArgumentException(
425: "Cannot register a null ObjectName");
426: Logger logger = getLogger();
427: if (logger.isEnabledFor(Logger.WARN))
428: logger.warn("pre Registering the RelationSupport");
429: m_server = server;
430: m_proxy = (RelationServiceMBean) MBeanServerInvocationHandler
431: .newProxyInstance(m_server,
432: m_relationServiceObjectName,
433: RelationServiceMBean.class, false);
434: return name;
435: }
436:
437: public void postRegister(Boolean registrationDone) {
438: Logger logger = getLogger();
439: boolean done = registrationDone.booleanValue();
440: if (!done) {
441: m_server = null;
442: logger.warn("RelationSupport was NOT registered");
443: } else {
444: if (logger.isEnabledFor(Logger.TRACE)) {
445: logger.trace("RelationSupport postRegistered");
446: }
447: }
448: }
449:
450: public void preDeregister() throws Exception {
451: Logger logger = getLogger();
452: if (logger.isEnabledFor(Logger.TRACE)) {
453: logger.debug("RelationSupport preDeregistered");
454: }
455: }
456:
457: public void postDeregister() {
458: Logger logger = getLogger();
459: if (logger.isEnabledFor(Logger.TRACE)) {
460: logger.debug("RelationSupport postDeregistered");
461: }
462: }
463:
464: private List getAllRoleNamesList() {
465: synchronized (m_roleNameToRole) {
466: return (new ArrayList(m_roleNameToRole.keySet()));
467: }
468: }
469:
470: private void initializeRoleList(RoleList roleList)
471: throws InvalidRoleValueException {
472: if (roleList == null)
473: return;
474: for (Iterator i = roleList.iterator(); i.hasNext();) {
475: Role currentRole = (Role) i.next();
476: String currentRoleName = currentRole.getRoleName();
477: // our map already holds the current roleName cannot re-use it let the user know
478: if (m_roleNameToRole.containsKey(currentRoleName)) {
479: throw new InvalidRoleValueException(
480: "RoleName already in use.");
481: }
482: // no existing roleName found add the values in the RoleList
483: addRolesToRoleMap(currentRoleName, currentRole);
484: }
485: }
486:
487: private void addRolesToRoleMap(String roleName, Role role) {
488: synchronized (m_roleNameToRole) {
489: m_roleNameToRole.put(roleName, role.clone());
490: }
491: }
492:
493: void updateRelationServiceMap(String relationId, Role role,
494: List oldRoleValue) throws IllegalArgumentException,
495: RelationServiceNotRegisteredException,
496: RelationNotFoundException {
497: Logger logger = getLogger();
498: if (m_proxy != null)
499: m_proxy.updateRoleMap(relationId, role, oldRoleValue);
500: else {
501: logger.warn("The RelationService cannot be registered.");
502: throw new RelationServiceNotRegisteredException(
503: "Please check the RelationService is registered in the server");
504: }
505: }
506:
507: void sendUpdateRoleNotification(String relationId, Role role,
508: List oldRoleValue)
509: throws RelationServiceNotRegisteredException,
510: RelationNotFoundException {
511: Logger logger = getLogger();
512: if (relationId == null)
513: throw new IllegalArgumentException(
514: "Null RelationId passed into sendUpdateRoleNotification");
515: if (role == null)
516: throw new IllegalArgumentException(
517: "Null role passed into sendUpdateRoleNotification");
518: if (oldRoleValue == null)
519: throw new IllegalArgumentException(
520: "Null list of role Values passed into sendUpdateRoleNotification");
521: if (m_proxy != null)
522: m_proxy.sendRoleUpdateNotification(relationId, role,
523: oldRoleValue);
524: else {
525: logger
526: .warn("cannot send an update notification as RelationService may not be registered, please check.");
527: throw new RelationServiceNotRegisteredException(
528: "Please check the relation service has been registered in the MBeanServer");
529: }
530: }
531:
532: private Logger getLogger() {
533: return Log.getLogger(getClass().getName());
534: }
535: }
|