Package javax.management

Source Code of javax.management.ObjectName

/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package javax.management;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.StreamCorruptedException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.jboss.mx.util.ObjectNamePatternHelper;
import org.jboss.mx.util.ObjectNamePatternHelper.PropertyPattern;
import org.jboss.mx.util.Serialization;

/**
* Object name represents the MBean reference.
*
* @see javax.management.MBeanServer
*
* @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
* @author  <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
* @author  <a href="mailto:adrian.brock@happeningtimes.com">Adrian Brock</a>.
* @version $Revision: 1.12 $
*
* <p><b>Revisions:</b>
* <p><b>20020521 Adrian Brock:</b>
* <ul>
* <li>Allow *,* in the hashtable properties to signify a property pattern
* </ul>
* <p><b>20020710 Adrian Brock:</b>
* <ul>
* <li> Serialization
* </ul>
*/
public class ObjectName
   implements java.io.Serializable, QueryExp
{

   // Attributes ----------------------------------------------------
   private transient boolean hasPattern = false;
   private transient boolean hasDomainPattern = false;
   private transient boolean hasPropertyPattern = false;
   private transient Hashtable propertiesHash = null;

   private transient String domain = null;
   private transient String kProps = null;
   private transient String ckProps = null;

   private transient int hash;
   private transient PropertyPattern propertyPattern;

   // Static --------------------------------------------------------

   private static final long serialVersionUID;
   private static final ObjectStreamField[] serialPersistentFields;

   static
   {
      switch (Serialization.version)
      {
      case Serialization.V1R0:
         serialVersionUID = -5467795090068647408L;
         serialPersistentFields = new ObjectStreamField[]
         {
            new ObjectStreamField("domain",             String.class),
            new ObjectStreamField("propertyList",       Hashtable.class),
            new ObjectStreamField("propertyListString", String.class),
            new ObjectStreamField("canonicalName"     , String.class),
            new ObjectStreamField("pattern"           , Boolean.TYPE),
            new ObjectStreamField("propertyPattern"   , Boolean.TYPE)
         };
         break;
      default:
         serialVersionUID = 1081892073854801359L;
         serialPersistentFields = new ObjectStreamField[0];
      }
   }

   /**
    * Return an instance of an ObjectName
    *
    * @todo Review: return common object names?
    * @param name a string representation of the object name
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null name
    */
   public static ObjectName getInstance(String name)
      throws MalformedObjectNameException
   {
      return new ObjectName(name);
   }

   /**
    * Return an instance of an ObjectName
    *
    * @todo Review: return common object names?
    * @param domain the domain of the object name
    * @param key the key of the single property
    * @param value the value of the single property
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null parameter
    */
   public static ObjectName getInstance(String domain, String key, String value)
      throws MalformedObjectNameException
   {
      return new ObjectName(domain, key, value);
   }

   /**
    * Return an instance of an ObjectName
    *
    * @todo Review: return common object names?
    * @param domain the domain of the object name
    * @param table of hashtable for key property pairs
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null parameter
    */
   public static ObjectName getInstance(String domain, Hashtable table)
      throws MalformedObjectNameException
   {
      return new ObjectName(domain, table);
   }

   // Constructors --------------------------------------------------

   /**
    *
    * @param String name a string representation of the object name
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null name
    */
   public ObjectName(String name) throws MalformedObjectNameException
   {
      init(name);
   }

   /**
    * Construct a new ObjectName
    *
    * @param domain the domain of the object name
    * @param key the key of the single property
    * @param value the value of the single property
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null parameter
    */
   public ObjectName(String domain, String key, String value)
      throws MalformedObjectNameException
   {
      initDomain(domain);

      if (null == key)
         throw new NullPointerException("properties key cannot be null");
      if (null == value)
         throw new NullPointerException("properties value cannot be null");

      Hashtable ptable = new Hashtable();
      ptable.put(key, value);

      initProperties(ptable);

      this.kProps = key + "=" + value;
   }

   /**
    * Construct a new ObjectName
    *
    * @param domain the domain of the object name
    * @param table of hashtable for key property pairs
    * @exception MalformedObjectNameException for an invalid object name
    * @exception NullPointerException for a null parameter
    */
   public ObjectName(String domain, Hashtable table) throws MalformedObjectNameException
   {
      if (table == null)
         throw new NullPointerException("null table");

      if (table.size() < 1)
         throw new MalformedObjectNameException("empty table");

      initDomain(domain);
      initProperties((Hashtable) table.clone());

      this.kProps = ckProps;
   }

   // Public ------------------------------------------------------
   public boolean equals(Object object)
   {
      if (object == this)
         return true;
      if (object == null)
         return false;

      if (object instanceof ObjectName)
      {
         ObjectName oname = (ObjectName) object;
         return (oname.hash == hash && domain.equals(oname.domain) &&
            ckProps.equals(oname.ckProps));
      }

      return false;
   }

   public int hashCode()
   {
      return hash;
   }

   public String toString()
   {
      return this.domain + ":" + kProps;
   }

   public boolean isPattern()
   {
      return hasPattern;
   }

   public String getCanonicalName()
   {
      return this.domain + ":" + ckProps;
   }

   public String getDomain()
   {
      return domain;
   }

   public String getKeyProperty(String property)
   {
      return (String) propertiesHash.get(property);
   }

   public Hashtable getKeyPropertyList()
   {
      return (Hashtable) propertiesHash.clone();
   }

   public String getKeyPropertyListString()
   {
      return kProps;
   }

   public String getCanonicalKeyPropertyListString()
   {
      return ckProps;
   }

   public boolean isPropertyPattern()
   {
      return hasPropertyPattern;
   }

   public boolean isDomainPattern()
   {
      return hasDomainPattern;
   }

   // QueryExp Implementation -------------------------------------

   public boolean apply(ObjectName name)
      throws BadStringOperationException,
             BadBinaryOpValueExpException,
             BadAttributeValueExpException,
             InvalidApplicationException
   {
       if (name.isPattern())
          return false;
       if (this == name)
          return true;

       if (ObjectNamePatternHelper.patternMatch(name.getDomain(), this.getDomain()))
       {
          if (propertyPattern == null)
             propertyPattern = new PropertyPattern(this);
          return propertyPattern.patternMatch(name);
       }
       return false;
   }

   public void setMBeanServer(MBeanServer server)
   {
      QueryEval.server.set(server);
   }

   // Private -----------------------------------------------------

   /**
    * constructs an object name from a string
    */
   private void init(String name) throws MalformedObjectNameException
   {
      if (name == null)
         throw new NullPointerException("null name");

      if (name.length() == 0)
         name = "*:*";

      int domainSep = name.indexOf(':');

      if (-1 == domainSep)
         throw new MalformedObjectNameException("missing domain");

      initDomain(name.substring(0, domainSep));
      initProperties(name.substring(domainSep + 1));
   }

   /**
    * checks for domain patterns and illegal characters
    */
   private void initDomain(String dstring) throws MalformedObjectNameException
   {
      if (null == dstring)
      {
         throw new MalformedObjectNameException("null domain");
      }

      if (isIllegalDomain(dstring))
      {
         throw new MalformedObjectNameException("domain contains illegal characters");
      }

      if (dstring.indexOf('*') > -1 || dstring.indexOf('?') > -1)
      {
         this.hasPattern = true;
         this.hasDomainPattern = 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);
      this.kProps = properties;
   }

   /**
    * 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())
      {
         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 (key.equals("*") && val.equals("*"))
         {
            it.remove();
            this.hasPropertyPattern = true;
            this.hasPattern = true;
            continue;
         }
         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())
      {
         strBuffer.append(it.next());
         if (it.hasNext())
         {
            strBuffer.append(',');
         }
      }

      if (this.hasPropertyPattern)
      {
         if (properties.size() > 0)
         {
            strBuffer.append(",*");
         }
         else
         {
            strBuffer.append("*");
         }
      }

      this.propertiesHash = properties;
      this.ckProps = strBuffer.toString();
      this.hash = getCanonicalName().hashCode();
   }

   /**
    * returns true if the key or value string is zero length or contains illegal characters
    */
   private boolean isIllegalKeyOrValue(String keyOrValue)
   {
      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;
   }

   /**
    * returns true if the domain contains illegal characters
    */
   private boolean isIllegalDomain(String dom)
   {
      char[] chars = dom.toCharArray();

      for (int i = 0; i < chars.length; i++)
      {
         switch (chars[i])
         {
            case ':':
            case ',':
            case '=':
               return true;
         }
      }

      return false;
   }

   private void readObject(ObjectInputStream ois)
      throws IOException, ClassNotFoundException
   {
      switch (Serialization.version)
      {
      case Serialization.V1R0:
         ObjectInputStream.GetField getField = ois.readFields();
         try
         {
            String name = (String) getField.get("canonicalName", null);
            if (name == null)
               throw new StreamCorruptedException("No canonical name for jmx1.0?");
            init(name);
         }
         catch (MalformedObjectNameException e)
         {
            throw new StreamCorruptedException(e.toString());
         }
         break;
      default:
         try
         {
            init((String) ois.readObject());
         }
         catch (MalformedObjectNameException e)
         {
            throw new StreamCorruptedException(e.toString());
         }
      }
   }

   private void writeObject(ObjectOutputStream oos)
      throws IOException
   {
      switch (Serialization.version)
      {
      case Serialization.V1R0:
         ObjectOutputStream.PutField putField = oos.putFields();
         putField.put("domain", domain);
         putField.put("propertyList", propertiesHash);
         putField.put("propertyListString", ckProps);
         putField.put("canonicalName", domain + ":" + ckProps);
         putField.put("pattern", hasPattern);
         putField.put("propertyPattern", hasPropertyPattern);
         oos.writeFields();
         break;
      default:
         oos.writeObject(domain + ":" + ckProps);
      }
   }
}
TOP

Related Classes of javax.management.ObjectName

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.