[jboss-svn-commits] JBL Code SVN: r25050 - in labs/jbosstm/trunk: common/classes/com/arjuna/common/internal/util/propertyservice/plugins/io and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Feb 2 07:38:31 EST 2009


Author: jhalliday
Date: 2009-02-02 07:38:31 -0500 (Mon, 02 Feb 2009)
New Revision: 25050

Added:
   labs/jbosstm/trunk/common/classes/com/arjuna/common/util/propertyservice/StringPropertyReplacer.java
Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml
   labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/plugins/io/XMLFilePlugin.java
Log:
Added string property substitution to xml config file parsing. JBTM-369


Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml	2009-02-02 12:09:58 UTC (rev 25049)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/etc/default-arjuna-properties.xml	2009-02-02 12:38:31 UTC (rev 25050)
@@ -30,6 +30,39 @@
 <transaction-service
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="transaction-service-2_0.xsd">
+    <properties name="documentation">
+        <!--
+        This is the JBossTS configuration file. Note that starting with JBossTS 4.6
+        the names jbossjta-properties.xml and jbossjts-properties.xml are obsolete.
+        
+        Both the JTA and JTS versions of JBossTS now read their configuration from
+        jbossts-properties.xml, although the contents of the file differs between
+        the JTA and JTS. Care should be taken to use the correct version of the file.
+        
+        ***************************
+        
+        Property values may be literals or be tokens of the form ${p1[,p2][:v]}
+        in which case the token values are substituted for the values of the corresponding system
+        properties as follows:
+ 
+        - Any occurance of ${p} with the System.getProperty(p) value.
+        If there is no such property p defined, then the ${p} reference will remain unchanged.
+
+        - If the property reference is of the form ${p:v} and there is no such property p,
+        then the default value v will be returned.
+
+        - If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
+        the primary and the secondary properties will be tried in turn, before
+        returning either the unchanged input, or the default value.
+        
+        The property ${/} is replaced with System.getProperty("file.separator")
+        value and the property ${:} is replaced with System.getProperty("path.separator").
+        
+        Note this substitution applies to property values only at the point they are read from
+        the config file. Tokens in system properties won't be substituted.
+        -->
+    </properties>
+    
     <properties name="arjuna" depends="common">
       <!--
         Transaction Reaper Timeout (default is 120000 ms).

Modified: labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/plugins/io/XMLFilePlugin.java
===================================================================
--- labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/plugins/io/XMLFilePlugin.java	2009-02-02 12:09:58 UTC (rev 25049)
+++ labs/jbosstm/trunk/common/classes/com/arjuna/common/internal/util/propertyservice/plugins/io/XMLFilePlugin.java	2009-02-02 12:38:31 UTC (rev 25050)
@@ -24,6 +24,7 @@
 import com.arjuna.common.util.propertyservice.propertycontainer.PropertyManagerPluginInterface;
 import com.arjuna.common.util.exceptions.LoadPropertiesException;
 import com.arjuna.common.util.propertyservice.PropertyManager;
+import com.arjuna.common.util.propertyservice.StringPropertyReplacer;
 import com.arjuna.common.util.FileLocator;
 import com.arjuna.common.util.exceptions.SavePropertiesException;
 
@@ -179,6 +180,9 @@
 							{
 								System.out.println( propertyName +"="+ propertyValue );
 							}
+                            
+                            // perform JBossAS style property substitutions. JBTM-369
+                            propertyValue = StringPropertyReplacer.replaceProperties(propertyValue);
 
 							/** Set the property but don't allow any system property to be overridden **/
 							pm.setProperty(propertyName, propertyValue, false);

Added: labs/jbosstm/trunk/common/classes/com/arjuna/common/util/propertyservice/StringPropertyReplacer.java
===================================================================
--- labs/jbosstm/trunk/common/classes/com/arjuna/common/util/propertyservice/StringPropertyReplacer.java	                        (rev 0)
+++ labs/jbosstm/trunk/common/classes/com/arjuna/common/util/propertyservice/StringPropertyReplacer.java	2009-02-02 12:38:31 UTC (rev 25050)
@@ -0,0 +1,268 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt 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 com.arjuna.common.util.propertyservice;
+
+// copied into the com.arjuna namespace from org.jboss.util
+// as we don't want JBossTS to depend on JBoss common-core just for this one class.
+// original version is jboss-common-core 2.2.8.GA
+// https://svn.jboss.org/repos/common/common-core/tags/2.2.8.GA/src/main/java/org/jboss/util/StringPropertyReplacer.java
+
+import java.util.Properties;
+import java.io.File;
+
+/**
+ * A utility class for replacing properties in strings.
+ *
+ * @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
+ * @author <a href="Scott.Stark at jboss.org">Scott Stark</a>
+ * @author <a href="claudio.vesco at previnet.it">Claudio Vesco</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="mailto:dimitris at jboss.org">Dimitris Andreadis</a>
+ * @version <tt>$Revision$</tt>
+ */
+public final class StringPropertyReplacer
+{
+   /** New line string constant */
+   public static final String NEWLINE = System.getProperty("line.separator", "\n");
+
+   /** File separator value */
+   private static final String FILE_SEPARATOR = File.separator;
+
+   /** Path separator value */
+   private static final String PATH_SEPARATOR = File.pathSeparator;
+
+   /** File separator alias */
+   private static final String FILE_SEPARATOR_ALIAS = "/";
+
+   /** Path separator alias */
+   private static final String PATH_SEPARATOR_ALIAS = ":";
+
+   // States used in property parsing
+   private static final int NORMAL = 0;
+   private static final int SEEN_DOLLAR = 1;
+   private static final int IN_BRACKET = 2;
+
+   /**
+    * Go through the input string and replace any occurance of ${p} with
+    * the System.getProperty(p) value. If there is no such property p defined,
+    * then the ${p} reference will remain unchanged.
+    *
+    * If the property reference is of the form ${p:v} and there is no such property p,
+    * then the default value v will be returned.
+    *
+    * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
+    * the primary and the secondary properties will be tried in turn, before
+    * returning either the unchanged input, or the default value.
+    *
+    * The property ${/} is replaced with System.getProperty("file.separator")
+    * value and the property ${:} is replaced with System.getProperty("path.separator").
+    *
+    * @param string - the string with possible ${} references
+    * @return the input string with all property references replaced if any.
+    *    If there are no valid references the input string will be returned.
+    */
+   public static String replaceProperties(final String string)
+   {
+      return replaceProperties(string, null);
+   }
+
+   /**
+    * Go through the input string and replace any occurance of ${p} with
+    * the props.getProperty(p) value. If there is no such property p defined,
+    * then the ${p} reference will remain unchanged.
+    *
+    * If the property reference is of the form ${p:v} and there is no such property p,
+    * then the default value v will be returned.
+    *
+    * If the property reference is of the form ${p1,p2} or ${p1,p2:v} then
+    * the primary and the secondary properties will be tried in turn, before
+    * returning either the unchanged input, or the default value.
+    *
+    * The property ${/} is replaced with System.getProperty("file.separator")
+    * value and the property ${:} is replaced with System.getProperty("path.separator").
+    *
+    * @param string - the string with possible ${} references
+    * @param props - the source for ${x} property ref values, null means use System.getProperty()
+    * @return the input string with all property references replaced if any.
+    *    If there are no valid references the input string will be returned.
+    */
+   public static String replaceProperties(final String string, final Properties props)
+   {
+      final char[] chars = string.toCharArray();
+      StringBuffer buffer = new StringBuffer();
+      boolean properties = false;
+      int state = NORMAL;
+      int start = 0;
+      for (int i = 0; i < chars.length; ++i)
+      {
+         char c = chars[i];
+
+         // Dollar sign outside brackets
+         if (c == '$' && state != IN_BRACKET)
+            state = SEEN_DOLLAR;
+
+         // Open bracket immediatley after dollar
+         else if (c == '{' && state == SEEN_DOLLAR)
+         {
+            buffer.append(string.substring(start, i - 1));
+            state = IN_BRACKET;
+            start = i - 1;
+         }
+
+         // No open bracket after dollar
+         else if (state == SEEN_DOLLAR)
+            state = NORMAL;
+
+         // Closed bracket after open bracket
+         else if (c == '}' && state == IN_BRACKET)
+         {
+            // No content
+            if (start + 2 == i)
+            {
+               buffer.append("${}"); // REVIEW: Correct?
+            }
+            else // Collect the system property
+            {
+               String value = null;
+
+               String key = string.substring(start + 2, i);
+
+               // check for alias
+               if (FILE_SEPARATOR_ALIAS.equals(key))
+               {
+                  value = FILE_SEPARATOR;
+               }
+               else if (PATH_SEPARATOR_ALIAS.equals(key))
+               {
+                  value = PATH_SEPARATOR;
+               }
+               else
+               {
+                  // check from the properties
+                  if (props != null)
+                     value = props.getProperty(key);
+                  else
+                     value = System.getProperty(key);
+
+                  if (value == null)
+                  {
+                     // Check for a default value ${key:default}
+                     int colon = key.indexOf(':');
+                     if (colon > 0)
+                     {
+                        String realKey = key.substring(0, colon);
+                        if (props != null)
+                           value = props.getProperty(realKey);
+                        else
+                           value = System.getProperty(realKey);
+
+                        if (value == null)
+                        {
+                           // Check for a composite key, "key1,key2"
+                           value = resolveCompositeKey(realKey, props);
+
+                           // Not a composite key either, use the specified default
+                           if (value == null)
+                              value = key.substring(colon+1);
+                        }
+                     }
+                     else
+                     {
+                        // No default, check for a composite key, "key1,key2"
+                        value = resolveCompositeKey(key, props);
+                     }
+                  }
+               }
+
+               if (value != null)
+               {
+                  properties = true;
+                  buffer.append(value);
+               }
+               else
+               {
+                  buffer.append("${");
+                  buffer.append(key);
+                  buffer.append('}');
+               }
+
+            }
+            start = i + 1;
+            state = NORMAL;
+         }
+      }
+
+      // No properties
+      if (properties == false)
+         return string;
+
+      // Collect the trailing characters
+      if (start != chars.length)
+         buffer.append(string.substring(start, chars.length));
+
+      // Done
+      return buffer.toString();
+   }
+
+   /**
+    * Try to resolve a "key" from the provided properties by
+    * checking if it is actually a "key1,key2", in which case
+    * try first "key1", then "key2". If all fails, return null.
+    *
+    * It also accepts "key1," and ",key2".
+    *
+    * @param key the key to resolve
+    * @param props the properties to use
+    * @return the resolved key or null
+    */
+   private static String resolveCompositeKey(String key, Properties props)
+   {
+      String value = null;
+
+      // Look for the comma
+      int comma = key.indexOf(',');
+      if (comma > -1)
+      {
+         // If we have a first part, try resolve it
+         if (comma > 0)
+         {
+            // Check the first part
+            String key1 = key.substring(0, comma);
+            if (props != null)
+               value = props.getProperty(key1);
+            else
+               value = System.getProperty(key1);
+         }
+         // Check the second part, if there is one and first lookup failed
+         if (value == null && comma < key.length() - 1)
+         {
+            String key2 = key.substring(comma + 1);
+            if (props != null)
+               value = props.getProperty(key2);
+            else
+               value = System.getProperty(key2);
+         }
+      }
+      // Return whatever we've found or null
+      return value;
+   }
+}
\ No newline at end of file




More information about the jboss-svn-commits mailing list