Added: felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java?rev=1450821&view=auto ============================================================================== --- felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java (added) +++ felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java Wed Feb 27 15:59:42 2013 @@ -0,0 +1,668 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.ipojo.handlers.jmx; + +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Dictionary; +import java.util.List; +import java.util.Properties; + +import javax.management.MBeanRegistration; +import javax.management.MBeanServer; +import javax.management.ObjectInstance; +import javax.management.ObjectName; + +import org.apache.felix.ipojo.FieldInterceptor; +import org.apache.felix.ipojo.InstanceManager; +import org.apache.felix.ipojo.PrimitiveHandler; +import org.apache.felix.ipojo.architecture.HandlerDescription; +import org.apache.felix.ipojo.metadata.Element; +import org.apache.felix.ipojo.parser.FieldMetadata; +import org.apache.felix.ipojo.parser.MethodMetadata; +import org.apache.felix.ipojo.parser.PojoMetadata; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * This class implements iPOJO Handler. it builds the dynamic MBean from + * metadata.xml and exposes it to the MBean Server. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class MBeanHandler extends PrimitiveHandler { + + /** + * The name of the MBeanRegistration postDeregister method. + */ + public static final String POST_DEREGISTER_METH_NAME = "postDeregister"; + + /** + * The name of the MBeanRegistration preDeregister method. + */ + public static final String PRE_DEREGISTER_METH_NAME = "preDeregister"; + + /** + * The name of the MBeanRegistration postRegister method. + */ + public static final String POST_REGISTER_METH_NAME = "postRegister"; + + /** + * The name of the MBeanRegistration preRegister method. + */ + public static final String PRE_REGISTER_METH_NAME = "preRegister"; + + /** + * The name of the global configuration element. + */ + private static final String JMX_CONFIG_ELT = "config"; + + /** + * The name of the global configuration element. + */ + private static final String JMX_CONFIG_ALT_ELT = "JmxBean"; + + /** + * The name of the component object full name attribute. + */ + private static final String JMX_OBJ_NAME_ELT = "objectName"; + + /** + * The name of the component object name domain attribute. + */ + private static final String JMX_OBJ_NAME_DOMAIN_ELT = "domain"; + + /** + * The name of the component object name attribute. + */ + private static final String JMX_OBJ_NAME_WO_DOMAIN_ELT = "name"; + + /** + * The name of the attribute indicating if the handler uses MOSGi MBean server. + */ + private static final String JMX_USES_MOSGI_ELT = "usesMOSGi"; + + /** + * The name of a method element. + */ + private static final String JMX_METHOD_ELT = "method"; + + /** + * The alternative name of a method element. + */ + private static final String JMX_METHOD_ELT_ALT = "JmxMethod"; + + /** + * The name of the property or method name attribute. + */ + private static final String JMX_NAME_ELT = "name"; + + /** + * The name of a method description attribute. + */ + private static final String JMX_DESCRIPTION_ELT = "description"; + + /** + * The name of a property element. + */ + private static final String JMX_PROPERTY_ELT = "property"; + + /** + * The alternative name of a property element. + */ + private static final String JMX_PROPERTY_ELT_ALT = "JmxProperty"; + + /** + * The name of the field attribute. + */ + private static final String JMX_FIELD_ELT = "field"; + + /** + * The name of the notification attribute. + */ + private static final String JMX_NOTIFICATION_ELT = "notification"; + + /** + * The name of the rights attribute. + */ + private static final String JMX_RIGHTS_ELT = "rights"; + + /** + * The instance manager. Used to store the InstanceManager instance. + */ + private InstanceManager m_instanceManager; + /** + * The service registration. Used to register and unregister the Dynamic MBean. + */ + private ServiceRegistration m_serviceRegistration; + /** + * Stores data when parsing metadata.xml. + */ + private JmxConfigFieldMap m_jmxConfigFieldMap; + /** + * Stores the Dynamic MBean. + */ + private DynamicMBeanImpl m_MBean; + /** + * Constant storing the name of the class. + */ + private String m_namespace = "org.apache.felix.ipojo.handlers.jmx"; + /** + * The flag used to inform if we use the MOSGi framework. + */ + private boolean m_usesMOSGi; + /** + * The ObjectName used to register the MBean. + */ + private ObjectName m_objectName; + /** + * The flag used to inform if the MBean is registered. + */ + private boolean m_registered; + /** + * The ObjectName specified in handler configuration. It can be null. + */ + private String m_completeObjNameElt; + /** + * The ObjectName without domain specified in handler configuration. It can be null. + */ + private String m_objNameWODomainElt; + + /** + * The ObjectName domain specified in handler configuration. It can be null. + */ + private String m_domainElt; + /** + * The flag informing if the POJO implements the MBeanRegistration interface. + */ + private boolean m_registerCallbacks; + /** + * The preRegister method of MBeanRegistration interface. It is null if POJO doesn't implement MBeanRegistration interface. + */ + private MethodMetadata m_preRegisterMeth; + /** + * The postRegister method of MBeanRegistration interface. It is null if POJO doesn't implement MBeanRegistration interface. + */ + private MethodMetadata m_postRegisterMeth; + /** + * The preDeregister method of MBeanRegistration interface. It is null if POJO doesn't implement MBeanRegistration interface. + */ + private MethodMetadata m_preDeregisterMeth; + /** + * The postDeregister method of MBeanRegistration interface. It is null if POJO doesn't implement MBeanRegistration interface. + */ + private MethodMetadata m_postDeregisterMeth; + + /** + * Constructs the structure JmxConfigFieldMap and the Dynamic Mbean. + * + * @param metadata the component metadata + * @param dict the instance configuration + */ + public void configure(Element metadata, Dictionary dict) { + + PojoMetadata manipulation = getPojoMetadata(); + + m_instanceManager = getInstanceManager(); + + m_jmxConfigFieldMap = new JmxConfigFieldMap(); + + // Build the hashmap + Element[] mbeans = metadata.getElements(JMX_CONFIG_ELT, m_namespace); + if (mbeans == null || mbeans.length == 0) { + mbeans = metadata.getElements(JMX_CONFIG_ALT_ELT, m_namespace); + } + + if (mbeans.length != 1) { + error("A component must have exactly one " + JMX_CONFIG_ELT + " or " + JMX_CONFIG_ALT_ELT + " element."); + error("The JMX handler configuration is ignored."); + return; + } + + Element mbean = mbeans[0]; + + // retrieve kind of MBeanServer to use + m_usesMOSGi = Boolean.parseBoolean(mbean.getAttribute(JMX_USES_MOSGI_ELT)); + + // retrieve object name + m_completeObjNameElt = mbean.getAttribute(JMX_OBJ_NAME_ELT); + m_domainElt = mbean.getAttribute(JMX_OBJ_NAME_DOMAIN_ELT); + m_objNameWODomainElt = mbean.getAttribute(JMX_OBJ_NAME_WO_DOMAIN_ELT); + + // test if Pojo is interested in registration callbacks + m_registerCallbacks = manipulation + .isInterfaceImplemented(MBeanRegistration.class.getName()); + if (m_registerCallbacks) { + // don't need to check that methods exist, the pojo implements + // MBeanRegistration interface + String[] preRegisterParams = { MBeanServer.class.getName(), + ObjectName.class.getName() }; + m_preRegisterMeth = manipulation.getMethod(PRE_REGISTER_METH_NAME, + preRegisterParams); + + String[] postRegisterParams = { Boolean.class.getName() }; + m_postRegisterMeth = manipulation.getMethod( + POST_REGISTER_METH_NAME, postRegisterParams); + + m_preDeregisterMeth = manipulation.getMethod( + PRE_DEREGISTER_METH_NAME, new String[0]); + + m_postDeregisterMeth = manipulation.getMethod( + POST_DEREGISTER_METH_NAME, new String[0]); + } + + // set property + Element[] attributes = mbean.getElements(JMX_PROPERTY_ELT, m_namespace); + Element[] attributesAlt = mbean.getElements(JMX_PROPERTY_ELT_ALT, m_namespace); + List<Element> listOfAttributes = new ArrayList<Element>(); + if (attributes != null) { + listOfAttributes.addAll(Arrays.asList(attributes)); + } + if (attributesAlt != null) { + listOfAttributes.addAll(Arrays.asList(attributesAlt)); + } + + Element[] attributesOld = mbeans[0].getElements(JMX_PROPERTY_ELT); + if (attributesOld != null) { + warn("The JMX property element should use the '" + m_namespace + "' namespace."); + listOfAttributes.addAll(Arrays.asList(attributesOld)); + } + + for (Element attribute : listOfAttributes) { + boolean notif = false; + String rights; + String name; + String field = attribute.getAttribute(JMX_FIELD_ELT); + + if (attribute.containsAttribute(JMX_NAME_ELT)) { + name = attribute.getAttribute(JMX_NAME_ELT); + } else { + name = field; + } + if (attribute.containsAttribute(JMX_RIGHTS_ELT)) { + rights = attribute.getAttribute(JMX_RIGHTS_ELT); + } else { + rights = "r"; + } + + PropertyField property = new PropertyField(name, field, rights, + getTypeFromAttributeField(field, manipulation)); + + if (attribute.containsAttribute(JMX_NOTIFICATION_ELT)) { + notif = Boolean.parseBoolean(attribute + .getAttribute(JMX_NOTIFICATION_ELT)); + } + + property.setNotifiable(notif); + + if (notif) { + // add the new notifiable property in structure + NotificationField notification = new NotificationField( + name, this.getClass().getName() + "." + field, null); + m_jmxConfigFieldMap.addNotificationFromName(name, + notification); + } + m_jmxConfigFieldMap.addPropertyFromName(name, property); + getInstanceManager().register(manipulation.getField(field), + this); + info("property exposed:" + name + " " + field + ":" + + getTypeFromAttributeField(field, manipulation) + " " + + rights + ", Notif=" + notif); + } + + // set methods + Element[] methods = mbean.getElements(JMX_METHOD_ELT, m_namespace); + Element[] methodsAlt = mbean.getElements(JMX_METHOD_ELT_ALT, m_namespace); + List<Element> listOfMethods = new ArrayList<Element>(); + if (methods != null) { + listOfMethods.addAll(Arrays.asList(methods)); + } + if (methodsAlt != null) { + listOfMethods.addAll(Arrays.asList(methodsAlt)); + } + + Element[] methodsOld = mbeans[0].getElements(JMX_PROPERTY_ELT); + if (methodsOld != null) { + warn("The JMX method element should use the '" + m_namespace + "' namespace."); + listOfMethods.addAll(Arrays.asList(methodsOld)); + } + + for (Element method : listOfMethods) { + String name = method.getAttribute(JMX_NAME_ELT); + if (name == null) { + name = method.getAttribute("method"); + } + String description = null; + if (method.containsAttribute(JMX_DESCRIPTION_ELT)) { + description = method.getAttribute(JMX_DESCRIPTION_ELT); + } + + MethodField[] meth = getMethodsFromName(name, manipulation, + description); + + for (int j = 0; j < meth.length; j++) { + m_jmxConfigFieldMap.addMethodFromName(name, meth[j]); + + info("method exposed:" + meth[j].getReturnType() + " " + name); + } + } + + } + + /** + * Registers the Dynamic Mbean. + */ + public void start() { + // create the corresponding MBean + if (m_registerCallbacks) { + m_MBean = new DynamicMBeanWRegisterImpl(m_jmxConfigFieldMap, + m_instanceManager, m_preRegisterMeth, m_postRegisterMeth, + m_preDeregisterMeth, m_postDeregisterMeth); + } else { + m_MBean = new DynamicMBeanImpl(m_jmxConfigFieldMap, + m_instanceManager); + } + + if (m_usesMOSGi) { + // use whiteboard pattern to register MBean + + if (m_serviceRegistration != null) { + m_serviceRegistration.unregister(); + } + + // Register the ManagedService + BundleContext bundleContext = m_instanceManager.getContext(); + Properties properties = new Properties(); + try { + m_objectName = new ObjectName(getObjectNameString()); + + properties.put("jmxagent.objectName", m_objectName.toString()); + + m_serviceRegistration = bundleContext.registerService( + javax.management.DynamicMBean.class.getName(), m_MBean, + properties); + + m_registered = true; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + try { + m_objectName = new ObjectName(getObjectNameString()); + ObjectInstance instance = ManagementFactory + .getPlatformMBeanServer().registerMBean(m_MBean, + m_objectName); + + // we must retrieve object name used to register the MBean. + // It can have been changed by preRegister method of + // MBeanRegistration interface. + if (m_registerCallbacks) { + m_objectName = instance.getObjectName(); + } + + m_registered = true; + } catch (Exception e) { + error("Registration of MBean failed.", e); + } + } + } + + /** + * Returns the object name of the exposed component. + * + * @return the object name of the exposed component. + */ + private String getObjectNameString() { + if (m_completeObjNameElt != null) { + return m_completeObjNameElt; + } + + String domain; + if (m_domainElt != null) { + domain = m_domainElt; + } else { + domain = getPackageName(m_instanceManager.getClassName()); + } + + String name = "type=" + m_instanceManager.getClassName() + ",instance=" + + m_instanceManager.getInstanceName(); + if (m_objNameWODomainElt != null) { + name = "name=" + m_objNameWODomainElt; + } + + StringBuffer sb = new StringBuffer(); + if ((domain != null) && (domain.length() > 0)) { + sb.append(domain + ":"); + } + sb.append(name); + + info("Computed Objectname: " + sb.toString()); + + return sb.toString(); + } + + /** + * Extracts the package name from of given type. + * + * @param className the type name. + * @return the package name of the given type. + */ + private String getPackageName(String className) { + String packageName = ""; + + int plotIdx = className.lastIndexOf("."); + if (plotIdx != -1) { + packageName = className.substring(0, plotIdx); + } + + return packageName; + } + + /** + * Unregisters the Dynamic Mbean. + */ + public void stop() { + if (m_usesMOSGi) { + if (m_serviceRegistration != null) { + m_serviceRegistration.unregister(); + } + } else { + if (m_objectName != null) { + try { + ManagementFactory.getPlatformMBeanServer().unregisterMBean( + m_objectName); + } catch (Exception e) { + error("Unregistration of MBean failed.", e); + } + m_objectName = null; + } + } + + m_MBean = null; + m_registered = false; + } + + /** + * Called when a POJO member is modified externally. + * + * @param pojo the modified POJO object + * @param fieldName the name of the modified field + * @param value the new value of the field + * @see FieldInterceptor#onSet(Object, String, Object) + */ + public void onSet(Object pojo, String fieldName, Object value) { + // Check if the field is a configurable property + + PropertyField propertyField = (PropertyField) m_jmxConfigFieldMap + .getPropertyFromField(fieldName); + if (propertyField != null) { + if (propertyField.isNotifiable()) { + // TODO should send notif only when value has changed to a value + // different than the last one. + m_MBean.sendNotification(propertyField.getName() + " changed", + propertyField.getName(), propertyField.getType(), + propertyField.getValue(), value); + } + propertyField.setValue(value); + } + } + + /** + * Called when a POJO member is read by the MBean. + * + * @param pojo the read POJO object. + * @param fieldName the name of the modified field + * @param value the old value of the field + * @return the (injected) value of the field + * @see FieldInterceptor#onGet(Object, String, Object) + */ + public Object onGet(Object pojo, String fieldName, Object value) { + + // Check if the field is a configurable property + PropertyField propertyField = (PropertyField) m_jmxConfigFieldMap + .getPropertyFromField(fieldName); + if (propertyField != null) { + // Do we have a value to inject ? + Object v = propertyField.getValue(); + if (v == null) { + String type = propertyField.getType(); + if ("boolean".equals(type)) { v = Boolean.FALSE; } + else if ("byte".equals(type)) { v = new Byte((byte) 0); } + else if ("short".equals(type)) { v = new Short((short) 0); } + else if ("int".equals(type)) { v = new Integer(0); } + else if ("long".equals(type)) { v = new Long(0); } + else if ("float".equals(type)) { v = new Float(0); } + else if ("double".equals(type)) { v =new Double(0); } + else if ("char".equals(type)) { v = new Character((char) 0); } + + return v; + } + m_instanceManager.onSet(pojo, fieldName, propertyField.getValue()); + return propertyField.getValue(); + } + return value; + } + + /** + * Gets the type from a field name. + * + * @param fieldRequire the name of the required field + * @param manipulation the metadata extracted from metadata.xml file + * @return the type of the field or {@code null} if it wasn't found + */ + private static String getTypeFromAttributeField(String fieldRequire, + PojoMetadata manipulation) { + + FieldMetadata field = manipulation.getField(fieldRequire); + if (field == null) { + return null; + } else { + return FieldMetadata.getReflectionType(field.getFieldType()); + } + } + + /** + * Gets all the methods available which get this name. + * + * @param methodName the name of the required methods + * @param manipulation the metadata extract from metadata.xml file + * @param description the description which appears in JMX console + * @return the array of methods with the right name + */ + private MethodField[] getMethodsFromName(String methodName, + PojoMetadata manipulation, String description) { + + MethodMetadata[] methods = manipulation.getMethods(methodName); + if (methods.length == 0) { + return null; + } + + MethodField[] ret = new MethodField[methods.length]; + + if (methods.length == 1) { + ret[0] = new MethodField(methods[0], description); + return ret; + } else { + for (int i = 0; i < methods.length; i++) { + ret[i] = new MethodField(methods[i], description); + } + return ret; + } + } + + /** + * Gets the JMX handler description. + * + * @return the JMX handler description. + * @see org.apache.felix.ipojo.Handler#getDescription() + */ + public HandlerDescription getDescription() { + return new JMXHandlerDescription(this); + } + + /** + * Returns the objectName used to register the MBean. If the MBean is not registered, return an empty string. + * + * @return the objectName used to register the MBean. + * @see org.apache.felix.ipojo.Handler#getDescription() + */ + public String getUsedObjectName() { + if (m_objectName != null) { + return m_objectName.toString(); + } else { + return ""; + } + } + + /** + * Returns true if the MBean is registered. + * + * @return true if the MBean is registered. + */ + public boolean isRegistered() { + return m_registered; + } + + /** + * Returns true if the MBean must be registered thanks to white board pattern of MOSGi. + * + * @return {@code true} if the MBean must be registered thanks to white board pattern of MOSGi, false otherwise. + */ + public boolean isUsesMOSGi() { + return m_usesMOSGi; + } + + /** + * Returns true if the MOSGi framework is present on the OSGi platform. + * + * @return {@code true} if the MOSGi framework is present on the OSGi platform, false otherwise. + */ + public boolean isMOSGiExists() { + for (Bundle bundle : m_instanceManager.getContext().getBundles()) { + String symbolicName = bundle.getSymbolicName(); + if ("org.apache.felix.mosgi.jmx.agent".equals(symbolicName)) { + return true; + } + } + + return false; + } +}
Added: felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java?rev=1450821&view=auto ============================================================================== --- felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java (added) +++ felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java Wed Feb 27 15:59:42 2013 @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.felix.ipojo.handlers.jmx; + +import javax.management.MBeanParameterInfo; + +import org.apache.felix.ipojo.parser.MethodMetadata; + +/** + * This class builds a method JMX description. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class MethodField { + + /** + * Stores the method description. + */ + private String m_description; + /** + * Stores the method properties. + */ + private MethodMetadata m_method; + + /** + * Constructor. + * + * @param method the method properties + * @param description the method description + */ + public MethodField(MethodMetadata method, String description) { + this.m_method = method; + this.m_description = description; + + } + + /** + * Gets the method. + * @return the method + */ + public MethodMetadata getMethod() { + return m_method; + } + + /** + * Gets the description. + * @return the description + */ + public String getDescription() { + return m_description; + } + + /** + * Gets the name. + * @return the name + */ + public String getName() { + return m_method.getMethodName(); + } + + /** + * Gets the parameter in JMX format. + * + * @return info on JMX format + */ + public MBeanParameterInfo[] getParams() { + MBeanParameterInfo[] mbean = new MBeanParameterInfo[m_method + .getMethodArguments().length]; + for (int i = 0; i < m_method.getMethodArguments().length; i++) { + mbean[i] = new MBeanParameterInfo("arg" + i, m_method + .getMethodArguments()[i], null); + } + return mbean; + } + + public String[] getSignature() { + return m_method.getMethodArguments(); + } + + public String getReturnType() { + return m_method.getMethodReturn(); + } + +} Added: felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/NotificationField.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/NotificationField.java?rev=1450821&view=auto ============================================================================== --- felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/NotificationField.java (added) +++ felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/NotificationField.java Wed Feb 27 15:59:42 2013 @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.felix.ipojo.handlers.jmx; + +import javax.management.MBeanNotificationInfo; + +/** + * This class builds the notification description structure. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class NotificationField { + /** + * The name of the notification. + */ + private String m_name; + /** + * The description of the notification. + */ + private String m_description; + /** + * The field of the notification. + */ + private String m_field; + + /** + * Constructor. + * + * @param name the name of the notification + * @param field the field which send a notification when it is modified + * @param description the description which appears in JMX console + */ + + public NotificationField(String name, String field, String description) { + this.m_name = name; + this.m_field = field; + this.m_description = description; + } + + /** + * Returns the MBeanNotificationInfo from this class. + * + * @return the type of the field or {@code null} if it wasn't found + */ + public MBeanNotificationInfo getNotificationInfo() { + String[] notificationTypes = new String[1]; + notificationTypes[0] = m_field; + MBeanNotificationInfo mbni = new MBeanNotificationInfo( + notificationTypes, m_name, m_description); + return mbni; + } +} Added: felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java?rev=1450821&view=auto ============================================================================== --- felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java (added) +++ felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java Wed Feb 27 15:59:42 2013 @@ -0,0 +1,196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.felix.ipojo.handlers.jmx; + +/** + * This class build the notification description structure. + * + * @author <a href="mailto:[email protected]">Felix Project Team</a> + */ +public class PropertyField { + + /** + * The name of the notification. + */ + private String m_name; + /** + * The name of the notification. + */ + private String m_field; + /** + * The name of the notification. + */ + private String m_rights; + /** + * The name of the notification. + */ + private String m_type; + /** + * The name of the notification. + */ + private Object m_value; + /** + * The name of the notification. + */ + private boolean m_notification; + + /** + * Constructor. + * + * @param name the name of the properety + * @param field the field which send a notification when it is modified + * @param rights the rights of the attribute (ie: 'r' or 'w') + * @param type the type of the attribute + */ + public PropertyField(String name, String field, String rights, String type) { + this.setName(name); + this.setField(field); + this.m_type = type; + if (isRightsValid(rights)) { + this.setRights(rights); + } else { + this.setField("r"); // default rights is read only + } + } + + /** + * Returns the field. + * @return the field + */ + public String getField() { + return m_field; + } + + /** + * Modifies the field. + * @param field the new field + */ + public void setField(String field) { + this.m_field = field; + } + + /** + * Returns the name. + * @return the name + */ + public String getName() { + return m_name; + } + + /** + * Modifies the name. + * @param name the new name + */ + public void setName(String name) { + this.m_name = name; + } + + /** + * Returns the rights. + * @return the rights + */ + public String getRights() { + return m_rights; + } + + /** + * Modifies the rights. + * @param rights the new rights + */ + public void setRights(String rights) { + this.m_rights = rights; + } + + /** + * Returns the value. + * @return the value + */ + public Object getValue() { + return m_value; + } + + /** + * Modifies the value. + * @param value the new value + */ + public void setValue(Object value) { + this.m_value = value; + } + + /** + * Returns the type. + * @return the type + */ + public String getType() { + return this.m_type; + } + + /** + * Returns the description. + * @return the description + */ + public String getDescription() { + //TODO Implement this method. + return null; + } + + /** + * Returns true if this property field is readable, false otherwise. + * @return {@code true} if this property field is readable, {@code false} otherwise. + */ + public boolean isReadable() { + return this.getRights().equals("r") || this.getRights().equals("w"); + } + + /** + * Returns true if this property field is writable, false otherwise. + * @return {@code true} if this property field is writable, {@code false} otherwise. + */ + public boolean isWritable() { + return this.getRights().equals("w"); + } + + /** + * Returns true if this property field is notifiable, false otherwise. + * @return {@code true} if this property field is notifiable, {@code false} otherwise. + */ + public boolean isNotifiable() { + return this.m_notification; + } + + /** + * Modify the notifiability of this property field. + * @param value the new notifiability of this property field. + */ + public void setNotifiable(boolean value) { + this.m_notification = value; + } + + /** + * Is the rights is valid or not ? (ie = 'r' || 'w'). + * + * @param rights string representing the rights + * @return boolean : return {@code true} if rights = 'r' or 'w' + */ + public static boolean isRightsValid(String rights) { + return rights != null && (rights.equals("r") || rights.equals("w")); + } + +} Added: felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/resources/jmx.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/resources/jmx.xsd?rev=1450821&view=auto ============================================================================== --- felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/resources/jmx.xsd (added) +++ felix/trunk/ipojo/handler/jmx/jmx-handler/src/main/resources/jmx.xsd Wed Feb 27 15:59:42 2013 @@ -0,0 +1,177 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<xs:schema targetNamespace="org.apache.felix.ipojo.handlers.jmx" + xmlns="org.apache.felix.ipojo.handlers.jmx" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified"> + <xs:element name="config" type="JMXType"></xs:element> + + <xs:complexType name="JMXType"> + + <xs:annotation> + <xs:documentation> + Description of a JMX managed component. + </xs:documentation> + </xs:annotation> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="method" type="JMXMethod"> + <xs:annotation> + <xs:documentation> + The list of methods to expose. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="property" type="JMXProperty"> + <xs:annotation> + <xs:documentation> + The list of attributes to expose. + </xs:documentation> + </xs:annotation> + </xs:element> + </xs:choice> + <xs:attribute name="usesMOSGi" type="xs:boolean" + use="optional"> + <xs:annotation> + <xs:documentation> + Determines if the component must be register on the + MOSGi MBean server or not. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="objectName" type="xs:string" + use="optional"> + <xs:annotation> + <xs:documentation> + The complete object name of the managed component. + The syntax of this attribute must be compliant with + the ObjectName syntax, detailed in the JMX + specification. If neither domain nor name attributes + are specified, the default value is determined by + the package, the type and the instance name of the + component. This attribute overrides the domain and + name attributes. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="domain" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation> + The domain of the managed object (i.e., the left + part of the object name). This attribute must be + compliant with the domain syntax, as described in + the JMX specification. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="name" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation> + The name property of the managed object. The value + of this attribute must comply with the ObjectName + value syntax, as described in the JMX specification. + </xs:documentation> + </xs:annotation> + </xs:attribute> + + <xs:attribute name="preRegister" type="xs:string" + use="optional"> + <xs:annotation> + <xs:documentation> + Specifies method to carry out operations before + beeing registered from the MBean server. The + signature of the specified method must be : + "ObjectName preRegister(MBeanServer server, + ObjectName name) throws Exception". + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="postRegister" type="xs:string" + use="optional"> + <xs:annotation> + <xs:documentation> + Specifies method to carry out operations after + beeing registered from the MBean server. The + signature of the specified method must be : "void + postRegister(Boolean registrationDone)". + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="preDeregister" type="xs:string" + use="optional"> + <xs:annotation> + <xs:documentation> + Specifies method to carry out operations before + beeing unregistered from the MBean server. The + signature of the specified method must be : "void + preDeregister() throws Exception". + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="postDeregister" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation> + Specifies method to carry out operations after + beeing unregistered from the MBean server. The + signature of the specified method must be : + "void postDeregister()".</xs:documentation> + </xs:annotation></xs:attribute> + </xs:complexType> + + <xs:complexType name="JMXProperty"> + <xs:annotation> + <xs:documentation>Description of an attribute to expose.</xs:documentation> + </xs:annotation> + <xs:attribute name="field" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>The name of the component's field to expose.</xs:documentation></xs:annotation></xs:attribute> + <xs:attribute name="name" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation>The name of the property as it will appear in JMX. If unspecified, the default value is the name of the exposed field.</xs:documentation></xs:annotation></xs:attribute> + <xs:attribute name="rights" use="optional"> + <xs:annotation> + <xs:documentation>Specify the access permission of the exposed field.</xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:annotation> + <xs:documentation>Access permission of an exposed field. Accepted values are "r" (read-only access, the default value) and "w" (read and write access).</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="r"></xs:enumeration> + <xs:enumeration value="w"></xs:enumeration> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name="notification" type="xs:boolean" use="optional"> + <xs:annotation> + <xs:documentation>Enable or disable attribute change notification sending for this property. If set to "true", a notification is sent each time the value of the field changes.</xs:documentation></xs:annotation></xs:attribute> + </xs:complexType> + + <xs:complexType name="JMXMethod"> + <xs:annotation> + <xs:documentation>Description of a method to expose.</xs:documentation> + </xs:annotation> + <xs:attribute name="name" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>The name of the method to expose. If multiple methods have the same name, all of them are exposed.</xs:documentation> + </xs:annotation></xs:attribute> + <xs:attribute name="description" type="xs:string" use="optional"> + <xs:annotation> + <xs:documentation>The description of the exposed method, as it will appear in JMX.</xs:documentation></xs:annotation></xs:attribute> + </xs:complexType> +</xs:schema> \ No newline at end of file Modified: felix/trunk/ipojo/handler/jmx/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/pom.xml?rev=1450821&r1=1450820&r2=1450821&view=diff ============================================================================== --- felix/trunk/ipojo/handler/jmx/pom.xml (original) +++ felix/trunk/ipojo/handler/jmx/pom.xml Wed Feb 27 15:59:42 2013 @@ -16,110 +16,100 @@ specific language governing permissions and limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <parent> - <groupId>org.apache.felix</groupId> - <artifactId>felix-parent</artifactId> - <version>1.2.1</version> - <relativePath>../../pom/pom.xml</relativePath> - </parent> - <modelVersion>4.0.0</modelVersion> - <packaging>bundle</packaging> - <name>Apache Felix iPOJO JMX Handler</name> - <artifactId>org.apache.felix.ipojo.handler.jmx</artifactId> - <version>1.5.0-SNAPSHOT</version> - - <description> - iPOJO extension to expose instances as MBean inside a MBean Server. - </description> - <url>http://felix.apache.org/site/ipojo-jmx-handler.html</url> - - <dependencies> - <dependency> - <groupId>org.apache.felix</groupId> - <artifactId>org.apache.felix.ipojo</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.core</artifactId> - <version>4.0.0</version> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <version>1.4.3</version> - <configuration> - <instructions> - <Private-Package> org.apache.felix.ipojo.handlers.jmx - </Private-Package> - <Bundle-Name>${project.name}</Bundle-Name> - <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> - <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor> - <Bundle-Description> iPOJO JMX Handler </Bundle-Description> - <Bundle-DocURL> - http://felix.apache.org/site/ipojo-jmx-handler.html - </Bundle-DocURL> - <Include-Resource> - META-INF/LICENSE=LICENSE, - META-INF/NOTICE=NOTICE, - META-INF/DEPENDENCIES=DEPENDENCIES - </Include-Resource> - </instructions> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>1.5</source> - <target>1.5</target> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-ipojo-plugin</artifactId> - <version>${project.version}</version> - <executions> - <execution> - <goals> - <goal>ipojo-bundle</goal> - </goals> - <configuration> - <metadata>metadata.xml</metadata> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>rat-maven-plugin</artifactId> - <configuration> - <excludeSubProjects>false</excludeSubProjects> - <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes> - <useMavenDefaultExcludes>true</useMavenDefaultExcludes> - <excludes> - <param>doc/**/*</param> - <param>maven-eclipse.xml</param> - <param>.checkstyle</param> - <param>.externalToolBuilders/*</param> - <param>LICENSE.asm</param> - </excludes> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-checkstyle-plugin</artifactId> - <configuration> - <enableRulesSummary>false</enableRulesSummary> - <violationSeverity>warning</violationSeverity> - <configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation> - </configuration> - </plugin> - </plugins> - </build> + <artifactId>felix-parent</artifactId> + <version>1.2.1</version> + <relativePath>../../pom/pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>org.apache.felix.ipojo.handler.jmx-handler-project</artifactId> + <version>1.5.0-SNAPSHOT</version> + <name>Apache Felix iPOJO Event Admin Handler Project</name> + <packaging>pom</packaging> + + <modules> + <module>jmx-handler</module> + <module>jmx-handler-it</module> + </modules> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>.</directory> + <targetPath>META-INF</targetPath> + <includes> + <include>LICENSE*</include> + <include>NOTICE*</include> + <include>DEPENDENCIES*</include> + </includes> + </resource> + </resources> + </build> + + <profiles> + <profile> + <id>release</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <descriptorRefs> + <descriptorRef>project</descriptorRef> + </descriptorRefs> + <!-- we don't want to attach all the assemblies, such as bz2 --> + <attach>false</attach> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <!-- only attach the project and bin assemblies, in tar.gz and zip flavors --> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-assemblies</id> + <phase>package</phase> + <goals> + <goal>attach-artifact</goal> + </goals> + <configuration> + <artifacts> + <artifact> + <file> + ${project.build.directory}/${project.artifactId}-${project.version}-project.tar.gz + </file> + <classifier>project</classifier> + <type>tar.gz</type> + </artifact> + <artifact> + <file> + ${project.build.directory}/${project.artifactId}-${project.version}-project.zip + </file> + <classifier>project</classifier> + <type>zip</type> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> </project>
