Author: ammulder Date: Mon May 15 17:32:14 2006 New Revision: 406785 URL: http://svn.apache.org/viewcvs?rev=406785&view=rev Log: Plugins can include files to copy into the Geronimo installation directory (GERONIMO-2029) Plugins automatically include themselves as obsoletes Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/DownloadResults.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/schema/plugins-1.1.xsd Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/DownloadResults.java URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/DownloadResults.java?rev=406785&r1=406784&r2=406785&view=diff ============================================================================== --- geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/DownloadResults.java (original) +++ geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/DownloadResults.java Mon May 15 17:32:14 2006 @@ -89,7 +89,6 @@ } public synchronized void setFailure(Exception failure) { -failure.printStackTrace(); this.failure = failure; } Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginInstallerGBean.java?rev=406785&r1=406784&r2=406785&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 Mon May 15 17:32:14 2006 @@ -569,6 +569,7 @@ } else { soFar.add(configID); } + // Download and install the main artifact //todo: check all repositories? Artifact[] matches = configManager.getArtifactResolver().queryArtifacts(configID); if(matches.length == 0) { // not present, needs to be downloaded @@ -617,7 +618,7 @@ monitor.getResults().addInstalledConfigID(configID); } } - + // Download and install the dependencies try { ConfigurationData data = null; if(!configID.isResolved()) { @@ -649,6 +650,63 @@ } catch (InvalidConfigException e) { throw new IllegalStateException("Installed configuration into repository but ConfigStore cannot load it: "+e.getMessage()); } + // Copy any files out of the artifact + PluginMetadata currentPlugin = configManager.isConfiguration(configID) ? getPluginMetadata(configID) : null; + for (int i = 0; i < currentPlugin.getFilesToCopy().length; i++) { + PluginMetadata.CopyFile data = currentPlugin.getFilesToCopy()[i]; + monitor.getResults().setCurrentFilePercent(-1); + monitor.getResults().setCurrentFile(data.getSourceFile()); + monitor.getResults().setCurrentMessage("Copying "+data.getSourceFile()+" from plugin to Geronimo installation"); + Set set; + try { + set = configStore.resolve(configID, null, data.getSourceFile()); + } catch (NoSuchConfigException e) { + throw new IllegalStateException("Unable to identify module "+configID+" to copy files from"); + } + if(set.size() == 0) { + log.error("Installed configuration into repository but cannot locate file to copy "+data.getSourceFile()); + continue; + } + File targetDir = data.isRelativeToVar() ? serverInfo.resolveServer("var/"+data.getDestDir()) : serverInfo.resolve(data.getDestDir()); + if(!targetDir.isDirectory()) { + log.error("Plugin install cannot write file "+data.getSourceFile()+" to "+data.getDestDir()+" because "+targetDir.getAbsolutePath()+" is not a directory"); + continue; + } + if(!targetDir.canWrite()) { + log.error("Plugin install cannot write file "+data.getSourceFile()+" to "+data.getDestDir()+" because "+targetDir.getAbsolutePath()+" is not writable"); + continue; + } + for (Iterator it = set.iterator(); it.hasNext();) { + URL url = (URL) it.next(); + String path = url.getPath(); + if(path.lastIndexOf('/') > -1) { + path = path.substring(path.lastIndexOf('/')); + } + File target = new File(targetDir, path); + if(!target.exists()) { + if(!target.createNewFile()) { + log.error("Plugin install cannot create new file "+target.getAbsolutePath()); + continue; + } + } + if(!target.canWrite()) { + log.error("Plugin install cannot write to file "+target.getAbsolutePath()); + continue; + } + copyFile(url.openStream(), new FileOutputStream(target)); + } + } + } + + private void copyFile(InputStream in, FileOutputStream out) throws IOException { + byte[] buf = new byte[4096]; + int count; + while((count = in.read(buf)) > -1) { + out.write(buf, 0, count); + } + in.close(); + out.flush(); + out.close(); } /** @@ -969,7 +1027,8 @@ meta.setGeronimoVersions(new String[]{serverInfo.getVersion()}); meta.setJvmVersions(new String[0]); meta.setLicenses(new PluginMetadata.License[0]); - meta.setObsoletes(new String[0]); + meta.setObsoletes(new String[]{new Artifact(data.getId().getGroupId(), data.getId().getArtifactId(), (Version)null, data.getId().getType()).toString()}); + meta.setFilesToCopy(new PluginMetadata.CopyFile[0]); List deps = new ArrayList(); PluginMetadata.Prerequisite prereq = null; prereq = processDependencyList(data.getEnvironment().getDependencies(), prereq, deps); @@ -1107,6 +1166,15 @@ Element elem = (Element) hashList.item(0); hash = new PluginMetadata.Hash(elem.getAttribute("type"), getText(elem)); } + NodeList fileList = plugin.getElementsByTagName("copy-file"); + PluginMetadata.CopyFile[] files = new PluginMetadata.CopyFile[fileList.getLength()]; + for (int i = 0; i < files.length; i++) { + Element node = (Element) fileList.item(i); + String relative = node.getAttribute("relative-to"); + String destDir = node.getAttribute("dest-dir"); + String fileName = getText(node); + files[i] = new PluginMetadata.CopyFile(relative.equals("server"), fileName, destDir); + } boolean eligible = true; NodeList preNodes = plugin.getElementsByTagName("prerequisite"); PluginMetadata.Prerequisite[] prereqs = new PluginMetadata.Prerequisite[preNodes.getLength()]; @@ -1161,6 +1229,7 @@ data.setLicenses(licenses); data.setPrerequisites(prereqs); data.setRepositories(repos); + data.setFilesToCopy(files); NodeList list = plugin.getElementsByTagName("dependency"); List start = new ArrayList(); String deps[] = new String[list.getLength()]; @@ -1384,6 +1453,14 @@ for (int i = 0; i < data.getRepositories().length; i++) { URL url = data.getRepositories()[i]; addTextChild(doc, config, "source-repository", url.toString()); + } + for (int i = 0; i < data.getFilesToCopy().length; i++) { + PluginMetadata.CopyFile file = data.getFilesToCopy()[i]; + Element copy = doc.createElement("copy-file"); + copy.setAttribute("relative-to", file.isRelativeToVar() ? "server" : "geronimo"); + copy.setAttribute("dest-dir", file.getDestDir()); + copy.appendChild(doc.createTextNode(file.getSourceFile())); + config.appendChild(copy); } return doc; } Modified: geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/java/org/apache/geronimo/system/plugin/PluginMetadata.java?rev=406785&r1=406784&r2=406785&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 Mon May 15 17:32:14 2006 @@ -42,6 +42,7 @@ private String[] forceStart = new String[0]; private String[] obsoletes = new String[0]; private URL[] repositories = new URL[0]; + private CopyFile[] filesToCopy = new CopyFile[0]; private final boolean installed; private final boolean eligible; @@ -191,6 +192,16 @@ return eligible; } + /** + * Gets a list of files to copy from the plugin CAR into the server installation. + */ + public CopyFile[] getFilesToCopy() { + return filesToCopy; + } + + public void setFilesToCopy(CopyFile[] filesToCopy) { + this.filesToCopy = filesToCopy; + } public int compareTo(Object o) { PluginMetadata other = (PluginMetadata) o; @@ -234,6 +245,30 @@ public String getValue() { return value; + } + } + + public static class CopyFile implements Serializable { + private final boolean relativeToVar; // if not, relative to the Geronimo install directory + private final String sourceFile; + private final String destDir; + + public CopyFile(boolean relativeToVar, String sourceFile, String destDir) { + this.relativeToVar = relativeToVar; + this.sourceFile = sourceFile; + this.destDir = destDir; + } + + public boolean isRelativeToVar() { + return relativeToVar; + } + + public String getSourceFile() { + return sourceFile; + } + + public String getDestDir() { + return destDir; } } Modified: geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/system/src/schema/plugins-1.1.xsd?rev=406785&r1=406784&r2=406785&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 Mon May 15 17:32:14 2006 @@ -310,6 +310,16 @@ + + + + Lets a plugin include files that should be copied into the Geronimo + installation tree, beyond copying the plugin into the repository. For + example, this could be used to copy files into geronimo/bin, geronimo/lib, + geronimo/var/security/keystores, or other Geronimo dirs. + + + @@ -382,6 +392,52 @@ MD5 SHA-1 + + + + + + + + + + + The name of a file in the plugin archive that should be copied into + the server installation tree somewhere when the plugin is installed. + There may be a path component (relative to the root of the plugin + archive), though that will not be used to construct the destination + location. For example: + + + resources/keystores/my-keystore + + + This will copy the file resources/keystores/my-keystore to e.g. + geronimo/var/security/keystores/my-keystore + + + + + + + + + Indicates whether the destination is relative to the Geronimo install + directory or the server instance var/ directory. The values presently + supported are: + + geronimo + server + + + + + + + + The directory to copy the file to, relative to either the Geronimo + install dir or the server's home directory (normally var/ but may + vary).