User: ejort Date: 02/02/22 08:44:33 Modified: src/main/org/jboss/mx/server/registry BasicMBeanRegistry.java MBeanRegistry.java Log: Default Domain, Querying, Various Other Fixes Revision Changes Path 1.6 +262 -24 jmx/src/main/org/jboss/mx/server/registry/BasicMBeanRegistry.java Index: BasicMBeanRegistry.java =================================================================== RCS file: /cvsroot/jboss/jmx/src/main/org/jboss/mx/server/registry/BasicMBeanRegistry.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- BasicMBeanRegistry.java 15 Dec 2001 01:12:38 -0000 1.5 +++ BasicMBeanRegistry.java 22 Feb 2002 16:44:33 -0000 1.6 @@ -6,16 +6,20 @@ */ package org.jboss.mx.server.registry; -import java.util.Map; -import java.util.HashMap; - +import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; +import javax.management.MalformedObjectNameException; import javax.management.ObjectName; - -import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** - * The registry for object name - object reference mapping in the + * The registry for object name - object reference mapping in the * MBean server. * <p> * The implementation of this class affects the invocation speed @@ -24,46 +28,280 @@ * @see org.jboss.mx.server.registry.MBeanRegistry * * @author <a href="mailto:[EMAIL PROTECTED]">Juha Lindfors</a>. - * @version $Revision: 1.5 $ - */ -public class BasicMBeanRegistry + * @author <a href="mailto:[EMAIL PROTECTED]">Trevor Squires</a>. + * @version $Revision: 1.6 $ + */ +public class BasicMBeanRegistry implements MBeanRegistry { // Attributes ---------------------------------------------------- - private Map mbeanMap = new ConcurrentReaderHashMap(); + private Map domainMap = new HashMap(); + private String defaultDomain; + + // Constructors -------------------------------------------------- + + public BasicMBeanRegistry(String defaultDomain) + { + this.defaultDomain = defaultDomain; + } - // Public -------------------------------------------------------- - public void add(MBeanEntry e) + + public synchronized void add(MBeanEntry entry) throws InstanceAlreadyExistsException { - mbeanMap.put(e.getObjectName(), e); + ObjectName name = entry.getObjectName(); + String domain = name.getDomain(); + String props = name.getCanonicalKeyPropertyListString(); + + Map mbeanMap = (Map) domainMap.get(domain); + if (mbeanMap == null) + { + mbeanMap = new HashMap(); + domainMap.put(domain, mbeanMap); + } + + if (mbeanMap.get(props) != null) + { + throw new InstanceAlreadyExistsException(name + " already registered."); + } + + mbeanMap.put(props, entry); } - public void remove(ObjectName name) throws InstanceNotFoundException + + public synchronized void remove(ObjectName name) throws InstanceNotFoundException { - Object o = mbeanMap.remove(name); - if (o == null) + String domain = name.getDomain(); + String props = name.getCanonicalKeyPropertyListString(); + Map mbeanMap = (Map) domainMap.get(domain); + + if (null == mbeanMap || null == mbeanMap.remove(props)) + { throw new InstanceNotFoundException(name + " not registered."); + } } - public MBeanEntry get(ObjectName name) throws InstanceNotFoundException + public synchronized MBeanEntry get(ObjectName name) throws InstanceNotFoundException { - MBeanEntry entry = (MBeanEntry)mbeanMap.get(name); + String domain = name.getDomain(); + if (domain.length() == 0) + domain = defaultDomain; + String props = name.getCanonicalKeyPropertyListString(); + Map mbeanMap = (Map) domainMap.get(domain); + Object o = null; - if (entry == null) + if (null == mbeanMap || null == (o = mbeanMap.get(props))) + { throw new InstanceNotFoundException(name + " not registered."); + } - return entry; + return (MBeanEntry) o; } - public boolean contains(ObjectName name) + public synchronized boolean contains(ObjectName name) { - return mbeanMap.containsKey(name); + String domain = name.getDomain(); + if (domain.length() == 0) + domain = defaultDomain; + String props = name.getCanonicalKeyPropertyListString(); + Map mbeanMap = (Map) domainMap.get(domain); + + return (null != mbeanMap && mbeanMap.containsKey(props)); } - public int getSize() + public synchronized int getSize() { - return mbeanMap.size(); + int retval = 0; + + for (Iterator iterator = domainMap.values().iterator(); iterator.hasNext();) + { + retval += ((Map)iterator.next()).size(); + } + return retval; + } + + /** + * Return a List of MBeanEntry objects with ObjectNames that match the specified pattern. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Trevor Squires</a>. + */ + public synchronized List findEntries(ObjectName pattern) + { + ArrayList retval = new ArrayList(); + + // There are a couple of shortcuts we can employ to make this a + // bit faster - they're commented. + + // First, if pattern == null or pattern.getCanonicalName() == "*:*" we want the + // set of all MBeans. + if (pattern == null || pattern.getCanonicalName().equals("*:*")) + { + for (Iterator domainIter = domainMap.values().iterator(); domainIter.hasNext();) + { + for (Iterator mbeanIter = ((Map)domainIter.next()).values().iterator(); mbeanIter.hasNext();) + { + retval.add(mbeanIter.next()); + } + } + } + // Next, if !pattern.isPattern() then we are doing a simple get (maybe defaultDomain). + else if (!pattern.isPattern()) + { + // simple get + try + { + retval.add(get(pattern)); + } + catch (InstanceNotFoundException e) + { + // we don't care + } + } + // Now we have to do a brute force, oh well. + else + { + String patternDomain = pattern.getDomain(); + if (patternDomain.length() == 0) + patternDomain = defaultDomain; + boolean patternIsPropertyPattern = pattern.isPropertyPattern(); + String patternCanonicalKPS = pattern.getCanonicalKeyPropertyListString(); + Object[] propkeys = null; + Object[] propvals = null; + + // prebuild arrays of keys and values for quick comparison + // when isPropertyPattern(). + if (patternIsPropertyPattern) + { + Hashtable patternKPList = pattern.getKeyPropertyList(); + propkeys = new Object[patternKPList.size()]; + propvals = new Object[propkeys.length]; + + int i = 0; + for (Iterator iterator = patternKPList.entrySet().iterator(); iterator.hasNext(); i++) + { + Map.Entry mapEntry = (Map.Entry) iterator.next(); + propkeys[i] = mapEntry.getKey(); + propvals[i] = mapEntry.getValue(); + } + } + + // Here we go, step through every domain and see if our pattern matches before optionally checking + // each ObjectName's properties for a match. + for (Iterator domainIter = domainMap.entrySet().iterator(); domainIter.hasNext();) + { + Map.Entry mapEntry = (Map.Entry) domainIter.next(); + if (domainMatches((String) mapEntry.getKey(), patternDomain)) + { + // yes it's a label, sue me. + CHOOSE_MBEAN: for (Iterator mbeanIter = ((Map)mapEntry.getValue()).values().iterator(); mbeanIter.hasNext();) + { + MBeanEntry entry = (MBeanEntry) mbeanIter.next(); + ObjectName name = entry.getObjectName(); + + if (patternIsPropertyPattern) + { + // another shortcut - we only compare the key properties list of the registered MBean + // if properties have been specifed in the pattern (i.e. something other than just "*") + if (propkeys.length > 0) + { + Hashtable nameKPList = name.getKeyPropertyList(); + + for (int i = 0; i < propkeys.length; i++) + { + // skip the current MBean if there isn't a match + if ( !propvals[i].equals(nameKPList.get(propkeys[i])) ) + { + continue CHOOSE_MBEAN; + } + } + } + retval.add(entry); + } + else + { + // Ok, it's a like-for-like comparison of the keyProperties. + // Knowing how our implementation of ObjectName works, it's *much* + // faster to compare the canonicalKeyProperties strings than it + // is to compare the two hashtables. + if (patternCanonicalKPS.equals(name.getCanonicalKeyPropertyListString())) + { + retval.add(entry); + } + } + } + } + } + } + + return retval; + } + + /** + * Compare the src and pat strings where ? and * chars are significant. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Trevor Squires</a>. + */ + protected boolean domainMatches(String src, String pat) + { + if (src.equals("*")) // no point doing more that we have to... + { + return true; + } + return domainMatches(src.toCharArray(), 0, pat.toCharArray(), 0); + } + + /** + * Compare the src and pat char arrays where ? and * chars are significant. + * + * I arrived at this solution after quite a bit of trial and error - it's + * all a bit interwoven. Obviously I'm no good at parsers and there must + * be a clearer or more elegant way to do this. I'm suitably in awe of + * the perl regex hackers now. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Trevor Squires</a>. + */ + protected boolean domainMatches(char[] src, int spos, char[] pat, int ppos) + { + int slen = src.length; + int plen = pat.length; + + while (ppos < plen) + { + char c = pat[ppos++]; + if ('?' == c) + { + // eat a src character and make sure we're not + // already at the end + if (spos++ == slen) + { + return false; + } + } + else if ('*' == c) + { + if (ppos == plen) // shortcut - * at the end of the pattern + { + return true; + } + + // hammer the src chars recursively until we + // get a match or we drop off the end of src + do + { + if (domainMatches(src, spos, pat, ppos)) + { + return true; + } + } + while (++spos < slen); + } + else if (spos == slen || c != src[spos++]) + { + return false; + } + } + // fell through with no falses so make sure all of src was examined + return (spos == slen); } } 1.2 +12 -1 jmx/src/main/org/jboss/mx/server/registry/MBeanRegistry.java Index: MBeanRegistry.java =================================================================== RCS file: /cvsroot/jboss/jmx/src/main/org/jboss/mx/server/registry/MBeanRegistry.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- MBeanRegistry.java 3 Dec 2001 02:18:43 -0000 1.1 +++ MBeanRegistry.java 22 Feb 2002 16:44:33 -0000 1.2 @@ -4,17 +4,28 @@ package org.jboss.mx.server.registry; import javax.management.ObjectName; +import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; +import java.util.List; + public interface MBeanRegistry { - void add(MBeanEntry e); + void add(MBeanEntry e) throws InstanceAlreadyExistsException; void remove(ObjectName name) throws InstanceNotFoundException; MBeanEntry get(ObjectName name) throws InstanceNotFoundException; boolean contains(ObjectName name); + + /** + * Return a List of MBeanEntry objects with ObjectNames that match the specified pattern. + * + * @param pattern the pattern to match + * @return a List of entries matching the pattern + */ + public List findEntries(ObjectName pattern); int getSize(); }
_______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development