package org.jfox.mx;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.net.URL;
import java.io.File;
import org.jfox.mx.util.PrimitiveHelper;
public class MxServer {
private static List mxs = new ArrayList();
private static final String DEFAULT_DOMAIN = "Default";
private String domain = "";
private RepositoryCtrl repo = null;
private MxServer(String domain) {
this.domain = domain;
repo = new RepositoryCtrl(domain);
}
public static synchronized MxServer getInstance() {
return getInstance(DEFAULT_DOMAIN);
}
public static synchronized MxServer getInstance(String domain){
if(domain == null || domain.equals("")) {
domain = DEFAULT_DOMAIN;
}
for(int i=0;i<mxs.size();i++){
MxServer mx = (MxServer)mxs.get(i);
if(mx.getDefaultDomain().equals(domain)) {
return mx;
}
}
MxServer mx = new MxServer(domain);
mxs.add(mx);
return mx;
}
public String getDefaultDomain(){
return domain;
}
public Mxable createMX(String className, ObjectName name) throws MxException {
return createMX(className,name,null,null);
}
public Mxable createMX(String className, ObjectName name, Object[] params, String[] signatures) throws MxException {
if(name.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + name.toString() + " is a pattern object name"));
if (className == null || className.trim().length() == 0){
throw new MxException("invalide className");
}
Class mxClass = null;
try {
mxClass = Thread.currentThread().getContextClassLoader().loadClass(className.trim());
}
catch(ClassNotFoundException e){
throw new MxException(e);
}
if(!Mxable.class.isAssignableFrom(mxClass)) {
throw new MxException(mxClass + " not implement Mxable!");
}
try {
Class[] signatureClasses = loadSignatures(signatures);
Mxable mxObject = (Mxable)mxClass.getConstructor(signatureClasses).newInstance(params);
registerMX(name,mxObject);
return mxObject;
}
catch(Exception e){
throw new MxException(e);
}
}
public MxInfo getMxInfo(ObjectName objectName) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
if(!repo.contains(objectName)) throw new MxException("instance not found: " + objectName.toString());
MxMetaData meta = repo.retrieve(objectName);
return meta.getMxInfo();
}
public boolean isInstanceOf(ObjectName objectName, String className) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
if(!repo.contains(objectName)) throw new MxException("instance not found: " + objectName.toString());
MxMetaData meta = repo.retrieve(objectName);
Class cls = loadClass(className);
return cls.isInstance(meta.getMxObject());
}
public ClassLoader getMxClassLoader(){
return Thread.currentThread().getContextClassLoader();
}
public boolean isRegistered(ObjectName objectName) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
return repo.contains(objectName);
}
public int getMxCount() {
return repo.getRepoSize();
}
public Mxable getMxObject(ObjectName objectName) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
if(!repo.contains(objectName)) throw new MxException("instance not found: " + objectName.toString());
return repo.retrieve(objectName).getMxObject();
}
private void registerMX(ObjectName objectName, Mxable mxObject) throws MxException{
if(repo.contains(objectName)) throw new MxException( objectName + " already exists.");
boolean isRegisterMBean = (mxObject instanceof MxRegistration) ? true : false;
if(isRegisterMBean == true) {
try {
((MxRegistration)mxObject).preRegister(this,objectName);
}
catch(Exception e) {
try{
((MxRegistration)mxObject).postRegister(Boolean.FALSE);
}
catch(Exception ex){
}
throw new MxException(e);
}
}
repo.store(objectName,new MxMetaData(objectName,mxObject));
if(isRegisterMBean == true) {
((MxRegistration)mxObject).postRegister(Boolean.TRUE);
}
}
public void unregisterMBean(ObjectName objectName) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
if(!repo.contains(objectName)) throw new MxException("instance not found: " + objectName.toString());
MxMetaData meta = repo.retrieve(objectName);
Mxable mxObject = meta.getMxObject();
boolean isRegisterMBean = (mxObject instanceof MxRegistration) ? true : false;
if(isRegisterMBean) {
try{
((MxRegistration)mxObject).preDeregister();
}
catch(Exception e){
try{
((MxRegistration)mxObject).postDeregister();
}
catch(Exception ex){
}
throw new MxException(e);
}
}
repo.remove(objectName);
if(isRegisterMBean){
try{
((MxRegistration)mxObject).postDeregister();
}
catch(Exception e){
throw new MxException(e);
}
}
}
public Object invoke(ObjectName objectName, String operationName, Object params[], String signatures[]) throws MxException {
if(objectName.isPattern()) throw new MxException(new IllegalArgumentException("ObjectName " + objectName.toString() + " is a pattern object name"));
if(!repo.contains(objectName)) throw new MxException("instance not found: " + objectName.toString());
if(operationName == null || operationName.trim().length() ==0) throw new MxException(new IllegalArgumentException("operation name cannot be null or empty"));
operationName = operationName.trim();
if(!operationName.startsWith("mx_")) {
throw new MxException(operationName + " is not a Management Operation, Management operation must start with \" mx_\"");
}
MxMetaData meta = repo.retrieve(objectName);
Class[] signatureClasses = loadSignatures(signatures);
return meta.invoke(operationName,params,signatureClasses);
}
public Object invoke(ObjectName objectName, String operationName) throws MxException {
return invoke(objectName,operationName,null,null);
}
public Iterator queryMX(String domain){
if(domain == null || domain.equals("")) domain = "*";
return repo.queryMBean(domain);
}
public String[] getDomains(){
return repo.getDomains();
}
private Class[] loadSignatures(String[] signatrues) throws MxException {
if(signatrues == null){
return null;
}
if(signatrues.length == 0) {
return new Class[0];
}
Class[] signatureClasses = new Class[signatrues.length];
for(int i=0;i<signatrues.length;i++) {
signatureClasses[i] = loadClass(signatrues[i]);
}
return signatureClasses;
}
private Class loadClass(String className) throws MxException {
if(className == null || className.trim().equals("")) {
throw new MxException(className + " is a invalide class name");
}
className = className.trim();
try {
Class cls = PrimitiveHelper.getPrimitiveClass(className);
if(cls == null) { cls = Thread.currentThread().getContextClassLoader().loadClass(className);
}
return cls;
}
catch(ClassNotFoundException e){
throw new MxException(e);
}
}
public static void main(String[] args) {
}
}