/*
* ============================================================================
* GNU Lesser General Public License
* ============================================================================
*
* Beanlet - JSE Application Container.
* Copyright (C) 2006 Leon van Zantvoort
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Leon van Zantvoort
* 243 Acalanes Drive #11
* Sunnyvale, CA 94086
* USA
*
* zantvoort@users.sourceforge.net
* http://beanlet.org
*/
package org.beanlet.management.impl;
import static org.beanlet.management.ManageableElementType.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import org.beanlet.metadata.AttributeReadMetaData;
import org.beanlet.metadata.AttributeWriteMetaData;
import org.beanlet.management.ManageableElementType;
import org.jargo.ComponentMetaData;
import org.jargo.ComponentReference;
import org.jargo.MetaData;
import org.beanlet.metadata.OperationMetaData;
import org.beanlet.management.ExposeElement;
import org.beanlet.management.HideElement;
import org.beanlet.management.Manageable;
/**
*
* @author Leon van Zantvoort
*/
public class BeanletMBeanInfoFactory {
public static MBeanInfo getMBeanInfo(ComponentReference reference,
Manageable manageable) {
ComponentMetaData metaData = reference.getComponentMetaData();
Set<ManageableElementType> types = new HashSet<ManageableElementType>(
Arrays.asList(manageable.exposed()));
return new MBeanInfo(metaData.getType().getName(),
reference.getComponentMetaData().getDescription(),
getAttributeInfo(reference, types.contains(ATTRIBUTE)),
getConstructorInfo(reference),
getOperationInfo(reference, types.contains(OPERATION)),
getNotificationInfo(reference));
}
private static MBeanAttributeInfo[] getAttributeInfo(ComponentReference<?>
reference, boolean expose) {
List<MBeanAttributeInfo> mbeanInfos = new ArrayList<MBeanAttributeInfo>();
Map<String, AttributeReadMetaData> readable =
new HashMap<String, AttributeReadMetaData>();
Map<String, AttributeWriteMetaData> writeable =
new HashMap<String, AttributeWriteMetaData>();
Set<String> all = new HashSet<String>();
for (MetaData m : reference.getComponentMetaData().getMetaData()) {
if (m instanceof AttributeReadMetaData) {
AttributeReadMetaData r = (AttributeReadMetaData) m;
boolean add = expose;
if (!add && r.isAnnotationPresent(ExposeElement.class)) {
add = true;
}
if (add && r.isAnnotationPresent(HideElement.class)) {
add = false;
}
if (add) {
readable.put(r.getAttributeName(), r);
all.add(r.getAttributeName());
}
}
if (m instanceof AttributeWriteMetaData) {
AttributeWriteMetaData w = (AttributeWriteMetaData) m;
boolean add = expose;
if (!add && w.isAnnotationPresent(ExposeElement.class)) {
add = true;
}
if (add && w.isAnnotationPresent(HideElement.class)) {
add = false;
}
if (add) {
writeable.put(w.getAttributeName(), w);
all.add(w.getAttributeName());
}
}
}
for (String name : all) {
AttributeReadMetaData r = readable.get(name);
AttributeWriteMetaData w = writeable.get(name);
assert r != null || w != null;
String type = r != null ? r.getType().getName() : w.getType().getName();
String description = r != null ? r.getDescription() : w.getDescription();
mbeanInfos.add(new MBeanAttributeInfo(name, type, description,
r != null, w != null, r != null && r.isIs()));
}
return mbeanInfos.toArray(new MBeanAttributeInfo[0]);
}
private static MBeanConstructorInfo[] getConstructorInfo(
ComponentReference<?> reference) {
return new MBeanConstructorInfo[0];
}
private static MBeanOperationInfo[] getOperationInfo(
ComponentReference<?> reference, boolean expose) {
List<MBeanOperationInfo> mbeanInfos =
new ArrayList<MBeanOperationInfo>();
for (MetaData metaData : reference.getComponentMetaData().getMetaData()) {
if (metaData instanceof OperationMetaData) {
OperationMetaData m = (OperationMetaData) metaData;
if (!m.isGetter() && !m.isSetter()) {
// This feature prevents that getter and setter operations
// are exposed.
boolean add = expose;
if (!add && m.isAnnotationPresent(ExposeElement.class)) {
add = true;
}
if (add && m.isAnnotationPresent(HideElement.class)) {
add = false;
}
if (add) {
MBeanParameterInfo[] signature =
new MBeanParameterInfo[m.getParameterTypes().length];
for (int i = 0; i < signature.length; i++) {
signature[i] = new MBeanParameterInfo("p" + (i + 1),
m.getParameterTypes()[i].getName(), "");
}
mbeanInfos.add(new MBeanOperationInfo(m.getOperationName(),
m.getDescription(), signature,
m.getReturnType().getName(),
MBeanOperationInfo.UNKNOWN));
}
}
}
// Clients can expose proxy method by exposing it as an operation as well.
// if (metaData instanceof ProxyMethodMetaData) {
// boolean add = expose;
// if (!add && ((ProxyMethodMetaData) metaData).isAnnotationPresent(ExposeElement.class)) {
// add = true;
// }
// if (add && ((ProxyMethodMetaData) metaData).isAnnotationPresent(HideElement.class)) {
// add = false;
// }
// if (add) {
// MBeanParameterInfo[] signature =
// new MBeanParameterInfo[3];
// signature[0] = new MBeanParameterInfo("name", String.class.getName(), "");
// signature[1] = new MBeanParameterInfo("parameterTypes", String[].class.getName(), "");
// signature[2] = new MBeanParameterInfo("parameters", Object[].class.getName(), "");
// mbeanInfos.add(new MBeanOperationInfo("invoke",
// ((ProxyMethodMetaData) metaData).getDescription(),
// signature, Object.class.getName(),
// MBeanOperationInfo.UNKNOWN));
// }
// }
}
return mbeanInfos.toArray(new MBeanOperationInfo[mbeanInfos.size()]);
}
private static MBeanNotificationInfo[] getNotificationInfo(ComponentReference
reference) {
return new MBeanNotificationInfo[0];
}
}