package javax.management.relation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.jboss.mx.util.MBeanProxy;
import org.jboss.mx.util.MBeanProxyCreationException;
public class RelationSupport
implements RelationSupportMBean, MBeanRegistration
{
String relationId;
ObjectName relationService;
private RelationServiceMBean serviceProxy;
MBeanServer server;
String relationTypeName;
HashMap roles;
Boolean registered;
public RelationSupport(String relationId, ObjectName relationService,
String relationTypeName, RoleList roleList)
throws IllegalArgumentException, InvalidRoleValueException
{
init(relationId, relationService, null, relationTypeName, roleList);
}
public RelationSupport(String relationId, ObjectName relationService,
MBeanServer mbeanServer, String relationTypeName,
RoleList roleList)
throws IllegalArgumentException, InvalidRoleValueException
{
init(relationId, relationService, mbeanServer, relationTypeName,
roleList);
}
public RoleResult getAllRoles()
throws RelationServiceNotRegisteredException
{
RoleList resolvedResult = new RoleList();
RoleUnresolvedList unresolvedResult = new RoleUnresolvedList();
RoleResult result = new RoleResult(resolvedResult, unresolvedResult);
synchronized (roles)
{
Iterator iterator = roles.values().iterator();
while (iterator.hasNext())
{
Role role = (Role) iterator.next();
int status = checkRoleReadable(role);
if (status == 0)
resolvedResult.add(role);
else
unresolvedResult.add(new RoleUnresolved(role.getRoleName(),
role.getRoleValue(),
status));
}
}
return result;
}
public Map getReferencedMBeans()
{
HashMap result = new HashMap();
synchronized (roles)
{
Iterator iterator = roles.values().iterator();
while (iterator.hasNext())
{
Role role = (Role) iterator.next();
String roleName = role.getRoleName();
ArrayList mbeans = (ArrayList) role.getRoleValue();
Iterator mbeanIterator = mbeans.iterator();
while (mbeanIterator.hasNext())
{
ObjectName mbean = (ObjectName) mbeanIterator.next();
ArrayList resultRoles = (ArrayList) result.get(mbean);
if (resultRoles == null)
{
resultRoles = new ArrayList();
result.put(mbean, resultRoles);
}
resultRoles.add(roleName);
}
}
}
return result;
}
public String getRelationId()
{
return relationId;
}
public ObjectName getRelationServiceName()
{
return relationService;
}
public String getRelationTypeName()
{
return relationTypeName;
}
public List getRole(String roleName)
throws IllegalArgumentException, RoleNotFoundException,
RelationServiceNotRegisteredException
{
if (roleName == null)
throw new IllegalArgumentException("null role name");
validateRoleReadable(roleName);
Role role = validateRoleFound(roleName);
return role.getRoleValue();
}
public Integer getRoleCardinality(String roleName)
throws IllegalArgumentException, RoleNotFoundException
{
if (roleName == null)
throw new IllegalArgumentException("null role name");
Role role = validateRoleFound(roleName);
return new Integer(role.getRoleValue().size());
}
public RoleResult getRoles(String[] roleNames)
throws IllegalArgumentException, RelationServiceNotRegisteredException
{
RoleList resolvedResult = new RoleList();
RoleUnresolvedList unresolvedResult = new RoleUnresolvedList();
RoleResult result = new RoleResult(resolvedResult, unresolvedResult);
for (int i = 0; i < roleNames.length; i++)
{
int status = RoleStatus.NO_ROLE_WITH_NAME;
List roleValue;
Role role = (Role) roles.get(roleNames[i]);
if (role != null)
{
roleValue = role.getRoleValue();
status = checkRoleReadable(role);
}
else
roleValue = new ArrayList();
if (status == 0)
resolvedResult.add(role);
else
unresolvedResult.add(new RoleUnresolved(roleNames[i], roleValue, status));
}
return result;
}
public void handleMBeanUnregistration(ObjectName objectName, String roleName)
throws IllegalArgumentException,
RoleNotFoundException, InvalidRoleValueException,
RelationServiceNotRegisteredException, RelationTypeNotFoundException,
RelationNotFoundException
{
checkRegistered();
Role role = validateRoleFound(roleName);
ArrayList values = (ArrayList) role.getRoleValue();
ArrayList oldRoleValue = new ArrayList(values);
if (values.remove(objectName) == false)
throw new InvalidRoleValueException(roleName + " " + objectName.toString());
role.setRoleValue(values);
updateRole(role, oldRoleValue);
}
public RoleList retrieveAllRoles()
{
RoleList result = new RoleList(roles.size());
synchronized (roles)
{
Iterator iterator = roles.values().iterator();
while (iterator.hasNext())
result.add((Role) iterator.next());
}
return result;
}
public void setRole(Role role)
throws IllegalArgumentException,
RoleNotFoundException,
RelationTypeNotFoundException,
InvalidRoleValueException,
RelationServiceNotRegisteredException,
RelationNotFoundException
{
if (role == null)
throw new IllegalArgumentException("null role");
Role copy = (Role) role.clone();
checkRegistered();
RoleValidator.validateRole(relationService, server, relationTypeName, copy,
true);
Role oldRole = (Role) roles.get(role.getRoleName());
ArrayList oldRoleValue = (ArrayList) oldRole.getRoleValue();
updateRole(copy, oldRoleValue);
}
public RoleResult setRoles(RoleList roleList)
throws IllegalArgumentException, RelationServiceNotRegisteredException,
RelationTypeNotFoundException, RelationNotFoundException
{
if (roleList == null)
throw new IllegalArgumentException("null role list");
RoleList copy = new RoleList(roleList);
checkRegistered();
RoleResult result = RoleValidator.checkRoles(relationService, server,
relationTypeName, copy, true);
synchronized (result.getRoles())
{
Iterator iterator = result.getRoles().iterator();
while (iterator.hasNext())
{
Role role = (Role) iterator.next();
Role oldRole = (Role) roles.get(role.getRoleName());
ArrayList oldRoleValue = (ArrayList) oldRole.getRoleValue();
updateRole(role, oldRoleValue);
}
}
return result;
}
public Boolean isInRelationService()
{
return registered;
}
public void setRelationServiceManagementFlag(Boolean value)
throws IllegalArgumentException
{
synchronized (registered)
{
registered = new Boolean(value.booleanValue());
}
}
public ObjectName preRegister(MBeanServer server, ObjectName objectName)
throws Exception
{
this.server = server;
return objectName;
}
public void postRegister(Boolean registered)
{
}
public void preDeregister()
throws Exception
{
}
public void postDeregister()
{
server = null;
}
private void init(String relationId, ObjectName relationService,
MBeanServer mbeanServer, String relationTypeName,
RoleList roleList)
throws IllegalArgumentException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
if (relationService == null)
throw new IllegalArgumentException("null relation service");
if (relationTypeName == null)
throw new IllegalArgumentException("null relation type name");
this.relationId = relationId;
this.relationTypeName = relationTypeName;
this.relationService = relationService;
if (mbeanServer != null)
server = mbeanServer;
registered = new Boolean(false);
if (roleList == null)
roles = new HashMap();
else
{
Object[] roleArray = roleList.toArray();
roles = new HashMap(roleArray.length);
for (int i = 0; i < roleArray.length; i++)
{
Role role = (Role) roleArray[i];
if (roles.containsKey(role.getRoleName()))
throw new IllegalArgumentException("duplicate role name");
Role copy = (Role) role.clone();
roles.put(role.getRoleName(), copy);
}
}
}
private void checkRegistered()
throws RelationNotFoundException
{
if (isInRelationService().booleanValue() == false)
throw new RelationNotFoundException("not registered with relation service");
}
private int checkRoleReadable(Role role)
throws RelationServiceNotRegisteredException
{
checkServiceProxy();
try
{
String roleName = role.getRoleName();
Integer result = serviceProxy.checkRoleReading(roleName, relationTypeName);
return result.intValue();
}
catch (RelationTypeNotFoundException e)
{
throw new RuntimeException(e.toString());
}
}
private void updateRole(Role role, ArrayList oldRoleValue)
{
roles.put(role.getRoleName(), role);
try
{
checkServiceProxy();
serviceProxy.updateRoleMap(relationId, role, oldRoleValue);
serviceProxy.sendRoleUpdateNotification(relationId, role, oldRoleValue);
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
private Role validateRoleFound(String roleName)
throws RoleNotFoundException
{
Role result = (Role) roles.get(roleName);
if (result == null)
throw new RoleNotFoundException(roleName);
return result;
}
private void validateRoleReadable(String roleName)
throws RoleNotFoundException, RelationServiceNotRegisteredException
{
int status = 0;
checkServiceProxy();
try
{
status = serviceProxy.checkRoleReading(roleName,
relationTypeName).intValue();
}
catch (RelationTypeNotFoundException e)
{
throw new RuntimeException(e.toString());
}
if (status == RoleStatus.NO_ROLE_WITH_NAME)
throw new RoleNotFoundException(roleName);
if (status == RoleStatus.ROLE_NOT_READABLE)
throw new RoleNotFoundException(roleName + " is not readable");
}
private void checkServiceProxy()
throws RelationServiceNotRegisteredException
{
if (serviceProxy == null)
{
try
{
serviceProxy = (RelationServiceMBean) MBeanProxy.get(
RelationServiceMBean.class, relationService, server);
}
catch (MBeanProxyCreationException e)
{
throw new RelationServiceNotRegisteredException(e.toString());
}
}
}
}