[jboss-cvs] JBossAS SVN: r81806 - in trunk: varia/src/main/org/jboss/services/binding and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Nov 29 09:25:37 EST 2008


Author: bstansberry at jboss.com
Date: 2008-11-29 09:25:37 -0500 (Sat, 29 Nov 2008)
New Revision: 81806

Added:
   trunk/varia/src/main/org/jboss/services/binding/ManagedServiceBinding.java
Modified:
   trunk/server/src/etc/conf/default/bootstrap/bindings.xml
   trunk/varia/src/main/org/jboss/services/binding/ElementServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/InetAddressServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/IntServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/ServiceBinding.java
   trunk/varia/src/main/org/jboss/services/binding/ServiceBindingManager.java
   trunk/varia/src/main/org/jboss/services/binding/ServiceBindingStore.java
   trunk/varia/src/main/org/jboss/services/binding/ServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/StringServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/URLServiceBindingValueSource.java
   trunk/varia/src/main/org/jboss/services/binding/impl/PojoServiceBindingStore.java
   trunk/varia/src/main/org/jboss/services/binding/impl/ServiceBindingSet.java
   trunk/varia/src/main/org/jboss/services/binding/impl/SimpleServiceBindingValueSourceImpl.java
   trunk/varia/src/main/org/jboss/services/binding/impl/StringReplacementServiceBindingValueSourceImpl.java
   trunk/varia/src/main/org/jboss/services/binding/impl/Util.java
   trunk/varia/src/main/org/jboss/services/binding/impl/XSLTServiceBindingValueSourceImpl.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingStore.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingValueSource.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/PojoServiceBindingStoreUnitTestCase.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingManagerUnitTestCase.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingSetUnitTestCase.java
   trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingUnitTestCase.java
Log:
[JBAS-6259] Management interface for ServiceBindingManager

Modified: trunk/server/src/etc/conf/default/bootstrap/bindings.xml
===================================================================
--- trunk/server/src/etc/conf/default/bootstrap/bindings.xml	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/server/src/etc/conf/default/bootstrap/bindings.xml	2008-11-29 14:25:37 UTC (rev 81806)
@@ -13,85 +13,142 @@
       <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.system:service=ServiceBindingManager", exposedInterface=org.jboss.services.binding.ServiceBindingManagerMBean.class, registerDirectly=true)</annotation>
             
       <constructor>
-         <!-- The set of bindings to use for this server -->
+         <!-- The name of the set of bindings to use for this server -->
          <parameter>${jboss.service.binding.set:ports-default}</parameter>
 
          <!-- The named sets of bindings -->
          <parameter>
             <bean name="ServiceBindingStore" class="org.jboss.services.binding.impl.PojoServiceBindingStore">
 
-               <constructor>
-                  <parameter>
-                     <map keyClass="java.lang.String" valueClass="java.util.Set">
-                        <entry>
-                            <key>ports-default</key>
-                            <value><inject bean="PortsDefaultBindings"/></value>
-                        </entry>
-                        <entry>
-                            <key>ports-01</key>
-                            <value><inject bean="Ports01Bindings"/></value>
-                        </entry>
-                        <entry>
-                            <key>ports-02</key>
-                            <value><inject bean="Ports02Bindings"/></value>
-                        </entry>
-                     </map>
-                  </parameter>
-               </constructor>
+               <!-- Base bindings that are used to create bindings for each set
+                    by adding the set's port offset to the base binding's port value -->
+               <property name="portOffsetBindings"><inject bean="PortOffsetBindings"/></property>
+               
+               <!-- Base bindings that are used to create bindings for each set
+                    but without altering the base binding's port value.  
+                    Typically used for multicast socket bindings, which do not 
+                    lead to port conflicts if multiple sockets are opened on 
+                    the same machine.-->
+               <property name="fixedBindings"><null/></property>
+               
+               <!-- The sets of bindings -->
+               <property name="serviceBindingSets">
+                  <set>
+                     <inject bean="PortsDefaultBindings"/>
+                     <inject bean="Ports01Bindings"/>
+                     <inject bean="Ports02Bindings"/>
+                     <inject bean="Ports03Bindings"/>
+                  </set>
+               </property>
             </bean>
          </parameter>
       </constructor>
 
    </bean>
 
-   <!-- The default bindings -->
+   <!-- The ports-default bindings are obtained by taking the base bindings and adding 0 to each port value  -->
    <bean name="PortsDefaultBindings"  class="org.jboss.services.binding.impl.ServiceBindingSet">
+      <constructor>
+         <!--  The name of the set -->
+         <parameter>ports-default</parameter>
+         <!-- Default host name -->
+         <parameter>${jboss.bind.address}</parameter>
+         <!-- The port offset -->
+         <parameter>0</parameter>
+         <!-- Set of bindings to which the "offset by X" approach can't be applied -->
+         <parameter><null/></parameter>
+      </constructor>
+   </bean>
 
+   <!-- The ports-01 bindings are obtained by taking the base bindings and adding 100 to each port value -->
+   <bean name="Ports01Bindings" class="org.jboss.services.binding.impl.ServiceBindingSet">
       <constructor>
+         <!--  The name of the set -->
+         <parameter>ports-01</parameter>
+         <!-- Default host name -->
+         <parameter>${jboss.bind.address}</parameter>
+         <!-- The port offset -->
+         <parameter>100</parameter>
+         <!-- Set of bindings to which the "offset by X" approach can't be applied -->
+         <parameter><null/></parameter>
+      </constructor>
+   </bean>
+
+   <!-- The ports-02 bindings are obtained by taking ports-default and adding 200 to each port value -->
+   <bean name="Ports02Bindings" class="org.jboss.services.binding.impl.ServiceBindingSet">
+      <constructor>
+         <!--  The name of the set -->
+         <parameter>ports-02</parameter>
+         <!-- Default host name -->
+         <parameter>${jboss.bind.address}</parameter>
+         <!-- The port offset -->
+         <parameter>200</parameter>
+         <!-- Set of bindings to which the "offset by X" approach can't be applied -->
+         <parameter><null/></parameter>
+      </constructor>
+   </bean>
+
+   <!-- The ports-03 bindings are obtained by taking ports-default and adding 300 to each port value -->
+   <bean name="Ports03Bindings" class="org.jboss.services.binding.impl.ServiceBindingSet">
+      <constructor>
+         <!--  The name of the set -->
+         <parameter>ports-03</parameter>
+         <!-- Default host name -->
+         <parameter>${jboss.bind.address}</parameter>
+         <!-- The port offset -->
+         <parameter>300</parameter>
+         <!-- Set of bindings to which the "offset by X" approach can't be applied -->
+         <parameter><null/></parameter>
+      </constructor>
+   </bean>
+
+   <!-- Base bindings that ServiceBindingStore uses to create bindings for each set
+        by adding the set's port offset to the base binding's port value -->
+   <bean name="PortOffsetBindings" class="java.util.HashSet" 
+         elementClass="org.jboss.services.binding.ManagedServiceBinding">
+      <constructor>
          <parameter>
             <set>
             <!-- ********************* conf/jboss-service.xml ****************** -->
 
             <!-- Naming Service -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=Naming</parameter>
                   <parameter>Port</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
+                  <parameter><null/></parameter>
                   <parameter>1099</parameter>
                </constructor>
             </bean>
 
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=Naming</parameter>
                   <parameter>RmiPort</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
+                  <parameter><null/></parameter>
                   <parameter>1098</parameter>
                </constructor>
             </bean>
 
             <!-- Remote classloading service -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=WebService</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>8083</parameter>
                </constructor>
             </bean>
 
             <!-- Remoting Connector -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>UnifiedInvokerConnector</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4446</parameter>
                </constructor>
             </bean>
             
             <!-- Used to create a multihome Remoting server.   See -->
             <!-- deploy/remoting-jboss-beans.xml for more details. -->
-            <!--bean class="org.jboss.services.binding.ServiceBinding">
+            <!--bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>UnifiedInvokerConnector:bindingHome1</parameter>
                   <parameter>192.168.2.2</parameter>
@@ -101,7 +158,7 @@
             
             <!-- Used to create a multihome Remoting server.   See -->
             <!-- deploy/remoting-jboss-beans.xml for more details. -->
-            <!--bean class="org.jboss.services.binding.ServiceBinding">
+            <!--bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>UnifiedInvokerConnector:bindingHome2</parameter>
                   <parameter>10.11.12.238</parameter>
@@ -112,39 +169,37 @@
             <!-- ********************* deploy/remoting-service.xml ****************** -->
 
             <!-- RMI/JRMP invoker -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=invoker,type=jrmp</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4444</parameter>
                </constructor>
             </bean>
 
             <!-- Pooled invoker -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=invoker,type=pooled</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4445</parameter>
                </constructor>
             </bean>
 
             <!-- ********************* deploy/cluster/hajndi-service.xml ****************** -->
 
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=HAJNDI</parameter>
                   <parameter>Port</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
+                  <parameter><null/></parameter>
                   <parameter>1100</parameter>
                </constructor>
             </bean>
 
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=HAJNDI</parameter>
                   <parameter>RmiPort</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
+                  <parameter><null/></parameter>
                   <parameter>1101</parameter>
                </constructor>
             </bean>
@@ -152,29 +207,26 @@
             <!-- ********************* deploy/cluster/ha-legacy-service.xml ****************** -->
 
             <!-- HA RMI/JRMP invoker -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=invoker,type=jrmpha</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4447</parameter>
                </constructor>
             </bean>
 
             <!-- HA Pooled invoker -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=invoker,type=pooledha</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4448</parameter>
                </constructor>
             </bean>
 
             <!-- ********************* deploy/iiop-service.xml ****************** -->
 
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=CorbaORB</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>3528</parameter>
                </constructor>
             </bean>
@@ -182,29 +234,26 @@
             <!-- ********************* deploy/snmp-adaptor.sar **************** -->
 
             <!-- Trap receiver that acts as an SNMP Manager -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.jmx:name=SnmpAgent,service=trapd,type=logger</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>1162</parameter>
                </constructor>
             </bean>
 
             <!-- The SNMP adaptor MBean -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.jmx:name=SnmpAgent,service=snmp,type=adaptor</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>1161</parameter>
                </constructor>
             </bean>
 
             <!-- ********************* deploy/jmx-remoting.sar **************** -->
 
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.remoting:service=JMXConnectorServer,protocol=rmi</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>1090</parameter>
                </constructor>
             </bean>
@@ -232,10 +281,9 @@
                 jboss:service=invoker,type=http,target=HAJNDI
                 jboss.ws:service=ServiceEndpointManager
             -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.web:service=WebServer</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>8080</parameter>
                </constructor>
 
@@ -250,12 +298,11 @@
 
             <!-- For services like those listed above that need to know the
                  port of the HTTPS connector -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.web:service=WebServer</parameter>
                   <parameter>HttpsConnector</parameter>
-                  <!-- The address/port of the JBoss Web HTTPS Connector below -->
-                  <parameter>${jboss.bind.address}</parameter>
+                  <parameter><null/></parameter>
                   <parameter>8443</parameter>
                </constructor>
             </bean>
@@ -263,10 +310,9 @@
             <!-- ********************* deploy/messaging/remoting-bisocket-service.xml ********************** -->
 
             <!-- Standard JBM bisocket connector -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.messaging:service=Connector,transport=bisocket</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>4457</parameter>
                </constructor>
             </bean>
@@ -274,28 +320,28 @@
             <!-- ********************* deploy/transaction-jboss-beans.xml ********************** -->
 
             <!-- JBossTS Recovery Manager -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                 <constructor>
                     <parameter>TransactionManager</parameter>
                     <parameter>recoveryManager</parameter>
-                    <parameter>${jboss.bind.address}</parameter>
+                    <parameter><null/></parameter>
                     <parameter>4712</parameter>
                 </constructor>
             </bean>
 
             <!-- JBossTS Transaction Status Manager -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                 <constructor>
                     <parameter>TransactionManager</parameter>
                     <parameter>transactionStatusManager</parameter>
-                    <parameter>${jboss.bind.address}</parameter>
+                    <parameter><null/></parameter>
                     <parameter>4713</parameter>
                 </constructor>
             </bean>
 
             <!-- JBossTS SocketProcessId.  The address part is ignored,
-                it will always use null/localhost/127.0.0.1. -->
-            <bean class="org.jboss.services.binding.ServiceBinding">
+                it will always use localhost/127.0.0.1. -->
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                 <constructor>
                     <parameter>TransactionManager</parameter>
                     <parameter>socketProcessId</parameter>
@@ -309,10 +355,9 @@
 
             <!-- Commented out as tcp/ip access to Hypersonic is not enabled by default -->
             <!--
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss:service=Hypersonic</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>1701</parameter>
                </constructor>
             </bean>
@@ -325,54 +370,18 @@
                  configure the http invocation layer using the jboss.web:service=WebServer binding above
              -->
             <!--
-            <bean class="org.jboss.services.binding.ServiceBinding">
+            <bean class="org.jboss.services.binding.ManagedServiceBinding">
                <constructor>
                   <parameter>jboss.mq:service=InvocationLayer,type=UIL2</parameter>
-                  <parameter>${jboss.bind.address}</parameter>
                   <parameter>8093</parameter>
                </constructor>
             </bean>
             -->
          </set>
          </parameter>
-
-         <!-- The port offset -->
-         <parameter>0</parameter>
-         <!-- Default host name -->
-         <parameter>${jboss.bind.address}</parameter>
       </constructor>
-
    </bean>
 
-   <!-- The ports-01 bindings are obtained by taking ports-default and adding 100 to each port value -->
-   <bean name="Ports01Bindings" class="org.jboss.services.binding.impl.ServiceBindingSet">
-
-      <constructor>
-         <parameter><inject bean="PortsDefaultBindings"/></parameter>
-         <!-- The port offset -->
-         <parameter>100</parameter>
-         <!-- Set of bindings to which the "offset by 100" approach can't be applied -->
-         <parameter><null/></parameter>
-         <!-- Default host name -->
-         <parameter>${jboss.bind.address}</parameter>
-      </constructor>
-   </bean>
-
-   <!-- The ports-02 bindings are obtained by taking ports-default and adding 200 to each port value -->
-   <bean name="Ports02Bindings" class="org.jboss.services.binding.impl.ServiceBindingSet">
-
-      <constructor>
-         <parameter><inject bean="PortsDefaultBindings"/></parameter>
-         <!-- The port offset -->
-         <parameter>200</parameter>
-         <!-- Set of bindings to which the "offset by 200" approach can't be applied -->
-         <parameter><null/></parameter>
-         <!-- Default host name -->
-         <parameter>${jboss.bind.address}</parameter>
-      </constructor>
-   </bean>
-
-
    <!-- Conversion of selected bindings into system properties -->
    <bean name="SystemPropertyBinder" class="org.jboss.services.binding.SystemPropertyBinder">
 

Modified: trunk/varia/src/main/org/jboss/services/binding/ElementServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ElementServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/ElementServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -38,5 +38,5 @@
     * @param binding the binding. Cannot be <code>null</code>
     * @return an String to use as the binding value. May return <code>null</code>.
     */
-   Element getElementServiceBindingValue(ServiceBinding binding, Element input) throws Exception;
+   Element getElementServiceBindingValue(ServiceBinding binding, Element input);
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/InetAddressServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/InetAddressServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/InetAddressServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -39,5 +39,5 @@
     * @param binding the binding. Cannot be <code>null</code>
     * @return an InetAddress to use as the binding value. May return <code>null</code>.
     */
-   InetAddress getInetAddressServiceBindingValue(ServiceBinding binding) throws Exception;
+   InetAddress getInetAddressServiceBindingValue(ServiceBinding binding);
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/IntServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/IntServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/IntServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -37,5 +37,5 @@
     * @param binding the binding. Cannot be <code>null</code>
     * @return an int to use as the binding value
     */
-   int getIntServiceBindingValue(ServiceBinding binding) throws Exception;
+   int getIntServiceBindingValue(ServiceBinding binding);// throws Exception;
 }

Added: trunk/varia/src/main/org/jboss/services/binding/ManagedServiceBinding.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ManagedServiceBinding.java	                        (rev 0)
+++ trunk/varia/src/main/org/jboss/services/binding/ManagedServiceBinding.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -0,0 +1,140 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.services.binding;
+
+import java.net.UnknownHostException;
+
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
+import org.jboss.managed.api.annotation.ViewUse;
+
+/**
+ * {@link ServiceBinding} subclass that exposes an editing interface that
+ * management tools can use.
+ * @author Brian Stansberry
+ */
+ at ManagementObject(componentType=@ManagementComponent(type="MCBean", subtype="ServiceBinding"),
+      properties=ManagementProperties.EXPLICIT)
+public class ManagedServiceBinding extends ServiceBinding
+{
+   // ------------------------------------------------------------ Constructors
+   
+   /**
+    * Create a new ManagedServiceBinding.
+    * 
+    * @param serviceName
+    * @param port
+    * @throws UnknownHostException
+    */
+   public ManagedServiceBinding(String serviceName, int port) throws UnknownHostException
+   {
+      super(serviceName, port);
+   }
+
+   /**
+    * Create a new ManagedServiceBinding.
+    * 
+    * @param serviceName
+    * @param hostName
+    * @param port
+    * @throws UnknownHostException
+    */
+   public ManagedServiceBinding(String serviceName, String hostName, int port) throws UnknownHostException
+   {
+      super(serviceName, hostName, port);
+   }
+
+   /**
+    * Create a new ManagedServiceBinding.
+    * 
+    * @param serviceName
+    * @param bindingName
+    * @param hostName
+    * @param port
+    * @throws UnknownHostException
+    */
+   public ManagedServiceBinding(String serviceName, String bindingName, String hostName, int port)
+         throws UnknownHostException
+   {
+      super(serviceName, bindingName, hostName, port);
+   } 
+   
+   /**
+    * Copy constructor.
+    * 
+    * @param source
+    * @throws UnknownHostException
+    * @throws NullPointerException if source is null
+    */
+   public ManagedServiceBinding(ServiceBinding source) throws UnknownHostException
+   {
+      this(source.getServiceName(), source.getBindingName(), source.getHostName(), source.getPort());
+      setServiceBindingValueSource(source.getServiceBindingValueSource());
+      setServiceBindingValueSourceConfig(source.getServiceBindingValueSourceConfig());
+   }
+   
+   // ------------------------------------------------------------  Properties
+
+   @Override
+   @ManagementProperty(use={ViewUse.CONFIGURATION}) // overrides superclass annotation's use attribute
+   public String getHostName()
+   {
+      // TODO Auto-generated method stub
+      return super.getHostName();
+   }
+
+   @Override
+   @ManagementProperty(use={ViewUse.CONFIGURATION}) // overrides superclass annotation's use attribute
+   public int getPort()
+   {
+      // TODO Auto-generated method stub
+      return super.getPort();
+   }
+
+   /**
+    * {@inheritDoc}
+    * 
+    * Exposes the superclass method as public.
+    */
+   @Override
+   public void setHostName(String hostName)
+   {
+      // TODO Auto-generated method stub
+      super.setHostName(hostName);
+   }
+
+   /**
+    * {@inheritDoc}
+    * 
+    * Exposes the superclass method as public.
+    */
+   @Override
+   public void setPort(int port)
+   {
+      // TODO Auto-generated method stub
+      super.setPort(port);
+   }  
+   
+}

Modified: trunk/varia/src/main/org/jboss/services/binding/ServiceBinding.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ServiceBinding.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/ServiceBinding.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -27,6 +27,13 @@
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementObjectID;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
+import org.jboss.managed.api.annotation.ViewUse;
+
 /** A ServiceBinding is a {name,virtualHost,port,interfaceAddress}
  * quad specifying a named binding for a service.
  *
@@ -34,6 +41,8 @@
  * @author Scott.Stark at jboss.org
  * @version $Revision$
  */
+ at ManagementObject(componentType=@ManagementComponent(type="MCBean", subtype="ServiceBinding"),
+      properties=ManagementProperties.EXPLICIT)
 public class ServiceBinding
 {
    /**
@@ -71,21 +80,24 @@
     */
    private final String bindingName;
    
+   /** The bindingName, if any, concatenated to serviceName */
+   private final String fullyQualifiedName;
+   
    /** The virtual host name. This is the interface name used to
     construct the bindAddress value. A null value implies bind on any
     interface.
     */
-   private final String hostName;
+   private String hostName;
    
    /** The port the service should listen on. A 0 value implies an
     anonymous port.
     */
-   private final int port;
+   private int port;
    
    /** The interface on which the service should bind its listening port. A
     null address implies bind on any interface.
     */
-   private final InetAddress bindAddress;
+   private InetAddress bindAddress;
    
    /** The ServiceBindingValueSource implementation class
     */
@@ -103,14 +115,15 @@
    // -----------------------------------------------------------  Constructors
 
    /**
-    * Creates a new instance of ServiceBinding
+    * Creates a new instance of ServiceBinding with a host name indicating
+    * the loopback interface.
     *
-    * @param bindingName The name of the binding. A null or empty name
-    * implies that default binding for a service.
+    * @param serviceName the name of the service to which this binding applies.
+    *                    Cannot be <code>null</code>.
     * @param port The port the service should listen on. A 0 value implies an
-    * anonymous port.
-    *
-    * @exception UnknownHostException
+    * ephemeral port.
+    *                                   
+    * @throws UnknownHostException if no IP address for the loopback interface could be found 
     */
    public ServiceBinding(String serviceName, int port)
       throws UnknownHostException
@@ -121,12 +134,14 @@
    /**
     * Creates a new instance of ServiceBinding
     *
-    * @param bindingName The name of the binding. A null or empty name
-    * implies that default binding for a service.
+    * @param serviceName the name of the service to which this binding applies.
+    *                    Cannot be <code>null</code>.
+    * @param hostName The virtual host name. This is the interface name used to
+    * construct the bindAddress value. A null value implies bind on the loopback interface.
     * @param port The port the service should listen on. A 0 value implies an
-    * anonymous port.
-    *
-    * @exception UnknownHostException
+    * ephemeral port.
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
     */
    public ServiceBinding(String serviceName, String hostName, int port)
       throws UnknownHostException
@@ -137,17 +152,16 @@
    /**
     * Creates a new instance of ServiceBinding
     *
-    * @param config the ServiceConfig associated with this binding. May be
-    *               <code>null</code>, in which case {@link #setServiceConfig(ServiceConfig)}
-    *               should be promptly called.
-    * @param bindingName The name of the binding. A null or empty name
+    * @param serviceName the name of the service to which this binding applies.
+    *                    Cannot be <code>null</code>.
+    * @param bindingName The name qualifier for the binding. A null or empty name
     * implies the default binding for a service.
     * @param hostName The virtual host name. This is the interface name used to
     * construct the bindAddress value. A null value implies bind on the loopback interface.
     * @param port The port the service should listen on. A 0 value implies an
-    * anonymous port.
-    *
-    * @exception UnknownHostException If hostName is not resolvable.
+    * ephemeral port.
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
     */
    public ServiceBinding(String serviceName, String bindingName, String hostName, int port)
       throws UnknownHostException
@@ -158,70 +172,138 @@
       // If the serviceName looks like an object name, canonicalize it      
       this.serviceName = canonicalizeServiceName(serviceName);
       this.bindingName = bindingName;
+      this.fullyQualifiedName = (bindingName == null) ? serviceName : serviceName + ":" + bindingName;
       this.port = port;
       this.hostName = hostName;
       this.bindAddress = InetAddress.getByName(hostName);
    } 
+   
+   /**
+    * Copy constructor.
+    * 
+    * @param source
+    * @throws UnknownHostException
+    * @throws NullPointerException if source is null
+    */
+   public ServiceBinding(ServiceBinding source) throws UnknownHostException
+   {
+      this(source.getServiceName(), source.getBindingName(), source.getHostName(), source.getPort());
+      setServiceBindingValueSource(source.getServiceBindingValueSource());
+      setServiceBindingValueSourceConfig(source.getServiceBindingValueSourceConfig());
+   }
 
    // -------------------------------------------------------------  Properties
    
+   /**
+    * Gets the name of the service to which this binding applies.
+    * 
+    * @return the name. Will not be <code>null</code>.
+    */
+   @ManagementProperty
    public String getServiceName()
    {
       return serviceName;
    }
 
    /**
-    * Getter for property name.
+    * Gets a qualifier identifying which particularly binding within 
+    * {@link #getServiceName() the service} this is.
     *
-    * @return The name of the binding
+    * @return the name, or <code>null</code> if this is an unnamed default binding
+    *         for the service.
     */
+   @ManagementProperty
    public String getBindingName()
    {
       return this.bindingName;
    }
+   
+   /**
+    * Gets the fully qualified binding name.
+    * 
+    * @return the {@link #getServiceName() serviceName}:{@link #getBindingName() bindingName} or
+    *         just the service name if the binding name is <code>null</code>.
+    */
+   @ManagementProperty
+   @ManagementObjectID(type="ServiceBinding")
+   public String getFullyQualifiedName()
+   {
+      return fullyQualifiedName;
+   }
 
    /**
-    * Returns host name
+    * Gets the host name or string notation IP address to use for the binding.
     *
     * @return the hostname or address
     */
+   @ManagementProperty(use={ViewUse.STATISTIC})
    public String getHostName()
    {
       return this.hostName;
    }
 
    /**
-    * Gets the port attribute of the ServiceDescriptor object
+    * Gets the port to use for the binding.
     *
-    * @return The listen port number
+    * @return The port
     */
+   @ManagementProperty(use={ViewUse.STATISTIC})
    public int getPort()
    {
       return this.port;
    }
 
    /**
-    * Gets the bindAddress attribute of the ServiceDescriptor object
+    * Gets the InetAddress of the interface to use for the binding.
     *
-    * @return  The listen address
+    * @return  The binding address
     */
+   @ManagementProperty(use={ViewUse.STATISTIC})
    public InetAddress getBindAddress()
    {
       return this.bindAddress;
    }
 
-   public synchronized ServiceBindingValueSource getServiceBindingValueSource() 
-      throws ClassNotFoundException, InstantiationException, IllegalAccessException
+   /**
+    * Gets the object that can return this ServiceBinding's values in formats
+    * usable by consumers. If unset (the norm), {@link ServiceBindingManager} will use
+    * reasonable defaults based on the format requested by the consumer.
+    * 
+    * @return the ServiceBindingValueSource; may be <code>null</code>
+    * 
+    * @throws ClassNotFoundException
+    * @throws InstantiationException
+    * @throws IllegalAccessException
+    */
+   public synchronized ServiceBindingValueSource getServiceBindingValueSource()
    {
       if (this.serviceBindingValueSource == null && this.serviceBindingValueSourceClassName != null)
       {
          ClassLoader loader = Thread.currentThread().getContextClassLoader();
-         Class<?> delegateClass = loader.loadClass(serviceBindingValueSourceClassName);
-         this.serviceBindingValueSource = (ServiceBindingValueSource) delegateClass.newInstance();
+         try
+         {
+            Class<?> delegateClass = loader.loadClass(serviceBindingValueSourceClassName);
+            this.serviceBindingValueSource = (ServiceBindingValueSource) delegateClass.newInstance();
+         }
+         catch (RuntimeException e)
+         {
+            throw e;
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException("Failed creating ServiceBindingValueSource of type " + 
+                  serviceBindingValueSourceClassName, e);
+         }
       }
       return this.serviceBindingValueSource;
    }
 
+   /**
+    * Sets the object that can return this ServiceBinding's values in formats
+    * usable by consumers.
+    * 
+    * @param serviceBindingValueSource the ServiceBindingValueSource; may be <code>null</code>
+    */
    public void setServiceBindingValueSource(ServiceBindingValueSource serviceBindingValueSource)
    {
       this.serviceBindingValueSource = serviceBindingValueSource;
@@ -232,26 +314,42 @@
    }
 
    /** 
-    * Getter for property serviceBindingValueSourceClassName.
+    * Gets the fully qualified class name of the {@link #getServiceBindingValueSource() serviceBindingValueSource}.
+    * 
+    * @return the binding value source class, or <code>null</code>
     */
    public String getServiceBindingValueSourceClassName()
    {
       return serviceBindingValueSourceClassName;
    }
 
+   /** 
+    * Sets the fully qualified class name of the {@link #getServiceBindingValueSource() serviceBindingValueSource}.
+    * 
+    * @param serviceBindingValueSourceClassName the binding value source class, or <code>null</code>
+    */
    public void setServiceBindingValueSourceClassName(String serviceBindingValueSourceClassName)
    {
       this.serviceBindingValueSourceClassName = serviceBindingValueSourceClassName;
    }
 
    /** 
-    * Getter for property serviceBindingValueSourceConfig.
+    * Gets the configuration object the {@link #getServiceBindingValueSource() serviceBindingValueSource}
+    * should use.
+    * 
+    * @return the configuration object, or <code>null</code>
     */
    public Object getServiceBindingValueSourceConfig()
    {
       return serviceBindingValueSourceConfig;
    }
    
+   /** 
+    * Sets the configuration object the {@link #getServiceBindingValueSource() serviceBindingValueSource}
+    * should use.
+    * 
+    * @param serviceBindingValueSourceConfig the configuration object, or <code>null</code>
+    */
    public void setServiceBindingValueSourceConfig(Object serviceBindingValueSourceConfig)
    {
       this.serviceBindingValueSourceConfig = serviceBindingValueSourceConfig;
@@ -259,9 +357,28 @@
 
    // ----------------------------------------------------------------   Public
    
+   /**
+    * Gets a <code>ServiceBinding</code> that matches this one except the
+    * binding port has been adjusted by <code>offset</code>.
+    * 
+    * @param offset amount to adjust the binding port
+    */
    public ServiceBinding getOffsetBinding(int offset) throws UnknownHostException
    {
-      ServiceBinding result = new ServiceBinding(serviceName, bindingName, hostName, port + offset);
+      return getOffsetBinding(offset, this.hostName);
+   }
+   
+   /**
+    * Gets a <code>ServiceBinding</code> that matches this one except the
+    * binding port has been adjusted by <code>offset</code> and the hostname
+    * has been changed to defaultHostName if this object's hostName is null.
+    * 
+    * @param offset amount to adjust the binding port
+    */
+   public ServiceBinding getOffsetBinding(int offset, String defaultHostName) throws UnknownHostException
+   {
+      String newHost = this.hostName == null ? defaultHostName : this.hostName;
+      ServiceBinding result = new ServiceBinding(serviceName, bindingName, newHost, port + offset);
       result.setServiceBindingValueSourceClassName(serviceBindingValueSourceClassName);
       result.setServiceBindingValueSource(serviceBindingValueSource);
       result.setServiceBindingValueSourceConfig(serviceBindingValueSourceConfig);
@@ -329,6 +446,26 @@
       return sBuf.toString();
    }
 
+   // ------------------------------------------------------------ -  Protected
+
+   protected void setHostName(String hostName)
+   {
+      this.hostName = hostName;
+      try
+      {
+         this.bindAddress = InetAddress.getByName(hostName);
+      }
+      catch (UnknownHostException e)
+      {
+         throw new RuntimeException("Unknown hostName " + hostName, e);
+      }
+   }
+
+   protected void setPort(int port)
+   {
+      this.port = port;
+   }
+
    // ----------------------------------------------------------------  Private
    
    private boolean safeEquals(Object a, Object b)

Modified: trunk/varia/src/main/org/jboss/services/binding/ServiceBindingManager.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ServiceBindingManager.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/ServiceBindingManager.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -25,7 +25,14 @@
 import java.net.InetAddress;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.util.Set;
 
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementObjectID;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
+import org.jboss.managed.api.annotation.ViewUse;
 import org.jboss.services.binding.impl.SimpleServiceBindingValueSourceImpl;
 import org.jboss.services.binding.impl.StringReplacementServiceBindingValueSourceImpl;
 import org.jboss.services.binding.impl.Util;
@@ -48,6 +55,8 @@
  *
  * @jmx:mbean
  */
+ at ManagementObject(componentType=@ManagementComponent(type="MCBean", subtype="ServiceBindingManager"),
+                  properties=ManagementProperties.EXPLICIT)
 public class ServiceBindingManager
    implements ServiceBindingManagerMBean
 {  
@@ -70,7 +79,6 @@
     * @throws IllegalStateException if no appropriate ServiceBindingValueSource can be identified
     */
    public static ServiceBindingValueSource getServiceBindingValueSource(ServiceBinding binding, BindingType bindingType)
-         throws ClassNotFoundException, InstantiationException, IllegalAccessException
    {
       ServiceBindingValueSource source = binding.getServiceBindingValueSource();
       if (source == null)
@@ -134,21 +142,73 @@
    // -------------------------------------------------------------  Properties
    
    /**
+    * The value of the <code>serverName</code> param this instance should pass 
+    * to <code>ServiceBindingStore</code> when 
+    * {@link ServiceBindingStore#getServiceBinding(String, String, String) requesting bindings}.
+    * 
+    * @return name of the set of bindings this server uses
+    * 
     * @jmx:managed-attribute
     */
+   @ManagementProperty(description="the value of the serverName param  this " +
+   		"instance should pass to ServiceBindingStore when requesting bindings")
+   @ManagementObjectID(type="ServiceBindingManager")
    public String getServerName()
    {
       return this.serverName;
    }
+   
+   @ManagementProperty(description="the set of service binding configurations associated with this instance",
+                       use={ViewUse.STATISTIC})
+   public Set<ServiceBinding> getServiceBindings(String serverName)
+   {
+      return this.store.getServiceBindings(this.serverName);
+   }
 
    // ----------------------------------------------------------------- Public
    
-   public int getIntBinding(String serviceName) throws Exception
+   /**
+    * Gets the <code>int</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and no binding name qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getPort() port}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    *                    
+    * @return the binding value as an <code>int</code>
+    *  
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    * 
+    * @see IntServiceBindingValueSource
+    */
+   public int getIntBinding(String serviceName) throws NoSuchBindingException
    {
       return getIntBinding(serviceName, null);
    }
    
-   public int getIntBinding(String serviceName, String bindingName) throws Exception
+   /**
+    * Gets the <code>int</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getPort() port}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    *                    
+    * @return the binding value as an <code>int</code>
+    * 
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                    
+    * @see IntServiceBindingValueSource
+    */
+   public int getIntBinding(String serviceName, String bindingName) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.INT);
@@ -162,7 +222,29 @@
       }
    }
    
-   public int getIntBinding(String serviceName, String bindingName, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getIntBinding(String, String)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *                  
+    * @return the binding value as an <code>int</code>
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
+    */
+   public int getIntBinding(String serviceName, String bindingName, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -170,24 +252,58 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getIntBinding(serviceName, bindingName);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getIntBinding(serviceName, bindingName);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
-
-   private void createBindingFromDefaults(String serviceName, String bindingName, String hostName, int basePort)
-         throws UnknownHostException, DuplicateServiceException
-   {
-      ServiceBinding sb = new ServiceBinding(serviceName, bindingName, hostName, basePort);
-      store.addServiceBinding(sb);
-   }
    
-   public InetAddress getInetAddressBinding(String serviceName) throws Exception
+   /**
+    * Gets the <code>InetAddress</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and no binding name qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getBindAddress() bind address}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    *   
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                   
+    * @see InetAddressServiceBindingValueSource
+    */
+   public InetAddress getInetAddressBinding(String serviceName) throws NoSuchBindingException
    {
       return getInetAddressBinding(serviceName, null);
    }
    
-   public InetAddress getInetAddressBinding(String serviceName, String bindingName) throws Exception
+   /**
+    * Gets the <code>InetAddress</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getBindAddress() bind address}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see InetAddressServiceBindingValueSource
+    */
+   public InetAddress getInetAddressBinding(String serviceName, String bindingName) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.INETADDRESS);
@@ -201,7 +317,30 @@
       }
    }
    
-   public InetAddress getInetAddressBinding(String serviceName, String bindingName, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getInetAddressBinding(String, String)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *                  
+    * @return the binding value as an <code>InetAddress</code>
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found
+    */
+   public InetAddress getInetAddressBinding(String serviceName, String bindingName, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -209,17 +348,70 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getInetAddressBinding(serviceName, bindingName);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getInetAddressBinding(serviceName, bindingName);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
    
-   public String getStringBinding(String serviceName, String input) throws Exception
+   /**
+    * Gets the <code>String</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and no binding name qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getHostName() host name}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    *              
+    * @return the raw binding value, or a transformed string based on the raw
+    *         binding value and <code>input</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see StringServiceBindingValueSource
+    */
+   public String getStringBinding(String serviceName, String input) throws NoSuchBindingException
    {
       return getStringBinding(serviceName, null, input);
    }
    
-   public String getStringBinding(String serviceName, String bindingName, String input) throws Exception
+   /**
+    * Gets the <code>String</code> binding value for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * This is typically the {@link ServiceBinding#getHostName() host name}.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    *              
+    * @return the raw binding value, or a transformed string based on the raw
+    *         binding value and <code>input</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see StringServiceBindingValueSource
+    */
+   public String getStringBinding(String serviceName, String bindingName, String input) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.STRING);
@@ -233,7 +425,34 @@
       }
    }
    
-   public String getStringBinding(String serviceName, String bindingName, String input, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getStringBinding(String, String, String)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *              
+    * @return the raw binding value, or a transformed string based on the raw
+    *         binding value and <code>input</code>.
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
+    */
+   public String getStringBinding(String serviceName, String bindingName, String input, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -241,17 +460,64 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getStringBinding(serviceName, bindingName, input);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getStringBinding(serviceName, bindingName, input);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
    
-   public Element getElementBinding(String serviceName, Element input) throws Exception
+   /**
+    * Gets an <code>Element</code> containing the binding values for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and no binding name qualifier.
+    * <p>
+    * Used to perform transformations on values embedded in DOM elements.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param input element that should be used as a source for transformations 
+    *              
+    * @return transformed element based on the raw binding value(s) and <code>input</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see ElementServiceBindingValueSource
+    */
+   public Element getElementBinding(String serviceName, Element input) throws NoSuchBindingException
    {
       return getElementBinding(serviceName, null, input);
    }
    
-   public Element getElementBinding(String serviceName, String bindingName, Element input) throws Exception
+   /**
+    * Gets an <code>Element</code> containing the binding values for the
+    * <code>ServiceBinding</code> with the given <code>serviceName</code> 
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * Used to perform transformations on values embedded in DOM elements.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input element that should be used as a source for transformations 
+    *              
+    * @return transformed element based on the raw binding value(s) and <code>input</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see ElementServiceBindingValueSource
+    */
+   public Element getElementBinding(String serviceName, String bindingName, Element input) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.ELEMENT);
@@ -265,7 +531,33 @@
       }
    }
    
-   public Element getElementBinding(String serviceName, String bindingName, Element input, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getElementBinding(String, String, Element)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *              
+    * @return transformed element based on the raw binding value(s) and <code>input</code>.
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
+    */
+   public Element getElementBinding(String serviceName, String bindingName, Element input, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -273,17 +565,68 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getElementBinding(serviceName, bindingName, input);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getElementBinding(serviceName, bindingName, input);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
    
-   public URL getURLBinding(String serviceName, URL input) throws Exception
+   /**
+    * Gets a <code>URL</code> pointing to content that contains the binding values
+    * for the <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and no binding name qualifier.
+    * <p>
+    * Typical usage is in file transformation operations, where the content
+    * of the given <code>input</code> URL is read, transformed, written to a 
+    * temp file, and the URL of the temp file returned.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param input URL of content that should be used as a source for transformations 
+    *              
+    * @return URL pointing to the output of the transformation.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see URLServiceBindingValueSource
+    */
+   public URL getURLBinding(String serviceName, URL input) throws NoSuchBindingException
    {
       return getURLBinding(serviceName, null, input);
    }
    
-   public URL getURLBinding(String serviceName, String bindingName, URL input) throws Exception
+   /**
+    * Gets a <code>URL</code> pointing to content that contains the binding values
+    * for the <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * Typical usage is in file transformation operations, where the content
+    * of the given <code>input</code> URL is read, transformed, written to a 
+    * temp file, and the URL of the temp file returned.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input URL of content that should be used as a source for transformations 
+    *              
+    * @return URL pointing to the output of the transformation.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see URLServiceBindingValueSource
+    */
+   public URL getURLBinding(String serviceName, String bindingName, URL input) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.URL);
@@ -297,7 +640,33 @@
       }
    }
    
-   public URL getURLBinding(String serviceName, String bindingName, URL input, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getURLBinding(String, String, URL)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *              
+    * @return URL pointing to the output of the transformation.
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
+    */
+   public URL getURLBinding(String serviceName, String bindingName, URL input, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -305,17 +674,76 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getURLBinding(serviceName, bindingName, input);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getURLBinding(serviceName, bindingName, input);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
    
-   public String getResourceBinding(String serviceName, String input) throws Exception
+   /**
+    * Gets a filesystem path pointing to content that contains the binding values
+    * for the <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and no binding name qualifier.
+    * <p>
+    * Typical usage is in file transformation operations, where the content
+    * of the given <code>input</code> classpath resource is read, transformed, written to a 
+    * temp file, and the filesystem path of the temp file returned.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param input location of content that should be used as a source for transformations;
+    *              either a String representation of a URL or a value that
+    *              can be passed to {@link ClassLoader#getResourceAsStream(String)}. 
+    *              Cannot be <code>null</code>.
+    *              
+    * @return a filesystem path pointing to the output of the transformation. 
+    *         May return <code>null</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see URLServiceBindingValueSource
+    */
+   public String getResourceBinding(String serviceName, String input) throws NoSuchBindingException
    {
       return getResourceBinding(serviceName, null, input);
    }
    
-   public String getResourceBinding(String serviceName, String bindingName, String input) throws Exception
+   /**
+    * Gets a filesystem path pointing to content that contains the binding values
+    * for the <code>ServiceBinding</code> with the given <code>serviceName</code>
+    * and <code>bindingName</code> qualifier.
+    * <p>
+    * Typical usage is in file transformation operations, where the content
+    * of the given <code>input</code> classpath resource is read, transformed, written to a 
+    * temp file, and the filesystem path of the temp file returned.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input location of content that should be used as a source for transformations;
+    *              either a String representation of a URL or a value that
+    *              can be passed to {@link ClassLoader#getResourceAsStream(String)}. 
+    *              Cannot be <code>null</code>.
+    *              
+    * @return a filesystem path pointing to the output of the transformation. 
+    *         May return <code>null</code>.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see URLServiceBindingValueSource
+    */
+   public String getResourceBinding(String serviceName, String bindingName, String input) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.RESOURCE);
@@ -329,7 +757,34 @@
       }
    }
    
-   public String getResourceBinding(String serviceName, String bindingName, String input, String hostName, int basePort) throws Exception
+   /**
+    * Same as {@link #getResourceBinding(String, String, String)} but, if no matching
+    * service binding is found, creates a new one using the given
+    * <code>hostName</code> and <code>basePort</code>.
+    *  
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param input string that should be used as a source for transformations 
+    *              (e.g. string replacement), or <code>null</code> if no
+    *              transformation is needed
+    * @param hostName    Host name to use for new service binding if one is
+    *                    created.
+    * @param basePort    base port to use for the binding; ServiceBindingStore
+    *                    may adjust this.
+    *              
+    * @return a filesystem path pointing to the output of the transformation. 
+    *         May return <code>null</code>.
+    * 
+    * @throws DuplicateServiceException in unlikely event of concurrent attempts
+    *                                   to create same binding with different
+    *                                   binding values
+    *                                   
+    * @throws UnknownHostException if no IP address for the <code>hostName</code> could be found 
+    */
+   public String getResourceBinding(String serviceName, String bindingName, String input, 
+         String hostName, int basePort) throws UnknownHostException, DuplicateServiceException
    {
       try
       {
@@ -337,31 +792,77 @@
       }
       catch (NoSuchBindingException e)
       {
-         createBindingFromDefaults(serviceName, bindingName, hostName, basePort);
-         return getResourceBinding(serviceName, bindingName, input);
+         createBindingFromDefaults(serviceName, bindingName, hostName, basePort, false);
+         
+         try
+         {
+            return getResourceBinding(serviceName, bindingName, input);
+         }
+         catch (NoSuchBindingException e1)
+         {
+            // Shouldn't be possible
+            throw new IllegalStateException("Newly created binding not found", e1);
+         }
       }
    }
    
-   public Object getGenericBinding(String serviceName, Object ... params) throws Exception
+   /**
+    * Gets the detyped binding value for the <code>ServiceBinding</code> with 
+    * the given <code>serviceName</code> and <code>bindingName</code> qualifier.
+    * <p>
+    * This method is an extension point to allow integration of custom
+    * {@link ServiceBindingValueSource} implementations.
+    * </p>
+    * 
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>.
+    * @param params arbitrary parameters understood by the @{link {@link ServiceBindingValueSource}
+    *               associated with the binding.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see ServiceBinding#getServiceBindingValueSource()
+    */
+   public Object getGenericBinding(String serviceName, Object ... params) throws NoSuchBindingException
    {
       return getGenericBinding(serviceName, null, params);
    }
    
    /**
-    * Generic extension point, allowing arbitrary return types based
-    * on arbitrary sets of parameters.
+    * Gets the detyped binding value for the <code>ServiceBinding</code> with 
+    * the given <code>serviceName</code> and <code>bindingName</code> qualifier.
+    * <p>
+    * This method is an extension point to allow integration of custom
+    * {@link ServiceBindingValueSource} implementations.
+    * </p>
     * 
-    * @param serviceName
-    * @param bindingName
-    * @param params
-    * @return
-    * @throws Exception
+    * @param serviceName value to match to {@link ServiceBinding#getServiceName()}
+    *                    to identify the appropriate binding. Cannot be <code>null</code>. 
+    * @param bindingName value to match to {@link ServiceBinding#getBindingName()}
+    *                    to identify the appropriate binding. May be <code>null</code>.
+    * @param params arbitrary parameters understood by the @{link {@link ServiceBindingValueSource}
+    *               associated with the binding.
+    *      
+    * @throws NoSuchBindingException if a matching ServiceBinding could not be found
+    *                
+    * @see ServiceBinding#getServiceBindingValueSource()
     */
-   public Object getGenericBinding(String serviceName, String bindingName, Object ... params) throws Exception
+   public Object getGenericBinding(String serviceName, String bindingName, Object ... params) throws NoSuchBindingException
    {
       ServiceBinding binding = store.getServiceBinding(serverName, serviceName, bindingName);      
       ServiceBindingValueSource source = getServiceBindingValueSource(binding, BindingType.GENERIC);
       return source.getServiceBindingValue(binding, params); 
    }   
+
+   // ----------------------------------------------------------------- Private
    
+   private void createBindingFromDefaults(String serviceName, String bindingName, 
+         String hostName, int basePort, boolean fixedPort) throws UnknownHostException, DuplicateServiceException
+   {
+      String host = hostName == null ? store.getDefaultHostName(getServerName()) : hostName;
+      int port = fixedPort ? basePort : basePort + store.getDefaultPortOffset(getServerName());
+      ServiceBinding sb = new ServiceBinding(serviceName, bindingName, host, port);
+      store.addServiceBinding(getServerName(), sb);
+   }
+   
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/ServiceBindingStore.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ServiceBindingStore.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/ServiceBindingStore.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,9 +22,12 @@
 package org.jboss.services.binding;
 
 import java.net.InetAddress;
+import java.util.Set;
 
 
-/** Interface for API to persist, read, and look up service configs
+/** 
+ * SPI through which {@link ServiceBindingManager} interacts with a store 
+ * of service binding metadata.
  *
  * @version $Revision: 37459 $
  * @author <a href="mailto:bitpushr at rochester.rr.com">Mike Finn</a>.
@@ -33,12 +36,12 @@
  */
 public interface ServiceBindingStore 
 {
-   /** Obtain a ServiceBinding object for the given server instance, target
-    * service and binidng name. This is called by the JBoss service configuration
-    * layer to obtain service attribute binding overrides.
+   /** 
+    * Obtain a ServiceBinding object for the given server name, target
+    * service and binding name.
     *
-    * @param serverName the name identifying the JBoss server instance in
-    *    which the service is running.
+    * @param serverName the {@link ServiceBindingManager#getServerName() name identifying the server instance}
+    *  in which the service is running.
     * @param serviceName the name of the service
     * @param bindingName the name of the binding, or <code>null</code> to indicate
     *                    the default binding.
@@ -46,13 +49,26 @@
     *         tuple.
     *         
     * @throws NoSuchBindingException if no matching binding exists
+    * 
+    * @throws IllegalArgumentException if serverName is unknown to the store.
     */
    ServiceBinding getServiceBinding(String serverName, String serviceName, String bindingName) 
       throws NoSuchBindingException;
 
+   /**
+    * Gets all service bindings for the given server name.
+    * 
+    * @param serverName the {@link ServiceBindingManager#getServerName() name identifying the server instance}
+    *  in which the service is running. Cannot be <code>null</code>.
+    *  
+    * @return the set of service bindings for the server name. Will not be null.
+    * 
+    * @throws IllegalArgumentException if serverName is unknown to the store.
+    */
+   Set<ServiceBinding> getServiceBindings(String serverName);
+   
    /** 
-    * Add a ServiceBinding to the store. This is an optional method not used
-    * by the JBoss service configuration layer.
+    * Add a ServiceBinding to the store for the given serverName.
     *
     * @param serverName the name identifying the JBoss server instance in
     *    which the service is running.
@@ -61,61 +77,22 @@
     * 
     * @throws DuplicateServiceException thrown if a configuration for the
     *    <serverName, serviceName> pair already exists.
+    * 
+    * @throws IllegalArgumentException if serverName is unknown to the store.
     */
    void addServiceBinding(String serverName, ServiceBinding binding)
       throws DuplicateServiceException;
 
    /** 
-    * Remove a service configuration from the store. This is an optonal method
-    * not used by the JBoss service configuration layer.
+    * Remove a ServiceBinding from the store for the given serverName.
     *
     * @param serverName the name identifying the JBoss server instance in
     *    which the service is running.
     * @param serviceBinding the binding
-    */
-   void removeServiceBinding(String serverName, ServiceBinding binding);
-
-   /** 
-    * Remove a service configuration from the store. This is an optonal method
-    * not used by the JBoss service configuration layer.
-    *
-    * @param serverName the name identifying the JBoss server instance in
-    *    which the service is running.
-    * @param serviceBinding the binding
-    */
-   void removeServiceBinding(String serverName, String serviceName, String bindingName);
-
-   /** 
-    * Add a ServiceBinding to all binding sets in the store. For each binding 
-    * set, a new ServiceBinding is added whose serviceName and bindingName
-    * properties match the passed binding. The new binding's hostName matches
-    * the target set's {@link #getDefaultHostName(String) default host name}.
-    * The new binding's port is derived by taking the port from the passed 
-    * binding and incrementing it by the target set's 
-    * {@link #getDefaultPortOffset(String) default port offset}.
-    *
-    * @param serviceName the JMX ObjectName of the service
-    * @param serviceConfig the configuration to add
     * 
-    * @throws DuplicateServiceException thrown if a configuration for the
-    *    <serverName, serviceName> pair already exists.
+    * @throws IllegalArgumentException if serverName is unknown to the store.
     */
-   void addServiceBinding(ServiceBinding binding)
-      throws DuplicateServiceException;
-
-   /** 
-    * Remove a service configuration from all binding sets in the store.
-    *
-    * @param serviceBinding the binding
-    */
-   void removeServiceBinding(ServiceBinding binding);
-
-   /** 
-    * Remove a service configuration from all binding sets in the store.
-    *
-    * @param serviceBinding the binding
-    */
-   void removeServiceBinding(String serviceName, String bindingName);
+   void removeServiceBinding(String serverName, ServiceBinding binding);
    
    /**
     * Gets the offset from a base value that by default should be added to
@@ -123,6 +100,8 @@
     * 
     * @param serverName the name of the binding set
     * @return the offset
+    * 
+    * @throws IllegalArgumentException if serverName is unknown to the store.
     */
    int getDefaultPortOffset(String serverName);
    
@@ -131,15 +110,9 @@
     * 
     * @param serverName the name of the binding set
     * @return the host name
+    * 
+    * @throws IllegalArgumentException if serverName is unknown to the store.
     */
    String getDefaultHostName(String serverName);
    
-   /**
-    * Value of <code>InetAddress.getByHost({@link #getDefaultHostName(String) getDefaultHost(serverName)})</code>.
-    * 
-    * @param serverName the name of the binding set
-    * @return the host name
-    */
-   InetAddress getDefaultBindAddress(String serverName);
-   
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/ServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/ServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/ServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -42,5 +42,5 @@
     *                                  not understood
     * @throws Exception if another exception occurs
     */
-   public Object getServiceBindingValue(ServiceBinding binding, Object ... params) throws Exception;
+   public Object getServiceBindingValue(ServiceBinding binding, Object ... params);
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/StringServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/StringServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/StringServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -37,7 +37,7 @@
     * @param binding the binding. Cannot be <code>null</code>
     * @param originalValue an unprocessed value to which transformation can be applied
     * 
-    * @return an String to use as the binding value. May return <code>null</code>.
+    * @return a String to use as the binding value. May return <code>null</code>.
     */
-   String getStringServiceBindingValue(ServiceBinding binding, String input) throws Exception;
+   String getStringServiceBindingValue(ServiceBinding binding, String input);
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/URLServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/URLServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/URLServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -28,9 +28,10 @@
  * A {@link ServiceBindingValueSource} that returns a URL or a String
  * representation of one.
  * <p>
- * Typical usage is in file transformation operations, where a given
- * the content of a given <code>input</code> URL or classpath resource is read,
+ * Typical usage is in file transformation operations, where the content
+ * of a given <code>input</code> URL or classpath resource is read,
  * transformed, written to a temp file, and the URL of the temp file returned.
+ * </p>
  * 
  * @author Brian Stansberry
  * @version $Revision$
@@ -45,7 +46,7 @@
     *  
     * @return a URL to use as the binding value. Will not return <code>null</code>.
     */
-   URL getURLServiceBindingValue(ServiceBinding binding, URL input) throws Exception;
+   URL getURLServiceBindingValue(ServiceBinding binding, URL input);
    
    /**
     * Returns a String representation of a URL path to use for the binding value.
@@ -56,5 +57,5 @@
     *              
     * @return a filesystem path to use as the binding value. May return <code>null</code>.
     */
-   String getResourceServiceBindingValue(ServiceBinding binding, String input) throws Exception;
+   String getResourceServiceBindingValue(ServiceBinding binding, String input);
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/PojoServiceBindingStore.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/PojoServiceBindingStore.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/PojoServiceBindingStore.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,73 +22,86 @@
 
 package org.jboss.services.binding.impl;
 
-import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.jboss.managed.api.ManagedOperation.Impact;
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementOperation;
+import org.jboss.managed.api.annotation.ManagementParameter;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
 import org.jboss.services.binding.DuplicateServiceException;
+import org.jboss.services.binding.ManagedServiceBinding;
 import org.jboss.services.binding.NoSuchBindingException;
 import org.jboss.services.binding.ServiceBinding;
 import org.jboss.services.binding.ServiceBindingStore;
 
 /**
- * A PojoServiceBindingStore.
+ * A Pojo implementation of {@link ServiceBindingStore}.
  * 
  * @author Brian Stansberry
  * @version $Revision$
  */
+ at ManagementObject(name="PojoServiceBindingStore",
+                  componentType=@ManagementComponent(type="MCBean", subtype="ServiceBindingStore"),
+      properties=ManagementProperties.EXPLICIT)
 public class PojoServiceBindingStore implements ServiceBindingStore
 {
+   /** Dummy value to make ConcurrentHashMap act like a Set */
    private static final Object VALUE = new Object();
    
+   // ------------------------------------------------------------ Constructors
+   
+   /** All bindings */
    private final ConcurrentMap<ServiceBindingKey, ServiceBinding> bindings = 
-      new ConcurrentHashMap<ServiceBindingKey, ServiceBinding>(16, (float) .75, 4);
+      new ConcurrentHashMap<ServiceBindingKey, ServiceBinding>(16, (float) .75, 2);
    
-   private final ConcurrentMap<String, Object> bindingSetNames = 
-      new ConcurrentHashMap<String, Object>(16, (float) .75, 4);
+   /** Injected binding sets*/
+   private final ConcurrentMap<String, ServiceBindingSet> bindingSets = 
+      new ConcurrentHashMap<String, ServiceBindingSet>(16, (float) .75, 2);
    
-   private final Map<String, String> defaultHostNames = new HashMap<String, String>();
+   /** Injected base bindings whose ports are incremented for each set */
+   private final Map<ManagedServiceBinding, Object> portOffsetBindings = 
+      new ConcurrentHashMap<ManagedServiceBinding, Object>(16, (float) .75, 2);
    
-   private final Map<String, InetAddress> defaultBindAddresses = new HashMap<String, InetAddress>();
+   /** Injected base bindings whose ports are fixed for each set */
+   private final Map<ManagedServiceBinding, Object> fixedBindings = 
+      new ConcurrentHashMap<ManagedServiceBinding, Object>(16, (float) .75, 2);
    
-   private final Map<String, Integer> defaultPortOffsets = new HashMap<String, Integer>();
+   private boolean started;
    
-   public PojoServiceBindingStore(Map<String, ServiceBindingSet> configSets)
-     throws DuplicateServiceException
-   {
-      if (configSets == null)
-         throw new IllegalArgumentException("configSets is null");
-      
-      for (Map.Entry<String, ServiceBindingSet> entry : configSets.entrySet())
-      {
-         String serverName = entry.getKey();
-         
-         bindingSetNames.put(serverName, VALUE);
-         
-         ServiceBindingSet bindingSet = entry.getValue();
-         
-         defaultHostNames.put(serverName, bindingSet.getDefaultHostName());
-         defaultBindAddresses.put(serverName, bindingSet.getDefaultBindAddress());
-         defaultPortOffsets.put(serverName, bindingSet.getPortOffset());
-         
-         for (ServiceBinding binding : bindingSet)
-         {
-            addServiceBinding(serverName, binding);
-         }
-      }
-   }
+   // ------------------------------------------------------------ Constructors
    
-   public void addServiceBinding(String serverName, ServiceBinding binding) throws DuplicateServiceException
+   /**
+    * Creates a new PojoServiceBindingStore
+    */
+   public PojoServiceBindingStore() {}
+   
+   // ----------------------------------------------------- ServiceBindingStore
+   
+   public void addServiceBinding(String serverName, ServiceBinding binding) 
+      throws DuplicateServiceException
    {      
       validateServerName(serverName);
-      Object oldBinding = bindings.putIfAbsent(new ServiceBindingKey(serverName, binding), binding);
-      if (oldBinding != null)
+      ServiceBinding masked = maskManagedBinding(binding);
+      ServiceBinding oldBinding = bindings.putIfAbsent(new ServiceBindingKey(serverName, binding), masked);
+      if (oldBinding != null && 
+            (safeEquals(oldBinding.getHostName(), binding.getHostName()) == false
+               || oldBinding.getPort() != binding.getPort()))
       {
          throw new DuplicateServiceException(serverName, binding);
       }
+      
+      // For management purposes, treat this as an override
+      ServiceBindingSet bindingSet = bindingSets.get(serverName);
+      bindingSet.getOverrideBindings().add(getManagedServiceBinding(binding));
    }
 
    public ServiceBinding getServiceBinding(String serverName, String serviceName, String bindingName)
@@ -101,24 +114,254 @@
       }
       return binding;
    }
+   
+   public Set<ServiceBinding> getServiceBindings(String serverName)
+   {
+      validateServerName(serverName);
+      
+      Set<ServiceBinding> result = new HashSet<ServiceBinding>();
+      for (Map.Entry<ServiceBindingKey, ServiceBinding> entry : bindings.entrySet())
+      {
+         if (serverName.equals(entry.getKey().serverName))
+         {
+            result.add(entry.getValue());
+         }
+      }
+      
+      return result;
+   }
 
    public void removeServiceBinding(String serverName, ServiceBinding binding)
    {
       validateServerName(serverName);
       bindings.remove(new ServiceBindingKey(serverName, binding));
+      
+      // For management purposes, treat this as an override
+      ServiceBindingSet bindingSet = bindingSets.get(serverName);
+      bindingSet.getOverrideBindings().remove(getManagedServiceBinding(binding));
    }
 
-   public void removeServiceBinding(String serverName, String serviceName, String bindingName)
+   public String getDefaultHostName(String serverName)
    {
       validateServerName(serverName);
-      bindings.remove(new ServiceBindingKey(serverName, serviceName, bindingName));
+      return bindingSets.get(serverName).getDefaultHostName();
    }
+
+   public int getDefaultPortOffset(String serverName)
+   {
+      validateServerName(serverName);
+      return bindingSets.get(serverName).getPortOffset();
+   }
    
-   public void addServiceBinding(ServiceBinding binding) throws DuplicateServiceException
+   // ------------------------------------------------------------------ Public
+   
+   /**
+    * Sets the base set of bindings that should be associated with each binding set,
+    * but with that binding set's {@link ServiceBindingSet#getPortOffset() port offset}
+    * applied to the port value.
+    * 
+    * @param bindings the set of base bindings. May be <code>null</code>
+    * 
+    * @throws IllegalStateException if invoked after {@link #start()}
+    */
+   public void setPortOffsetBindings(Set<ManagedServiceBinding> bindings)
    {
-      for (String serverName : bindingSetNames.keySet())
+      if (started)
       {
-         int port = binding.getPort() + getDefaultPortOffset(serverName);
+         throw new IllegalStateException("Cannot call setPortOffsetBindings() after start()");
+      }
+      portOffsetBindings.clear();
+      if (bindings != null)
+      {
+         for (ManagedServiceBinding binding : bindings)
+         {
+            portOffsetBindings.put(binding, VALUE);
+         }
+      }
+   }
+   
+   /**
+    * Sets the set of bindings that should be associated with each binding set,
+    * but whose hostname/port/bindAddress should not vary. Typically used for
+    * multicast socket bindings, which do not lead to port conflicts if multiple
+    * sockets are opened on the same machine.
+    * 
+    * @param bindings the set of fixed bindings. May be <code>null</code>
+    * 
+    * @throws IllegalStateException if invoked after {@link #start()}
+    */
+   public void setFixedBindings(Set<ManagedServiceBinding> bindings)
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Cannot call setFixedBindings() after start()");
+      }
+      
+      fixedBindings.clear();
+      if (bindings != null)
+      {
+         for (ManagedServiceBinding binding : bindings)
+         {
+            fixedBindings.put(binding, VALUE);
+         }
+      }
+   }
+   
+   public void setServiceBindingSets(Set<ServiceBindingSet> sets)
+   {
+      if (started)
+      {
+         throw new IllegalStateException("Cannot call setServiceBindingSets() after start()");
+      }
+      
+      this.bindingSets.clear();
+      
+      if (sets != null)
+      {      
+         for (ServiceBindingSet bindingSet : sets)
+         {
+            this.bindingSets.put(bindingSet.getName(), bindingSet);
+         }
+      }
+      
+   }
+   
+   /**
+    * Builds the runtime sets of bindings from the injected base bindings
+    * and ServiceBindingSets.
+    * 
+    * @throws DuplicateServiceException
+    * @throws UnknownHostException
+    */
+   public void start() throws DuplicateServiceException, UnknownHostException
+   {
+      // Establish the override bindings first, so when we add the
+      // fixed and portOffset, we get DuplicateServiceException
+      for (ServiceBindingSet bindingSet : bindingSets.values())
+      {
+         for (ServiceBinding binding : bindingSet.getOverrideBindings())
+         {
+            addServiceBinding(bindingSet.getName(), binding);
+         }
+      }
+      
+      // Establish the portOffset bindings   
+      for (ManagedServiceBinding fixed : portOffsetBindings.keySet())
+      {
+         for (ServiceBindingSet bindingSet : bindingSets.values())
+         {
+            ServiceBinding binding = fixed.getOffsetBinding(bindingSet.getPortOffset(), 
+                                                            bindingSet.getDefaultHostName());
+            try
+            {
+               addServiceBinding(bindingSet.getName(), binding);
+            }
+            catch (DuplicateServiceException e)
+            {
+               if (bindingSet.getOverrideBindings().contains(binding) == false)
+               {
+                  throw e;
+               }
+            }
+         }
+      } 
+      
+      // Establish the fixed bindings 
+      for (ManagedServiceBinding fixed : fixedBindings.keySet())
+      {
+         for (ServiceBindingSet bindingSet : bindingSets.values())
+         {
+            // We use getOffsetBinding(0) as a form of copy constructor
+            ServiceBinding binding = fixed.getOffsetBinding(0, bindingSet.getDefaultHostName());
+            try
+            {
+               addServiceBinding(bindingSet.getName(), binding);
+            }
+            catch (DuplicateServiceException e)
+            {
+               if (bindingSet.getOverrideBindings().contains(binding) == false)
+               {
+                  throw e;
+               }
+            }
+         }
+      }
+      
+      this.started = true;
+   }
+   
+   public void stop()
+   {
+      this.bindings.clear();
+      this.started = false;
+   }
+   
+   // -------------------------------------------------------------- Management
+
+   /**
+    * Gets the base set of bindings that should be associated with each binding set,
+    * but with that binding set's {@link ServiceBindingSet#getPortOffset() port offset}
+    * applied to the port value.
+    * 
+    * @return the set of base bindings
+    */
+   @ManagementProperty(description="the base set of bindings that should be associated " +
+        "with each binding set, but with that binding set's port offset applied " +
+        "to the port value.")
+   public Set<ManagedServiceBinding> getPortOffsetBindings()
+   {
+      return new HashSet<ManagedServiceBinding>(portOffsetBindings.keySet());
+   }
+   
+   /**
+    * Gets the set of bindings that should be associated with each binding set,
+    * but whose hostname/port/bindAddress should not vary. Typically used for
+    * multicast socket bindings, which do not lead to port conflicts if multiple
+    * sockets are opened on the same machine.
+    * 
+    * @return the set of fixed bindings
+    */
+   @ManagementProperty(description="the set of bindings that should be associated " +
+         "with each binding set, whose hostname/port/bindAddress should not vary")
+   public Set<ManagedServiceBinding> geFixedBindings()
+   {
+      return new HashSet<ManagedServiceBinding>(fixedBindings.keySet());
+   }
+   
+   @ManagementProperty
+   public Set<ServiceBindingSet> getBindingSets()
+   {
+      return new HashSet<ServiceBindingSet>(bindingSets.values());
+   }
+   
+   /** 
+    * Add a ServiceBinding to all binding sets in the store. For each binding 
+    * set, a new ServiceBinding is added whose serviceName and bindingName
+    * properties match the passed binding. If <the given <code>binding</code>'s
+    * <code>hostName</code> property is <code>null</code>, the new binding's 
+    * hostName matches the target set's {@link #getDefaultHostName(String) default host name}.
+    * If <code>fixed</code> is <code>false</code>, the new binding's port is 
+    * derived by taking the port from the passed binding and incrementing it 
+    * by the target set's {@link #getDefaultPortOffset(String) default port offset}.
+    *
+    * @param serviceName the JMX ObjectName of the service
+    * @param serviceConfig the configuration to add
+    * @param fixed <code>true</code> if the binding's port should remain fixed
+    *              when added to each binding set; <code>false</code> if it 
+    *              should be offset by the binding set's port offset
+    * 
+    * @throws DuplicateServiceException thrown if a configuration for the
+    *    <serverName, serviceName> pair already exists.
+    */
+   @ManagementOperation(description="adds a service binding", impact=Impact.WriteOnly,
+                        params={@ManagementParameter(name="binding"),
+                                @ManagementParameter(name="fixed")})
+   public void addServiceBinding(ManagedServiceBinding binding, boolean fixed) throws DuplicateServiceException
+   {
+      // Add to the runtime objects
+      for (String serverName : bindingSets.keySet())
+      {
+         int port = fixed ? binding.getPort() : binding.getPort() + getDefaultPortOffset(serverName);
          String hostName = binding.getHostName();
          if (hostName == null)
             hostName = getDefaultHostName(serverName);
@@ -132,45 +375,171 @@
             throw new IllegalStateException("Cannot convert " + hostName + " into an InetAddress");
          }
       }
+      
+      // Add to the managed object map
+      Map<ManagedServiceBinding, Object> map = fixed ? fixedBindings : portOffsetBindings;
+      map.put(getManagedServiceBinding(binding), VALUE);
    }
+   
+   /** 
+    * Adds a ServiceBinding to all binding sets in the store. For each binding 
+    * set, a new ServiceBinding is added whose serviceName and bindingName
+    * properties match the passed values. If <code>hostName</code>
+    * is <code>null</code>, the new binding's hostName matches
+    * the target set's {@link #getDefaultHostName(String) default host name}.
+    * If <code>fixed</code> is false, the new binding's port is derived by 
+    * taking the given <code>port</code> and incrementing it by the target set's 
+    * {@link #getDefaultPortOffset(String) default port offset}.
+    *
+    * @param serviceName the JMX ObjectName of the service
+    * @param serviceConfig the configuration to add
+    * @param fixed <code>true</code> if the binding's port should remain fixed
+    *              when added to each binding set; <code>false</code> if it 
+    *              should be offset by the binding set's port offset
+    * 
+    * @throws DuplicateServiceException thrown if a configuration for the
+    *    <serverName, serviceName> pair already exists.
+    */
+   @ManagementOperation(description="adds a service binding", impact=Impact.WriteOnly,
+                        params={@ManagementParameter(name="serviceName"),
+                                @ManagementParameter(name="bindingName"),
+                                @ManagementParameter(name="hostName"),
+                                @ManagementParameter(name="port"),
+                                @ManagementParameter(name="fixed")})
+   public void addServiceBinding(String serviceName, String bindingName, String hostName, int port, boolean fixed) 
+      throws DuplicateServiceException, UnknownHostException
+   {
+      addServiceBinding(new ManagedServiceBinding(serviceName, bindingName, hostName, port), fixed);
+   }
 
-   public void removeServiceBinding(ServiceBinding binding)
+   /** 
+    * Remove a service configuration from all binding sets in the store.
+    *
+    * @param serviceBinding the binding
+    */
+   @ManagementOperation(description="removes a service binding", impact=Impact.WriteOnly,
+                        params={@ManagementParameter(name="binding")})
+   public void removeServiceBinding(ManagedServiceBinding binding)
    {
-      for (String serverName : bindingSetNames.keySet())
+      // Remove from runtime sets
+      for (String serverName : bindingSets.keySet())
       {
          removeServiceBinding(serverName, binding);
       }
+      
+      // Remove from managed sets
+      ManagedServiceBinding msb = getManagedServiceBinding(binding);
+      if (fixedBindings.remove(msb) == null)
+      {
+         portOffsetBindings.remove(msb);
+      }
+      
    }
 
+   /** 
+    * Remove a service configuration from all binding sets in the store.
+    *
+    * @param serviceBinding the binding
+    */
+   @ManagementOperation(description="removes a service binding", impact=Impact.WriteOnly,
+         params={@ManagementParameter(name="serviceName"),
+                 @ManagementParameter(name="bindingName")})
    public void removeServiceBinding(String serviceName, String bindingName)
    {
-      for (String serverName : bindingSetNames.keySet())
+      try
       {
-         removeServiceBinding(serverName, serviceName, bindingName);
+         ManagedServiceBinding binding = new ManagedServiceBinding(serviceName, bindingName, null, 0);
+         removeServiceBinding(binding);         
       }
+      catch (UnknownHostException e)
+      {
+         // Do it by hand
+         for (ServiceBindingSet bindingSet : bindingSets.values())
+         {
+            bindings.remove(new ServiceBindingKey(bindingSet.getName(), serviceName, bindingName));
+
+            for (Iterator<ManagedServiceBinding> iter = bindingSet.getOverrideBindings().iterator(); iter.hasNext(); )
+            {
+               ServiceBinding b = iter.next();
+               if (b.getServiceName().equals(serviceName) && safeEquals(b.getBindingName(), bindingName))
+               {
+                  iter.remove();
+                  break;
+               }
+            }
+         }
+         
+         boolean removed = false;
+         for (Iterator<ManagedServiceBinding> iter = fixedBindings.keySet().iterator(); iter.hasNext(); )
+         {
+            ManagedServiceBinding b = iter.next();
+            if (b.getServiceName().equals(serviceName) && safeEquals(b.getBindingName(), bindingName))
+            {
+               iter.remove();
+               removed = true;
+               break;
+            }
+         }
+         if (!removed)
+         {
+            for (Iterator<ManagedServiceBinding> iter = portOffsetBindings.keySet().iterator(); iter.hasNext(); )
+            {
+               ManagedServiceBinding b = iter.next();
+               if (b.getServiceName().equals(serviceName) && safeEquals(b.getBindingName(), bindingName))
+               {
+                  iter.remove();
+                  break;
+               }
+            }
+         }
+      }
    }
+   
+   // ------------------------------------------------------------------ Private
 
-   public InetAddress getDefaultBindAddress(String serverName)
+   private static ServiceBinding maskManagedBinding(ServiceBinding toMask)
    {
-      validateServerName(serverName);
-      return defaultBindAddresses.get(serverName);
+      ServiceBinding masked = toMask;
+      if (toMask instanceof ManagedServiceBinding)
+      {
+         try
+         {
+            masked = new ServiceBinding(toMask);
+         }
+         catch (UnknownHostException e)
+         {
+            throw new IllegalStateException("Cannot create unmanaged binding from " + toMask, e);
+         }
+      }
+      return masked;
    }
-
-   public String getDefaultHostName(String serverName)
+   
+   private static ManagedServiceBinding getManagedServiceBinding(ServiceBinding source)
    {
-      validateServerName(serverName);
-      return defaultHostNames.get(serverName);
+      if (source instanceof ManagedServiceBinding)
+      {
+         return (ManagedServiceBinding) source;
+      }
+      
+      try
+      {
+         ManagedServiceBinding managed = new ManagedServiceBinding(source);          
+         return managed;
+      }
+      catch (UnknownHostException e)
+      {
+         throw new IllegalStateException("Cannot create managed binding from " + source, e);
+      }
    }
 
-   public int getDefaultPortOffset(String serverName)
-   {
-      validateServerName(serverName);
-      return defaultPortOffsets.get(serverName).intValue();
+   private static boolean safeEquals(Object a, Object b)
+   {      
+      return (a == b || (a != null && a.equals(b)));
    }
-
+   
    private void validateServerName(String serverName)
    {
-      if (bindingSetNames.containsKey(serverName) == false)
+      if (bindingSets.containsKey(serverName) == false)
          throw new IllegalArgumentException("unknown serverName " +serverName);
    }
 
@@ -218,11 +587,6 @@
          return result;
       }
       
-      private boolean safeEquals(Object a, Object b)
-      {
-         return (a == b || (a != null && a.equals(b)));
-      }
-      
    }
 
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/ServiceBindingSet.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/ServiceBindingSet.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/ServiceBindingSet.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,85 +22,133 @@
 
 package org.jboss.services.binding.impl;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.jboss.services.binding.ServiceBinding;
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementObjectID;
+import org.jboss.managed.api.annotation.ManagementProperties;
+import org.jboss.managed.api.annotation.ManagementProperty;
+import org.jboss.services.binding.ManagedServiceBinding;
 
 /**
- * Set<ServiceBinding> that populates itself by taking a base set
- * and duplicating its binding with a fixed offset to each port value.
+ * Encapsulates information used to configure a unique set of bindings.
  * 
  * @author Brian Stansberry
  * @version $Revision$
  */
-public class ServiceBindingSet extends HashSet<ServiceBinding>
+ at ManagementObject(componentType=@ManagementComponent(type="MCBean", subtype="ServiceBindingSet"),
+      properties=ManagementProperties.EXPLICIT)
+public class ServiceBindingSet
 {   
    /** The serialVersionUID */
    private static final long serialVersionUID = 765380451233486038L;
 
-   private final String defaultHostName;
-   private final InetAddress defaultBindAddress;
-   private final int portOffset;
+   private final String bindingSetName;
+   private String defaultHostName;
+   private int portOffset;
+   private final Set<ManagedServiceBinding> overrides;
    
-   public ServiceBindingSet(Set<ServiceBinding> base) throws UnknownHostException
+   // ------------------------------------------------------------ Constructors
+   
+   /**
+    * Same as ServiceBindingSet(name, null, 0, null)
+    */
+   public ServiceBindingSet(String name)
    {
-      this(base, 0, null, null);
+      this(name, null, 0, null);
    }
+   
+   /**
+    * Same as ServiceBindingSet(name, null, 0, overrides)
+    */
+   public ServiceBindingSet(String name, Set<ManagedServiceBinding> overrides)
+   {
+      this(name, null, 0, overrides);
+   }
 
-   public ServiceBindingSet(Set<ServiceBinding> base, int offset) throws UnknownHostException
+   /**
+    * Same as ServiceBindingSet(name, null, offset, null)
+    */
+   public ServiceBindingSet(String name, int offset)
    {
-      this(base, offset, null, null);
+      this(name, null, offset, null);
    }
 
-   public ServiceBindingSet(Set<ServiceBinding> base, int offset, String defaultHostName) throws UnknownHostException
+   /**
+    * Same as ServiceBindingSet(name, defaultHostName, offset, null)
+    */
+   public ServiceBindingSet(String name, String defaultHostName, int offset)
    {
-      this(base, offset, null, defaultHostName);
+      this(name, defaultHostName, offset, null);
    }
    
-   public ServiceBindingSet(Set<ServiceBinding> base, int offset, Set<ServiceBinding> overrides, String defaultHostName) throws UnknownHostException
+   /**
+    *  Create a new ServiceBindingSet.
+    * 
+    * @param name the name of the binding set. Cannot be <code>null</code>
+    * @param defaultHostName default host name to use for bindings associated
+    *                        with this set. May be <code>null</code>
+    * @param offset offset to apply to bindings associdated with this set
+    * @param overrides set of bindings whose values should override any matching
+    *                  default bindings found in the service binding store
+    *                  with which this set is associated
+    */
+   public ServiceBindingSet(String name, String defaultHostName, 
+                            int offset, 
+                            Set<ManagedServiceBinding> overrides)
    {
-      super(getOffsetBindings(base, offset));
-      if (overrides != null)
+      if (name == null)
       {
-         // HashSet.add() is not a replace operation, so must remove first
-         for (ServiceBinding binding : overrides)
-         {
-            remove(binding);
-            add(binding);
-         }
+         throw new IllegalArgumentException("name is null");
       }
       
+      this.overrides =  overrides == null ? new HashSet<ManagedServiceBinding>(0) : overrides; 
+      
+      this.bindingSetName = name;
       this.defaultHostName = defaultHostName;
-      this.defaultBindAddress = defaultHostName == null ? null : InetAddress.getByName(defaultHostName);
       this.portOffset = offset;
    }
+
+   // -------------------------------------------------------------- Properties
    
-   private static Set<ServiceBinding> getOffsetBindings(Set<ServiceBinding> base, int offset) throws UnknownHostException
+   @ManagementProperty
+   @ManagementObjectID(type="ServiceBindingSet")
+   public String getName()
    {
-      Set<ServiceBinding> altered = new HashSet<ServiceBinding>(base.size());
-      for (ServiceBinding binding : base)
-      {
-         altered.add(binding.getOffsetBinding(offset));
-      }
-      return altered;
+      return bindingSetName;
    }
 
+   @ManagementProperty
    public String getDefaultHostName()
    {
       return defaultHostName;
    }
 
-   public InetAddress getDefaultBindAddress()
+   public void setDefaultHostName(String defaultHostName)
    {
-      return defaultBindAddress;
+      this.defaultHostName = defaultHostName;
    }
 
+   @ManagementProperty
    public int getPortOffset()
    {
       return portOffset;
    }
+
+   public void setPortOffset(int portOffset)
+   {
+      this.portOffset = portOffset;
+   }
    
+   @ManagementProperty
+   public Set<ManagedServiceBinding> getOverrideBindings()
+   {
+      @SuppressWarnings("unchecked")      
+      Set<ManagedServiceBinding> result = overrides == null ? Collections.EMPTY_SET : overrides;
+      return result;
+   }
+   
 }

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/SimpleServiceBindingValueSourceImpl.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/SimpleServiceBindingValueSourceImpl.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/SimpleServiceBindingValueSourceImpl.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -31,7 +31,7 @@
 /**
  * ServiceBindingValueSource that returns the given binding's
  * {@link ServiceBinding#getBindAddress() bind address} and 
- * {@link ServiceBinding#getPort() port}.
+ * {@link ServiceBinding#getPort() port}. Does not perform any transformations.
  * 
  * @author Brian Stansberry
  * @version $Revision$
@@ -61,7 +61,7 @@
    /**
     * @return <code>new Integer(binding.{@link ServiceBinding#getPort() getPort()})</code>
     */
-   public Object getServiceBindingValue(ServiceBinding binding, Object... params) throws Exception
+   public Object getServiceBindingValue(ServiceBinding binding, Object... params)
    {
       if (params != null && params.length > 0)
          throw new IllegalArgumentException(getClass().getSimpleName() + ".getServiceBindingValue() does not accept argument 'params'");

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/StringReplacementServiceBindingValueSourceImpl.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/StringReplacementServiceBindingValueSourceImpl.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/StringReplacementServiceBindingValueSourceImpl.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -24,6 +24,7 @@
 
 import java.beans.PropertyEditor;
 import java.beans.PropertyEditorManager;
+import java.io.IOException;
 import java.net.URL;
 
 import org.jboss.services.binding.ElementServiceBindingValueSource;
@@ -33,7 +34,8 @@
 import org.w3c.dom.Element;
 
 /**
- * A StringReplacementServiceBindingValueSourceImpl.
+ * A {@link ServiceBindingValueSource} implementation that uses
+ * string replacement to perform any needed transformations.
  * 
  * @author Brian Stansberry
  * @version $Revision$
@@ -42,7 +44,7 @@
    implements StringServiceBindingValueSource, ElementServiceBindingValueSource, URLServiceBindingValueSource
 {
    
-   public String getStringServiceBindingValue(ServiceBinding binding, String input) throws Exception
+   public String getStringServiceBindingValue(ServiceBinding binding, String input)
    {
       if (input == null)
       {
@@ -54,7 +56,7 @@
    }  
       
 
-   public Element getElementServiceBindingValue(ServiceBinding binding, Element input) throws Exception
+   public Element getElementServiceBindingValue(ServiceBinding binding, Element input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
@@ -72,32 +74,46 @@
       return (Element) editor.getValue();
    }
 
-   public String getResourceServiceBindingValue(ServiceBinding binding, String input) throws Exception
+   public String getResourceServiceBindingValue(ServiceBinding binding, String input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
       
       StringReplacementServiceBindingValueSourceConfig config = getConfig(binding);      
       
-      String content = Util.getContentAsString(input);
-      String transformed = replaceHostAndPort(content, binding.getHostName(), binding.getPort(), config.getHostMarker(), config.getPortMarker());
-      return Util.writeToTempFile(transformed).getAbsolutePath();
+      try
+      {
+         String content = Util.getContentAsString(input);
+         String transformed = replaceHostAndPort(content, binding.getHostName(), binding.getPort(), config.getHostMarker(), config.getPortMarker());
+         return Util.writeToTempFile(transformed).getAbsolutePath();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException("Caught IOException during transformation", e);
+      }
    }
 
 
-   public URL getURLServiceBindingValue(ServiceBinding binding, URL input) throws Exception
+   public URL getURLServiceBindingValue(ServiceBinding binding, URL input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
       
       StringReplacementServiceBindingValueSourceConfig config = getConfig(binding);      
       
-      String content = Util.getContentAsString(input);
-      String transformed = replaceHostAndPort(content, binding.getHostName(), binding.getPort(), config.getHostMarker(), config.getPortMarker());
-      return Util.writeToTempFile(transformed).toURL();
+      try
+      {
+         String content = Util.getContentAsString(input);
+         String transformed = replaceHostAndPort(content, binding.getHostName(), binding.getPort(), config.getHostMarker(), config.getPortMarker());
+         return Util.writeToTempFile(transformed).toURL();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException("Caught IOException during transformation", e);
+      }
    }
 
-   public Object getServiceBindingValue(ServiceBinding binding, Object... params) throws Exception
+   public Object getServiceBindingValue(ServiceBinding binding, Object... params)
    {
       if (params == null)
       {

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/Util.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/Util.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/Util.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -148,7 +148,7 @@
       return targetFile;
    }
    
-   public static <T> T getBindingValue(ServiceBindingValueSource source, ServiceBinding binding, Class<T> expectedType) throws Exception
+   public static <T> T getBindingValue(ServiceBindingValueSource source, ServiceBinding binding, Class<T> expectedType)
    {
       Object[] params = null;
       Object obj = source.getServiceBindingValue(binding, params);
@@ -162,7 +162,8 @@
       } 
    }
    
-   public static <T> T getBindingValueWithInput(ServiceBindingValueSource source, ServiceBinding binding, Object input, Class<T> expectedType) throws Exception
+   public static <T> T getBindingValueWithInput(ServiceBindingValueSource source, 
+         ServiceBinding binding, Object input, Class<T> expectedType)
    {
       Object obj = source.getServiceBindingValue(binding, input);
       if (expectedType.isAssignableFrom(obj.getClass()))

Modified: trunk/varia/src/main/org/jboss/services/binding/impl/XSLTServiceBindingValueSourceImpl.java
===================================================================
--- trunk/varia/src/main/org/jboss/services/binding/impl/XSLTServiceBindingValueSourceImpl.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/main/org/jboss/services/binding/impl/XSLTServiceBindingValueSourceImpl.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -26,40 +26,45 @@
 import java.beans.PropertyEditorManager;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Map;
 
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
+import org.jboss.logging.Logger;
 import org.jboss.services.binding.ElementServiceBindingValueSource;
 import org.jboss.services.binding.ServiceBinding;
+import org.jboss.services.binding.ServiceBindingValueSource;
 import org.jboss.services.binding.URLServiceBindingValueSource;
 import org.jboss.util.StringPropertyReplacer;
 import org.w3c.dom.Element;
 
 /**
- * A XSLTServiceBindingValueSourceImpl.
+ * A {@link ServiceBindingValueSource} implementation that uses
+ * XSLT to perform any needed transformations.
  * 
+ * 
  * @author Brian Stansberry
  * @version $Revision$
  */
 public class XSLTServiceBindingValueSourceImpl implements URLServiceBindingValueSource, ElementServiceBindingValueSource
 {
-
-   public String getResourceServiceBindingValue(ServiceBinding binding, String input) throws Exception
+   private static final Logger log = Logger.getLogger(XSLTServiceBindingValueSourceImpl.class);
+   
+   public String getResourceServiceBindingValue(ServiceBinding binding, String input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
@@ -67,28 +72,19 @@
       XSLTServiceBindingValueSourceConfig config = getConfig(binding);
       
       Reader reader = null;
-      Writer writer = null;
       try
       {
          reader = Util.getInputStreamReader(input);
-
-         File targetFile = Util.createTempFile();
-         writer = new OutputStreamWriter(new FileOutputStream(targetFile));
-         
-         doXslTransform(binding, config, reader, writer);
-
-         return targetFile.getAbsolutePath();
       }
-      finally
+      catch (IOException e)
       {
-         if (reader != null)
-            reader.close();
-         if (writer != null)
-            writer.close();
+         throw new RuntimeException("Caught IOException during transformation", e);
       }
+      
+      return doFileTransform(input, reader, binding, config).getAbsolutePath();
    }
 
-   public URL getURLServiceBindingValue(ServiceBinding binding, URL input) throws Exception
+   public URL getURLServiceBindingValue(ServiceBinding binding, URL input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
@@ -96,28 +92,26 @@
       XSLTServiceBindingValueSourceConfig config = getConfig(binding);
       
       Reader reader = null;
-      Writer writer = null;
       try
       {
          reader = Util.getInputStreamReader(input);
-
-         File targetFile = Util.createTempFile();
-         writer = new OutputStreamWriter(new FileOutputStream(targetFile));
-         
-         doXslTransform(binding, config, reader, writer);
-
-         return targetFile.toURL();
       }
-      finally
+      catch (IOException e)
       {
-         if (reader != null)
-            reader.close();
-         if (writer != null)
-            writer.close();
+         throw new RuntimeException("Caught IOException during transformation", e);
       }
+      
+      try
+      {
+         return doFileTransform(input, reader, binding, config).toURL();
+      }
+      catch (MalformedURLException e)
+      {
+         throw new RuntimeException("Unexpected exception creating URL from File", e);
+      }
    }
 
-   public Element getElementServiceBindingValue(ServiceBinding binding, Element input) throws Exception
+   public Element getElementServiceBindingValue(ServiceBinding binding, Element input)
    {
       if (input == null)
          throw new IllegalArgumentException("input cannot be null");
@@ -136,7 +130,7 @@
       return (Element) editor.getValue();
    }
 
-   public Object getServiceBindingValue(ServiceBinding binding, Object... params) throws Exception
+   public Object getServiceBindingValue(ServiceBinding binding, Object... params)
    {
       if (params == null || params.length != 1)
       {
@@ -159,6 +153,51 @@
       throw new IllegalArgumentException(getClass().getSimpleName() + ".getServiceBindingValue() requires a single-value 'params' of type String, Element or URL");
    }
    
+   private File doFileTransform(Object input, Reader reader, ServiceBinding binding, 
+         XSLTServiceBindingValueSourceConfig config)
+   {
+      Writer writer = null;
+      File targetFile = null;
+      try
+      {
+         targetFile = Util.createTempFile();
+         writer = new OutputStreamWriter(new FileOutputStream(targetFile));
+         
+         doXslTransform(binding, config, reader, writer);
+
+         return targetFile;
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException("Caught IOException during transformation", e);
+      }
+      finally
+      {
+         if (reader != null)
+         {
+            try
+            {
+               reader.close();
+            }
+            catch (IOException e)
+            {
+               log.warn("Failed closing Reader for " + input, e);
+            }
+         }
+         if (writer != null)
+         {
+            try
+            {
+               writer.close();
+            }
+            catch (IOException e)
+            {
+               log.warn("Failed closing Writer to " + targetFile, e);
+            }
+         }
+      }
+   }
+   
    private XSLTServiceBindingValueSourceConfig getConfig(ServiceBinding binding)
    {
       Object config = binding.getServiceBindingValueSourceConfig();
@@ -176,31 +215,38 @@
    }
 
    private void doXslTransform(ServiceBinding binding, XSLTServiceBindingValueSourceConfig config, 
-         Reader reader, Writer writer) throws TransformerException
+         Reader reader, Writer writer)
    {
       Source xmlSource = new StreamSource(reader);
       Result xmlResult = new StreamResult(writer);         
       Source xslSource = new StreamSource(new StringReader(config.getXslt()));
       
       TransformerFactory factory = TransformerFactory.newInstance();
-      Transformer transformer = factory.newTransformer(xslSource);
-
-      transformer.setParameter("port", new Integer(binding.getPort()));
-      String host = binding.getHostName();
-      if (host != null)
+      try
       {
-         transformer.setParameter("host", host);
+         Transformer transformer = factory.newTransformer(xslSource);
+   
+         transformer.setParameter("port", new Integer(binding.getPort()));
+         String host = binding.getHostName();
+         if (host != null)
+         {
+            transformer.setParameter("host", host);
+         }
+   
+         // Check for any arbitrary attributes
+         Map<String, String> attributes = config.getAdditionalAttributes();
+         for(Map.Entry<String, String> entry : attributes.entrySet())
+         {
+            String attrValue = StringPropertyReplacer.replaceProperties(entry.getValue());
+            transformer.setParameter(entry.getKey(), attrValue);
+         }
+   
+         transformer.transform(xmlSource, xmlResult);
       }
-
-      // Check for any arbitrary attributes
-      Map<String, String> attributes = config.getAdditionalAttributes();
-      for(Map.Entry<String, String> entry : attributes.entrySet())
+      catch (TransformerException e)
       {
-         String attrValue = StringPropertyReplacer.replaceProperties(entry.getValue());
-         transformer.setParameter(entry.getKey(), attrValue);
+         throw new RuntimeException("Caught TransformerException during transformation", e);
       }
-
-      transformer.transform(xmlSource, xmlResult);
    }
 
 }

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingStore.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingStore.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingStore.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,8 +22,8 @@
 
 package org.jboss.test.services.binding.test;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.util.Collections;
+import java.util.Set;
 
 import org.jboss.services.binding.DuplicateServiceException;
 import org.jboss.services.binding.NoSuchBindingException;
@@ -49,11 +49,6 @@
       this.serverName = serverName;
    }
 
-   public void addServiceBinding(String serverName, ServiceBinding binding) throws DuplicateServiceException
-   {
-      throw new UnsupportedOperationException("unimplemented");
-   }
-
    public ServiceBinding getServiceBinding(String serverName, String serviceName, String bindingName)
          throws NoSuchBindingException
    {
@@ -67,6 +62,13 @@
       
       return binding;
    }
+   
+   public Set<ServiceBinding> getServiceBindings(String serverName)
+   {
+      if (this.serverName.equals(serverName) == false)
+         throw new IllegalArgumentException("Invalid serverName " + serverName);
+      return Collections.singleton(binding);
+   }
 
    public void removeServiceBinding(String serverName, ServiceBinding binding)
    {
@@ -78,25 +80,16 @@
       throw new UnsupportedOperationException("unimplemented");
    }
 
-   public void addServiceBinding(ServiceBinding binding) throws DuplicateServiceException
+   public void addServiceBinding(String serverName, ServiceBinding binding) throws DuplicateServiceException
    {
       if (this.binding != null)
          throw new IllegalStateException("MockServiceBindingStore already has a binding");
+      if (this.serverName.equals(serverName) == false)
+         throw new IllegalArgumentException("Invalid serverName " + serverName);
+      
       this.binding = binding;
    }
 
-   public InetAddress getDefaultBindAddress(String serverName)
-   {      
-      try
-      {
-         return InetAddress.getByName(HOSTNAME);
-      }
-      catch (UnknownHostException e)
-      {
-         throw new IllegalStateException("Can't create InetAddress for " + HOSTNAME, e);
-      }
-   }
-
    public String getDefaultHostName(String serverName)
    {      
       return HOSTNAME;
@@ -107,18 +100,6 @@
       return 1000;
    }
 
-   public void removeServiceBinding(ServiceBinding binding)
-   {
-      // TODO Auto-generated method stub
-      
-   }
-
-   public void removeServiceBinding(String serviceName, String bindingName)
-   {
-      // TODO Auto-generated method stub
-      
-   }
-
    /**
     * Set the binding.
     * 

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingValueSource.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingValueSource.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/MockServiceBindingValueSource.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -47,7 +47,7 @@
       this.returnValue = returnValue;
    }
 
-   public Object getServiceBindingValue(ServiceBinding binding, Object... params) throws Exception
+   public Object getServiceBindingValue(ServiceBinding binding, Object... params)
    {
       this.params = params;
       return returnValue;

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/PojoServiceBindingStoreUnitTestCase.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/PojoServiceBindingStoreUnitTestCase.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/PojoServiceBindingStoreUnitTestCase.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -24,14 +24,13 @@
 
 import java.net.InetAddress;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import junit.framework.TestCase;
 
 import org.jboss.services.binding.DuplicateServiceException;
+import org.jboss.services.binding.ManagedServiceBinding;
 import org.jboss.services.binding.NoSuchBindingException;
 import org.jboss.services.binding.ServiceBinding;
 import org.jboss.services.binding.impl.PojoServiceBindingStore;
@@ -50,11 +49,13 @@
    private static final String C = "C";
    private static final String D = "D";
    
-   private static ServiceBinding AA;
-   private static ServiceBinding AB;
-   private static ServiceBinding Anull;
+   private static ManagedServiceBinding AA;
+   private static ManagedServiceBinding AB;
+   private static ManagedServiceBinding Anull;
+   private static ManagedServiceBinding BA;
    
-   private Map<String, ServiceBindingSet> bindings = new HashMap<String, ServiceBindingSet>();
+   private Set<ManagedServiceBinding> bindings = new HashSet<ManagedServiceBinding>();
+   private Set<ServiceBindingSet> bindingSets = new HashSet<ServiceBindingSet>();
    
    /**
     * Create a new PojoServiceBindingStoreUnitTestCase.
@@ -70,21 +71,29 @@
    {
       super.setUp();
       
-      AA = new ServiceBinding(A, A, "localhost", 1);
-      AB = new ServiceBinding(A, B, "localhost", 1);
-      Anull = new ServiceBinding(A, null, "localhost", 1);
+      AA = new ManagedServiceBinding(A, A, "localhost", 1);
+      bindings.add(AA);
+      AB = new ManagedServiceBinding(A, B, "localhost", 1);
+      bindings.add(AB);
+      Anull = new ManagedServiceBinding(A, null, "localhost", 1);
+      bindings.add(Anull);
       
-      Set<ServiceBinding> set = new HashSet<ServiceBinding>();
+      // This one doesn't go in the standard bindings set
+      BA = new ManagedServiceBinding(B, A, "localhost", 1);
+      
+      Set<ManagedServiceBinding> set = new HashSet<ManagedServiceBinding>();
       set.addAll(Arrays.asList(AA, AB, Anull));
-      ServiceBindingSet sbs = new ServiceBindingSet(set);
-      bindings.put(A, sbs);
-      bindings.put(B, sbs);
-      bindings.put(C, sbs);
+      bindingSets.add(new ServiceBindingSet(A));
+      bindingSets.add(new ServiceBindingSet(B));
+      bindingSets.add(new ServiceBindingSet(C));
    }
    
    public void testGetServiceBinding() throws Exception
    {
-      PojoServiceBindingStore store = new PojoServiceBindingStore(bindings);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();      
+      store.setServiceBindingSets(bindingSets);
+      store.setPortOffsetBindings(bindings);
+      store.start();
       
       assertEquals(AA, store.getServiceBinding(A, A, A));      
       assertEquals(AA, store.getServiceBinding(B, A, A));     
@@ -122,7 +131,10 @@
    
    public void testAddServiceBinding() throws Exception
    {
-      PojoServiceBindingStore store = new PojoServiceBindingStore(bindings);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();      
+      store.setServiceBindingSets(bindingSets);
+      store.setPortOffsetBindings(bindings);
+      store.start();
       
       ServiceBinding new1 = new ServiceBinding(B, A, "localhost", 1);
       store.addServiceBinding(A, new1);
@@ -151,7 +163,10 @@
    
    public void testRemoveServiceBinding() throws Exception
    {
-      PojoServiceBindingStore store = new PojoServiceBindingStore(bindings);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();      
+      store.setServiceBindingSets(bindingSets);
+      store.setPortOffsetBindings(bindings);
+      store.start();
       
       store.removeServiceBinding(A, AA);
       
@@ -162,7 +177,7 @@
       }
       catch (NoSuchBindingException e) {}
       
-      store.removeServiceBinding(B, A, A);
+      store.removeServiceBinding(B, AA);
       
       try
       {
@@ -180,7 +195,7 @@
       }
       catch (NoSuchBindingException e) {}
       
-      store.removeServiceBinding(B, A, null);
+      store.removeServiceBinding(B, Anull);
       
       try
       {
@@ -191,30 +206,27 @@
       
       ServiceBinding new1 = new ServiceBinding(B, A, "localhost", 1);
       store.removeServiceBinding(A, new1);
-      store.removeServiceBinding(A, B, A);
+      store.removeServiceBinding(A, BA);
    }
    
    
    public void testAddServiceBindingToAll() throws Exception
    {
-      Set<ServiceBinding> set = new HashSet<ServiceBinding>();
+      Set<ManagedServiceBinding> set = new HashSet<ManagedServiceBinding>();
       set.addAll(Arrays.asList(AA, AB, Anull));
       
-      ServiceBindingSet sbs = new ServiceBindingSet(set, 10, null); 
-      Map<String, ServiceBindingSet> map = new HashMap<String, ServiceBindingSet>();
-      map.put(A, sbs);
+      Set<ServiceBindingSet> ourSets = new HashSet<ServiceBindingSet>();
+      ourSets.add(new ServiceBindingSet(A, null, 10, set));      
+      ourSets.add(new ServiceBindingSet(B, "localhost", 20, set));
+      ourSets.add(new ServiceBindingSet(C, "192.168.0.10", 30, set));
       
-      sbs = new ServiceBindingSet(set, 20, "localhost"); 
-      map.put(B, sbs);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();
+      store.setServiceBindingSets(ourSets);
+      store.start();
       
-      sbs = new ServiceBindingSet(set, 30, "192.168.0.10"); 
-      map.put(C, sbs);
+      ManagedServiceBinding new1 = new ManagedServiceBinding(B, A, "192.168.0.22", 1);
+      store.addServiceBinding(new1, false);
       
-      PojoServiceBindingStore store = new PojoServiceBindingStore(map);
-      
-      ServiceBinding new1 = new ServiceBinding(B, A, "192.168.0.22", 1);
-      store.addServiceBinding(new1);
-      
       InetAddress address = InetAddress.getByName("192.168.0.22");
       
       ServiceBinding got = store.getServiceBinding(A, B, A);
@@ -230,21 +242,21 @@
       assertEquals(address, got.getBindAddress());
       
       got = store.getServiceBinding(C, B, A);
-      assertEquals(new1, got);    
+      assertEquals(new1, got);
       assertEquals(31, got.getPort());
       assertEquals("192.168.0.22", got.getHostName());
       assertEquals(address, got.getBindAddress());
       
-      ServiceBinding new2 = new ServiceBinding(B, A, "localhost", 2);
+      ManagedServiceBinding new2 = new ManagedServiceBinding(B, A, "localhost", 2);
       try
       {
-         store.addServiceBinding(new2); 
+         store.addServiceBinding(new2, false); 
          fail("duplicate add succeeded");
       }
       catch (DuplicateServiceException good) {}
       
-      ServiceBinding new3 = new ServiceBinding(C, C, null, 3);
-      store.addServiceBinding(new3);
+      ManagedServiceBinding new3 = new ManagedServiceBinding(C, C, null, 3);
+      store.addServiceBinding(new3, false);
       
       got = store.getServiceBinding(A, C, C);
       assertEquals(new3, got);    
@@ -268,7 +280,10 @@
    
    public void testRemoveServiceBindingFromAll() throws Exception
    {
-      PojoServiceBindingStore store = new PojoServiceBindingStore(bindings);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();      
+      store.setServiceBindingSets(bindingSets);
+      store.setPortOffsetBindings(bindings);
+      store.start();
       
       store.removeServiceBinding(AA);
       
@@ -279,7 +294,7 @@
       }
       catch (NoSuchBindingException e) {}
       
-      store.removeServiceBinding(B, A, A);
+      store.removeServiceBinding(B, AA);
       
       try
       {
@@ -319,52 +334,48 @@
       }
       catch (NoSuchBindingException e) {}
       
-      ServiceBinding new1 = new ServiceBinding(B, A, "localhost", 1);
+      ManagedServiceBinding new1 = new ManagedServiceBinding(B, A, "localhost", 1);
       store.removeServiceBinding(new1);
       store.removeServiceBinding(B, A);
    }
    
    public void testDefaultDefaults() throws Exception
    {
-      PojoServiceBindingStore store = new PojoServiceBindingStore(bindings);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();      
+      store.setServiceBindingSets(bindingSets);
+      store.setPortOffsetBindings(bindings);
+      store.start();
       
       String[] names = {A, B, C};
       
       for (String name :names)
       {
          assertNull(store.getDefaultHostName(name));
-         assertNull(store.getDefaultBindAddress(name));
          assertEquals(0, store.getDefaultPortOffset(name));
       }
    }
    
    public void testDefaults() throws Exception
    {
-      Set<ServiceBinding> set = new HashSet<ServiceBinding>();
+      Set<ManagedServiceBinding> set = new HashSet<ManagedServiceBinding>();
       set.addAll(Arrays.asList(AA, AB, Anull));
       
-      ServiceBindingSet sbs = new ServiceBindingSet(set, 10, null); 
-      Map<String, ServiceBindingSet> map = new HashMap<String, ServiceBindingSet>();
-      map.put(A, sbs);
+      Set<ServiceBindingSet> sbs = new HashSet<ServiceBindingSet>();
+      sbs.add(new ServiceBindingSet(A, null, 10, set));
+      sbs.add(new ServiceBindingSet(B, "localhost", 20, set));      
+      sbs.add(new ServiceBindingSet(C, "192.168.0.10", 30, set));
       
-      sbs = new ServiceBindingSet(set, 20, "localhost"); 
-      map.put(B, sbs);
+      PojoServiceBindingStore store = new PojoServiceBindingStore();
+      store.setServiceBindingSets(sbs);
+      store.start();
       
-      sbs = new ServiceBindingSet(set, 30, "192.168.0.10"); 
-      map.put(C, sbs);
-      
-      PojoServiceBindingStore store = new PojoServiceBindingStore(map);
-      
       assertNull(store.getDefaultHostName(A));
-      assertNull(store.getDefaultBindAddress(A));
       assertEquals(10, store.getDefaultPortOffset(A));
       
       assertEquals("localhost", store.getDefaultHostName(B));
-      assertEquals(InetAddress.getByName("localhost"), store.getDefaultBindAddress(B));
       assertEquals(20, store.getDefaultPortOffset(B));
       
       assertEquals("192.168.0.10", store.getDefaultHostName(C));
-      assertEquals(InetAddress.getByName("192.168.0.10"), store.getDefaultBindAddress(C));
       assertEquals(30, store.getDefaultPortOffset(C));
    }
    

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingManagerUnitTestCase.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingManagerUnitTestCase.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingManagerUnitTestCase.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -98,9 +98,9 @@
    public void testGetIntBindingNoBinding() throws Exception
    {
       mockStore.setBinding(null);
-      assertEquals(binding.getPort(), testee.getIntBinding(SVC_NAME, BINDING_NAME, binding.getHostName(), binding.getPort()));
+      assertEquals(binding.getPort() + mockStore.getDefaultPortOffset(SERVER), testee.getIntBinding(SVC_NAME, BINDING_NAME, binding.getHostName(), binding.getPort()));
       mockStore.setBinding(null);
-      assertEquals(binding.getPort(), testee.getIntBinding(SVC_NAME, BINDING_NAME, null, binding.getPort()));
+      assertEquals(binding.getPort() + mockStore.getDefaultPortOffset(SERVER), testee.getIntBinding(SVC_NAME, BINDING_NAME, null, binding.getPort()));
    }
 
 
@@ -136,7 +136,7 @@
       mockStore.setBinding(null);
       assertEquals(binding.getBindAddress(), testee.getInetAddressBinding(SVC_NAME, BINDING_NAME, binding.getHostName(), binding.getPort()));
       mockStore.setBinding(null);
-      assertEquals(InetAddress.getByName(null), testee.getInetAddressBinding(SVC_NAME, BINDING_NAME, null, binding.getPort()));
+      assertEquals(InetAddress.getByName(mockStore.getDefaultHostName(SERVER)), testee.getInetAddressBinding(SVC_NAME, BINDING_NAME, null, binding.getPort()));
    }
 
    /**
@@ -172,7 +172,7 @@
       mockStore.setBinding(null);
       assertEquals(binding.getHostName(), testee.getStringBinding(SVC_NAME, BINDING_NAME, INPUT, binding.getHostName(), binding.getPort()));
       mockStore.setBinding(null);
-      assertEquals(InetAddress.getByName(null).getHostName(), testee.getStringBinding(SVC_NAME, BINDING_NAME, INPUT, null, binding.getPort()));
+      assertEquals(InetAddress.getByName(mockStore.getDefaultHostName(SERVER)).getHostName(), testee.getStringBinding(SVC_NAME, BINDING_NAME, INPUT, null, binding.getPort()));
    }
 
    /**
@@ -185,7 +185,7 @@
       editor.setAsText(ELEMENT_INPUT);
       Element input = (Element) editor.getValue();
       Element output = testee.getElementBinding(SVC_NAME, input);
-      validateOutputElement(output);
+      validateOutputElement(output, false, false);
    }
 
    /**
@@ -230,13 +230,11 @@
       editor.setAsText(ELEMENT_INPUT);
       Element input = (Element) editor.getValue();
       Element output = testee.getElementBinding(SVC_NAME, BINDING_NAME, input, binding.getHostName(), binding.getPort());
-      validateOutputElement(output);
+      validateOutputElement(output, false, true);
+      
       mockStore.setBinding(null);
       output =  testee.getElementBinding(SVC_NAME, BINDING_NAME, input, null, binding.getPort());
-
-      assertNotNull(output);
-      assertEquals("localhost", output.getAttribute("host"));
-      assertEquals(String.valueOf(PORT), output.getFirstChild().getNodeValue());
+      validateOutputElement(output, true, true);
    }
 
    /**
@@ -297,15 +295,14 @@
       URL output = testee.getURLBinding(SVC_NAME, BINDING_NAME, input, binding.getHostName(), binding.getPort());
       assertNotNull(output);
       Element element = getDocumentElement(output);
-      validateOutputElement(element);     
+      validateOutputElement(element, false, true);     
       
       mockStore.setBinding(null);
       output = testee.getURLBinding(SVC_NAME, BINDING_NAME, input, null, binding.getPort());
 
       assertNotNull(output);
       element = getDocumentElement(output);
-      assertEquals("localhost", element.getAttribute("host"));
-      assertEquals(String.valueOf(PORT), element.getFirstChild().getNodeValue());
+      validateOutputElement(element, true, true);  
    }
 
    /**
@@ -361,15 +358,14 @@
       String output = testee.getResourceBinding(SVC_NAME, BINDING_NAME, input, binding.getHostName(), binding.getPort());
       assertNotNull(output);
       Element element = getDocumentElement(output);
-      validateOutputElement(element);     
+      validateOutputElement(element, false, true);     
       
       mockStore.setBinding(null);
       output = testee.getResourceBinding(SVC_NAME, BINDING_NAME, input, null, binding.getPort());
 
       assertNotNull(output);
       element = getDocumentElement(output);
-      assertEquals("localhost", element.getAttribute("host"));
-      assertEquals(String.valueOf(PORT), element.getFirstChild().getNodeValue());
+      validateOutputElement(element, true, true);  
    }
 
    /**
@@ -411,5 +407,13 @@
       }
       catch (IllegalStateException good) {}
    }
+   
+   protected void validateOutputElement(Element output, boolean expectDefaultHost, boolean expectOffset)
+   {
+      assertNotNull(output);
+      assertEquals(expectDefaultHost ? mockStore.getDefaultHostName(SERVER) : HOST, output.getAttribute("host"));
+      int expectedPort = PORT + (expectOffset ? mockStore.getDefaultPortOffset(SERVER) : 0); 
+      assertEquals(String.valueOf(expectedPort), output.getFirstChild().getNodeValue());
+   }
 
 }

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingSetUnitTestCase.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingSetUnitTestCase.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingSetUnitTestCase.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,7 +22,6 @@
 
 package org.jboss.test.services.binding.test;
 
-import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -30,6 +29,7 @@
 
 import junit.framework.TestCase;
 
+import org.jboss.services.binding.ManagedServiceBinding;
 import org.jboss.services.binding.ServiceBinding;
 import org.jboss.services.binding.impl.ServiceBindingSet;
 
@@ -44,11 +44,11 @@
    private static final String A = "A";
    private static final String B = "B";
    
-   private static ServiceBinding AA;
-   private static ServiceBinding AB;
-   private static ServiceBinding Anull;
+   private static ManagedServiceBinding AA;
+   private static ManagedServiceBinding AB;
+   private static ManagedServiceBinding Anull;
 
-   private Set<ServiceBinding> bindings = new HashSet<ServiceBinding>();
+   private Set<ManagedServiceBinding> bindings = new HashSet<ManagedServiceBinding>();
    
    /**
     * Create a new ServiceBindingSetUnitTestCase.
@@ -64,17 +64,20 @@
    {
       super.setUp();
       
-      AA = new ServiceBinding(A, A, "localhost", 1);
-      AB = new ServiceBinding(A, B, "localhost", 1);
-      Anull = new ServiceBinding(A, null, "localhost", 1);
+      AA = new ManagedServiceBinding(A, A, "localhost", 1);
+      AB = new ManagedServiceBinding(A, B, "localhost", 1);
+      Anull = new ManagedServiceBinding(A, null, "localhost", 1);
       
       bindings.addAll(Arrays.asList(AA, AB, Anull));
    }
    
    public void testBasicConstructor() throws UnknownHostException
    {
-      ServiceBindingSet set = new ServiceBindingSet(bindings);
-      for (ServiceBinding binding : set)
+      ServiceBindingSet set = new ServiceBindingSet(A, new HashSet<ManagedServiceBinding>(bindings));
+      
+      assertEquals(A, set.getName());
+      
+      for (ServiceBinding binding : set.getOverrideBindings())
       {
          assertEquals(1, binding.getPort());
          assertTrue(bindings.remove(binding));
@@ -83,7 +86,6 @@
       assertEquals(0, bindings.size());
       
       assertNull(set.getDefaultHostName());
-      assertNull(set.getDefaultBindAddress());
       assertEquals(0, set.getPortOffset());
    }
 
@@ -93,33 +95,31 @@
     */
    public void testOffsetConstructor() throws UnknownHostException
    {
-      ServiceBindingSet set = new ServiceBindingSet(bindings, 5);
-      for (ServiceBinding binding : set)
-      {
-         assertEquals(6, binding.getPort());
-         assertTrue(bindings.remove(binding));
-      }
+      ServiceBindingSet set = new ServiceBindingSet(A, 5);
       
-      assertEquals(0, bindings.size());
+      assertEquals(A, set.getName());
       
+      assertEquals(0, set.getOverrideBindings().size());
+      
       assertNull(set.getDefaultHostName());
-      assertNull(set.getDefaultBindAddress());
       assertEquals(5, set.getPortOffset());
    }
    
    public void testOffsetConstructorWithDefaultHost() throws UnknownHostException
    {
-      ServiceBindingSet set = new ServiceBindingSet(bindings, 5, "192.168.0.10");
-      for (ServiceBinding binding : set)
+      ServiceBindingSet set = new ServiceBindingSet(A, "192.168.0.10", 5, new HashSet<ManagedServiceBinding>(bindings));
+      
+      assertEquals(A, set.getName());
+      
+      for (ServiceBinding binding : set.getOverrideBindings())
       {
-         assertEquals(6, binding.getPort());
+         assertEquals(1, binding.getPort());
          assertTrue(bindings.remove(binding));
       }
       
       assertEquals(0, bindings.size());
       
       assertEquals("192.168.0.10", set.getDefaultHostName());
-      assertEquals(InetAddress.getByName("192.168.0.10"), set.getDefaultBindAddress());
       assertEquals(5, set.getPortOffset());
    }
 
@@ -129,26 +129,17 @@
     */
    public void testOverrideConstructor() throws UnknownHostException
    {
-      ServiceBinding bb = new ServiceBinding(B, B, "localhost", 1);
-      Set<ServiceBinding> overrides = new HashSet<ServiceBinding>();
-      overrides.add(bb);
-      overrides.add(AA);
-      
-      ServiceBindingSet set = new ServiceBindingSet(bindings, 10, overrides, "192.168.0.10");
-      for (ServiceBinding binding : set)
+      ServiceBindingSet set = new ServiceBindingSet(A, new HashSet<ManagedServiceBinding>(bindings));
+      for (ServiceBinding binding : set.getOverrideBindings())
       {         
-         boolean override = overrides.remove(binding);
-         assertEquals(override ? 1 : 11, binding.getPort());
-         assertTrue(bindings.remove(binding) || override);
+         assertTrue(bindings.remove(binding));
          
       }
       
-      assertEquals(0, overrides.size());
       assertEquals(0, bindings.size());
       
-      assertEquals("192.168.0.10", set.getDefaultHostName());
-      assertEquals(InetAddress.getByName("192.168.0.10"), set.getDefaultBindAddress());
-      assertEquals(10, set.getPortOffset());
+      assertEquals(null, set.getDefaultHostName());
+      assertEquals(0, set.getPortOffset());
    }
 
 }

Modified: trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingUnitTestCase.java
===================================================================
--- trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingUnitTestCase.java	2008-11-29 13:25:13 UTC (rev 81805)
+++ trunk/varia/src/tests/org/jboss/test/services/binding/test/ServiceBindingUnitTestCase.java	2008-11-29 14:25:37 UTC (rev 81806)
@@ -22,6 +22,8 @@
 
 package org.jboss.test.services.binding.test;
 
+import java.net.InetAddress;
+
 import org.jboss.services.binding.ServiceBinding;
 import org.jboss.services.binding.impl.XSLTServiceBindingValueSourceImpl;
 
@@ -88,6 +90,38 @@
    }
 
    /**
+    * Test method for {@link org.jboss.services.binding.ServiceBinding#getOffsetBinding(int, String)}.
+    */
+   public void testGetOffsetBindingWithHost() throws Exception
+   {
+      ServiceBinding binding = new ServiceBinding("svc", "binding", "192.168.0.2", 1);
+      String className = XSLTServiceBindingValueSourceImpl.class.getName();
+      binding.setServiceBindingValueSourceClassName(className);
+      
+      ServiceBinding binding2 = binding.getOffsetBinding(10, "192.168.0.3");
+      assertEquals(binding.getServiceName(), binding2.getServiceName());
+      assertEquals(binding.getBindingName(), binding2.getBindingName());
+      assertEquals(binding.getHostName(), binding2.getHostName());
+      assertEquals(binding.getBindAddress(), binding2.getBindAddress());
+      
+      assertEquals(1, binding.getPort());
+      assertEquals(11, binding2.getPort());
+      
+      binding = new ServiceBinding("svc", "binding", null, 1);
+      className = XSLTServiceBindingValueSourceImpl.class.getName();
+      binding.setServiceBindingValueSourceClassName(className);
+      
+      binding2 = binding.getOffsetBinding(10, "192.168.0.3");
+      assertEquals(binding.getServiceName(), binding2.getServiceName());
+      assertEquals(binding.getBindingName(), binding2.getBindingName());
+      assertEquals("192.168.0.3", binding2.getHostName());
+      assertEquals(InetAddress.getByName("192.168.0.3"), binding2.getBindAddress());
+      
+      assertEquals(1, binding.getPort());
+      assertEquals(11, binding2.getPort());
+   }
+
+   /**
     * Test method for {@link org.jboss.services.binding.ServiceBinding#equals(java.lang.Object)}.
     */
    public void testEquals() throws Exception




More information about the jboss-cvs-commits mailing list