You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by am...@apache.org on 2006/05/19 20:57:38 UTC

svn commit: r407884 - in /geronimo/branches/1.1: configs/rmi-naming/src/plan/ modules/system/src/java/org/apache/geronimo/system/configuration/ modules/system/src/java/org/apache/geronimo/system/plugin/ modules/system/src/java/org/apache/geronimo/syste...

Author: ammulder
Date: Fri May 19 11:57:37 2006
New Revision: 407884

URL: http://svn.apache.org/viewvc?rev=407884&view=rev
Log:
Plugins can include config.xml data

Added:
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java   (with props)
Modified:
    geronimo/branches/1.1/configs/rmi-naming/src/plan/plan.xml
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/GBeanOverride.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ServerOverride.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/util/PluginRepositoryExporter.java
    geronimo/branches/1.1/modules/system/src/schema/local-attributes-1.1.xsd
    geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd
    geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/configuration/ServerOverrideTest.java
    geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/plugin/PluginInstallerTest.java

Modified: geronimo/branches/1.1/configs/rmi-naming/src/plan/plan.xml
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/configs/rmi-naming/src/plan/plan.xml?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/configs/rmi-naming/src/plan/plan.xml (original)
+++ geronimo/branches/1.1/configs/rmi-naming/src/plan/plan.xml Fri May 19 11:57:37 2006
@@ -89,6 +89,9 @@
       <reference name="ThreadPool">
         <name>DefaultThreadPool</name>
       </reference>
+      <reference name="PluginAttributeStore">
+        <name>AttributeManager</name>
+      </reference>
     </gbean>
 
     <gbean name="DownloadedPluginRepos" class="org.apache.geronimo.system.plugin.PluginRepositoryDownloader">

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationOverride.java Fri May 19 11:57:37 2006
@@ -21,6 +21,7 @@
 import org.apache.geronimo.kernel.repository.Artifact;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.Document;
 
 import java.io.PrintWriter;
 import java.util.Iterator;
@@ -96,21 +97,19 @@
         gbeans.put(gbeanName, gbean);
     }
 
-    public void writeXml(PrintWriter out) {
-        out.print("  <module name=\"" + name + "\"");
-        if (!load) {
-            out.print(" load=\"false\"");
+    public Element writeXml(Document doc, Element root) {
+        Element module = doc.createElement("module");
+        root.appendChild(module);
+        module.setAttribute("name", name.toString());
+        if(!load) {
+            module.setAttribute("load", "false");
         }
-        out.println(">");
-
         // GBeans
         for (Iterator gb = gbeans.entrySet().iterator(); gb.hasNext();) {
             Map.Entry gbean = (Map.Entry) gb.next();
-
             GBeanOverride gbeanOverride = (GBeanOverride) gbean.getValue();
-            gbeanOverride.writeXml(out);
+            gbeanOverride.writeXml(doc, module);
         }
-
-        out.println("  </module>");
+        return module;
     }
 }

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/GBeanOverride.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/GBeanOverride.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/GBeanOverride.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/GBeanOverride.java Fri May 19 11:57:37 2006
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.io.Serializable;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -43,11 +44,12 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.Document;
 
 /**
  * @version $Rev$ $Date$
  */
-class GBeanOverride {
+public class GBeanOverride implements Serializable {
     private final Object name;
     private boolean load;
     private final Map attributes = new LinkedHashMap();
@@ -128,7 +130,7 @@
                         .decrypt(attribute.getAttribute("value")));
                 continue;
             }
-            
+
             // Check to see if there is a null attribute
             if (attribute.hasAttribute("null")) {
                 String nullString = attribute.getAttribute("null");
@@ -159,7 +161,7 @@
 
             Set objectNamePatterns = new LinkedHashSet();
             NodeList patterns = reference.getElementsByTagName("pattern");
-            
+
             // If there is no pattern, then its an empty set, so its a
             // cleared value
             if (patterns.getLength() == 0) {
@@ -261,7 +263,7 @@
     public ArrayList getClearAttributes() {
         return clearAttributes;
     }
-    
+
     public ArrayList getNullAttributes() {
         return nullAttributes;
     }
@@ -269,7 +271,7 @@
     public boolean getNullAttribute(String attributeName) {
         return nullAttributes.contains(attributeName);
     }
-    
+
     public boolean getClearAttribute(String attributeName) {
         return clearAttributes.contains(attributeName);
     }
@@ -286,7 +288,7 @@
         if (!clearAttributes.contains(attributeName))
             clearAttributes.add(attributeName);
     }
-    
+
     public void setNullAttribute(String attributeName) {
         if (!nullAttributes.contains(attributeName))
             nullAttributes.add(attributeName);
@@ -318,7 +320,12 @@
         references.put(name, patterns);
     }
 
-    public void writeXml(PrintWriter out) {
+    /**
+     * 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.
+     */
+    public Element writeXml(Document doc, Element parent) {
         String gbeanName;
         if (name instanceof String) {
             gbeanName = (String) name;
@@ -326,15 +333,15 @@
             gbeanName = name.toString();
         }
 
-        out.print("    <gbean name=\"" + gbeanName + "\"");
+        Element gbean = doc.createElement("gbean");
+        parent.appendChild(gbean);
+        gbean.setAttribute("name", gbeanName);
         if (gbeanInfo != null) {
-            out.print(" gbeanInfo=\"" + gbeanInfo + "\"");
+            gbean.setAttribute("gbeanInfo", gbeanInfo);
         }
-
         if (!load) {
-            out.print(" load=\"false\"");
+            gbean.setAttribute("load", "false");
         }
-        out.println(">");
 
         // attributes
         for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
@@ -344,22 +351,30 @@
             if(name.toLowerCase().indexOf("password") > -1) {
                 value = EncryptionManager.encrypt(value);
             }
+            Element attribute = doc.createElement("attribute");
+            gbean.appendChild(attribute);
+            attribute.setAttribute("name", name);
             if (value.length() == 0)
-                out.println("      <attribute name=\"" + name + "\" value=\"\" />");
+                attribute.setAttribute("value", "");
             else
-                out.println("      <attribute name=\"" + name + "\">" +  value + "</attribute>");
+                attribute.appendChild(doc.createTextNode(value));
         }
 
         // cleared attributes
         for (Iterator iterator = clearAttributes.iterator(); iterator.hasNext();) {
             String name = (String) iterator.next();
-            out.println("      <attribute name=\"" + name + "\" />");
+            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();
-            out.println("      <attribute name=\"" + name + "\" null=\"true\" />");
+            Element attribute = doc.createElement("attribute");
+            gbean.appendChild(attribute);
+            attribute.setAttribute("name", name);
+            attribute.setAttribute("null", "true");
         }
 
         // references
@@ -368,7 +383,9 @@
             String name = (String) entry.getKey();
             ReferencePatterns patterns = (ReferencePatterns) entry.getValue();
 
-            out.println("      <reference name=\"" + name + "\">");
+            Element reference = doc.createElement("reference");
+            reference.setAttribute("name", name);
+            gbean.appendChild(reference);
             Set patternSet;
             if(patterns.isResolved()) {
                 patternSet = Collections.singleton(new AbstractNameQuery(patterns.getAbstractName()));
@@ -377,40 +394,54 @@
             }
             for (Iterator patternIterator = patternSet.iterator(); patternIterator.hasNext();) {
                 AbstractNameQuery pattern = (AbstractNameQuery) patternIterator.next();
-                out.println("          <pattern>");
+                Element pat = doc.createElement("pattern");
+                reference.appendChild(pat);
                 Artifact artifact = pattern.getArtifact();
                 if (artifact != null) {
                     if (artifact.getGroupId() != null) {
-                        out.println("              <groupId>" + artifact.getGroupId() + "</groupId>");
+                        Element group = doc.createElement("groupId");
+                        group.appendChild(doc.createTextNode(artifact.getGroupId()));
+                        pat.appendChild(group);
+                    }
+                    if(artifact.getArtifactId() != null) {
+                        Element art = doc.createElement("artifactId");
+                        art.appendChild(doc.createTextNode(artifact.getArtifactId()));
+                        pat.appendChild(art);
                     }
-                    out.println("              <artifactId>" + artifact.getArtifactId() + "</artifactId>");
                     if (artifact.getVersion() != null) {
-                        out.println("              <version>" + artifact.getVersion() + "</version>");
+                        Element version = doc.createElement("version");
+                        version.appendChild(doc.createTextNode(artifact.getVersion().toString()));
+                        pat.appendChild(version);
                     }
                     if (artifact.getType() != null) {
-                        out.println("              <type>" + artifact.getType() + "</type>");
+                        Element type = doc.createElement("type");
+                        type.appendChild(doc.createTextNode(artifact.getType()));
+                        pat.appendChild(type);
                     }
                     Map nameMap = pattern.getName();
                     if (nameMap.get("module") != null) {
-                        out.println("              <module>" + nameMap.get("module") + "</module>");
+                        Element module = doc.createElement("module");
+                        module.appendChild(doc.createTextNode(nameMap.get("module").toString()));
+                        pat.appendChild(module);
                     }
                     if (nameMap.get("name") != null) {
-                        out.println("              <name>" + nameMap.get("name") + "</name>");
+                        Element patName = doc.createElement("name");
+                        patName.appendChild(doc.createTextNode(nameMap.get("name").toString()));
+                        pat.appendChild(patName);
                     }
                 }
-                out.print(pattern.toString());
-                out.println("</pattern>");
+//                out.print(pattern.toString());
             }
-            out.println("      </reference>");
         }
 
         // cleared references
         for (Iterator iterator = clearReferences.iterator(); iterator.hasNext();) {
             String name = (String) iterator.next();
-            out.println("      <reference name=\"" + name + "\" />");
+            Element reference = doc.createElement("reference");
+            reference.setAttribute("name", name);
+            gbean.appendChild(reference);
         }
-
-        out.println("    </gbean>");
+        return gbean;
     }
 
     public static String getAsText(Object value, String type) throws InvalidAttributeException {

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/LocalAttributeManager.java Fri May 19 11:57:37 2006
@@ -41,12 +41,16 @@
 
 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.FileWriter;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -61,7 +65,7 @@
  *
  * @version $Rev$ $Date$
  */
-public class LocalAttributeManager implements ManageableAttributeStore, PersistentConfigurationList, GBeanLifecycle {
+public class LocalAttributeManager implements PluginAttributeStore, PersistentConfigurationList, GBeanLifecycle {
     private final static Log log = LogFactory.getLog(LocalAttributeManager.class);
 
     private final static String CONFIG_FILE_PROPERTY = "org.apache.geronimo.config.file";
@@ -245,6 +249,18 @@
         }
     }
 
+    public void setModuleGBeans(Artifact moduleName, GBeanOverride[] gbeans) {
+        if (readOnly) {
+            return;
+        }
+        ConfigurationOverride configuration = serverOverride.getConfiguration(moduleName, true);
+        for (int i = 0; i < gbeans.length; i++) {
+            GBeanOverride gbean = gbeans[i];
+            configuration.addGBean(gbean);
+        }
+        attributeChanged();
+    }
+
     public synchronized void setValue(Artifact configurationName, AbstractName gbeanName, GAttributeInfo attribute, Object value) {
         if (readOnly) {
             return;
@@ -369,9 +385,7 @@
         }
 
         // write the new configuration to the temp file
-        PrintWriter out = new PrintWriter(new FileWriter(tempFile), true);
-        serverOverride.writeXml(out);
-        out.close();
+        saveXmlToFile(tempFile, serverOverride);
 
         // delete the current backup file
         if (backupFile.exists()) {
@@ -390,6 +404,29 @@
         // rename the temp file the the configuration file
         if (!tempFile.renameTo(attributeFile)) {
             throw new IOException("EXTREMELY CRITICAL!  Unable to move manageable attributes working file to proper file name!  Configuration will revert to defaults unless this is manually corrected!  (could not rename " + tempFile.getAbsolutePath() + " to " + attributeFile.getAbsolutePath() + ")");
+        }
+    }
+
+    private static void saveXmlToFile(File file, ServerOverride serverOverride) {
+        DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
+        dFactory.setValidating(true);
+        dFactory.setNamespaceAware(true);
+        dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
+                             "http://www.w3.org/2001/XMLSchema");
+        dFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
+                             LocalAttributeManager.class.getResourceAsStream("/META-INF/schema/local-attributes-1.1.xsd"));
+        try {
+            Document doc = dFactory.newDocumentBuilder().newDocument();
+            serverOverride.writeXml(doc);
+            TransformerFactory xfactory = TransformerFactory.newInstance();
+            Transformer xform = xfactory.newTransformer();
+            xform.setOutputProperty(OutputKeys.INDENT, "yes");
+            xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+            xform.transform(new DOMSource(doc), new StreamResult(file));
+        } catch (ParserConfigurationException e) {
+            log.error("Unable to write config.xml", e);
+        } catch (TransformerException e) {
+            log.error("Unable to write config.xml", e);
         }
     }
 

Added: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java?rev=407884&view=auto
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java (added)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java Fri May 19 11:57:37 2006
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  Licensed 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.
+ */
+package org.apache.geronimo.system.configuration;
+
+import org.apache.geronimo.kernel.config.ManageableAttributeStore;
+import org.apache.geronimo.kernel.repository.Artifact;
+
+/**
+ * Extension to the ManageableAttributeStore that supports the plugin
+ * installer.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public interface PluginAttributeStore extends ManageableAttributeStore {
+
+    /**
+     * Adds a group of settings to the attribute store.  This is used by e.g.
+     * the plugin installer to add the settings needed for a new plugin.
+     */
+    public void setModuleGBeans(Artifact moduleName, GBeanOverride[] gbeans);
+}

Propchange: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/PluginAttributeStore.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ServerOverride.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ServerOverride.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ServerOverride.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ServerOverride.java Fri May 19 11:57:37 2006
@@ -27,6 +27,7 @@
 import org.apache.geronimo.kernel.repository.Artifact;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.Document;
 
 /**
  * @version $Rev$ $Date$
@@ -90,23 +91,21 @@
         return (Artifact[]) list.toArray(new Artifact[list.size()]);
     }
 
-    public void writeXml(PrintWriter out) {
-        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-        out.println();
-        out.println("<!-- ======================================================== -->");
-        out.println("<!-- Warning - This XML file is re-generated by Geronimo when -->");
-        out.println("<!-- changes are made to Geronimo's configuration, therefore  -->");
-        out.println("<!-- any comments added to this file will be lost.            -->");
-        out.println("<!-- Do not edit this file while Geronimo is running.         -->");
-        out.println("<!-- ======================================================== -->");
-        out.println();
-        out.println("<attributes xmlns=\"http://geronimo.apache.org/xml/ns/attributes-1.1\">");
+    public Element writeXml(Document doc) {
+        Element root = doc.createElement("attributes");
+        root.setAttribute("xmlns", "http://geronimo.apache.org/xml/ns/attributes-1.1");
+        doc.appendChild(doc.createComment(" ======================================================== "));
+        doc.appendChild(doc.createComment(" Warning - This XML file is re-generated by Geronimo when "));
+        doc.appendChild(doc.createComment(" changes are made to Geronimo's configuration, therefore  "));
+        doc.appendChild(doc.createComment(" any comments added to this file will be lost.            "));
+        doc.appendChild(doc.createComment(" Do not edit this file while Geronimo is running.         "));
+        doc.appendChild(doc.createComment(" ======================================================== "));
+        doc.appendChild(root);
         for (Iterator it = configurations.entrySet().iterator(); it.hasNext();) {
             Map.Entry entry = (Map.Entry) it.next();
             ConfigurationOverride configurationOverride = (ConfigurationOverride) entry.getValue();
-            configurationOverride.writeXml(out);
+            configurationOverride.writeXml(doc, root);
         }
-        out.println("</attributes>");
-        out.close();
+        return root;
     }
 }

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java Fri May 19 11:57:37 2006
@@ -70,7 +70,10 @@
 import org.apache.geronimo.kernel.repository.Repository;
 import org.apache.geronimo.kernel.repository.Version;
 import org.apache.geronimo.kernel.repository.WritableListableRepository;
+import org.apache.geronimo.kernel.InvalidGBeanException;
 import org.apache.geronimo.system.configuration.ConfigurationStoreUtil;
+import org.apache.geronimo.system.configuration.GBeanOverride;
+import org.apache.geronimo.system.configuration.PluginAttributeStore;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
 import org.apache.geronimo.system.threads.ThreadPool;
 import org.apache.geronimo.util.encoders.Base64;
@@ -99,8 +102,9 @@
     private ServerInfo serverInfo;
     private Map asyncKeys;
     private ThreadPool threadPool;
+    private PluginAttributeStore attributeStore;
 
-    public PluginInstallerGBean(ConfigurationManager configManager, WritableListableRepository repository, ConfigurationStore configStore, ServerInfo serverInfo, ThreadPool threadPool) {
+    public PluginInstallerGBean(ConfigurationManager configManager, WritableListableRepository repository, ConfigurationStore configStore, ServerInfo serverInfo, ThreadPool threadPool, PluginAttributeStore store) {
         this.configManager = configManager;
         this.writeableRepo = repository;
         this.configStore = configStore;
@@ -108,6 +112,7 @@
         this.threadPool = threadPool;
         resolver = new DefaultArtifactResolver(null, writeableRepo);
         asyncKeys = Collections.synchronizedMap(new HashMap());
+        attributeStore = store;
     }
 
     /**
@@ -380,9 +385,6 @@
                     configManager.uninstallConfiguration(artifact);
                 }
                 // 5. Installation of this configuration finished successfully
-                if(metadata.getModuleId() != null) {
-                    poller.addInstalledConfigID(metadata.getModuleId());
-                }
             }
 
             // Step 3: Start anything that's marked accordingly
@@ -510,6 +512,7 @@
             if(data.getModuleId() != null) {
                 ResultsFileWriteMonitor monitor = new ResultsFileWriteMonitor(poller);
                 writeableRepo.copyToRepository(carFile, data.getModuleId(), monitor);
+                installConfigXMLData(data.getModuleId(), data);
             }
 
             // 4. Use the standard logic to remove obsoletes, install dependencies, etc.
@@ -616,6 +619,7 @@
                     log.warn("Unable to delete temporary download file "+tempFile.getAbsolutePath());
                     tempFile.deleteOnExit();
                 }
+                installConfigXMLData(result.getConfigID(), pluginData);
                 if(dependency) {
                     monitor.getResults().addDependencyInstalled(configID);
                     configID = result.getConfigID();
@@ -1140,7 +1144,11 @@
         factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                              "http://www.w3.org/2001/XMLSchema");
         factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
-                             PluginInstallerGBean.class.getResourceAsStream("/META-INF/schema/plugins-1.1.xsd"));
+                             new InputStream[]{
+                                     PluginInstallerGBean.class.getResourceAsStream("/META-INF/schema/local-attributes-1.1.xsd"),
+                                     PluginInstallerGBean.class.getResourceAsStream("/META-INF/schema/plugins-1.1.xsd"),
+                             }
+        );
         DocumentBuilder builder = factory.newDocumentBuilder();
         builder.setErrorHandler(new ErrorHandler() {
             public void error(SAXParseException exception) throws SAXException {
@@ -1190,6 +1198,16 @@
             String fileName = getText(node);
             files[i] = new PluginMetadata.CopyFile(relative.equals("server"), fileName, destDir);
         }
+        NodeList gbeans = plugin.getElementsByTagName("gbean");
+        GBeanOverride[] overrides = new GBeanOverride[gbeans.getLength()];
+        for (int i = 0; i < overrides.length; i++) {
+            Element node = (Element) gbeans.item(i);
+            try {
+                overrides[i] = new GBeanOverride(node);
+            } catch (InvalidGBeanException e) {
+                log.error("Unable to process config.xml entry "+node.getAttribute("name")+" ("+node+")", e);
+            }
+        }
         boolean eligible = true;
         NodeList preNodes = plugin.getElementsByTagName("prerequisite");
         PluginMetadata.Prerequisite[] prereqs = new PluginMetadata.Prerequisite[preNodes.getLength()];
@@ -1245,6 +1263,7 @@
         data.setPrerequisites(prereqs);
         data.setRepositories(repos);
         data.setFilesToCopy(files);
+        data.setConfigXmls(overrides);
         NodeList list = plugin.getElementsByTagName("dependency");
         List start = new ArrayList();
         String deps[] = new String[list.getLength()];
@@ -1477,6 +1496,11 @@
             copy.appendChild(doc.createTextNode(file.getSourceFile()));
             config.appendChild(copy);
         }
+        for (int i = 0; i < data.getConfigXmls().length; i++) {
+            GBeanOverride override = data.getConfigXmls()[i];
+            Element gbean = override.writeXml(doc, config);
+            gbean.setAttribute("xmlns", "http://geronimo.apache.org/xml/ns/attributes-1.1");
+        }
         return doc;
     }
 
@@ -1494,6 +1518,17 @@
     }
 
     /**
+     * If a plugin includes config.xml content, copy it into the attribute
+     * store.
+     */
+    private void installConfigXMLData(Artifact configID, PluginMetadata pluginData) {
+        if(configManager.isConfiguration(configID) && attributeStore != null
+                && pluginData != null && pluginData.getConfigXmls().length > 0) {
+            attributeStore.setModuleGBeans(configID, pluginData.getConfigXmls());
+        }
+    }
+
+    /**
      * Gets a token unique to this run of the server, used to track asynchronous
      * downloads.
      */
@@ -1634,9 +1669,11 @@
         infoFactory.addReference("ConfigStore", ConfigurationStore.class, "ConfigurationStore");
         infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
         infoFactory.addReference("ThreadPool", ThreadPool.class, "GBean");
+        infoFactory.addReference("PluginAttributeStore", PluginAttributeStore.class, "AttributeStore");
         infoFactory.addInterface(PluginInstaller.class);
 
-        infoFactory.setConstructor(new String[]{"ConfigManager", "Repository", "ConfigStore", "ServerInfo","ThreadPool"});
+        infoFactory.setConstructor(new String[]{"ConfigManager", "Repository", "ConfigStore",
+                                                "ServerInfo", "ThreadPool", "PluginAttributeStore"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java Fri May 19 11:57:37 2006
@@ -19,6 +19,7 @@
 import java.io.Serializable;
 import java.net.URL;
 import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.system.configuration.GBeanOverride;
 
 /**
  * Various metadata on a configuration that's used when listing, importing,
@@ -43,6 +44,7 @@
     private String[] obsoletes = new String[0];
     private URL[] repositories = new URL[0];
     private CopyFile[] filesToCopy = new CopyFile[0];
+    private GBeanOverride[] configXmls = new GBeanOverride[0];
 
     private final boolean installed;
     private final boolean eligible;
@@ -201,6 +203,17 @@
 
     public void setFilesToCopy(CopyFile[] filesToCopy) {
         this.filesToCopy = filesToCopy;
+    }
+
+    /**
+     * Gets a list of settings to populate in config.xml
+     */
+    public GBeanOverride[] getConfigXmls() {
+        return configXmls;
+    }
+
+    public void setConfigXmls(GBeanOverride[] configXmls) {
+        this.configXmls = configXmls;
     }
 
     public int compareTo(Object o) {

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/util/PluginRepositoryExporter.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/util/PluginRepositoryExporter.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/util/PluginRepositoryExporter.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/util/PluginRepositoryExporter.java Fri May 19 11:57:37 2006
@@ -169,7 +169,7 @@
                 return null;
             }
         };
-        installer = new PluginInstallerGBean(null, destRepo, store, info, null);
+        installer = new PluginInstallerGBean(null, destRepo, store, info, null, null);
     }
 
     public void execute() throws IOException {

Modified: geronimo/branches/1.1/modules/system/src/schema/local-attributes-1.1.xsd
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/schema/local-attributes-1.1.xsd?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/schema/local-attributes-1.1.xsd (original)
+++ geronimo/branches/1.1/modules/system/src/schema/local-attributes-1.1.xsd Fri May 19 11:57:37 2006
@@ -92,6 +92,7 @@
             <xsd:extension base="xsd:string">
                 <xsd:attribute name="name" use="required"/>
                 <xsd:attribute name="null" use="optional"/>
+                <xsd:attribute name="value" use="optional"/>
             </xsd:extension>
         </xsd:simpleContent>
     </xsd:complexType>

Modified: geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd (original)
+++ geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd Fri May 19 11:57:37 2006
@@ -19,10 +19,15 @@
 <xs:schema
         targetNamespace="http://geronimo.apache.org/xml/ns/plugins-1.1"
         xmlns:list="http://geronimo.apache.org/xml/ns/plugins-1.1"
+        xmlns:atts="http://geronimo.apache.org/xml/ns/attributes-1.1"
         xmlns:xs="http://www.w3.org/2001/XMLSchema"
         elementFormDefault="qualified"
         attributeFormDefault="unqualified"
         >
+
+    <xs:import namespace="http://geronimo.apache.org/xml/ns/attributes-1.1"
+               schemaLocation="local-attributes-1.1.xsd"/>
+
     <xs:annotation>
         <xs:documentation>
             Schema for a list of Geronimo plugins available at some external site
@@ -320,6 +325,22 @@
                     </xs:documentation>
                 </xs:annotation>
             </xs:element>
+            <xs:element name="config-xml-content" minOccurs="0">
+                <xs:annotation>
+                    <xs:documentation>
+                        Lets a plugin declare data that should be inserted into config.xml
+                        when the plugin is installed.  This is normally used to add ports
+                        and other settings that the user is likely to want to change.  The
+                        gbean entries declared here will be written into config.xml for the
+                        new module when the plugin is installed.
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element ref="atts:gbean" maxOccurs="unbounded"/>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
         </xs:sequence>
     </xs:complexType>
 
@@ -384,7 +405,7 @@
 
         <xs:simpleContent>
             <xs:extension base="xs:string">
-                <xs:attribute name="type" use="required" type="xs:string">
+                <xs:attribute name="type" use="required">
                     <xs:annotation>
                         <xs:documentation>
                             Indicates the type of hash.  The values presently supported are:
@@ -394,6 +415,12 @@
 
                         </xs:documentation>
                     </xs:annotation>
+                    <xs:simpleType>
+                        <xs:restriction base="xs:NMTOKEN">
+                            <xs:enumeration value="MD5"/>
+                            <xs:enumeration value="SHA-1"/>
+                        </xs:restriction>
+                    </xs:simpleType>
                 </xs:attribute>
             </xs:extension>
         </xs:simpleContent>
@@ -419,7 +446,7 @@
 
         <xs:simpleContent>
             <xs:extension base="xs:string">
-                <xs:attribute name="relative-to" use="required" type="xs:string">
+                <xs:attribute name="relative-to" use="required">
                     <xs:annotation>
                         <xs:documentation>
                             Indicates whether the destination is relative to the Geronimo install
@@ -431,6 +458,12 @@
 
                         </xs:documentation>
                     </xs:annotation>
+                    <xs:simpleType>
+                        <xs:restriction base="xs:NMTOKEN">
+                            <xs:enumeration value="geronimo"/>
+                            <xs:enumeration value="server"/>
+                        </xs:restriction>
+                    </xs:simpleType>
                 </xs:attribute>
                 <xs:attribute name="dest-dir" use="required" type="xs:string">
                     <xs:annotation>

Modified: geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/configuration/ServerOverrideTest.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/configuration/ServerOverrideTest.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/configuration/ServerOverrideTest.java (original)
+++ geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/configuration/ServerOverrideTest.java Fri May 19 11:57:37 2006
@@ -22,10 +22,18 @@
 import org.apache.geronimo.kernel.repository.Artifact;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 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.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
@@ -255,41 +263,52 @@
     }
 
     private ServerOverride copy(ServerOverride server) throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        server.writeXml(new PrintWriter(out, true));
-        System.out.println();
-        System.out.println();
-        System.out.println(new String(out.toByteArray()));
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        Element element = parseXml(in);
-        return new ServerOverride(element);
+        Document doc = createDocument();
+        return new ServerOverride(readElement(server.writeXml(doc), "attributes"));
     }
 
     private ConfigurationOverride copy(ConfigurationOverride configuration) throws Exception {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        configuration.writeXml(new PrintWriter(out, true));
-        System.out.println();
-        System.out.println();
-        System.out.println(new String(out.toByteArray()));
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        Element element = parseXml(in);
-        return new ConfigurationOverride(element);
+        Document doc = createDocument();
+        Element root = doc.createElement("temp");
+        doc.appendChild(root);
+        return new ConfigurationOverride(readElement(configuration.writeXml(doc, root), "module"));
     }
 
     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"));
+    }
+
+    private Element parseXml(InputStream in, String name) throws Exception {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        Document doc = documentBuilderFactory.newDocumentBuilder().parse(in);
+        Element elem = doc.getDocumentElement();
+        if(elem.getNodeName().equals(name)) {
+            return elem;
+        }
+        NodeList list = elem.getElementsByTagName(name);
+        return (Element) list.item(0);
+    }
+
+    private Document createDocument() throws ParserConfigurationException {
+        DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
+        dFactory.setValidating(false);
+        return dFactory.newDocumentBuilder().newDocument();
+    }
+
+    private Element readElement(Element e, String name) throws Exception {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        gbean.writeXml(new PrintWriter(out, true));
+        TransformerFactory xfactory = TransformerFactory.newInstance();
+        Transformer xform = xfactory.newTransformer();
+        xform.setOutputProperty(OutputKeys.INDENT, "yes");
+        xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+        xform.transform(new DOMSource(e), new StreamResult(out));
         System.out.println();
         System.out.println();
         System.out.println(new String(out.toByteArray()));
         ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        Element element = parseXml(in);
-        return new GBeanOverride(element);
-    }
-
-    private Element parseXml(InputStream in) throws Exception {
-        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-        Document doc = documentBuilderFactory.newDocumentBuilder().parse(in);
-        return doc.getDocumentElement();
+        return parseXml(in, name);
     }
 }

Modified: geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/plugin/PluginInstallerTest.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/plugin/PluginInstallerTest.java?rev=407884&r1=407883&r2=407884&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/plugin/PluginInstallerTest.java (original)
+++ geronimo/branches/1.1/modules/system/src/test/org/apache/geronimo/system/plugin/PluginInstallerTest.java Fri May 19 11:57:37 2006
@@ -70,7 +70,7 @@
             public void execute(String consumerName, Runnable runnable) {
                 new Thread(runnable).start();
             }
-        });
+        }, null);
     }
 
     public void testParsing() throws Exception {