geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r514355 - in /geronimo/server/trunk: assemblies/geronimo-jetty6-jee5/src/main/var/config/ configs/j2ee-system/src/plan/ modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ modules/geronimo-system/src/main/java/or...
Date Sun, 04 Mar 2007 04:30:00 GMT
Author: djencks
Date: Sat Mar  3 20:29:59 2007
New Revision: 514355

URL: http://svn.apache.org/viewvc?view=rev&rev=514355
Log:
GERONIMO-2735 Property substitution in config.xml, using jexl expressions.  Small example in the jetty config.xml

Added:
    geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties   (with props)
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java   (contents, props changed)
      - copied, changed from r514267, geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/ExpressionParser.java
Removed:
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/ExpressionParser.java
Modified:
    geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config.xml
    geronimo/server/trunk/configs/j2ee-system/src/plan/plan.xml
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/GBeanOverride.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ServerOverride.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/SwitchableLocalAttributeManager.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlConditionParser.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/OgnlConditionParser.java
    geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java
    geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/LocalAttributeManagerTest.java
    geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/MockGBean.java
    geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/ServerOverrideTest.java

Added: geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties?view=auto&rev=514355
==============================================================================
--- geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties (added)
+++ geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties Sat Mar  3 20:29:59 2007
@@ -0,0 +1,22 @@
+##
+##   Licensed to the Apache Software Foundation (ASF) under one or more
+##   contributor license agreements.  See the NOTICE file distributed with
+##   this work for additional information regarding copyright ownership.
+##   The ASF licenses this file to You under the Apache License, Version 2.0
+##   (the "License"); you may not use this file except in compliance with
+##   the License.  You may obtain a copy of the License at
+##
+##       http://www.apache.org/licenses/LICENSE-2.0
+##
+##   Unless required by applicable law or agreed to in writing, software
+##   distributed under the License is distributed on an "AS IS" BASIS,
+##   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+##   See the License for the specific language governing permissions and
+##   limitations under the License.
+##
+##   Put variables and their substitution values in this file: they will be used when processing config.xml
+##   Values in this file will be overridden by environment variables and system properties
+hostName=localhost
+httpPort=8080
+httpsPort=8443
+portOffset=0
\ No newline at end of file

Propchange: geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config-substitutions.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config.xml?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config.xml (original)
+++ geronimo/server/trunk/assemblies/geronimo-jetty6-jee5/src/main/var/config/config.xml Sat Mar  3 20:29:59 2007
@@ -89,13 +89,13 @@
 
     <module name="org.apache.geronimo.configs/jetty6/${version}/car">
         <gbean name="JettyWebConnector">
-            <attribute name="host">${PlanServerHostname}</attribute>
-            <attribute name="port">${PlanHTTPPortPrimary}</attribute>
-            <attribute name="redirectPort">${PlanHTTPSPortPrimary}</attribute>
+            <attribute name="host">${hostName}</attribute>
+            <attribute name="port">${httpPort + portOffset}</attribute>
+            <attribute name="redirectPort">${httpsPort + portOffset}</attribute>
         </gbean>
         <gbean name="JettySSLConnector">
-            <attribute name="host">${PlanServerHostname}</attribute>
-            <attribute name="port">${PlanHTTPSPortPrimary}</attribute>
+            <attribute name="host">${hostName}</attribute>
+            <attribute name="port">${httpsPort + portOffset}</attribute>
         </gbean>
 <!--        <gbean name="JettyAJP13Connector">
             <attribute name="host">0.0.0.0</attribute>

Modified: geronimo/server/trunk/configs/j2ee-system/src/plan/plan.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/configs/j2ee-system/src/plan/plan.xml?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/configs/j2ee-system/src/plan/plan.xml (original)
+++ geronimo/server/trunk/configs/j2ee-system/src/plan/plan.xml Sat Mar  3 20:29:59 2007
@@ -52,6 +52,7 @@
             <name>ServerInfo</name>
         </reference>
         <attribute name="configFile">var/config/config.xml</attribute>
+        <attribute name="substitutionsFile">var/config/config-substitutions.properties</attribute>
     </gbean>
 
     <!-- ArtifactManager -->
@@ -97,5 +98,5 @@
             <name>ServerInfo</name>
         </reference>
     </gbean>
-    
+
 </module>

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java Sat Mar  3 20:29:59 2007
@@ -17,20 +17,18 @@
 
 package org.apache.geronimo.system.configuration;
 
-import org.apache.geronimo.system.configuration.condition.ConditionParser;
-import org.apache.geronimo.system.configuration.condition.JexlConditionParser;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import org.apache.geronimo.gbean.AbstractName;
 import org.apache.geronimo.kernel.InvalidGBeanException;
 import org.apache.geronimo.kernel.repository.Artifact;
-
+import org.apache.geronimo.system.configuration.condition.ConditionParser;
+import org.apache.geronimo.system.configuration.condition.JexlConditionParser;
+import org.apache.geronimo.system.configuration.condition.JexlExpressionParser;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.Document;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
 
 /**
  * @version $Rev$ $Date$
@@ -39,7 +37,7 @@
     private final Artifact name;
     private boolean load;
     private String condition;
-    private final Map gbeans = new LinkedHashMap();
+    private final Map<Object, GBeanOverride> gbeans = new LinkedHashMap<Object, GBeanOverride>();
 
     /**
      * Cached condition parser; lazy init on the first call to {@link #parseCondition()}
@@ -61,15 +59,13 @@
         this.name = name;
         this.load = base.load;
         this.condition = base.condition;
-        for (Iterator it = base.gbeans.keySet().iterator(); it.hasNext();) {
-            Object gbeanName = it.next();
-            GBeanOverride gbean = (GBeanOverride) base.gbeans.get(gbeanName);
+        for (GBeanOverride gbean : base.gbeans.values()) {
             GBeanOverride replacement = new GBeanOverride(gbean, base.name.toString(), name.toString());
             gbeans.put(replacement.getName(), replacement);
         }
     }
 
-    public ConfigurationOverride(Element element) throws InvalidGBeanException {
+    public ConfigurationOverride(Element element, JexlExpressionParser expressionParser) throws InvalidGBeanException {
         name = Artifact.create(element.getAttribute("name"));
         
         condition = element.getAttribute("condition");
@@ -80,7 +76,7 @@
         NodeList gbeans = element.getElementsByTagName("gbean");
         for (int g = 0; g < gbeans.getLength(); g++) {
             Element gbeanElement = (Element) gbeans.item(g);
-            GBeanOverride gbean = new GBeanOverride(gbeanElement);
+            GBeanOverride gbean = new GBeanOverride(gbeanElement, expressionParser);
             addGBean(gbean);
         }
     }
@@ -120,7 +116,7 @@
     }
     
     public GBeanOverride getGBean(String gbeanName) {
-        return (GBeanOverride) gbeans.get(gbeanName);
+        return gbeans.get(gbeanName);
     }
 
     public void addGBean(GBeanOverride gbean) {
@@ -136,7 +132,7 @@
     }
 
     public GBeanOverride getGBean(AbstractName gbeanName) {
-        return (GBeanOverride) gbeans.get(gbeanName);
+        return gbeans.get(gbeanName);
     }
 
     public void addGBean(AbstractName gbeanName, GBeanOverride gbean) {
@@ -155,9 +151,7 @@
         }
 
         // GBeans
-        for (Iterator gb = gbeans.entrySet().iterator(); gb.hasNext();) {
-            Map.Entry gbean = (Map.Entry) gb.next();
-            GBeanOverride gbeanOverride = (GBeanOverride) gbean.getValue();
+        for (GBeanOverride gbeanOverride : gbeans.values()) {
             gbeanOverride.writeXml(doc, module);
         }
         return module;

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/GBeanOverride.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/GBeanOverride.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/GBeanOverride.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/GBeanOverride.java Sat Mar  3 20:29:59 2007
@@ -19,9 +19,9 @@
 import java.beans.PropertyEditor;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.io.Serializable;
 import java.io.StringReader;
+import java.io.StringWriter;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -32,9 +32,11 @@
 import java.util.Map;
 import java.util.Set;
 
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.common.propertyeditor.PropertyEditors;
 import org.apache.geronimo.gbean.AbstractName;
 import org.apache.geronimo.gbean.AbstractNameQuery;
@@ -42,46 +44,55 @@
 import org.apache.geronimo.gbean.GBeanData;
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.ReferencePatterns;
+import org.apache.geronimo.gbean.GReferenceInfo;
 import org.apache.geronimo.kernel.InvalidGBeanException;
-import org.apache.geronimo.kernel.util.XmlUtil;
+import org.apache.geronimo.kernel.config.InvalidConfigException;
 import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.kernel.util.XmlUtil;
 import org.apache.geronimo.util.EncryptionManager;
+import org.apache.geronimo.system.configuration.condition.JexlExpressionParser;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
 
 /**
  * @version $Rev$ $Date$
  */
 public class GBeanOverride implements Serializable {
+
+    private static final Log log = LogFactory.getLog(GBeanOverride.class);
+
     private final Object name;
     private boolean load;
-    private final Map attributes = new LinkedHashMap();
-    private final Map references = new LinkedHashMap();
-    private final ArrayList clearAttributes = new ArrayList();
-    private final ArrayList nullAttributes = new ArrayList();
-    private final ArrayList clearReferences = new ArrayList();
+    private final Map<String, String> attributes = new LinkedHashMap<String, String>();
+    private final Map<String, ReferencePatterns> references = new LinkedHashMap<String, ReferencePatterns>();
+    private final ArrayList<String> clearAttributes = new ArrayList<String>();
+    private final ArrayList<String> nullAttributes = new ArrayList<String>();
+    private final ArrayList<String> clearReferences = new ArrayList<String>();
     private final String gbeanInfo;
+    private final JexlExpressionParser expressionParser;
 
-    public GBeanOverride(String name, boolean load) {
+    public GBeanOverride(String name, boolean load, JexlExpressionParser expressionParser) {
         this.name = name;
         this.load = load;
         gbeanInfo = null;
+        this.expressionParser = expressionParser;
     }
 
-    public GBeanOverride(AbstractName name, boolean load) {
+    public GBeanOverride(AbstractName name, boolean load, JexlExpressionParser expressionParser) {
         this.name = name;
         this.load = load;
         gbeanInfo = null;
+        this.expressionParser = expressionParser;
     }
 
     public GBeanOverride(GBeanOverride original, String oldArtifact, String newArtifact) {
         Object name = original.name;
-        if(name instanceof String) {
-            name = replace((String)name, oldArtifact, newArtifact);
-        } else if(name instanceof AbstractName) {
+        if (name instanceof String) {
+            name = replace((String) name, oldArtifact, newArtifact);
+        } else if (name instanceof AbstractName) {
             String value = name.toString();
             value = replace(value, oldArtifact, newArtifact);
             name = new AbstractName(URI.create(value));
@@ -94,26 +105,27 @@
         this.nullAttributes.addAll(original.nullAttributes);
         this.clearReferences.addAll(original.clearReferences);
         this.gbeanInfo = original.gbeanInfo;
+        this.expressionParser = original.expressionParser;
     }
 
     private static String replace(String original, String oldArtifact, String newArtifact) {
         int pos = original.indexOf(oldArtifact);
-        if(pos == -1) {
+        if (pos == -1) {
             return original;
         }
         int last = -1;
         StringBuffer buf = new StringBuffer();
-        while(pos > -1) {
-            buf.append(original.substring(last+1, pos));
+        while (pos > -1) {
+            buf.append(original.substring(last + 1, pos));
             buf.append(newArtifact);
-            last = pos+oldArtifact.length()-1;
+            last = pos + oldArtifact.length() - 1;
             pos = original.indexOf(oldArtifact, last);
         }
-        buf.append(original.substring(last+1));
+        buf.append(original.substring(last + 1));
         return buf.toString();
     }
 
-    public GBeanOverride(GBeanData gbeanData) throws InvalidAttributeException {
+    public GBeanOverride(GBeanData gbeanData, JexlExpressionParser expressionParser) throws InvalidAttributeException {
         GBeanInfo gbeanInfo = gbeanData.getGBeanInfo();
         this.gbeanInfo = gbeanInfo.getSourceClass();
         if (this.gbeanInfo == null) {
@@ -123,8 +135,8 @@
         load = true;
 
         // set attributes
-        for (Iterator iterator = gbeanData.getAttributes().entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
+        for (Object o : gbeanData.getAttributes().entrySet()) {
+            Map.Entry entry = (Map.Entry) o;
             String attributeName = (String) entry.getKey();
             GAttributeInfo attributeInfo = gbeanInfo.getAttribute(attributeName);
             if (attributeInfo == null) {
@@ -136,9 +148,10 @@
 
         // references can be coppied in blind
         references.putAll(gbeanData.getReferences());
+        this.expressionParser = expressionParser;
     }
 
-    public GBeanOverride(Element gbean) throws InvalidGBeanException {
+    public GBeanOverride(Element gbean, JexlExpressionParser expressionParser) throws InvalidGBeanException {
         String nameString = gbean.getAttribute("name");
         if (nameString.indexOf('?') > -1) {
             name = new AbstractName(URI.create(nameString));
@@ -199,7 +212,7 @@
 
             String referenceName = reference.getAttribute("name");
 
-            Set objectNamePatterns = new LinkedHashSet();
+            Set<AbstractNameQuery> objectNamePatterns = new LinkedHashSet<AbstractNameQuery>();
             NodeList patterns = reference.getElementsByTagName("pattern");
 
             // If there is no pattern, then its an empty set, so its a
@@ -225,7 +238,7 @@
                 if (artifactId != null) {
                     referenceArtifact = new Artifact(groupId, artifactId, version, type);
                 }
-                Map nameMap = new HashMap();
+                Map<String, String> nameMap = new HashMap<String, String>();
                 if (module != null) {
                     nameMap.put("module", module);
                 }
@@ -238,6 +251,7 @@
 
             setReferencePatterns(referenceName, new ReferencePatterns(objectNamePatterns));
         }
+        this.expressionParser = expressionParser;
     }
 
     private static String getChildAsText(Element element, String name) throws InvalidGBeanException {
@@ -292,19 +306,19 @@
         this.load = load;
     }
 
-    public Map getAttributes() {
+    public Map<String, String> getAttributes() {
         return attributes;
     }
 
     public String getAttribute(String attributeName) {
-        return (String) attributes.get(attributeName);
+        return attributes.get(attributeName);
     }
 
-    public ArrayList getClearAttributes() {
+    public ArrayList<String> getClearAttributes() {
         return clearAttributes;
     }
 
-    public ArrayList getNullAttributes() {
+    public ArrayList<String> getNullAttributes() {
         return nullAttributes;
     }
 
@@ -316,7 +330,7 @@
         return clearAttributes.contains(attributeName);
     }
 
-    public ArrayList getClearReferences() {
+    public ArrayList<String> getClearReferences() {
         return clearReferences;
     }
 
@@ -341,29 +355,116 @@
 
     public void setAttribute(String attributeName, Object attributeValue, String attributeType) throws InvalidAttributeException {
         String stringValue = getAsText(attributeValue, attributeType);
-        attributes.put(attributeName, stringValue);
+        setAttribute(attributeName, stringValue);
     }
 
     public void setAttribute(String attributeName, String attributeValue) {
         attributes.put(attributeName, attributeValue);
     }
 
-    public Map getReferences() {
+    public Map<String, ReferencePatterns> getReferences() {
         return references;
     }
 
     public ReferencePatterns getReferencePatterns(String name) {
-        return (ReferencePatterns) references.get(name);
+        return references.get(name);
     }
 
     public void setReferencePatterns(String name, ReferencePatterns patterns) {
         references.put(name, patterns);
     }
 
+    public boolean applyOverrides(GBeanData data, Artifact configName, AbstractName gbeanName, ClassLoader classLoader) throws InvalidConfigException {
+        if (!isLoad()) {
+            return false;
+        }
+
+        GBeanInfo gbeanInfo = data.getGBeanInfo();
+
+        // set attributes
+        for (Map.Entry<String, String> entry : getAttributes().entrySet()) {
+            String attributeName = entry.getKey();
+            GAttributeInfo attributeInfo = gbeanInfo.getAttribute(attributeName);
+            if (attributeInfo == null) {
+                throw new InvalidConfigException("No attribute: " + attributeName + " for gbean: " + data.getAbstractName());
+            }
+            String valueString = entry.getValue();
+            Object value = getValue(attributeInfo, valueString, configName, gbeanName, classLoader);
+            data.setAttribute(attributeName, value);
+        }
+
+        //Clear attributes
+        for (String attribute : getClearAttributes()) {
+            if (getClearAttribute(attribute)) {
+                data.clearAttribute(attribute);
+            }
+        }
+
+        //Null attributes
+        for (String attribute : getNullAttributes()) {
+            if (getNullAttribute(attribute)) {
+                data.setAttribute(attribute, null);
+            }
+        }
+
+        // set references
+        for (Map.Entry<String, ReferencePatterns> entry : getReferences().entrySet()) {
+
+            String referenceName = entry.getKey();
+            GReferenceInfo referenceInfo = gbeanInfo.getReference(referenceName);
+            if (referenceInfo == null) {
+                throw new InvalidConfigException("No reference: " + referenceName + " for gbean: " + data.getAbstractName());
+            }
+
+            ReferencePatterns referencePatterns = entry.getValue();
+
+            data.setReferencePatterns(referenceName, referencePatterns);
+        }
+
+        //Clear references
+        for (String reference : getClearReferences()) {
+            if (getClearReference(reference)) {
+                data.clearReference(reference);
+            }
+        }
+
+        return true;
+    }
+
+    private synchronized Object getValue(GAttributeInfo attribute, String value, Artifact configurationName, AbstractName gbeanName, ClassLoader classLoader) {
+        if (value == null) {
+            return null;
+        }
+        value = substituteVariables(attribute.getName(), value);
+        try {
+            PropertyEditor editor = PropertyEditors.findEditor(attribute.getType(), classLoader);
+            if (editor == null) {
+                log.debug("Unable to parse attribute of type " + attribute.getType() + "; no editor found");
+                return null;
+            }
+            editor.setAsText(value);
+            log.debug("Setting value for " + configurationName + "/" + gbeanName + "/" + attribute.getName() + " to value " + value);
+            return editor.getValue();
+        } catch (ClassNotFoundException e) {
+            log.error("Unable to load attribute type " + attribute.getType());
+            return null;
+        }
+    }
+
+    public String substituteVariables(String attributeName, String input) {
+        if (expressionParser != null) {
+            return expressionParser.parse(input);
+        }
+        return input;
+    }
+
     /**
      * Creates a new child of the supplied parent with the data for this
      * GBeanOverride, adds it to the parent, and then returns the new
      * child element.
+     * @param doc document containing the module, hence also the element returned from this method.
+     * @param parent module element this override will be inserted into
+     * @return newly created element for this override
      */
     public Element writeXml(Document doc, Element parent) {
         String gbeanName;
@@ -384,14 +485,12 @@
         }
 
         // attributes
-        for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            String name = (String) entry.getKey();
-            String value = (String) entry.getValue();
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            String name = entry.getKey();
+            String value = entry.getValue();
             if (value == null) {
                 setNullAttribute(name);
-            }
-            else {
+            } else {
                 if (getNullAttribute(name)) {
                     nullAttributes.remove(name);
                 }
@@ -403,18 +502,27 @@
                 gbean.appendChild(attribute);
                 if (value.length() == 0) {
                     attribute.setAttribute("value", "");
-                }
-                else {
+                } else {
                     try {
                         //
                         // NOTE: Construct a new document to handle mixed content attribute values
                         //       then add nodes which are children of the first node.  This allows
                         //       value to be XML or text.
                         //
-                        
+
                         DocumentBuilderFactory factory = XmlUtil.newDocumentBuilderFactory();
                         DocumentBuilder builder = factory.newDocumentBuilder();
 
+//                        String unsubstitutedValue = unsubstitutedAttributes.get(name);
+//                        if (unsubstitutedValue != null) {
+//                            log.debug("writeXML attribute " + name
+//                                    + " using raw value "
+//                                    + unsubstitutedValue
+//                                    + " instead of cooked value "
+//                                    + value + ".");
+//                            value = unsubstitutedValue;
+//                        }
+
                         // Wrap value in an element to be sure we can handle xml or text values
                         String xml = "<fragment>" + value + "</fragment>";
                         InputSource input = new InputSource(new StringReader(xml));
@@ -422,7 +530,7 @@
 
                         Node root = fragment.getFirstChild();
                         NodeList children = root.getChildNodes();
-                        for (int i=0; i<children.getLength(); i++) {
+                        for (int i = 0; i < children.getLength(); i++) {
                             Node child = children.item(i);
 
                             // Import the child (and its children) into the new document
@@ -438,16 +546,14 @@
         }
 
         // cleared attributes
-        for (Iterator iterator = clearAttributes.iterator(); iterator.hasNext();) {
-            String name = (String) iterator.next();
+        for (String name : clearAttributes) {
             Element attribute = doc.createElement("attribute");
             gbean.appendChild(attribute);
             attribute.setAttribute("name", name);
         }
 
         // Null attributes
-        for (Iterator iterator = nullAttributes.iterator(); iterator.hasNext();) {
-            String name = (String) iterator.next();
+        for (String name : nullAttributes) {
             Element attribute = doc.createElement("attribute");
             gbean.appendChild(attribute);
             attribute.setAttribute("name", name);
@@ -455,24 +561,22 @@
         }
 
         // references
-        for (Iterator iterator = references.entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            String name = (String) entry.getKey();
-            ReferencePatterns patterns = (ReferencePatterns) entry.getValue();
+        for (Map.Entry<String, ReferencePatterns> entry : references.entrySet()) {
+            String name = entry.getKey();
+            ReferencePatterns patterns = entry.getValue();
 
             Element reference = doc.createElement("reference");
             reference.setAttribute("name", name);
             gbean.appendChild(reference);
 
-            Set patternSet;
+            Set<AbstractNameQuery> patternSet;
             if (patterns.isResolved()) {
                 patternSet = Collections.singleton(new AbstractNameQuery(patterns.getAbstractName()));
             } else {
                 patternSet = patterns.getPatterns();
             }
 
-            for (Iterator patternIterator = patternSet.iterator(); patternIterator.hasNext();) {
-                AbstractNameQuery pattern = (AbstractNameQuery) patternIterator.next();
+            for (AbstractNameQuery pattern : patternSet) {
                 Element pat = doc.createElement("pattern");
                 reference.appendChild(pat);
                 Artifact artifact = pattern.getArtifact();
@@ -516,8 +620,7 @@
         }
 
         // cleared references
-        for (Iterator iterator = clearReferences.iterator(); iterator.hasNext();) {
-            String name = (String) iterator.next();
+        for (String name : clearReferences) {
             Element reference = doc.createElement("reference");
             reference.setAttribute("name", name);
             gbean.appendChild(reference);

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java Sat Mar  3 20:29:59 2007
@@ -16,6 +16,36 @@
  */
 package org.apache.geronimo.system.configuration;
 
+import java.beans.PropertyEditor;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.geronimo.common.propertyeditor.PropertyEditors;
@@ -27,13 +57,14 @@
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.gbean.GReferenceInfo;
 import org.apache.geronimo.gbean.ReferencePatterns;
+import org.apache.geronimo.kernel.InvalidGBeanException;
+import org.apache.geronimo.kernel.config.Configuration;
 import org.apache.geronimo.kernel.config.InvalidConfigException;
 import org.apache.geronimo.kernel.config.ManageableAttributeStore;
 import org.apache.geronimo.kernel.config.PersistentConfigurationList;
-import org.apache.geronimo.kernel.config.Configuration;
 import org.apache.geronimo.kernel.repository.Artifact;
-import org.apache.geronimo.kernel.InvalidGBeanException;
 import org.apache.geronimo.kernel.util.XmlUtil;
+import org.apache.geronimo.system.configuration.condition.JexlExpressionParser;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -42,37 +73,6 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.dom.DOMSource;
-
-import java.beans.PropertyEditor;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.BufferedOutputStream;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
 /**
  * Stores managed attributes in an XML file on the local filesystem.
  *
@@ -82,6 +82,7 @@
     private static final Log log = LogFactory.getLog(LocalAttributeManager.class);
 
     private static final String CONFIG_FILE_PROPERTY = "org.apache.geronimo.config.file";
+    private final static String SUBSTITUTIONS_FILE_PROPERTY = "org.apache.geronimo.config.substitutions.file";
 
     private static final String BACKUP_EXTENSION = ".bak";
     private static final String TEMP_EXTENSION = ".working";
@@ -90,6 +91,7 @@
     private final ServerInfo serverInfo;
     private final String configFile;
     private final boolean readOnly;
+    private final JexlExpressionParser expressionParser;
 
     private File attributeFile;
     private File backupFile;
@@ -101,20 +103,23 @@
 
     private boolean kernelFullyStarted;
 
-    public LocalAttributeManager(String configFile, boolean readOnly, ServerInfo serverInfo) {
+    public LocalAttributeManager(String configFile, String configSubstitutionsFile, boolean readOnly, ServerInfo serverInfo) {
         this.configFile = System.getProperty(CONFIG_FILE_PROPERTY, configFile);
+        String resolvedPropertiesFile = System.getProperty(SUBSTITUTIONS_FILE_PROPERTY, configSubstitutionsFile);
+        expressionParser = loadProperties(resolvedPropertiesFile, serverInfo);
         this.readOnly = readOnly;
         this.serverInfo = serverInfo;
         serverOverride = new ServerOverride();
+        log.debug("setting configSubstitutionsFile to " + configSubstitutionsFile + ".");
     }
 
     public boolean isReadOnly() {
         return readOnly;
     }
 
-    public synchronized Collection applyOverrides(Artifact configName, Collection gbeanDatas, ClassLoader classLoader) throws InvalidConfigException {
+    public synchronized Collection applyOverrides(Artifact configName, Collection untypedGbeanDatas, ClassLoader classLoader) throws InvalidConfigException {
         // clone the datas since we will be modifying this collection
-        gbeanDatas = new ArrayList(gbeanDatas);
+        Collection<GBeanData> gbeanDatas = new ArrayList<GBeanData>(untypedGbeanDatas);
 
         ConfigurationOverride configuration = serverOverride.getConfiguration(configName);
         if (configuration == null) {
@@ -122,16 +127,15 @@
         }
 
         // index the incoming datas
-        Map datasByName = new HashMap();
-        for (Iterator iterator = gbeanDatas.iterator(); iterator.hasNext();) {
-            GBeanData gbeanData = (GBeanData) iterator.next();
+        Map<Object, GBeanData> datasByName = new HashMap<Object, GBeanData>();
+        for (GBeanData gbeanData : gbeanDatas) {
             datasByName.put(gbeanData.getAbstractName(), gbeanData);
             datasByName.put(gbeanData.getAbstractName().getName().get("name"), gbeanData);
         }
 
         // add the new GBeans
-        for (Iterator iterator = configuration.getGBeans().entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
+        for (Object o : configuration.getGBeans().entrySet()) {
+            Map.Entry entry = (Map.Entry) o;
             Object name = entry.getKey();
             GBeanOverride gbean = (GBeanOverride) entry.getValue();
             if (!datasByName.containsKey(name) && gbean.isLoad()) {
@@ -150,7 +154,7 @@
                     throw new InvalidConfigException(message.toString());
                 }
                 GBeanInfo gbeanInfo = GBeanInfo.getGBeanInfo(gbean.getGBeanInfo(), classLoader);
-                AbstractName abstractName = (AbstractName)name;
+                AbstractName abstractName = (AbstractName) name;
                 GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo);
                 gbeanDatas.add(gBeanData);
             }
@@ -170,12 +174,12 @@
     /**
      * Set the attributes from the attribute store on a single gbean, and return whether or not to load the gbean.
      *
-     * @param data
-     * @param configuration
-     * @param configName
-     * @param classLoader
+     * @param data GBeanData we are going to override attributes on
+     * @param configuration the module override the gbean relates to
+     * @param configName name of the module (why can't this be determined from the configuration?)
+     * @param classLoader ClassLoader to use for property objects/PropertyEditors
      * @return true if the gbean should be loaded, false otherwise.
-     * @throws org.apache.geronimo.kernel.config.InvalidConfigException
+     * @throws org.apache.geronimo.kernel.config.InvalidConfigException if we cannot update the gbeanData
      *
      */
     private synchronized boolean setAttributes(GBeanData data, ConfigurationOverride configuration, Artifact configName, ClassLoader classLoader) throws InvalidConfigException {
@@ -190,86 +194,7 @@
             return true;
         }
 
-        if (!gbean.isLoad()) {
-            return false;
-        }
-
-        GBeanInfo gbeanInfo = data.getGBeanInfo();
-
-        // set attributes
-        for (Iterator iterator = gbean.getAttributes().entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            String attributeName = (String) entry.getKey();
-            GAttributeInfo attributeInfo = gbeanInfo.getAttribute(attributeName);
-            if (attributeInfo == null) {
-                throw new InvalidConfigException("No attribute: " + attributeName + " for gbean: " + data.getAbstractName());
-            }
-            String valueString = (String) entry.getValue();
-            Object value = getValue(attributeInfo, valueString, configName, gbeanName, classLoader);
-            data.setAttribute(attributeName, value);
-        }
-
-        //Clear attributes
-        for (Iterator iterator = gbean.getClearAttributes().iterator(); iterator.hasNext();){
-           String attribute = (String) iterator.next();
-           if (gbean.getClearAttribute(attribute)){
-               data.clearAttribute(attribute);
-           }
-        }
-
-        //Null attributes
-        for (Iterator iterator = gbean.getNullAttributes().iterator(); iterator.hasNext();){
-           String attribute = (String) iterator.next();
-           if (gbean.getNullAttribute(attribute)){
-               data.setAttribute(attribute, null);
-           }
-        }
-
-        // set references
-        for (Iterator iterator = gbean.getReferences().entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-
-            String referenceName = (String) entry.getKey();
-            GReferenceInfo referenceInfo = gbeanInfo.getReference(referenceName);
-            if (referenceInfo == null) {
-                throw new InvalidConfigException("No reference: " + referenceName + " for gbean: " + data.getAbstractName());
-            }
-
-            ReferencePatterns referencePatterns = (ReferencePatterns) entry.getValue();
-
-            data.setReferencePatterns(referenceName, referencePatterns);
-        }
-
-        //Clear references
-        for (Iterator iterator = gbean.getClearReferences().iterator(); iterator.hasNext();){
-           String reference = (String) iterator.next();
-           if (gbean.getClearReference(reference)){
-               data.clearReference(reference);
-           }
-        }
-
-        return true;
-    }
-
-
-    private synchronized Object getValue(GAttributeInfo attribute, String value, Artifact configurationName, AbstractName gbeanName, ClassLoader classLoader) {
-        if (value == null) {
-            return null;
-        }
-
-        try {
-            PropertyEditor editor = PropertyEditors.findEditor(attribute.getType(), classLoader);
-            if (editor == null) {
-                log.debug("Unable to parse attribute of type " + attribute.getType() + "; no editor found");
-                return null;
-            }
-            editor.setAsText(value);
-            log.debug("Setting value for " + configurationName + "/" + gbeanName + "/" + attribute.getName() + " to value " + value);
-            return editor.getValue();
-        } catch (ClassNotFoundException e) {
-            log.error("Unable to load attribute type " + attribute.getType());
-            return null;
-        }
+        return gbean.applyOverrides(data, configName, gbeanName, classLoader);
     }
 
     public void setModuleGBeans(Artifact moduleName, GBeanOverride[] gbeans) {
@@ -277,8 +202,7 @@
             return;
         }
         ConfigurationOverride configuration = serverOverride.getConfiguration(moduleName, true);
-        for (int i = 0; i < gbeans.length; i++) {
-            GBeanOverride gbean = gbeans[i];
+        for (GBeanOverride gbean : gbeans) {
             configuration.addGBean(gbean);
         }
         attributeChanged();
@@ -293,7 +217,7 @@
         if (gbean == null) {
             gbean = configuration.getGBean((String) gbeanName.getName().get("name"));
             if (gbean == null) {
-                gbean = new GBeanOverride(gbeanName, true);
+                gbean = new GBeanOverride(gbeanName, true, expressionParser);
                 configuration.addGBean(gbeanName, gbean);
             }
         }
@@ -315,9 +239,9 @@
         ConfigurationOverride configuration = serverOverride.getConfiguration(configurationName, true);
         GBeanOverride gbean = configuration.getGBean(gbeanName);
         if (gbean == null) {
-            gbean = configuration.getGBean((String)gbeanName.getName().get("name"));
+            gbean = configuration.getGBean((String) gbeanName.getName().get("name"));
             if (gbean == null) {
-                gbean = new GBeanOverride(gbeanName, true);
+                gbean = new GBeanOverride(gbeanName, true, expressionParser);
                 configuration.addGBean(gbeanName, gbean);
             }
         }
@@ -334,11 +258,11 @@
         GBeanOverride gbean = configuration.getGBean(gbeanName);
         if (gbean == null) {
             // attempt to lookup by short name
-            gbean = configuration.getGBean((String)gbeanName.getName().get("name"));
+            gbean = configuration.getGBean((String) gbeanName.getName().get("name"));
         }
 
         if (gbean == null) {
-            gbean = new GBeanOverride(gbeanName, load);
+            gbean = new GBeanOverride(gbeanName, load, expressionParser);
             configuration.addGBean(gbeanName, gbean);
         } else {
             gbean.setLoad(load);
@@ -356,7 +280,7 @@
             return;
         }
         try {
-            GBeanOverride gbean = new GBeanOverride(gbeanData);
+            GBeanOverride gbean = new GBeanOverride(gbeanData, expressionParser);
             configuration.addGBean(gbean);
             attributeChanged();
         } catch (InvalidAttributeException e) {
@@ -370,29 +294,28 @@
         if (!attributeFile.exists()) {
             return;
         }
-        
         InputStream input = new BufferedInputStream(new FileInputStream(attributeFile));
         InputSource source = new InputSource(input);
         source.setSystemId(attributeFile.toString());
         DocumentBuilderFactory dFactory = XmlUtil.newDocumentBuilderFactory();
-        
+
         try {
             dFactory.setValidating(true);
             dFactory.setNamespaceAware(true);
             dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
-                                 "http://www.w3.org/2001/XMLSchema");
-            
+                    "http://www.w3.org/2001/XMLSchema");
+
             dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
-                                 LocalAttributeManager.class.getResourceAsStream("/META-INF/schema/attributes-1.1.xsd"));
+                    LocalAttributeManager.class.getResourceAsStream("/META-INF/schema/attributes-1.1.xsd"));
 
             DocumentBuilder builder = dFactory.newDocumentBuilder();
             builder.setErrorHandler(new ErrorHandler() {
                 public void error(SAXParseException e) {
                     log.error("Unable to read saved manageable attributes. " +
-                        "SAX parse error: " + e.getMessage() +
-                        " at line " + e.getLineNumber() +
-                        ", column " + e.getColumnNumber() +
-                        " in entity " + e.getSystemId());
+                            "SAX parse error: " + e.getMessage() +
+                            " at line " + e.getLineNumber() +
+                            ", column " + e.getColumnNumber() +
+                            " in entity " + e.getSystemId());
 
                     if (log.isTraceEnabled()) {
                         log.trace("Exception deatils", e);
@@ -407,11 +330,11 @@
                             " at line " + e.getLineNumber() +
                             ", column " + e.getColumnNumber() +
                             " in entity " + e.getSystemId());
-                    
+
                     if (log.isTraceEnabled()) {
                         log.trace("Exception deatils", e);
                     }
-                    
+
                     // TODO throw an exception here?
                 }
 
@@ -421,16 +344,16 @@
                             " at line " + e.getLineNumber() +
                             ", column " + e.getColumnNumber() +
                             " in entity " + e.getSystemId());
-                    
+
                     if (log.isTraceEnabled()) {
                         log.trace("Exception deatils", e);
                     }
                 }
             });
-            
+
             Document doc = builder.parse(source);
             Element root = doc.getDocumentElement();
-            serverOverride = new ServerOverride(root);
+            serverOverride = new ServerOverride(root, expressionParser);
         } catch (SAXException e) {
             log.error("Unable to read saved manageable attributes", e);
         } catch (ParserConfigurationException e) {
@@ -483,9 +406,9 @@
         dFactory.setValidating(true);
         dFactory.setNamespaceAware(true);
         dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
-                             "http://www.w3.org/2001/XMLSchema");
+                "http://www.w3.org/2001/XMLSchema");
         dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
-                             LocalAttributeManager.class.getResourceAsStream("/META-INF/schema/attributes-1.1.xsd"));
+                LocalAttributeManager.class.getResourceAsStream("/META-INF/schema/attributes-1.1.xsd"));
 
         OutputStream output = null;
         try {
@@ -533,12 +456,11 @@
     }
 
     public synchronized List restore() throws IOException {
-        List configs = new ArrayList();
-        for (Iterator iterator = serverOverride.getConfigurations().entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            ConfigurationOverride configuration = (ConfigurationOverride) entry.getValue();
+        List<Artifact> configs = new ArrayList<Artifact>();
+        for (Map.Entry<Artifact, ConfigurationOverride> entry : serverOverride.getConfigurations().entrySet()) {
+            ConfigurationOverride configuration = entry.getValue();
             if (configuration.isLoad()) {
-                Artifact configID = (Artifact) entry.getKey();
+                Artifact configID = entry.getKey();
                 configs.add(configID);
             }
         }
@@ -547,7 +469,7 @@
 
     public void startConfiguration(Artifact configurationName) {
         ConfigurationOverride configuration = serverOverride.getConfiguration(configurationName, false);
-        if(configuration == null) {
+        if (configuration == null) {
             return;
         }
         configuration.setLoad(true);
@@ -558,7 +480,7 @@
         // Check whether we have it already
         ConfigurationOverride configuration = serverOverride.getConfiguration(configurationName, false);
         // If not, initialize it
-        if(configuration == null) {
+        if (configuration == null) {
             configuration = serverOverride.getConfiguration(configurationName, true);
             configuration.setLoad(false);
             attributeChanged();
@@ -589,7 +511,7 @@
 
     public void migrateConfiguration(Artifact oldName, Artifact newName, Configuration configuration) {
         ConfigurationOverride configInfo = serverOverride.getConfiguration(oldName);
-        if(configInfo == null) {
+        if (configInfo == null) {
             throw new IllegalArgumentException("Trying to migrate unknown configuration: " + oldName);
         }
         serverOverride.removeConfiguration(oldName);
@@ -685,6 +607,28 @@
         }
     }
 
+    private static JexlExpressionParser loadProperties(String propertiesFile, ServerInfo serverInfo) {
+        Map<Object, Object> vars = new HashMap<Object, Object>();
+        //properties file is least significant
+        if (propertiesFile != null) {
+            Properties properties = new Properties();
+            File thePropertiesFile = serverInfo.resolveServer(propertiesFile);
+            log.debug("Loading properties file " + thePropertiesFile.getAbsolutePath());
+            try {
+                properties.load(new FileInputStream(propertiesFile));
+            } catch (Exception e) {
+                log.error("Caught exception " + e
+                        + " trying to open properties file " + thePropertiesFile.getAbsolutePath());
+            }
+            vars.putAll(properties);
+        }
+        //environment variables are next
+        vars.putAll(System.getenv());
+        //most significant are the command line system properties
+        vars.putAll(System.getProperties());
+        return new JexlExpressionParser(vars);
+    }
+
     public static final GBeanInfo GBEAN_INFO;
 
     static {
@@ -692,10 +636,11 @@
         infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
         infoFactory.addAttribute("configFile", String.class, true);
         infoFactory.addAttribute("readOnly", boolean.class, true);
+        infoFactory.addAttribute("substitutionsFile", String.class, true);
         infoFactory.addInterface(ManageableAttributeStore.class);
         infoFactory.addInterface(PersistentConfigurationList.class);
 
-        infoFactory.setConstructor(new String[]{"configFile", "readOnly", "ServerInfo"});
+        infoFactory.setConstructor(new String[]{"configFile", "substitutionsFile", "readOnly", "ServerInfo"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ServerOverride.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ServerOverride.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ServerOverride.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/ServerOverride.java Sat Mar  3 20:29:59 2007
@@ -25,6 +25,7 @@
 
 import org.apache.geronimo.kernel.InvalidGBeanException;
 import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.system.configuration.condition.JexlExpressionParser;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Document;
@@ -33,16 +34,16 @@
  * @version $Rev$ $Date$
  */
 class ServerOverride {
-    private final Map configurations = new LinkedHashMap();
+    private final Map<Artifact, ConfigurationOverride> configurations = new LinkedHashMap<Artifact, ConfigurationOverride>();
 
     public ServerOverride() {
     }
 
-    public ServerOverride(Element element) throws InvalidGBeanException {
+    public ServerOverride(Element element, JexlExpressionParser expressionParser) throws InvalidGBeanException {
         NodeList configs = element.getElementsByTagName("module");
         for (int i = 0; i < configs.getLength(); i++) {
             Element configurationElement = (Element) configs.item(i);
-            ConfigurationOverride configuration = new ConfigurationOverride(configurationElement);
+            ConfigurationOverride configuration = new ConfigurationOverride(configurationElement, expressionParser);
             addConfiguration(configuration);
         }
 
@@ -50,7 +51,7 @@
         configs = element.getElementsByTagName("configuration");
         for (int i = 0; i < configs.getLength(); i++) {
             Element configurationElement = (Element) configs.item(i);
-            ConfigurationOverride configuration = new ConfigurationOverride(configurationElement);
+            ConfigurationOverride configuration = new ConfigurationOverride(configurationElement, expressionParser);
             addConfiguration(configuration);
         }
     }
@@ -76,7 +77,7 @@
         configurations.remove(configurationName);
     }
 
-    public Map getConfigurations() {
+    public Map<Artifact, ConfigurationOverride> getConfigurations() {
         return configurations;
     }
 

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/SwitchableLocalAttributeManager.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/SwitchableLocalAttributeManager.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/SwitchableLocalAttributeManager.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/SwitchableLocalAttributeManager.java Sat Mar  3 20:29:59 2007
@@ -34,8 +34,8 @@
 public class SwitchableLocalAttributeManager extends LocalAttributeManager implements SwitchablePersistentConfigurationList {
     private boolean online;
     
-    public SwitchableLocalAttributeManager(String configFile, boolean readOnly, ServerInfo serverInfo) {
-        super(configFile, readOnly, serverInfo);
+    public SwitchableLocalAttributeManager(String configFile, String substitutionsFile, boolean readOnly, ServerInfo serverInfo) {
+        super(configFile, substitutionsFile, readOnly, serverInfo);
     }
 
     @Override

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlConditionParser.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlConditionParser.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlConditionParser.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlConditionParser.java Sat Mar  3 20:29:59 2007
@@ -16,17 +16,16 @@
  */
 package org.apache.geronimo.system.configuration.condition;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
 import org.apache.commons.jexl.Expression;
 import org.apache.commons.jexl.ExpressionFactory;
 import org.apache.commons.jexl.JexlContext;
 import org.apache.commons.jexl.JexlHelper;
-
-import java.util.Properties;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * Provides a simple facility to evaluate condition expressions using the
@@ -43,11 +42,11 @@
 {
     private static final Log log = LogFactory.getLog(JexlConditionParser.class);
 
-    private final Map vars;
+    private final Map<String, Object> vars;
 
     public JexlConditionParser() {
         // Setup the default vars
-        vars = new HashMap();
+        vars = new HashMap<String, Object>();
         
         vars.put("java", new JavaVariable());
         vars.put("os", new OsVariable());
@@ -87,7 +86,7 @@
         }
 
         if (result instanceof Boolean) {
-            return ((Boolean)result).booleanValue();
+            return (Boolean) result;
         }
         else {
             throw new ConditionParserException("Expression '" + expression + "' did not evaluate to a boolean value; found: " + result);

Copied: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java (from r514267, geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/ExpressionParser.java)
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java?view=diff&rev=514355&p1=geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/ExpressionParser.java&r1=514267&p2=geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/ExpressionParser.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java Sat Mar  3 20:29:59 2007
@@ -31,13 +31,12 @@
  *
  * @version $Rev$ $Date$
  */
-public class ExpressionParser
-{
-    private static final Log log = LogFactory.getLog(ExpressionParser.class);
+public class JexlExpressionParser {
+    private static final Log log = LogFactory.getLog(JexlExpressionParser.class);
 
     protected JexlContext context;
 
-    public ExpressionParser(final Map vars) {
+    public JexlExpressionParser(final Map vars) {
         if (vars == null) {
             throw new IllegalArgumentException("vars");
         }
@@ -50,7 +49,7 @@
         }
     }
 
-    public ExpressionParser() {
+    public JexlExpressionParser() {
         this(System.getProperties());
     }
 

Propchange: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/JexlExpressionParser.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/OgnlConditionParser.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/OgnlConditionParser.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/OgnlConditionParser.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/configuration/condition/OgnlConditionParser.java Sat Mar  3 20:29:59 2007
@@ -17,16 +17,14 @@
 
 package org.apache.geronimo.system.configuration.condition;
 
-import java.util.Properties;
-import java.util.Map;
 import java.util.HashMap;
-import java.util.Collections;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.util.Map;
+import java.util.Properties;
 
 import ognl.Ognl;
 import ognl.OgnlContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * Provides a simple facility to evaluate condition expressions using the
@@ -43,11 +41,11 @@
 {
     private static final Log log = LogFactory.getLog(OgnlConditionParser.class);
     
-    private final Map vars;
+    private final Map<String, Object> vars;
     
     public OgnlConditionParser() {
         // Setup the default vars
-        vars = new HashMap();
+        vars = new HashMap<String, Object>();
         
         vars.put("java", new JavaVariable());
         vars.put("os", new OsVariable());
@@ -87,7 +85,7 @@
         }
 
         if (result instanceof Boolean) {
-            return ((Boolean)result).booleanValue();
+            return (Boolean) result;
         }
         else {
             throw new ConditionParserException("Expression '" + expression + "' did not evaluate to a boolean value; found: " + result);

Modified: geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/main/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java Sat Mar  3 20:29:59 2007
@@ -1361,7 +1361,8 @@
         for (int i = 0; i < overrides.length; i++) {
             Element node = (Element) gbeans.item(i);
             try {
-                overrides[i] = new GBeanOverride(node);
+                //TODO figure out whether property substitutions should be allowed here
+                overrides[i] = new GBeanOverride(node, null);
             } catch (InvalidGBeanException e) {
                 log.error("Unable to process config.xml entry "+node.getAttribute("name")+" ("+node+")", e);
             }

Modified: geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/LocalAttributeManagerTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/LocalAttributeManagerTest.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/LocalAttributeManagerTest.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/LocalAttributeManagerTest.java Sat Mar  3 20:29:59 2007
@@ -218,7 +218,7 @@
 
     protected void setUp() throws Exception {
         super.setUp();
-        localAttributeManager = new LocalAttributeManager("target/test-config.xml", false, new BasicServerInfo(basedir));
+        localAttributeManager = new LocalAttributeManager("target/test-config.xml", "target/test-config-substitutions.properties", false, new BasicServerInfo(basedir));
         configurationName = Artifact.create("configuration/name/1/car");
         ObjectName objectName = ObjectName.getInstance(":name=gbean,parent="+configurationName+",foo=bar");
         gbeanName = new AbstractName(configurationName, objectName.getKeyPropertyList(), objectName);

Modified: geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/MockGBean.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/MockGBean.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/MockGBean.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/MockGBean.java Sat Mar  3 20:29:59 2007
@@ -22,9 +22,10 @@
 
 public class MockGBean {
 
-    private static final GBeanInfo GBEAN_INFO;
+    public static final GBeanInfo GBEAN_INFO;
 
     private String value;
+    private int port;
 
     public String getValue() {
         return value;
@@ -34,6 +35,15 @@
         this.value = value;
     }
 
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
     public static GBeanInfo getGBeanInfo() {
         return GBEAN_INFO;
     }
@@ -41,6 +51,7 @@
     static {
         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(MockGBean.class);
         infoFactory.addAttribute("value", String.class, true);
+        infoFactory.addAttribute("port", int.class, true);
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/ServerOverrideTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/ServerOverrideTest.java?view=diff&rev=514355&r1=514354&r2=514355
==============================================================================
--- geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/ServerOverrideTest.java (original)
+++ geronimo/server/trunk/modules/geronimo-system/src/test/java/org/apache/geronimo/system/configuration/ServerOverrideTest.java Sat Mar  3 20:29:59 2007
@@ -19,8 +19,10 @@
 import junit.framework.TestCase;
 import org.apache.geronimo.gbean.AbstractNameQuery;
 import org.apache.geronimo.gbean.ReferencePatterns;
+import org.apache.geronimo.gbean.GBeanData;
 import org.apache.geronimo.kernel.repository.Artifact;
 import org.apache.geronimo.kernel.util.XmlUtil;
+import org.apache.geronimo.system.configuration.condition.JexlExpressionParser;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -43,6 +45,7 @@
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.HashMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -52,9 +55,18 @@
  */
 public class ServerOverrideTest extends TestCase {
     private static final Log log = LogFactory.getLog(ServerOverrideTest.class);
-    
+    private JexlExpressionParser expressionParser;
+
+    protected void setUp() throws java.lang.Exception {
+        HashMap<String, String> subs = new HashMap<String, String>();
+        subs.put("host", "localhost");
+        subs.put("port", "8080");
+        subs.put("portOffset", "1");
+        expressionParser = new JexlExpressionParser(subs);
+    }
+
     public void testBasics() throws Exception {
-        GBeanOverride pizza = new GBeanOverride("Pizza", true);
+        GBeanOverride pizza = new GBeanOverride("Pizza", true, expressionParser);
         assertTrue(pizza.isLoad());
 
         pizza.setLoad(false);
@@ -99,7 +111,7 @@
     }
 
     public void testGBeanXml() throws Exception {
-        GBeanOverride pizza = new GBeanOverride("Pizza", true);
+        GBeanOverride pizza = new GBeanOverride("Pizza", true, expressionParser);
         assertCopyIdentical(pizza);
 
         pizza.setLoad(false);
@@ -130,7 +142,7 @@
         dinnerMenu.setLoad(false);
         assertCopyIdentical(dinnerMenu);
 
-        GBeanOverride pizza = new GBeanOverride("Pizza", false);
+        GBeanOverride pizza = new GBeanOverride("Pizza", false, expressionParser);
         pizza.setAttribute("cheese", "mozzarella");
         pizza.setAttribute("size", "x-large");
         pizza.setAttribute("emptyString", "");
@@ -149,7 +161,7 @@
         dinnerMenu.addGBean(pizza);
         assertCopyIdentical(dinnerMenu);
 
-        GBeanOverride garlicCheeseBread = new GBeanOverride("Garlic Cheese Bread", true);
+        GBeanOverride garlicCheeseBread = new GBeanOverride("Garlic Cheese Bread", true, expressionParser);
         ReferencePatterns toasterOvenPatterns = new ReferencePatterns(Collections.singleton(toasterOvenQuery));
         garlicCheeseBread.setReferencePatterns("oven", toasterOvenPatterns);
         dinnerMenu.addGBean(garlicCheeseBread);
@@ -162,7 +174,7 @@
 
         ConfigurationOverride dinnerMenu = new ConfigurationOverride(new Artifact("test","Dinner Menu","1.0","car"), false);
         restaurant.addConfiguration(dinnerMenu);
-        GBeanOverride pizza = new GBeanOverride("Pizza", false);
+        GBeanOverride pizza = new GBeanOverride("Pizza", false, expressionParser);
         pizza.setAttribute("cheese", "mozzarella");
         pizza.setAttribute("size", "x-large");
         pizza.setAttribute("emptyString", "");
@@ -175,7 +187,7 @@
         pizza.setReferencePatterns("oven", ovenPatterns);
         pizza.setClearReference("microwave");
         dinnerMenu.addGBean(pizza);
-        GBeanOverride garlicCheeseBread = new GBeanOverride("Garlic Cheese Bread", true);
+        GBeanOverride garlicCheeseBread = new GBeanOverride("Garlic Cheese Bread", true, expressionParser);
         ReferencePatterns toasterOvenPatterns = new ReferencePatterns(Collections.singleton(toasterOvenQuery));
         garlicCheeseBread.setReferencePatterns("oven", toasterOvenPatterns);
         dinnerMenu.addGBean(garlicCheeseBread);
@@ -183,7 +195,7 @@
 
         ConfigurationOverride drinkMenu = new ConfigurationOverride(new Artifact("test","Drink Menu","1.0","car"), false);
         restaurant.addConfiguration(drinkMenu);
-        GBeanOverride beer = new GBeanOverride("Beer", true);
+        GBeanOverride beer = new GBeanOverride("Beer", true, expressionParser);
         pizza.setReferencePatterns("glass", getReferencePatterns(new AbstractNameQuery[] {
             getAbstractNameQuery(":name=PintGlass"),
             getAbstractNameQuery(":name=BeerStein"),
@@ -191,7 +203,7 @@
             getAbstractNameQuery(":name=BeerCan")
         }));
         drinkMenu.addGBean(beer);
-        GBeanOverride wine = new GBeanOverride("Wine", true);
+        GBeanOverride wine = new GBeanOverride("Wine", true, expressionParser);
         wine.setReferencePatterns("glass", getReferencePatterns(new AbstractNameQuery[] {
             getAbstractNameQuery(":name=WineGlass"),
             getAbstractNameQuery(":name=WineBottle"),
@@ -222,8 +234,31 @@
     public void testReferenceXml() throws Exception {
         InputStream in = new ByteArrayInputStream(REFERENCE_XML.getBytes());
         Element gbeanElement = parseXml(in, "gbean");
-        GBeanOverride gbean = new GBeanOverride(gbeanElement);
+        GBeanOverride gbean = new GBeanOverride(gbeanElement, expressionParser);
+        assertCopyIdentical(gbean);
+    }
+
+    private static final String EXPRESSION_XML =
+            "        <gbean name=\"mockGBean\">\n" +
+                    "            <attribute name=\"value\">${host}</attribute>\n" +
+                    "            <attribute name=\"port\">${port}</attribute>\n" +
+                    "        </gbean>";
+
+    public void testExpressionXml() throws Exception {
+        InputStream in = new ByteArrayInputStream(EXPRESSION_XML.getBytes());
+        Element gbeanElement = parseXml(in, "gbean");
+        GBeanOverride gbean = new GBeanOverride(gbeanElement, expressionParser);
         assertCopyIdentical(gbean);
+        GBeanData data = new GBeanData(MockGBean.GBEAN_INFO);
+        gbean.setAttribute("port", "${port}");
+        gbean.applyOverrides(data, null, null, getClass().getClassLoader());
+        assertEquals(8080, data.getAttribute("port"));
+        gbean.setAttribute("port", "${port + 1}");
+        gbean.applyOverrides(data, null, null, getClass().getClassLoader());
+        assertEquals(8081, data.getAttribute("port"));
+        gbean.setAttribute("port", "${port + portOffset}");
+        gbean.applyOverrides(data, null, null, getClass().getClassLoader());
+        assertEquals(8081, data.getAttribute("port"));
     }
 
     private void assertCopyIdentical(ServerOverride server) throws Exception {
@@ -294,21 +329,21 @@
 
     private ServerOverride copy(ServerOverride server) throws Exception {
         Document doc = createDocument();
-        return new ServerOverride(readElement(server.writeXml(doc), "attributes"));
+        return new ServerOverride(readElement(server.writeXml(doc), "attributes"), expressionParser);
     }
 
     private ConfigurationOverride copy(ConfigurationOverride configuration) throws Exception {
         Document doc = createDocument();
         Element root = doc.createElement("temp");
         doc.appendChild(root);
-        return new ConfigurationOverride(readElement(configuration.writeXml(doc, root), "module"));
+        return new ConfigurationOverride(readElement(configuration.writeXml(doc, root), "module"), expressionParser);
     }
 
     private GBeanOverride copy(GBeanOverride gbean) throws Exception {
         Document doc = createDocument();
         Element root = doc.createElement("temp");
         doc.appendChild(root);
-        return new GBeanOverride(readElement(gbean.writeXml(doc, root), "gbean"));
+        return new GBeanOverride(readElement(gbean.writeXml(doc, root), "gbean"), expressionParser);
     }
 
     private Element parseXml(InputStream in, String name) throws Exception {



Mime
View raw message