Coverage Report - net.sf.snmpadaptor4j.core.mapping.XmlMappingParser
 
Classes in this File Line Coverage Branch Coverage Complexity
XmlMappingParser
100 %
107/107
100 %
76/76
4,6
 
 1  
 package net.sf.snmpadaptor4j.core.mapping;
 2  
 
 3  
 import java.net.URL;
 4  
 import java.util.ArrayList;
 5  
 import java.util.HashMap;
 6  
 import java.util.Iterator;
 7  
 import java.util.List;
 8  
 import java.util.Map;
 9  
 import javax.management.MBeanAttributeInfo;
 10  
 import javax.management.ObjectName;
 11  
 import javax.xml.bind.JAXBContext;
 12  
 import javax.xml.bind.JAXBElement;
 13  
 import javax.xml.bind.Unmarshaller;
 14  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.GenericTrap;
 15  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.MBean;
 16  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.MBeanAttribute;
 17  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.MBeanNotifications;
 18  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.Mapping;
 19  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.SpecificTrap;
 20  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.TrapEnterprise;
 21  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.TrapUserData;
 22  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.TrapUserDataEntry;
 23  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.TrapUserDataMap;
 24  
 import net.sf.snmpadaptor4j.core.mapping.jaxb.TrapVariableBindings;
 25  
 import net.sf.snmpadaptor4j.object.SnmpDataType;
 26  
 import net.sf.snmpadaptor4j.object.GenericSnmpTrapType;
 27  
 import net.sf.snmpadaptor4j.object.SnmpOid;
 28  
 
 29  
 /**
 30  
  * Parser of SNMP mapping file (XML).
 31  
  * @author <a href="http://fr.linkedin.com/in/jpminetti/">Jean-Philippe MINETTI</a>
 32  
  */
 33  
 public final class XmlMappingParser {
 34  
 
 35  
         /**
 36  
          * {@link URL} to the SNMP mapping file.
 37  
          */
 38  
         private final URL url;
 39  
 
 40  
         /**
 41  
          * JAXB representation of the SNMP mapping file.
 42  
          */
 43  
         private final JAXBElement<Mapping> jaxbElement;
 44  
 
 45  
         /**
 46  
          * Creates and returns a new instance of {@link XmlMappingParser}.
 47  
          * @param url {@link URL} to the SNMP mapping file.
 48  
          * @return New instance of {@link XmlMappingParser}.
 49  
          * @throws Exception Exception if an error occurred.
 50  
          */
 51  
         public static XmlMappingParser newInstance (final URL url) throws Exception {
 52  26
                 final JAXBContext jaxbContext = JAXBContext.newInstance(Mapping.class.getPackage().getName());
 53  26
                 final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
 54  
                 @SuppressWarnings("unchecked")
 55  26
                 final JAXBElement<Mapping> jaxbElement = (JAXBElement<Mapping>) unmarshaller.unmarshal(url);
 56  26
                 return new XmlMappingParser(url, jaxbElement);
 57  
         }
 58  
 
 59  
         /**
 60  
          * Constructor.
 61  
          * @param url {@link URL} to the SNMP mapping file.
 62  
          * @param jaxbElement JAXB representation of the SNMP mapping file.
 63  
          */
 64  
         private XmlMappingParser (final URL url, final JAXBElement<Mapping> jaxbElement) {
 65  26
                 super();
 66  26
                 this.url = url;
 67  26
                 this.jaxbElement = jaxbElement;
 68  26
         }
 69  
 
 70  
         /**
 71  
          * Finds a base OID of a MBean instance in the mapping.
 72  
          * @param mBeanName MBean name.
 73  
          * @param rootOidMap Map of root OIDs where the attributes of the application will stay.
 74  
          * @param defaultRootOid Default root OID containing the attributes of the current application.
 75  
          * @param mainDefaultRootOid Default root OID containing the attributes of the main application (must not be <code>NULL</code>).
 76  
          * @return Base OID found (can be <code>NULL</code>).
 77  
          */
 78  
         public String findBaseOid (final ObjectName mBeanName, final Map<String, String> rootOidMap, final String defaultRootOid, final String mainDefaultRootOid) {
 79  15
                 String baseOid = null;
 80  15
                 final Mapping mapping = this.jaxbElement.getValue();
 81  15
                 if (mapping.getMbeans() != null) {
 82  12
                         final Iterator<MBean> mBeanIterator = mapping.getMbeans().getMbean().iterator();
 83  12
                         final String desiredName = mBeanName.toString();
 84  
                         MBean mBean;
 85  38
                         while (mBeanIterator.hasNext() && (baseOid == null)) {
 86  26
                                 mBean = mBeanIterator.next();
 87  26
                                 if (mBean.getName().equals(desiredName)) {
 88  9
                                         if (mBean.getRoot() != null) {
 89  3
                                                 baseOid = rootOidMap.get(mBean.getRoot());
 90  
                                         }
 91  9
                                         if (baseOid == null) {
 92  8
                                                 baseOid = defaultRootOid;
 93  
                                         }
 94  9
                                         if (baseOid == null) {
 95  2
                                                 baseOid = mainDefaultRootOid;
 96  
                                         }
 97  9
                                         baseOid = baseOid + "." + mBean.getOid();
 98  
                                 }
 99  
                         }
 100  
                 }
 101  15
                 return baseOid;
 102  
         }
 103  
 
 104  
         /**
 105  
          * Creates and returns the list of mapping for access to each attribute of an MBean.
 106  
          * @param mBeanAttributeInfoMap Map of informations on each MBean attribute.
 107  
          * @param classLoader {@link ClassLoader} where the MBean has been created.
 108  
          * @param baseOid Base OID of MBean instance.
 109  
          * @return List of mapping for access to each attribute of an MBean (never <code>NULL</code>).
 110  
          * @throws Exception Exception if an error occurred.
 111  
          */
 112  
         public List<MBeanAttributeMapping> newMBeanAttributeMappingList (final Map<String, MBeanAttributeInfo> mBeanAttributeInfoMap, final ClassLoader classLoader,
 113  
                         final String baseOid) throws Exception {
 114  9
                 final List<MBeanAttributeMapping> mappingList = new ArrayList<MBeanAttributeMapping>();
 115  9
                 final Iterator<MBeanAttribute> attributeIterator = this.jaxbElement.getValue().getAttributes().getAttribute().iterator();
 116  
                 MBeanAttribute attribute;
 117  
                 String attributeName;
 118  
                 MBeanAttributeInfo mBeanAttributeInfo;
 119  
                 SnmpOid oid;
 120  
                 SnmpDataType snmpDataType;
 121  
                 Class<?> jmxDataType;
 122  
                 boolean readable;
 123  
                 boolean writable;
 124  102
                 while (attributeIterator.hasNext()) {
 125  93
                         attribute = attributeIterator.next();
 126  
 
 127  
                         // Property name & info
 128  93
                         attributeName = attribute.getName().substring(0, 1).toUpperCase() + attribute.getName().substring(1);
 129  93
                         mBeanAttributeInfo = mBeanAttributeInfoMap.get(attributeName);
 130  
 
 131  
                         // OID
 132  93
                         oid = SnmpOid.newInstance(baseOid, attribute.getNode(), 0);
 133  
 
 134  
                         // snmpDataType
 135  93
                         snmpDataType = SnmpDataType.valueOf(attribute.getType().value());
 136  
 
 137  
                         // jmxDataType
 138  93
                         jmxDataType = toClass(classLoader, mBeanAttributeInfo.getType());
 139  
 
 140  
                         // readable
 141  93
                         readable = (mBeanAttributeInfo.isReadable() && !attribute.isDisabled());
 142  
 
 143  
                         // writable
 144  93
                         writable = (readable && mBeanAttributeInfo.isWritable() && attribute.isWritable());
 145  
 
 146  93
                         mappingList.add(new MBeanAttributeMapping(oid, attributeName, snmpDataType, jmxDataType, readable, writable));
 147  
                 }
 148  9
                 return mappingList;
 149  
         }
 150  
 
 151  
         /**
 152  
          * Converts a class name to its instance.
 153  
          * @param classLoader {@link ClassLoader} where the MBean has been created.
 154  
          * @param className Class name.
 155  
          * @return Class instance.
 156  
          * @throws Exception Exception if an error occurred.
 157  
          */
 158  
         private Class<?> toClass (final ClassLoader classLoader, final String className) throws Exception {
 159  
                 Class<?> result;
 160  93
                 if (byte.class.getName().equals(className)) {
 161  7
                         result = byte.class;
 162  
                 }
 163  86
                 else if (short.class.getName().equals(className)) {
 164  7
                         result = short.class;
 165  
                 }
 166  79
                 else if (int.class.getName().equals(className)) {
 167  7
                         result = int.class;
 168  
                 }
 169  72
                 else if (boolean.class.getName().equals(className)) {
 170  7
                         result = boolean.class;
 171  
                 }
 172  65
                 else if (long.class.getName().equals(className)) {
 173  16
                         result = long.class;
 174  
                 }
 175  49
                 else if (byte[].class.getName().equals(className)) {
 176  7
                         result = byte[].class;
 177  
                 }
 178  42
                 else if (short[].class.getName().equals(className)) {
 179  7
                         result = short[].class;
 180  
                 }
 181  35
                 else if (int[].class.getName().equals(className)) {
 182  7
                         result = int[].class;
 183  
                 }
 184  28
                 else if (long[].class.getName().equals(className)) {
 185  7
                         result = long[].class;
 186  
                 }
 187  
                 else {
 188  21
                         result = classLoader.loadClass(className);
 189  
                 }
 190  93
                 return result;
 191  
         }
 192  
 
 193  
         /**
 194  
          * Creates and returns the map of mapping to build SNMP traps from JMX notifications for each notification type.
 195  
          * @param baseOid Base OID of MBean instance.
 196  
          * @return Map of mapping to build SNMP traps from the JMX notifications for each notification type (never <code>NULL</code>).
 197  
          */
 198  
         public Map<String, SnmpTrapMapping> newSnmpTrapMappingMap (final String baseOid) {
 199  13
                 final Map<String, SnmpTrapMapping> trapMapping = new HashMap<String, SnmpTrapMapping>();
 200  13
                 final MBeanNotifications notifications = this.jaxbElement.getValue().getNotifications();
 201  13
                 if (notifications != null) {
 202  10
                         final Map<String, DataMapTrapMapping> dataMapMappingMap = newDataMapTrapMappingMap(baseOid, notifications.getVariableBindings());
 203  10
                         final DataMapTrapMapping defaultDataMapMapping = newDefaultDataMapTrapMapping(baseOid, notifications.getVariableBindings());
 204  
                         DataMapTrapMapping dataMapMapping;
 205  
                         SnmpOid source;
 206  
                         GenericSnmpTrapType genericType;
 207  10
                         for (final TrapEnterprise enterprise : notifications.getEnterprise()) {
 208  30
                                 for (final GenericTrap trap : enterprise.getGenericTrap()) {
 209  40
                                         dataMapMapping = findDataMapTrapMapping(dataMapMappingMap, defaultDataMapMapping, enterprise, trap.getUserdata());
 210  40
                                         source = SnmpOid.newInstance(baseOid, enterprise.getNode(), 0);
 211  40
                                         genericType = GenericSnmpTrapType.valueOf(trap.getCode().value());
 212  40
                                         trapMapping.put(trap.getNotifType(), new GenericSnmpTrapMapping(source, dataMapMapping, genericType));
 213  
                                 }
 214  30
                                 for (final SpecificTrap trap : enterprise.getSpecificTrap()) {
 215  30
                                         dataMapMapping = findDataMapTrapMapping(dataMapMappingMap, defaultDataMapMapping, enterprise, trap.getUserdata());
 216  30
                                         source = SnmpOid.newInstance(baseOid, enterprise.getNode(), 0);
 217  30
                                         trapMapping.put(trap.getNotifType(), new SpecificSnmpTrapMapping(source, dataMapMapping, trap.getCode()));
 218  
                                 }
 219  
                         }
 220  
                 }
 221  13
                 return trapMapping;
 222  
         }
 223  
 
 224  
         /**
 225  
          * Find a mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} by its name.
 226  
          * @param dataMapMappingMap Map of mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX
 227  
          *            notifications (must not be <code>NULL</code>).
 228  
          * @param defaultDataMapMapping Default mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX
 229  
          *            notifications (must not be <code>NULL</code>).
 230  
          * @param enterprise Represents the contents of <code>enterprise</code> tag of XML file.
 231  
          * @param userDataName Name of mapping to find for build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap}.
 232  
          * @return Mapping found to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap}.
 233  
          */
 234  
         private DataMapTrapMapping findDataMapTrapMapping (final Map<String, DataMapTrapMapping> dataMapMappingMap, final DataMapTrapMapping defaultDataMapMapping,
 235  
                         final TrapEnterprise enterprise, final String userDataName) {
 236  70
                 DataMapTrapMapping dataMapMapping = null;
 237  70
                 String dataMapMappingName = (userDataName != null ? userDataName : enterprise.getUserdata());
 238  70
                 if (dataMapMappingName != null) {
 239  48
                         dataMapMapping = dataMapMappingMap.get(dataMapMappingName);
 240  
                 }
 241  70
                 if (dataMapMapping == null) {
 242  22
                         dataMapMapping = defaultDataMapMapping;
 243  
                 }
 244  70
                 return dataMapMapping;
 245  
         }
 246  
 
 247  
         /**
 248  
          * Creates and returns the map of mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX
 249  
          * notifications.
 250  
          * @param baseOid Base OID of MBean instance.
 251  
          * @param variableBindings Represents the contents of <code>variable-bindings</code> tag of XML file.
 252  
          * @return Map of mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX notifications (never
 253  
          *         <code>NULL</code>).
 254  
          */
 255  
         private Map<String, DataMapTrapMapping> newDataMapTrapMappingMap (final String baseOid, final TrapVariableBindings variableBindings) {
 256  10
                 final Map<String, DataMapTrapMapping> dataMapMappingMap = new HashMap<String, DataMapTrapMapping>();
 257  10
                 if (variableBindings != null) {
 258  9
                         final SnmpOid sequenceNumberOid = (variableBindings.getSequenceNumber() != null ? SnmpOid.newInstance(baseOid, variableBindings.getSequenceNumber()
 259  
                                         .getNode(), 0) : null);
 260  9
                         final SnmpOid messageOid = (variableBindings.getMessage() != null ? SnmpOid.newInstance(baseOid, variableBindings.getMessage().getNode(), 0) : null);
 261  9
                         final boolean hasSystemInfo = variableBindings.isSystemInfo();
 262  
                         DataMapTrapMapping dataMapMapping;
 263  
                         SnmpDataType userDataType;
 264  
                         SnmpOid userDataOid;
 265  9
                         for (final TrapUserData userData : variableBindings.getUserdata()) {
 266  8
                                 userDataType = SnmpDataType.valueOf(userData.getType().value());
 267  8
                                 userDataOid = SnmpOid.newInstance(baseOid, userData.getNode(), 0);
 268  8
                                 dataMapMapping = new SimpleDataMapTrapMapping(sequenceNumberOid, messageOid, hasSystemInfo, userDataType, userDataOid);
 269  8
                                 dataMapMappingMap.put(userData.getName(), dataMapMapping);
 270  
                         }
 271  
                         MapDataMapTrapMapping mapDataMapMapping;
 272  9
                         for (final TrapUserDataMap userDataMap : variableBindings.getUserdataMap()) {
 273  16
                                 mapDataMapMapping = new MapDataMapTrapMapping(sequenceNumberOid, messageOid, hasSystemInfo);
 274  16
                                 for (final TrapUserDataEntry entry : userDataMap.getEntry()) {
 275  32
                                         userDataType = SnmpDataType.valueOf(entry.getType().value());
 276  32
                                         userDataOid = SnmpOid.newInstance(baseOid, entry.getNode(), 0);
 277  32
                                         mapDataMapMapping.addUserDataEntry(entry.getKey(), userDataType, userDataOid);
 278  
                                 }
 279  16
                                 dataMapMappingMap.put(userDataMap.getName(), mapDataMapMapping);
 280  
                         }
 281  
                 }
 282  10
                 return dataMapMappingMap;
 283  
         }
 284  
 
 285  
         /**
 286  
          * Creates and returns the default mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX
 287  
          * notifications.
 288  
          * @param baseOid Base OID of MBean instance.
 289  
          * @param variableBindings Represents the contents of <code>variable-bindings</code> tag of XML file.
 290  
          * @return Default mapping to build the <code>dataMap</code> field of {@link net.sf.snmpadaptor4j.object.SnmpTrap SnmpTrap} from JMX notifications (never
 291  
          *         <code>NULL</code>).
 292  
          */
 293  
         private DefaultDataMapTrapMapping newDefaultDataMapTrapMapping (final String baseOid, final TrapVariableBindings variableBindings) {
 294  
                 DefaultDataMapTrapMapping defaultDataMapMapping;
 295  10
                 if (variableBindings != null) {
 296  9
                         final SnmpOid sequenceNumberOid = (variableBindings.getSequenceNumber() != null ? SnmpOid.newInstance(baseOid, variableBindings.getSequenceNumber()
 297  
                                         .getNode(), 0) : null);
 298  9
                         final SnmpOid messageOid = (variableBindings.getMessage() != null ? SnmpOid.newInstance(baseOid, variableBindings.getMessage().getNode(), 0) : null);
 299  9
                         final boolean hasSystemInfo = variableBindings.isSystemInfo();
 300  9
                         defaultDataMapMapping = new DefaultDataMapTrapMapping(sequenceNumberOid, messageOid, hasSystemInfo);
 301  9
                 }
 302  
                 else {
 303  1
                         defaultDataMapMapping = new DefaultDataMapTrapMapping(null, null, false);
 304  
                 }
 305  10
                 return defaultDataMapMapping;
 306  
         }
 307  
 
 308  
         /*
 309  
          * {@inheritDoc}
 310  
          * @see java.lang.Object#toString()
 311  
          */
 312  
         @Override
 313  
         public String toString () {
 314  1
                 return "XmlMappingParser[" + this.url + "]";
 315  
         }
 316  
 
 317  
 }