User: squirest
  Date: 01/12/20 19:01:45

  Modified:    src/main/javax/management ObjectName.java
  Log:
  made it pass all the testcases
  
  Revision  Changes    Path
  1.3       +240 -72   jmx/src/main/javax/management/ObjectName.java
  
  Index: ObjectName.java
  ===================================================================
  RCS file: /cvsroot/jboss/jmx/src/main/javax/management/ObjectName.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ObjectName.java   2001/12/07 00:19:49     1.2
  +++ ObjectName.java   2001/12/21 03:01:45     1.3
  @@ -6,105 +6,111 @@
    */
   package javax.management;
   
  -import java.util.Map;
  -import java.util.Hashtable;
  -import java.util.HashMap;
  -import java.util.Arrays;
  -import java.util.Collections;
  -import java.util.List;
   import java.util.ArrayList;
  +import java.util.Collections;
  +import java.util.Hashtable;
   import java.util.Iterator;
   import java.util.StringTokenizer;
   
  -
   /**
    * Object name represents the MBean reference.
    *
    * @see javax.management.MBeanServer
    *
    * @author  <a href="mailto:[EMAIL PROTECTED]";>Juha Lindfors</a>.
  - * @version $Revision: 1.2 $
  - *   
  + * @author  <a href="mailto:[EMAIL PROTECTED]";>Trevor Squires</a>.
  + * @version $Revision: 1.3 $
  + *
    */
   public class ObjectName implements java.io.Serializable
   {
  +
  +   // Attributes ----------------------------------------------------
  +   private boolean hasPattern = false;
  +   private boolean hasPropertyPattern = false;
  +   private Hashtable propertiesHash = null;
  +
  +   private String domain = null;
  +   private String keyProperties = null;
  +   private String canonicalKeyProperties = null;
   
  -   // Attributes ----------------------------------------------------      
  -   private boolean isPattern  = false;
  -   private boolean isPropertyPattern = false;
  -   private Map keyMap = new HashMap();
  -   private String domain = "";
  -   private String canonicalName = null;
  +   private int precompHashCode;
   
  -   // Constructors --------------------------------------------------   
  +   // Constructors --------------------------------------------------
      public ObjectName(String name) throws MalformedObjectNameException
      {
         if (name == null)
            throw new MalformedObjectNameException("null name");
  +
  +      int domainSep = name.indexOf(':');
   
  -      if (name.indexOf(':') == -1)
  +      if (-1 == domainSep)
            throw new MalformedObjectNameException("missing domain");
   
  -      if (!(name.startsWith(":")))
  -         this.domain = name.substring(0, name.indexOf(':'));
  +      initDomain(name.substring(0, domainSep));
  +      initProperties(name.substring(domainSep + 1));
  +   }
   
  -      String keys = name.substring(name.indexOf(':') + 1, name.length());
  -      StringTokenizer tokenizer = new StringTokenizer(keys, ",");
  +   public ObjectName(String domain, String key, String value)
  +      throws MalformedObjectNameException
  +   {
  +      initDomain(domain);
   
  -      while(tokenizer.hasMoreTokens())
  +      if (null == key || null == value)
         {
  -         String key = tokenizer.nextToken();
  -         keyMap.put(key.substring(0, key.indexOf('=')),
  -                    key.substring(key.indexOf('=') + 1, key.length()));
  +         throw new MalformedObjectNameException("properties key or value cannot be 
null");
         }
   
  -      this.canonicalName = getDomain() + ":" + getCanonicalKeyPropertyListString();
  -   }
  +      Hashtable ptable = new Hashtable();
  +      ptable.put(key, value);
   
  -   public ObjectName(String domain, String key, String value)
  -   throws MalformedObjectNameException
  -   {
  -      this.domain = domain;
  -      this.keyMap.put(key, value);
  -      this.canonicalName = domain + ":" + key + "=" + value;
  +      initProperties(ptable);
  +
  +      this.keyProperties = key + "=" + value;
      }
   
      public ObjectName(String domain, Hashtable table) throws 
MalformedObjectNameException
      {
  -      this.domain = domain;
  -      this.keyMap.putAll(table);
  -      this.canonicalName = domain + ":" + getCanonicalKeyPropertyListString();
  +      if (null == table || table.size() < 1)
  +      {
  +         throw new MalformedObjectNameException("null or empty properties");
  +      }
  +
  +      initDomain(domain);
  +      initProperties((Hashtable) table.clone());
  +
  +      this.keyProperties = canonicalKeyProperties;
      }
   
  -   // Public ------------------------------------------------------   
  +   // Public ------------------------------------------------------
      public boolean equals(Object object)
      {
         if (!(object instanceof ObjectName))
            return false;
   
  -      ObjectName oname = (ObjectName)object;
  +      ObjectName oname = (ObjectName) object;
   
  -      return (oname.getCanonicalName().equals(canonicalName));
  +      return (oname.hashCode() == this.precompHashCode);
      }
   
      public int hashCode()
      {
  -      return canonicalName.hashCode();
  +      return precompHashCode;
      }
   
      public String toString()
      {
  -      return canonicalName;
  +      return this.domain + ":" + keyProperties;
      }
   
      public boolean isPattern()
      {
  -      return isPattern;
  +      return hasPattern;
      }
   
      public String getCanonicalName()
      {
  -      return canonicalName;
  +      return this.domain + ":" + canonicalKeyProperties;
      }
   
      public String getDomain()
  @@ -114,63 +120,225 @@
   
      public String getKeyProperty(String property)
      {
  -      return (String)keyMap.get(property);
  +      return (String) propertiesHash.get(property);
      }
   
      public Hashtable getKeyPropertyList()
      {
  -      return new Hashtable(keyMap);
  +      return (Hashtable) propertiesHash.clone();
      }
   
      public String getKeyPropertyListString()
      {
  -      // FIXME: its immutable object, build this only once
  -      String[] keys = (String[])keyMap.keySet().toArray(new String[0]);
  -      StringBuffer strBuffer = new StringBuffer(1000);
  -
  -      for (int i = 0; i < keys.length; ++i)
  -      {
  -         String key = keys[i];
  -         strBuffer.append(key);
  -         strBuffer.append('=');
  -         strBuffer.append(keyMap.get(key));
  -         strBuffer.append(',');
  -      }
  -      strBuffer.deleteCharAt(strBuffer.length() - 1);
  -      return strBuffer.toString();
  +      return keyProperties;
      }
   
      public String getCanonicalKeyPropertyListString()
      {
  -      // FIXME: its immutable object, build this only once
  -      Iterator it = keyMap.keySet().iterator();
  +      return canonicalKeyProperties;
  +   }
  +
  +   public boolean isPropertyPattern()
  +   {
  +      // FIXME: patterns not implemented
  +      return hasPropertyPattern;
  +   }
  +
  +   // Private -----------------------------------------------------
  +
  +   /**
  +    * checks for domain patterns and illegal characters
  +    */
  +   private void initDomain(String dstring) throws MalformedObjectNameException
  +   {
  +      if (null == dstring)
  +      {
  +         throw new MalformedObjectNameException("null domain");
  +      }
  +
  +      if (dstring.indexOf(',') > -1 || dstring.indexOf('=') > -1)
  +      {
  +         throw new MalformedObjectNameException("domain contains illegal 
characters");
  +      }
  +
  +      if (dstring.indexOf('*') > -1 || dstring.indexOf('?') > -1)
  +      {
  +         this.hasPattern = true;
  +      }
  +
  +      this.domain = dstring;
  +   }
  +
  +   /**
  +    * takes the properties string and breaks it up into key/value pairs for
  +    * insertion into a newly created hashtable.
  +    *
  +    * minimal validation is performed so that it doesn't blow up when
  +    * constructing the kvp strings.
  +    *
  +    * checks for duplicate keys
  +    *
  +    * detects property patterns
  +    *
  +    */
  +   private void initProperties(String properties) throws 
MalformedObjectNameException
  +   {
  +      if (null == properties || properties.length() < 1)
  +      {
  +         throw new MalformedObjectNameException("null or empty properties");
  +      }
  +
  +      // The StringTokenizer below hides malformations such as ',,' in the
  +      // properties string or ',' as the first or last character.
  +      // Rather than asking for tokens and building a state machine I'll
  +      // just manually check for those 3 scenarios.
  +
  +      if (properties.startsWith(",") || properties.endsWith(",") || 
properties.indexOf(",,") != -1)
  +      {
  +         throw new MalformedObjectNameException("empty key/value pair in properties 
string");
  +      }
  +
  +      Hashtable ptable = new Hashtable();
  +
  +      StringTokenizer tokenizer = new StringTokenizer(properties, ",");
  +      while (tokenizer.hasMoreTokens())
  +      {
  +         String chunk = tokenizer.nextToken();
  +
  +         if (chunk.equals("*"))
  +         {
  +            this.hasPropertyPattern = true;
  +            this.hasPattern = true;
  +            continue;
  +         }
  +
  +         int keylen = chunk.length();
  +         int eqpos = chunk.indexOf('=');
  +
  +         // test below: as in '=value' or 'key=' so that our substrings don't blow 
up
  +         if (eqpos < 1 || (keylen == eqpos + 1))
  +         {
  +            throw new MalformedObjectNameException("malformed key/value pair: " + 
chunk);
  +         }
  +
  +         String key = chunk.substring(0, eqpos);
  +         if (ptable.containsKey(key))
  +         {
  +            throw new MalformedObjectNameException("duplicate key: " + key);
  +         }
  +
  +         ptable.put(key, chunk.substring(eqpos + 1, keylen));
  +      }
  +
  +      initProperties(ptable);
  +
  +      // if it's not a propertyPattern then preserve the original string
  +      if (!this.hasPropertyPattern)
  +      {
  +         this.keyProperties = properties;
  +      }
  +      else
  +      {
  +         this.keyProperties = canonicalKeyProperties;
  +      }
  +   }
  +
  +   /**
  +    * validates incoming properties hashtable
  +    *
  +    * builds canonical string
  +    *
  +    * precomputes the hashcode
  +    */
  +   private void initProperties(Hashtable properties) throws 
MalformedObjectNameException
  +   {
  +      if (null == properties || (!this.hasPropertyPattern && properties.size() < 1))
  +      {
  +         throw new MalformedObjectNameException("null or empty properties");
  +      }
  +
  +      Iterator it = properties.keySet().iterator();
         ArrayList list = new ArrayList();
   
  -      while(it.hasNext())
  +      while (it.hasNext())
         {
  -         String key = (String)it.next();
  -         list.add(new String(key + "=" + keyMap.get(key)));
  +         String key = null;
  +         try
  +         {
  +            key = (String) it.next();
  +         }
  +         catch (ClassCastException e)
  +         {
  +            throw new MalformedObjectNameException("key is not a string");
  +         }
  +
  +         String val = null;
  +         try
  +         {
  +            val = (String) properties.get(key);
  +         }
  +         catch (ClassCastException e)
  +         {
  +            throw new MalformedObjectNameException("value is not a string");
  +         }
  +
  +         if (isIllegalKeyOrValue(key) || isIllegalKeyOrValue(val))
  +         {
  +            throw new MalformedObjectNameException("malformed key/value pair: " + 
key + "=" + val);
  +         }
  +         list.add(new String(key + "=" + val));
         }
   
         Collections.sort(list);
         StringBuffer strBuffer = new StringBuffer();
   
         it = list.iterator();
  -      while(it.hasNext())
  +      while (it.hasNext())
         {
            strBuffer.append(it.next());
  -         strBuffer.append(',');
  +         if (it.hasNext())
  +         {
  +            strBuffer.append(',');
  +         }
         }
  -      strBuffer.deleteCharAt(strBuffer.length() -1);
  -      return strBuffer.toString();
  +
  +      this.propertiesHash = properties;
  +      this.canonicalKeyProperties = strBuffer.toString();
  +
  +      // now precompute the hashcode
  +      // just need it to be unique
  +      strBuffer.append(':').append(this.domain).append(':');
  +      strBuffer.append(isPattern()).append(isPropertyPattern());
  +      this.precompHashCode = strBuffer.toString().hashCode();
      }
   
  -   public boolean isPropertyPattern()
  +   /**
  +    * returns true if the key or value string is zero length or contains illegal 
characters
  +    */
  +   private boolean isIllegalKeyOrValue(String keyOrValue)
      {
  -      // FIXME: patterns not implemented
  -      return isPropertyPattern;
  -   }
  +      char[] chars = keyOrValue.toCharArray();
  +
  +      if (chars.length == 0)
  +      {
  +         return true;
  +      }
   
  +      for (int i = 0; i < chars.length; i++)
  +      {
  +         switch (chars[i])
  +         {
  +            case ':':
  +            case ',':
  +            case '=':
  +            case '*':
  +            case '?':
  +               return true;
  +         }
  +      }
  +
  +      return false;
  +   }
   }
   
   
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to