/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* bstefanescu
*/
package org.eclipse.ecr.build;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*
*/
public class Installer {
protected File installDir;
protected URL repoUrl;
protected Graph graph;
protected ProfileManager profileMgr;
public Installer(File installDir, String repoUrl) throws Exception {
this.installDir = installDir;
try {
this.repoUrl = new URL(repoUrl);
} catch (MalformedURLException e) {
this.repoUrl = new File(repoUrl).toURI().toURL();
}
String url = this.repoUrl.toExternalForm();
String profilesUrl = url;
if (url.endsWith("/")) {
url = url + "content.jar";
profilesUrl = profilesUrl + "profiles.xml";
} else {
url = url + "/content.jar";
profilesUrl = profilesUrl + "/profiles.xml";
}
graph = new GraphLoader().loadZip(new URL(url));
profileMgr = new ProfileManager(profilesUrl);
}
/**
* @return the installDir
*/
public File getInstallDir() {
return installDir;
}
public Set<Node> getResolvedNodes(String profile) throws Exception {
return graph.getResolver().resolveProfile(profileMgr, profile);
}
public void install(String profile) throws Exception {
install(profile, false);
}
public void install(String profile, boolean zipIt) throws Exception {
if (profile == null) {
profile = "default";
}
System.out.println("Using profile: "+profile);
installDir.mkdirs();
Set<Node> nodes = getResolvedNodes(profile);
List<Node> sortedNodes = new ArrayList<Node>(nodes);
Collections.sort(sortedNodes);
System.out.println("Installing plugins");
File dir = new File(installDir, "plugins");
dir.mkdirs();
if (repoUrl.getProtocol().startsWith("http")) {
downloadPlugins(sortedNodes, dir);
} else {
copyPlugins(sortedNodes, dir);
}
System.out.println("Generating configuration");
Map<String, String> vars = generateConfigFile(sortedNodes);
System.out.println("Generating launch scripts");
copyTemplateResource("scripts/run.sh", "run.sh", vars).setExecutable(true);
copyTemplateResource("scripts/run.bat", "run.bat", vars).setExecutable(true);
copyResource("epl-v10.html", "epl-v10.html");
copyResource("notice.html", "notice.html");
File target = installDir;
if (zipIt) {
System.out.println("Zipping");
target = new File(installDir.getParentFile(), installDir.getName()+".zip");
Utils.zipDir(target, installDir, true);
Utils.deleteTree(installDir);
}
System.out.println("Done.");
System.out.println();
System.out.println("Product installed in "+target);
System.out.println();
}
public void copyPlugins(Collection<Node> nodes, File toDir) throws Exception {
File plugins = new File(Utils.toFile(repoUrl), "plugins");
for (Node node : nodes) {
String name = node.getFileName();
Utils.copyFile(new File(plugins, name), new File(toDir, name));
}
}
public void downloadPlugins(Collection<Node> nodes, File toDir) throws Exception {
Downloader downloader = new Downloader();
String plugins = repoUrl.toExternalForm();
if (plugins.endsWith("/")) {
plugins = plugins +"plugins/";
} else {
plugins = plugins +"/plugins/";
}
for (Node node : nodes) {
String name = node.getFileName();
URL url = new URL(plugins+name);
downloader.download(url, new File(toDir, name));
}
downloader.awaitTermination();
}
public Map<String,String> generateConfigFile(Collection<Node> nodes) throws IOException {
HashMap<String, String> vars = new HashMap<String, String>();
File file = new File(installDir, "configuration");
file.mkdirs();
file = new File(file, "config.ini");
String sysBundle = null;
StringBuilder bundles = new StringBuilder();
for (Node node : nodes) {
String name = node.getFileName();
if (name.startsWith("org.eclipse.osgi_")) {
sysBundle = "file\\:plugins/"+name;
vars.put("system.bundle", name);
} else {
if (name.startsWith("org.eclipse.equinox.launcher_")) {
vars.put("launcher.bundle", name);
}
bundles.append(",reference\\:file\\:").append(name);
int startLevel = node.getStartLevel();
if (startLevel > -1) {
if (node.isAutostart()) {
bundles.append("@").append(startLevel).append("\\:start");
} else {
bundles.append("@").append(startLevel);
}
} else if (node.isAutostart()) {
bundles.append("@start");
}
}
}
if (sysBundle == null) {
throw new RuntimeException("No system bundle found!");
}
if (bundles.length() == 0) {
throw new RuntimeException("No bundles found!");
}
FileWriter writer = new FileWriter(file);
try {
writer.write("osgi.configuration.cascaded=false\r\n");
writer.write("osgi.framework="+sysBundle);
writer.write("\r\n");
writer.write("osgi.bundles="+bundles.substring(1));
writer.write("\r\n");
} finally {
writer.close();
}
return vars;
}
protected void copyResource(String path, String toName) throws IOException {
InputStream in = Installer.class.getClassLoader().getResourceAsStream(path);
File file = new File(installDir, toName);
try {
Utils.writeTo(in, file);
file.setExecutable(true);
} finally {
in.close();
}
}
protected File copyTemplateResource(String path, String toName, Map<String,String> vars) throws IOException {
InputStream in = Installer.class.getClassLoader().getResourceAsStream(path);
String data = Utils.read(in);
data = Vars.expand(data, vars);
File file = new File(installDir, toName);
Utils.writeTo(data, file);
return file;
}
}