Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.services » binding » [javadoc | source]
    1   /*
    2   * JBoss, Home of Professional Open Source
    3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4   * by the @authors tag. See the copyright.txt in the distribution for a
    5   * full listing of individual contributors.
    6   *
    7   * This is free software; you can redistribute it and/or modify it
    8   * under the terms of the GNU Lesser General Public License as
    9   * published by the Free Software Foundation; either version 2.1 of
   10   * the License, or (at your option) any later version.
   11   *
   12   * This software is distributed in the hope that it will be useful,
   13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15   * Lesser General Public License for more details.
   16   *
   17   * You should have received a copy of the GNU Lesser General Public
   18   * License along with this software; if not, write to the Free
   19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21   */
   22   package org.jboss.services.binding;
   23   
   24   import java.util.HashMap;
   25   import java.beans.PropertyEditorManager;
   26   import java.beans.PropertyEditor;
   27   import javax.management.Attribute;
   28   import javax.management.MBeanServer;
   29   import javax.management.ObjectName;
   30   import javax.management.MBeanInfo;
   31   import javax.management.MBeanAttributeInfo;
   32   
   33   import org.w3c.dom.Element;
   34   import org.w3c.dom.NodeList;
   35   
   36   import org.jboss.logging.Logger;
   37   import org.jboss.metadata.MetaData;
   38   import org.jboss.util.StringPropertyReplacer;
   39   import org.jboss.util.Classes;
   40   import org.jboss.deployment.DeploymentException;
   41   
   42   /** An implementation of the ServicesConfigDelegate that expects a delegate-config
   43    element of the form:
   44       <delegate-config portName="portAttrName" hostName="hostAttrName">
   45         <attribute name="mbeanAttrName">host-port-expr</attribute>
   46         ...
   47       </delegate-config>
   48    where the portAttrName is the attribute name of the mbean service
   49    to which the (int port) value should be applied and the hostAttrName
   50    is the attribute name of the mbean service to which the (String virtualHost)
   51    value should be applied.
   52   
   53    Any mbeanAttrName attribute reference has the corresponding value replaced
   54    with any ${host} and ${port} references with the associated host and port
   55    bindings.
   56   
   57    @author Scott.Stark@jboss.org
   58    @version $Revision: 37459 $
   59    */
   60   public class AttributeMappingDelegate
   61      implements ServicesConfigDelegate
   62   {
   63      private static Logger log = Logger.getLogger(AttributeMappingDelegate.class);
   64   
   65      /** Take the given config and map it onto the service specified in the
   66       config using JMX via the given server.
   67       @param config, the service name and its config bindings
   68       @param server, the JMX server to use to apply the config
   69       */
   70      public void applyConfig(ServiceConfig config, MBeanServer server)
   71         throws Exception
   72      {
   73         Element delegateConfig = (Element) config.getServiceConfigDelegateConfig();
   74         if( delegateConfig == null )
   75            throw new IllegalArgumentException("ServiceConfig.ServiceConfigDelegateConfig is null");
   76         // Check for a port and host name
   77         String portAttrName = delegateConfig.getAttribute("portName");
   78         if( portAttrName.length() == 0 )
   79            portAttrName = null;
   80         String hostAttrName = delegateConfig.getAttribute("hostName");
   81         if( hostAttrName.length() == 0 )
   82            hostAttrName = null;
   83   
   84         // Check for any arbitrary attributes
   85         NodeList attributes = delegateConfig.getElementsByTagName("attribute");
   86   
   87         // Only the first binding is used as only one (host,port) pair is mapped
   88         ServiceBinding[] bindings = config.getBindings();
   89         if( bindings != null && bindings.length > 0 )
   90         {
   91            // Build a mapping of the attribute names to their type name
   92            ObjectName serviceName = new ObjectName(config.getServiceName());
   93            MBeanInfo info = server.getMBeanInfo(serviceName);
   94            MBeanAttributeInfo[] attrInfo = info.getAttributes();
   95            HashMap attrTypeMap = new HashMap();
   96            for(int a = 0; a < attrInfo.length; a ++)
   97            {
   98               MBeanAttributeInfo attr = attrInfo[a];
   99               attrTypeMap.put(attr.getName(), attr.getType());
  100            }
  101   
  102            int port = bindings[0].getPort();
  103            String host = bindings[0].getHostName();
  104            // Apply the port setting override if the port name was given
  105            if( portAttrName != null )
  106            {
  107               Attribute portAttr = new Attribute(portAttrName, new Integer(port));
  108               log.debug("setPort, name='"+portAttrName+"' value="+port);
  109               server.setAttribute(serviceName, portAttr);
  110            }
  111            // Apply the host setting override if the port name was given
  112            if( hostAttrName != null )
  113            {
  114               Attribute hostAttr = createAtribute(port, host, attrTypeMap,
  115                  hostAttrName, host);
  116               log.debug("setHost, name='"+hostAttrName+"' value="+host);
  117               server.setAttribute(serviceName, hostAttr);
  118            }
  119   
  120            /* Apply any other host/port based attributes with replacement of
  121             the ${host} and ${port} strings.
  122            */
  123            for(int a = 0; a < attributes.getLength(); a ++)
  124            {
  125               Element attr = (Element) attributes.item(a);
  126               String name = attr.getAttribute("name");
  127               if( name.length() == 0 )
  128                  throw new IllegalArgumentException("attribute element #"+a+" has no name attribute");
  129               String attrExp = MetaData.getElementContent(attr);
  130               Attribute theAttr = createAtribute(port, host, attrTypeMap,
  131                  name, attrExp);
  132               server.setAttribute(serviceName, theAttr);
  133            }
  134         }
  135         else
  136         {
  137            /**
  138             * Apply attributes even if not using port or host
  139             */
  140            for(int a = 0; a < attributes.getLength(); a ++)
  141            {
  142               Element attr = (Element) attributes.item(a);
  143               String name = attr.getAttribute("name");
  144               if( name.length() == 0 )
  145                  throw new IllegalArgumentException("attribute element #"+a+" has no name attribute");
  146               String attrExp = MetaData.getElementContent(attr);
  147               Attribute attribute = new Attribute(name, attrExp);
  148               ObjectName serviceName = new ObjectName(config.getServiceName());
  149               server.setAttribute(serviceName, attribute);
  150            }
  151         }
  152      }
  153   
  154      /** Create a JMX Attribute with the correct type value object. This
  155       * converts the given attrExp into an Attribute for attrName with
  156       * replacement of any ${host} ${port} references in the attrExp
  157       * replaced with the given port/host values.
  158       * @param port The binding port value
  159       * @param host The binding host value
  160       * @param attrTypeMap the name to type map for the service attributes
  161       * @param attrName the name of the attribute to create
  162       * @param attrExp the string exp for the attribute value
  163       * @return the JMX attribute instance
  164       * @throws Exception thrown on an invalid attribute name or inability
  165       *    to find a valid property editor
  166       */
  167      private Attribute createAtribute(int port, String host,
  168         HashMap attrTypeMap, String attrName, String attrExp)
  169         throws Exception
  170      {
  171         String attrText = replaceHostAndPort(attrExp, host, ""+port);
  172         String typeName = (String) attrTypeMap.get(attrName);
  173         if( typeName == null )
  174         {
  175            throw new DeploymentException("No such attribute: " + attrName);
  176         }
  177         // Convert the type
  178         Class attrType = Classes.loadClass(typeName);
  179         PropertyEditor editor = PropertyEditorManager.findEditor(attrType);
  180         if( editor == null )
  181         {
  182            String msg = "No property editor for attribute: " + attrName +
  183               "; type=" + typeName;
  184            throw new DeploymentException(msg);
  185         }
  186         editor.setAsText(attrText);
  187         Object attrValue = editor.getValue();
  188         log.debug("setAttribute, name='"+attrName+"', text="+attrText
  189            +", value="+attrValue);
  190         Attribute theAttr = new Attribute(attrName, attrValue);
  191         return theAttr;
  192      }
  193   
  194      /** Loop over text and replace any ${host} and ${port} strings. If there are
  195       * any ${x} system property references in the resulting replacement string
  196       * these will be replaced with the corresponding System.getProperty("x")
  197       * value if one exists.
  198       * @param text the text exp with optional ${host} ${port} references
  199       * @param host the binding host value
  200       * @param port the binding port value
  201       */
  202      private String replaceHostAndPort(String text, String host, String port)
  203      {
  204         if( text == null )
  205            return null;
  206   
  207         StringBuffer replacement = new StringBuffer(text);
  208         if( host == null )
  209            host = "localhost";
  210         // Simple looping should be replaced with regex package
  211         String test = replacement.toString();
  212         int index;
  213         while( (index = test.indexOf("${host}")) >= 0 )
  214         {
  215            replacement.replace(index, index+7, host);
  216            test = replacement.toString();
  217         }
  218         while( (index = test.indexOf("${port}")) >= 0 )
  219         {
  220            replacement.replace(index, index+7, port);
  221            test = replacement.toString();
  222         }
  223         return StringPropertyReplacer.replaceProperties(replacement.toString());
  224      }
  225   }

Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.services » binding » [javadoc | source]