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/04/21 02:07:43 UTC

svn commit: r395739 - in /geronimo/branches/1.1: applications/console-standard/src/java/org/apache/geronimo/console/car/ applications/console-standard/src/webapp/WEB-INF/view/car/ modules/system/src/java/org/apache/geronimo/system/configuration/

Author: ammulder
Date: Thu Apr 20 17:07:41 2006
New Revision: 395739

URL: http://svn.apache.org/viewcvs?rev=395739&view=rev
Log:
Now can edit plugin metadata for a configuration and export it with the
plugin metadata in place.

Added:
    geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java   (with props)
    geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java   (with props)
    geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp   (with props)
    geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp   (with props)
Modified:
    geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/BaseImportExportHandler.java
    geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ImportExportPortlet.java
    geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/index.jsp
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigInstallerGBean.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationInstaller.java
    geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationList.java

Modified: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/BaseImportExportHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/BaseImportExportHandler.java?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/BaseImportExportHandler.java (original)
+++ geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/BaseImportExportHandler.java Thu Apr 20 17:07:41 2006
@@ -29,6 +29,8 @@
     protected static final String LIST_MODE = "list";
     protected static final String DOWNLOAD_MODE = "download";
     protected static final String RESULTS_MODE = "results";
+    protected static final String CONFIGURE_EXPORT_MODE = "configure";
+    protected static final String CONFIRM_EXPORT_MODE = "confirm";
 
     protected BaseImportExportHandler(String mode, String viewName) {
         super(mode, viewName);

Added: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java?rev=395739&view=auto
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java (added)
+++ geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java Thu Apr 20 17:07:41 2006
@@ -0,0 +1,226 @@
+/**
+ *
+ * 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.console.car;
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.util.List;
+import java.util.ArrayList;
+import java.net.URL;
+import java.net.MalformedURLException;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.console.MultiPageModel;
+import org.apache.geronimo.console.util.PortletManager;
+import org.apache.geronimo.kernel.config.ConfigurationManager;
+import org.apache.geronimo.kernel.config.ConfigurationUtil;
+import org.apache.geronimo.kernel.KernelRegistry;
+import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.system.configuration.ConfigurationArchiveData;
+import org.apache.geronimo.system.configuration.ConfigurationMetadata;
+
+/**
+ * Handler for the screen where you configure plugin data before exporting
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class ExportConfigHandler extends BaseImportExportHandler {
+    private final static Log log = LogFactory.getLog(ExportConfigHandler.class);
+
+    public ExportConfigHandler() {
+        super(CONFIGURE_EXPORT_MODE, "/WEB-INF/view/car/pluginParams.jsp");
+    }
+
+    public String actionBeforeView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
+        String configId = request.getParameter("configId");
+        if(configId != null) {
+            response.setRenderParameter("configId", configId);
+        }
+        return getMode();
+    }
+
+    public void renderView(RenderRequest request, RenderResponse response, MultiPageModel model) throws PortletException, IOException {
+        String configId = request.getParameter("configId");
+        ConfigurationArchiveData data = PortletManager.getCurrentServer(request).getConfigurationInstaller().getPluginMetadata(Artifact.create(configId));
+        request.setAttribute("configId", data.getConfiguration().getConfigId());
+        request.setAttribute("name", data.getConfiguration().getName());
+        request.setAttribute("sourceRepository", data.getRepository() == null ? null : data.getRepository().toString());
+        request.setAttribute("backupRepository", combine(data.getBackups()));
+        request.setAttribute("category", data.getConfiguration().getCategory());
+        request.setAttribute("description", data.getConfiguration().getDescription());
+        ConfigurationMetadata.License[] licenses = data.getConfiguration().getLicenses();
+        if(licenses != null && licenses.length > 0) {
+            request.setAttribute("license", licenses[0].getName());
+            if(licenses[0].isOsiApproved()) {
+                request.setAttribute("licenseOSI", "true");
+            }
+            if(licenses.length > 1) {
+                log.warn("Unable to edit plugin metadata containing more than one license!  Additional license data will not be editable.");
+            }
+        }
+        request.setAttribute("gerVersions", combine(data.getConfiguration().getGeronimoVersions()));
+        request.setAttribute("jvmVersions", combine(data.getConfiguration().getJvmVersions()));
+        request.setAttribute("dependencies", combine(data.getConfiguration().getDependencies()));
+        request.setAttribute("obsoletes", combine(data.getConfiguration().getObsoletes()));
+        ConfigurationMetadata.Prerequisite[] reqs = data.getConfiguration().getPrerequisites();
+        if(reqs != null && reqs.length > 0) {
+            for (int i = 0; i < reqs.length; i++) {
+                ConfigurationMetadata.Prerequisite req = reqs[i];
+                String prefix = "prereq" + (i+1);
+                request.setAttribute(prefix, req.getConfigId().toString());
+                request.setAttribute(prefix +"type", req.getResourceType());
+                request.setAttribute(prefix +"desc", req.getDescription());
+            }
+            if(reqs.length > 3) {
+                log.warn("Unable to edit plugin metadata containing more than three prerequisites!  Additional prereqs will not be editable.");
+            }
+        }
+    }
+
+    public String actionAfterView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
+        String configId = request.getParameter("configId");
+        String name = request.getParameter("name");
+        String repo = request.getParameter("sourceRepository");
+        String backups = request.getParameter("backupRepository");
+        String category = request.getParameter("category");
+        String description = request.getParameter("description");
+        String license = request.getParameter("license");
+        String osi = request.getParameter("licenseOSI");
+        String gers = request.getParameter("gerVersions");
+        String jvms = request.getParameter("jvmVersions");
+        String deps = request.getParameter("dependencies");
+        String obsoletes = request.getParameter("obsoletes");
+        ConfigurationArchiveData data = PortletManager.getCurrentServer(request).getConfigurationInstaller().getPluginMetadata(Artifact.create(configId));
+        ConfigurationMetadata metadata = new ConfigurationMetadata(data.getConfiguration().getConfigId(),
+                name, description, category, true, false);
+        metadata.setDependencies(split(deps));
+        metadata.setGeronimoVersions(split(gers));
+        metadata.setJvmVersions(split(jvms));
+        metadata.setObsoletes(split(obsoletes));
+        List licenses = new ArrayList();
+        if(license != null && !license.trim().equals("")) {
+            licenses.add(new ConfigurationMetadata.License(license.trim(), osi != null && !osi.equals("")));
+        }
+        for (int i = 1; i < data.getConfiguration().getLicenses().length; i++) {
+            licenses.add(data.getConfiguration().getLicenses()[i]);
+        }
+        metadata.setLicenses((ConfigurationMetadata.License[]) licenses.toArray(new ConfigurationMetadata.License[licenses.size()]));
+        List prereqs = new ArrayList();
+        int counter = 1;
+        while(true) {
+            String prefix = "prereq" + counter;
+            ++counter;
+            String id = request.getParameter(prefix);
+            if(id == null || id.trim().equals("")) {
+                break;
+            }
+            String type = request.getParameter(prefix+"type");
+            String desc = request.getParameter(prefix+"desc");
+            if(type != null && type.trim().equals("")) {
+                type = null;
+            }
+            if(desc != null && desc.trim().equals("")) {
+                desc = null;
+            }
+            prereqs.add(new ConfigurationMetadata.Prerequisite(Artifact.create(id), false, type, desc));
+        }
+        for (int i = 3; i < data.getConfiguration().getPrerequisites().length; i++) {
+            ConfigurationMetadata.Prerequisite req = data.getConfiguration().getPrerequisites()[i];
+            prereqs.add(req);
+        }
+        metadata.setPrerequisites((ConfigurationMetadata.Prerequisite[]) prereqs.toArray(new ConfigurationMetadata.Prerequisite[prereqs.size()]));
+        URL repoURL = null;
+        if(repo != null && !repo.trim().equals("")) {
+            repoURL = new URL(repo);
+        }
+        URL[] backupURLs = splitURLs(backups);
+        data = new ConfigurationArchiveData(repoURL, backupURLs, metadata);
+        PortletManager.getCurrentServer(request).getConfigurationInstaller().updatePluginMetadata(data);
+
+        response.setRenderParameter("configId", configId);
+        response.setRenderParameter("name", name);
+
+        return CONFIRM_EXPORT_MODE+BEFORE_ACTION;
+    }
+
+    private URL[] splitURLs(String backups) throws MalformedURLException {
+        String[] strings = split(backups);
+        URL[] result = new URL[strings.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = new URL(strings[i]);
+        }
+        return result;
+    }
+
+
+    private String[] split(String deps) {
+        if(deps == null || deps.equals("")) {
+            return new String[0];
+        }
+        List list = new ArrayList();
+        BufferedReader in = new BufferedReader(new StringReader(deps));
+        String line;
+        try {
+            while((line = in.readLine()) != null) {
+                line = line.trim();
+                if(!line.equals("")) {
+                    list.add(line);
+                }
+            }
+            in.close();
+        } catch (IOException e) {
+            log.error("Unable to parse request arguments", e);
+        }
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    private String combine(String[] strings) {
+        if(strings == null || strings.length == 0) {
+            return null;
+        }
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < strings.length; i++) {
+            String string = strings[i];
+            if(i > 0) {
+                buf.append("\n");
+            }
+            buf.append(string);
+        }
+        return buf.toString();
+    }
+
+    private String combine(URL[] urls) {
+        if(urls == null || urls.length == 0) {
+            return null;
+        }
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < urls.length; i++) {
+            URL url = urls[i];
+            if(i > 0) {
+                buf.append("\n");
+            }
+            buf.append(url.toString());
+        }
+        return buf.toString();
+    }
+}

Propchange: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportConfigHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java?rev=395739&view=auto
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java (added)
+++ geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java Thu Apr 20 17:07:41 2006
@@ -0,0 +1,51 @@
+/**
+ *
+ * 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.console.car;
+
+import java.io.IOException;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import org.apache.geronimo.console.MultiPageModel;
+import org.apache.geronimo.console.util.ConfigurationData;
+import org.apache.geronimo.console.util.PortletManager;
+
+/**
+ * Handler for the import export main screen.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class ExportHandler extends BaseImportExportHandler {
+    public ExportHandler() {
+        super(CONFIRM_EXPORT_MODE, "/WEB-INF/view/car/confirmExport.jsp");
+    }
+
+    public String actionBeforeView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
+        return getMode();
+    }
+
+    public void renderView(RenderRequest request, RenderResponse response, MultiPageModel model) throws PortletException, IOException {
+        request.setAttribute("configId", request.getParameter("configId"));
+        request.setAttribute("name", request.getParameter("name"));
+    }
+
+    public String actionAfterView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
+        return LIST_MODE+BEFORE_ACTION;
+    }
+}

Propchange: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ExportHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ImportExportPortlet.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ImportExportPortlet.java?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ImportExportPortlet.java (original)
+++ geronimo/branches/1.1/applications/console-standard/src/java/org/apache/geronimo/console/car/ImportExportPortlet.java Thu Apr 20 17:07:41 2006
@@ -35,6 +35,8 @@
         addHelper(new ListHandler(), config);
         addHelper(new DownloadCARHandler(), config);
         addHelper(new ResultsHandler(), config);
+        addHelper(new ExportConfigHandler(), config);
+        addHelper(new ExportHandler(), config);
     }
 
     protected String getModelJSPVariableName() {

Added: geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp?rev=395739&view=auto
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp (added)
+++ geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp Thu Apr 20 17:07:41 2006
@@ -0,0 +1,15 @@
+<%@ page import="org.apache.geronimo.console.util.PortletManager"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
+<portlet:defineObjects/>
+
+<p><b>Export Plugin</b> -- Save to Disk</p>
+
+<p>Use the button below to save the plugin "${name}" to disk.</p>
+
+<%-- todo: calculate the /console prefix somehow --%>
+<form action="/console/car-export" method="GET">
+    <input type="hidden" name="configId" value="${configId}" />
+    <input type="submit" value="Export Plugin" />
+</form>

Propchange: geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/confirmExport.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/index.jsp
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/index.jsp?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/index.jsp (original)
+++ geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/index.jsp Thu Apr 20 17:07:41 2006
@@ -35,8 +35,8 @@
    <i>Note: at present, you must manually add a <tt>META-INF/geronimo-plugin.xml</tt>
    file to the CAR after you export it in order for it to be a valid plugin.</i></p>
 
-<%-- todo: calculate the /console prefix somehow --%>
-<form action="/console/car-export">
+<form name="<portlet:namespace/>ExportForm" action="<portlet:actionURL/>" method="POST">
+    <input type="hidden" name="mode" value="configure-before" />
     <select name="configId">
         <option />
       <c:forEach var="config" items="${configurations}">

Added: geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp?rev=395739&view=auto
==============================================================================
--- geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp (added)
+++ geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp Thu Apr 20 17:07:41 2006
@@ -0,0 +1,339 @@
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
+<portlet:defineObjects/>
+
+<p><b>Export Plugin</b> -- Configure Plugin Data</p>
+
+<!--   FORM TO COLLECT DATA FOR THIS PAGE   -->
+<form name="<portlet:namespace/>PluginForm" action="<portlet:actionURL/>" method="POST">
+    <input type="hidden" name="mode" value="configure-after" />
+    <input type="hidden" name="configId" value="${configId}" />
+    <table border="0">
+
+
+        <!-- ENTRY FIELD: Name -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Human Readable Name:</div></th>
+            <td><input name="name" type="text" size="30" value="${name}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A human-readable name that will be displayed for this plugin.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Config ID -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Unique ID:</div></th>
+            <td><b>${configId}</b></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The globally unique ID for this plugin.  This is determined from
+              the installation in the server you're exporting.  This defines
+              the version number for the plugin, so make sure it's correct.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Source Repository -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Download Repository:</div></th>
+            <td><input name="sourceRepository" type="text" size="30" value="${sourceRepository}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The main repository that should be checked when downloading dependencies
+              for this plugin.  This should be a URL, such as
+              <tt>http://geronimoplugins.com/repository/</tt>
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Backup Repository -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Additional Repositories:</div></th>
+            <td><textarea rows="5" cols="60" name="backupRepository">${backupRepository}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A list of additional repositories to check for any dependencies that are
+              not present in the main repository.  This should be a list of one URL per
+              line, with values such as <tt>http://www.ibiblio.org/maven2/</tt>
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Category -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Category:</div></th>
+            <td><input name="category" type="text" size="30" value="${category}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The category this plugin falls into.  Plugins in the same category will
+              be listed together.  If this plugin is intended to be listed on
+              geronimoplugins.com then you should use one of the category names there
+              if any of them fit.  Otherwise, you can select this freely, or according
+              to the categories acceptable to the repository where you plan to post
+              this.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Description -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Description:</div></th>
+            <td><textarea rows="10" cols="60" name="description">${description}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A description of this plugin.  You should use plain text only, with
+              blank lines to separate paragraphs.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: License -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">License:</div></th>
+            <td><input name="license" type="text" size="30" value="${license}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The name of the license that this plugin is covered by.  Ideally, it would
+              be prefixed by the class of license, like "BSD -- (name)" or "GPL -- (name)".
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: License Is Open Source-->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Open Source:</div></th>
+            <td>
+                <input type="checkbox" name="licenseOSI"<c:if test="${!(empty licenseOSI)}"> checked="checked"</c:if> />
+            </td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              Check this box if the license is an OSI-approved open source license
+              (see <a href="http://www.opensource.org/licenses/index.php">http://www.opensource.org/licenses/index.php</a>).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Geronimo Versions -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Geronimo Versions:</div></th>
+            <td><textarea rows="5" cols="60" name="gerVersions">${gerVersions}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              An optional list of Geronimo versions supported by this plugin.  If no values
+              are listed, the plugin can be installed in any version of Geronimo.  Otherwise,
+              list one acceptable Geronimo version per line, like
+              "1.1&nbsp;\n&nbsp;1.1.1&nbsp;\n&nbsp;1.1.2&nbsp;\n&nbsp;..."
+              (ideally, of course, this means you've actually tested the plugin with each
+              Geronimo version listed here).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: JVM Versions -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">JVM Versions:</div></th>
+            <td><textarea rows="5" cols="60" name="jvmVersions">${jvmVersions}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              An optional list of JVM version prefixes supported by this plugin.  If no values
+              are listed, the plugin can be installed in Geronimo running in any version of
+              the JVM.  Otherwise, list one acceptable JVM version perfix per line, like
+              "1.4.2&nbsp;\n&nbsp;1.5&nbsp;\n&nbsp;..."
+              (ideally, of course, this means you've actually tested the plugin with Geronimo
+              on each JVM version listed here).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Dependencies -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Dependencies:</div></th>
+            <td><textarea rows="5" cols="60" name="dependencies">${dependencies}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A list of JARs or other module IDs that this plugin depends on.  These
+              will be downloaded automatically when this plugin is installed.  Normally
+              you shouldn't change this list.  However, you can move entries from the
+              dependency list to the <b>prerequisite</b> list if the user must install the
+              dependency manually before installing the plugin (e.g. for a database pool
+              where a plugin wouldn't know what server to connect to).<br /><br />
+              Each entry in this list should use the Unique ID format like is used for
+              this plugin above.  You may remove the version number if you'd like to
+              work with any version of the dependency, though that may be risky.  Each
+              value should be on a separate line.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Obsoletes -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Obsoletes:</div></th>
+            <td><textarea rows="5" cols="60" name="obsoletes">${obsoletes}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A list of module IDs that this plugin replaces.  Those plugins or
+              modules will be removed when this one is installed.  That may include
+              previous versions of this plugin if you want installing it to "upgrade"
+              rather than just offering an additional alternative.  This should be a
+              list with one module ID per line.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 1 -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 1 ID:</div></th>
+            <td><input name="prereq1" type="text" size="30" value="${prereq1}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The module ID of a prerequisite for this plugin.  This is a module that
+              must be present in the server before the plugin can be installed.  It
+              may be something like a specific web container for a web application
+              (<tt>geronimo/jetty/*/car</tt>) or something like a database pool or
+              security realm that the user must install because the plugin author can't
+              create a value that will be valid in the destination server.  You may want
+              to leave out as many segments of the module ID as possible in order to
+              accomodate more users (e.g. <tt>*/mypool/*/*</tt> rather than
+              <tt>myapp/mypool/1.2/car</tt>).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 1 Type -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 1 Type:</div></th>
+            <td><input name="prereq1type" type="text" size="30" value="${prereq1type}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A brief description of the type of prerequisite this is (for the benefit
+              of the user).  Examples could include <tt>Database Pool</tt> or
+              <tt>Web Container</tt>.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 1 Description -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prereq 1 Description:</div></th>
+            <td><textarea rows="5" cols="60" name="prereq1desc">${prereq1desc}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A longer description of what the user needs to do to comply with this
+              prerequisite (for example, instructions to set up a database pool listing
+              the supported database products and telling the user where to find a script
+              to initialize the database).  This should be plain text with empty lines
+              to separate paragraphs.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 2 -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 2 ID:</div></th>
+            <td><input name="prereq2" type="text" size="30" value="${prereq2}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The module ID of a prerequisite for this plugin.  This is a module that
+              must be present in the server before the plugin can be installed.  It
+              may be something like a specific web container for a web application
+              (<tt>geronimo/jetty/*/car</tt>) or something like a database pool or
+              security realm that the user must install because the plugin author can't
+              create a value that will be valid in the destination server.  You may want
+              to leave out as many segments of the module ID as possible in order to
+              accomodate more users (e.g. <tt>*/mypool/*/*</tt> rather than
+              <tt>myapp/mypool/1.2/car</tt>).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 2 Type -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 2 Type:</div></th>
+            <td><input name="prereq2type" type="text" size="30" value="${prereq2type}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A brief description of the type of prerequisite this is (for the benefit
+              of the user).  Examples could include <tt>Database Pool</tt> or
+              <tt>Web Container</tt>.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 2 Description -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prereq 2 Description:</div></th>
+            <td><textarea rows="5" cols="60" name="prereq2desc">${prereq2desc}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A longer description of what the user needs to do to comply with this
+              prerequisite (for example, instructions to set up a database pool listing
+              the supported database products and telling the user where to find a script
+              to initialize the database).  This should be plain text with empty lines
+              to separate paragraphs.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 3 -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 3 ID:</div></th>
+            <td><input name="prereq3" type="text" size="30" value="${prereq3}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              The module ID of a prerequisite for this plugin.  This is a module that
+              must be present in the server before the plugin can be installed.  It
+              may be something like a specific web container for a web application
+              (<tt>geronimo/jetty/*/car</tt>) or something like a database pool or
+              security realm that the user must install because the plugin author can't
+              create a value that will be valid in the destination server.  You may want
+              to leave out as many segments of the module ID as possible in order to
+              accomodate more users (e.g. <tt>*/mypool/*/*</tt> rather than
+              <tt>myapp/mypool/1.2/car</tt>).
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 3 Type -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prerequisite 3 Type:</div></th>
+            <td><input name="prereq3type" type="text" size="30" value="${prereq3type}" /></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A brief description of the type of prerequisite this is (for the benefit
+              of the user).  Examples could include <tt>Database Pool</tt> or
+              <tt>Web Container</tt>.
+            </td>
+          </tr>
+        <!-- ENTRY FIELD: Prerequisite 3 Description -->
+          <tr>
+            <th style="min-width: 140px"><div align="right">Prereq 3 Description:</div></th>
+            <td><textarea rows="5" cols="60" name="prereq3desc">${prereq3desc}</textarea></td>
+          </tr>
+          <tr>
+            <td></td>
+            <td>
+              A longer description of what the user needs to do to comply with this
+              prerequisite (for example, instructions to set up a database pool listing
+              the supported database products and telling the user where to find a script
+              to initialize the database).  This should be plain text with empty lines
+              to separate paragraphs.
+            </td>
+          </tr>
+    <!-- SUBMIT BUTTON -->
+      <tr>
+        <td></td>
+        <td><input type="submit" value="Save Plugin Data" /></td>
+      </tr>
+    </table>
+</form>
+<!--   END OF FORM TO COLLECT DATA FOR THIS PAGE   -->
+
+
+<p><a href="<portlet:actionURL portletMode="view">
+              <portlet:param name="mode" value="index" />
+            </portlet:actionURL>">Cancel</a></p>

Propchange: geronimo/branches/1.1/applications/console-standard/src/webapp/WEB-INF/view/car/pluginParams.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigInstallerGBean.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigInstallerGBean.java?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigInstallerGBean.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigInstallerGBean.java Thu Apr 20 17:07:41 2006
@@ -16,31 +16,39 @@
  */
 package org.apache.geronimo.system.configuration;
 
+import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.FileNotFoundException;
-import java.io.File;
 import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.net.MalformedURLException;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.LinkedList;
 import java.util.Arrays;
-import java.util.Set;
-import java.util.Map;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.jar.JarFile;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
 import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
 import javax.security.auth.login.FailedLoginException;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+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.gbean.GBeanInfo;
@@ -54,19 +62,21 @@
 import org.apache.geronimo.kernel.repository.ArtifactResolver;
 import org.apache.geronimo.kernel.repository.DefaultArtifactResolver;
 import org.apache.geronimo.kernel.repository.Dependency;
-import org.apache.geronimo.kernel.repository.WritableListableRepository;
+import org.apache.geronimo.kernel.repository.FileWriteMonitor;
+import org.apache.geronimo.kernel.repository.ImportType;
 import org.apache.geronimo.kernel.repository.MissingDependencyException;
 import org.apache.geronimo.kernel.repository.Repository;
-import org.apache.geronimo.kernel.repository.ImportType;
-import org.apache.geronimo.kernel.repository.FileWriteMonitor;
-import org.apache.geronimo.util.encoders.Base64;
+import org.apache.geronimo.kernel.repository.WritableListableRepository;
 import org.apache.geronimo.system.serverinfo.ServerInfo;
 import org.apache.geronimo.system.threads.ThreadPool;
+import org.apache.geronimo.util.encoders.Base64;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * A GBean that knows how to download configurations from a Maven repository.
@@ -102,6 +112,75 @@
         return new Integer(value);
     }
 
+    public Map getInstalledPlugins() {
+        SortedSet artifacts = writeableRepo.list();
+
+        Map plugins = new HashMap();
+        for (Iterator i = artifacts.iterator(); i.hasNext();) {
+            Artifact configId = (Artifact) i.next();
+            File dir = writeableRepo.getLocation(configId);
+            File meta = new File(dir, "META-INF");
+            if(!meta.isDirectory() || !meta.canRead()) {
+                continue;
+            }
+            File xml = new File(meta, "geronimo-plugin.xml");
+            if(!xml.isFile() || !xml.canRead() || xml.length() == 0) {
+                continue;
+            }
+            readNameAndID(xml, plugins);
+        }
+        return plugins;
+    }
+
+    public ConfigurationArchiveData getPluginMetadata(Artifact configId) {
+        File dir = writeableRepo.getLocation(configId);
+        File meta = new File(dir, "META-INF");
+        if(!meta.isDirectory() || !meta.canRead()) {
+            return null;
+        }
+        File xml = new File(meta, "geronimo-plugin.xml");
+        try {
+            if(!xml.isFile() || !xml.canRead() || xml.length() == 0) {
+                return new ConfigurationArchiveData(null, new URL[0], createDefaultMetadata(configStore.loadConfiguration(configId)));
+            }
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document doc = builder.parse(xml);
+            return loadConfigurationMetadata(doc, xml);
+        } catch (InvalidConfigException e) {
+            log.warn("Unable to generate metadata for "+configId, e);
+        } catch (Exception e) {
+            log.warn("Invalid XML at "+xml.getAbsolutePath(), e);
+        }
+        return null;
+    }
+
+    public void updatePluginMetadata(ConfigurationArchiveData metadata) {
+        File dir = writeableRepo.getLocation(metadata.getConfiguration().getConfigId());
+        if(dir == null) {
+            throw new IllegalArgumentException(metadata.getConfiguration().getConfigId()+" is not installed!");
+        }
+        File meta = new File(dir, "META-INF");
+        if(!meta.isDirectory() || !meta.canRead()) {
+            throw new IllegalArgumentException(metadata.getConfiguration().getConfigId()+" is not a plugin!");
+        }
+        File xml = new File(meta, "geronimo-plugin.xml");
+        try {
+            if(!xml.isFile()) {
+                if(!xml.createNewFile()) {
+                    throw new RuntimeException("Cannot create plugin metadata file for "+metadata.getConfiguration().getConfigId());
+                }
+            }
+            Document doc = writeConfigurationMetadata(metadata);
+            TransformerFactory xfactory = TransformerFactory.newInstance();
+            Transformer xform = xfactory.newTransformer();
+            xform.setOutputProperty(OutputKeys.INDENT, "yes");
+            xform.transform(new DOMSource(doc), new StreamResult(xml));
+        } catch (Exception e) {
+            log.error("Unable to save plugin metadata for "+metadata.getConfiguration().getConfigId(), e);
+        }
+    }
+
     public ConfigurationList listConfigurations(URL mavenRepository, String username, String password) throws IOException, FailedLoginException {
         String repository = mavenRepository.toString();
         if(!repository.endsWith("/")) {
@@ -144,6 +223,10 @@
         } finally {
             jar.close();
         }
+        return loadConfigurationMetadata(doc, file);
+    }
+
+    private ConfigurationArchiveData loadConfigurationMetadata(Document doc, File file) throws SAXException, MalformedURLException {
         Element root = doc.getDocumentElement();
         NodeList configs = root.getElementsByTagName("configuration");
         if(configs.getLength() != 1) {
@@ -430,7 +513,7 @@
 
             // 2. Validate that we can install this
             validateConfiguration(data.getConfiguration());
-            
+
             // 3. Install the CAR into the repository (it shouldn't be re-downloaded)
             if(data.getConfiguration().getConfigId() != null) {
                 ResultsFileWriteMonitor monitor = new ResultsFileWriteMonitor(poller);
@@ -724,6 +807,159 @@
         public DownloadPoller getResults() {
             return results;
         }
+    }
+
+    private void readNameAndID(File xml, Map plugins) {
+        try {
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            SAXParser parser = factory.newSAXParser();
+            PluginNameIDHandler handler = new PluginNameIDHandler();
+            parser.parse(xml, handler);
+            if(handler.isComplete()) {
+                plugins.put(handler.getName(), handler.getID());
+            }
+        } catch (Exception e) {
+            log.warn("Invalid XML at "+xml.getAbsolutePath(), e);
+        }
+    }
+
+    private static class PluginNameIDHandler extends DefaultHandler {
+        private String id = "";
+        private String name = "";
+        private String element = null;
+
+        public void characters(char ch[], int start, int length) throws SAXException {
+            if(element != null) {
+                if(element.equals("config-id")) {
+                    id += new String(ch, start, length);
+                } else if(element.equals("name")) {
+                    name += new String(ch, start, length);
+                }
+            }
+        }
+
+        public void endElement(String uri, String localName, String qName) throws SAXException {
+            element = null;
+        }
+
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+            if(localName.equals("config-id") || localName.equals("name")) {
+                element = localName;
+            }
+        }
+
+        public void endDocument() throws SAXException {
+            id = id.trim();
+            name = name.trim();
+        }
+
+        public String getID() {
+            return id;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean isComplete() {
+            return !id.equals("") && !name.equals("");
+        }
+    }
+
+    private ConfigurationMetadata createDefaultMetadata(ConfigurationData data) {
+        ConfigurationMetadata meta = new ConfigurationMetadata(data.getId(), data.getId().toString(),
+                "Please provide a description", "Unknown", true, false);
+        meta.setGeronimoVersions(new String[]{serverInfo.getVersion()});
+        meta.setJvmVersions(new String[0]);
+        meta.setLicenses(new ConfigurationMetadata.License[0]);
+        meta.setObsoletes(new String[0]);
+        List deps = new ArrayList();
+        ConfigurationMetadata.Prerequisite prereq = null;
+        List real = data.getEnvironment().getDependencies();
+        for (int i = 0; i < real.size(); i++) {
+            Dependency dep = (Dependency) real.get(i);
+            if(dep.getArtifact().getGroupId().equals("geronimo")) {
+                if(dep.getArtifact().getArtifactId().equals("jetty")) {
+                    if(prereq == null) {
+                        prereq = new ConfigurationMetadata.Prerequisite(dep.getArtifact(), true, "Web Container", "This plugin works with the Geronimo/Jetty distribution.  It is not intended to run in the Geronimo/Tomcat distribution.  There is a separate version of this plugin that works with Tomcat.");
+                    }
+                    continue;
+                } else if(dep.getArtifact().getArtifactId().equals("tomcay")) {
+                    if(prereq == null) {
+                        prereq = new ConfigurationMetadata.Prerequisite(dep.getArtifact(), true, "Web Container", "This plugin works with the Geronimo/Tomcat distribution.  It is not intended to run in the Geronimo/Jetty distribution.  There is a separate version of this plugin that works with Jetty.");
+                    }
+                    continue;
+                }
+            }
+            deps.add(dep.getArtifact().toString());
+        }
+        meta.setDependencies((String[]) deps.toArray(new String[deps.size()]));
+        meta.setPrerequisites(prereq == null ? new ConfigurationMetadata.Prerequisite[0] : new ConfigurationMetadata.Prerequisite[]{prereq});
+        return meta;
+    }
+
+    private static Document writeConfigurationMetadata(ConfigurationArchiveData metadata) throws ParserConfigurationException {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        Document doc = builder.newDocument();
+        Element root = doc.createElement("geronimo-plugin");
+        doc.appendChild(root);
+        Element config = doc.createElement("configuration");
+        root.appendChild(config);
+
+        ConfigurationMetadata data = metadata.getConfiguration();
+        addTextChild(doc, config, "name", data.getName());
+        addTextChild(doc, config, "config-id", data.getConfigId().toString());
+        addTextChild(doc, config, "category", data.getCategory());
+        addTextChild(doc, config, "description", data.getDescription());
+        for (int i = 0; i < data.getLicenses().length; i++) {
+            ConfigurationMetadata.License license = data.getLicenses()[i];
+            Element lic = doc.createElement("license");
+            lic.appendChild(doc.createTextNode(license.getName()));
+            lic.setAttribute("osi-approved", Boolean.toString(license.isOsiApproved()));
+            config.appendChild(lic);
+        }
+        for (int i = 0; i < data.getGeronimoVersions().length; i++) {
+            addTextChild(doc, config, "geronimo-version", data.getGeronimoVersions()[i]);
+        }
+        for (int i = 0; i < data.getJvmVersions().length; i++) {
+            addTextChild(doc, config, "jvm-version", data.getJvmVersions()[i]);
+        }
+        for (int i = 0; i < data.getPrerequisites().length; i++) {
+            ConfigurationMetadata.Prerequisite prereq = data.getPrerequisites()[i];
+            Element pre = doc.createElement("prerequisite");
+            addTextChild(doc, pre, "id", prereq.getConfigId().toString());
+            if(prereq.getResourceType() != null) {
+                addTextChild(doc, pre, "resource-type", prereq.getResourceType());
+            }
+            if(prereq.getDescription() != null) {
+                addTextChild(doc, pre, "description", prereq.getDescription());
+            }
+            config.appendChild(pre);
+        }
+        for (int i = 0; i < data.getDependencies().length; i++) {
+            addTextChild(doc, config, "dependency", data.getDependencies()[i]);
+        }
+        for (int i = 0; i < data.getObsoletes().length; i++) {
+            addTextChild(doc, config, "obsoletes", data.getObsoletes()[i]);
+        }
+
+        Element repo = doc.createElement("source-repository");
+        repo.appendChild(doc.createTextNode(metadata.getRepository().toString()));
+        root.appendChild(repo);
+        for (int i = 0; i < metadata.getBackups().length; i++) {
+            URL url = metadata.getBackups()[i];
+            Element backup = doc.createElement("backup-repository");
+            backup.appendChild(doc.createTextNode(url.toString()));
+            root.appendChild(backup);
+        }
+        return doc;
+    }
+
+    private static void addTextChild(Document doc, Element parent, String name, String text) {
+        Element child = doc.createElement(name);
+        child.appendChild(doc.createTextNode(text));
+        parent.appendChild(child);
     }
 
     public static final GBeanInfo GBEAN_INFO;

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationInstaller.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationInstaller.java?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationInstaller.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationInstaller.java Thu Apr 20 17:07:41 2006
@@ -19,7 +19,9 @@
 import java.io.IOException;
 import java.io.File;
 import java.net.URL;
+import java.util.Map;
 import javax.security.auth.login.FailedLoginException;
+import org.apache.geronimo.kernel.repository.Artifact;
 
 /**
  * Knows how to import and export configurations
@@ -36,6 +38,38 @@
      *                 Set this to null if no authentication is required.
      */
     public ConfigurationList listConfigurations(URL mavenRepository, String username, String password) throws IOException, FailedLoginException;
+
+    /**
+     * Lists the plugins installed in the local Geronimo server, by name and
+     * ID.
+     *
+     * @return A Map with key type String (plugin name) and value type Artifact
+     *         (config ID of the plugin).
+     */
+    public Map getInstalledPlugins();
+
+    /**
+     * Gets a CofigurationMetadata for a configuration installed in the local
+     * server.  Should load a saved one if available, or else create a new
+     * default one to the best of its abilities.
+     *
+     * @param configId Identifies the configuration.  This must match a
+     *                 configuration currently installed in the local server.
+     *                 The configId must be fully resolved (isResolved() == true)
+     */
+    public ConfigurationArchiveData getPluginMetadata(Artifact configId);
+
+    /**
+     * Saves a ConfigurationMetadata for a particular plugin, if the server is
+     * able to record it.  This can be used if you later re-export the plugin,
+     * or just want to review the information for a particular installed
+     * plugin.
+     *
+     * @param metadata The data to save.  The contained configId (which must
+     *                 be fully resolved) identifies the configuration to save
+     *                 this for.
+     */
+    public void updatePluginMetadata(ConfigurationArchiveData metadata);
 
     /**
      * Installs a configuration from a remote repository into the local Geronimo server,

Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationList.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationList.java?rev=395739&r1=395738&r2=395739&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationList.java (original)
+++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/configuration/ConfigurationList.java Thu Apr 20 17:07:41 2006
@@ -25,7 +25,7 @@
 import org.apache.geronimo.kernel.repository.Artifact;
 
 /**
- * ReplaceMe
+ * Metadata on a list of configurations available in a remote server.
  *
  * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
  */