JBossMicrocontainer Supply/Demand Customization

The supply and demand features of the MC allow one to express dependencies between beans that are not wired together using injection. For example, the following deployment fragment associates the Consumer beand with the Producer based on the matching SomethingUseful supply and demand values:

 

<bean name="Provider" class="com.acme.Provider"> 
    <supply>SomethingUseful</supply> 
</bean> 
<bean name="Consumer" class="com.acme.Consumer"> 
    <demand>SomethingUseful</demand> 
</bean> 

 

To control how a demand matches a supply you can specify a transformer that customizes how the demand value is matched to a supply value. The matching is customized by specifying a transformer to a demand. The transformer is an implementation of the following org.jboss.kernel.api.dependency.MatcherTransformer and associated org.jboss.kernel.api.dependency.Matcher interfaces:

 

package org.jboss.kernel.api.dependency;

public interface MatcherTransformer 
{ 
   /** 
    * Transform value param to Matcher instance. 
    * 
    * @param value the value 
    * @return Matcher instance 
    */ 
   Matcher transform(Object value); 
} 
package org.jboss.kernel.api.dependency; 
/** 
 * Matcher. 
 * Match this instance against any object.
 
 * 
 */ 
public interface Matcher 
{ 
   /** 
    * Do we match this object other param. 
    * 
    * @param other the object to match 
    * @return true if we match the other param, false otherwise 
    */ 
   boolean match(Object other); 
   /** 
    * Do we need an exact match. 
    * No match or single match is acceptable. 
    * 
    * @return true if matcher accepts only exact matches 
    */ 
   boolean needExactMatch(); 
} 

         There are a number of pre-existing implementations that may be referenced by a one of the following keys:

default : org.jboss.kernel.plugins.dependency.DefaultMatcherFactory a transformer that builds a matcher which simply uses object equality between the demand and supply values.

interval : org.jboss.kernel.plugins.dependency.IntervalMatcherTransformer a transformer that builds a matcher by using the demand value as a mathematical range to test supply values as integers against.

regex : org.jboss.kernel.plugins.dependency.RegexpMatcherTransformer a transformer that builds a matcher by using the demand value as a regular expression to match against the supply values.

 

Any other transformer value is treated as a class name which implements the MatcherTransformer

interface. Below is an example of a demand that specifies a custom implementation of org.jboss.kernel.api.dependency.MatcherTransformer.

import org.jboss.beans.metadata.api.annotations.Demands; 
import org.jboss.beans.metadata.api.annotations.Demand; 
@Demands({@Demand(value = "fragment", transformer = 
 "org.jboss.test.kernel.dependency.support.CapabilityMatcherTransfomer")})

public class CustomDemander 
{ 
}

The corresponding CapabilityMatcherTransfomer implementation is given in the following listing. This transformer treats the demand and supply values as java.util.Properties. The demand properties are matched if one or more are found among the supply properties.

package org.jboss.test.kernel.dependency.support; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.util.Properties; 
import org.jboss.kernel.api.dependency.Matcher; 
import org.jboss.kernel.api.dependency.NonNullMatcherTransformer; 
import org.jboss.kernel.api.dependency.ClassMatcher; 
public class CapabilityMatcherTransfomer extends NonNullMatcherTransformer 
{ 
   protected Matcher internalTransform(Object value) 
   { 
      return new PropertiesMatcher(value.toString()); 
   } 
   private class PropertiesMatcher extends ClassMatcher<Properties> 
   { 
      private Properties props; 
      public PropertiesMatcher(String string) 
      { 
         super(Properties.class); 
         if (string == null) 
            throw new IllegalArgumentException("Null fragment"); 
         
         this.props = new Properties(); 
         ByteArrayInputStream bais = new ByteArrayInputStream(string.getBytes()); 
         try 
         { 
            props.load(bais); 
         } 
         catch(IOException e)
         { 
            throw new IllegalStateException(e); 
         } 
      } 
      protected boolean matchByType(Properties other) 
      { 
         boolean matches = false; 
         for(Object key : props.keySet()) 
         { 
            String skey = key.toString(); 
            String requires = props.getProperty(skey); 
            String capability = other.getProperty(skey); 
            if(requires.equalsIgnoreCase(capability)) 
               matches |= true; 
         } 
         return matches; 
      } 
      public String toString() 
      { 
         return props.toString(); 
      } 
   } 
} 

 

An example of bean deployments where a demand matches a supply based on this matcher is shown in the following listing:

<?xml version="1.0" encoding="UTF-8"?> 
<deployment xmlns="urn:jboss:bean-deployer:2.0"> 
   <bean name="capabilitySupplier" 
 class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl"> 
      <supply class="java.util.Properties"> 
         key1=value1 
         key2=value2 
      </supply> 
      <supply class="java.util.Properties"> 
         key2.1=value2.1 
         key2.2=value2.2 
      </supply>
Service dependencies 
   </bean> 
   <bean name="requiresDemand" 
 class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl"> 
      <demand 
 transformer="org.jboss.test.kernel.dependency.support.CapabilityMatcherTransfomer"> 
      key1=value1 
      key2=value2 
      </demand> 
   </bean> 
</deployment>