001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.util;
016:
017: import java.util.Iterator;
018: import java.util.Map;
019: import java.util.Properties;
020:
021: /** Useful collection utilities class */
022: public class PropertiesUtils {
023: /** Returns the value of the specified property if it is present in the specified bag or throws Exception
024: * @param pPropertyName the name of the property lo look for
025: * @param pPropertiesSource the properties bag to look in for the property in
026: * @exception IllegalArgumentException thrown if value for the property is not present in the supplied property bag */
027: public static String getMandatoryProperty(String pPropertyName,
028: Properties pPropertiesSource)
029: throws IllegalArgumentException {
030: if (!pPropertiesSource.containsKey(pPropertyName))
031: throw new IllegalArgumentException(
032: "Value of the '"
033: + pPropertyName
034: + "' property is not defined in the given collection of properties.");
035: return pPropertiesSource.getProperty(pPropertyName);
036: }
037:
038: /** Returns the value of the specified property if it is present in the system properties or throws Exception
039: * @param pPropertyName the name of the property lo look for
040: * @param pPropertiesSource the properties bag to look in for the property in
041: * @exception IllegalArgumentException thrown if value for the property is not present in the supplied property bag */
042: public static String getMandatorySystemProperty(String pPropertyName)
043: throws IllegalArgumentException {
044: Properties lProperties = System.getProperties();
045: if (!lProperties.containsKey(pPropertyName))
046: throw new IllegalArgumentException(
047: "Value of the '"
048: + pPropertyName
049: + "' property is not defined in the system properties.");
050: return lProperties.getProperty(pPropertyName);
051: }
052:
053: /** Returns bag of properties, which is a subset of the given properties filtered down
054: * to only contain properties with required prefix
055: * @param pSource the source property bag
056: * @param pPrefix the prefix to look for
057: * @param pCutPrefix if equals true - the prefix itself will be cut from the property names in the returned proiperty bag
058: */
059: public static Properties filterProperties(Properties pSource,
060: String pPrefix, boolean pCutPrefix) {
061: Properties lResult = new Properties();
062: int lPrefixLength = pPrefix.length();
063: Iterator lIter = pSource.entrySet().iterator();
064: while (lIter.hasNext()) {
065: Map.Entry lEntry = (Map.Entry) lIter.next();
066: String lKey = lEntry.getKey().toString();
067: if (lKey.startsWith(pPrefix))
068: if (pCutPrefix)
069: lResult.put(lKey.substring(lPrefixLength), lEntry
070: .getValue());
071: else
072: lResult.put(lKey, lEntry.getValue());
073: }
074: return lResult;
075: }
076:
077: /** This method allows to use Ant - style variables in the properties. It returns bag of properties, which has all source properties
078: * with resolved macros. When looking for the value of the macro - this method looks at the source bag first and at the
079: * supplied known properties bag second.
080: * @param pSource the source property bag where whole or part value can be expressed as Ant style expression referring to other
081: * property.
082: * @param pKnownProperties the bag of already known properties
083: * @return bag of properties with resolved values
084: */
085: public static Properties resolveProperties(Properties pSource,
086: Properties pKnownProperties) {
087: Properties lResult = new Properties();
088: lResult.putAll(pSource);
089: // Loop over all properties
090: Properties[] lAllKnownProperties = new Properties[] { lResult,
091: pKnownProperties };
092: Iterator lEntries = lResult.entrySet().iterator();
093: while (lEntries.hasNext()) {
094: Map.Entry lEntry = (Map.Entry) lEntries.next();
095: // Loop until we have a situation where no replacement has been made
096: String lPropertyValueBefore = (String) lEntry.getValue();
097: String lPropertyValueAfter = null;
098: while (true) {
099: lPropertyValueAfter = substitutePropertyNamesWithValues(
100: (String) lEntry.getKey(), lPropertyValueBefore,
101: lAllKnownProperties);
102: if (lPropertyValueBefore.equals(lPropertyValueAfter))
103: break;
104: lPropertyValueBefore = lPropertyValueAfter;
105: }
106: lEntry.setValue(lPropertyValueAfter);
107: }
108: return lResult;
109: }
110:
111: private static String sStartToken = "${";
112: private static int sStartTokenLength = sStartToken.length();
113: private static String sEndToken = "}";
114: private static int sEndTokenLength = sEndToken.length();
115:
116: // This helper method is substituting property names with values
117: // Note that it only does one run - if string used in substitution had some property references itself
118: // they will be left unprocessed
119: private static String substitutePropertyNamesWithValues(
120: String pPropertyName, String pPropertyValue,
121: Properties[] pKnownProperties) {
122: StringBuffer lOutputBuffer = new StringBuffer(); // Start string constant
123: String lRemainderOfPropertyValue = pPropertyValue;
124: while (true) {
125: int lPos = lRemainderOfPropertyValue.indexOf(sStartToken);
126: if (lPos < 0) {
127: // Finished
128: lOutputBuffer.append(lRemainderOfPropertyValue);
129: break;
130: }
131: // Found another one
132: lOutputBuffer.append(lRemainderOfPropertyValue.substring(0,
133: lPos));
134: lRemainderOfPropertyValue = lRemainderOfPropertyValue
135: .substring(lPos + sStartTokenLength);
136: // The remainder begins with property name
137: lPos = lRemainderOfPropertyValue.indexOf(sEndToken);
138: if (lPos < 0)
139: throw new IllegalArgumentException("Unclosed "
140: + sStartToken + " tag in the value of "
141: + pPropertyName + " property.");
142: String lPropertyName = lRemainderOfPropertyValue.substring(
143: 0, lPos);
144: lRemainderOfPropertyValue = lRemainderOfPropertyValue
145: .substring(lPos + sEndTokenLength);
146: if (lPropertyName.equals(pPropertyName))
147: throw new IllegalArgumentException(
148: "Property "
149: + pPropertyName
150: + " value contains circular reference to itself.");
151: String lPropertyValue = null;
152: for (int i = 0; i < pKnownProperties.length; i++) {
153: Properties lPropertyBag = pKnownProperties[i];
154: if (lPropertyBag.containsKey(lPropertyName)) {
155: lPropertyValue = lPropertyBag
156: .getProperty(lPropertyName);
157: break;
158: }
159: }
160: if (lPropertyValue == null)
161: throw new IllegalArgumentException(
162: "Property "
163: + pPropertyName
164: + " value contains reference to undefined property: "
165: + sStartToken + lPropertyName
166: + sEndToken);
167: lOutputBuffer.append(lPropertyValue);
168: }
169: return lOutputBuffer.toString();
170: }
171: }
|