package com.aptana.ide.desktop.integration.protocolhandler;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.text.MessageFormat;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IStartup;
import com.aptana.ide.core.IdeLog;
import com.aptana.ide.core.PlatformUtils;
import com.aptana.ide.core.SetExecutableBits;
import com.aptana.ide.desktop.integration.protocolhandler.preferences.IPreferenceConstants;
public class ProtocolHandlerStartup implements IStartup {
private static final String ECLIPSE_LAUNCHER_TOKEN = Pattern.quote("@eclipse.launcher@"); //$NON-NLS-1$
public void earlyStartup() {
// Register protocol handler on the first run only
IPreferenceStore prefs = getPluginActivator().getPreferenceStore();
if (prefs
.getBoolean(IPreferenceConstants.APTANA_PLUGIN_INSTALLER_PROTOCOL_HANDLER_REGISTERED)
&& !Boolean.getBoolean("ALWAYS_REGISTER_PROTOCOL")) { //$NON-NLS-1$
return;
}
// Mark it as registered - only one attempt?
prefs.setValue(IPreferenceConstants.APTANA_PLUGIN_INSTALLER_PROTOCOL_HANDLER_REGISTERED, true);
if (Platform.OS_WIN32.equals(Platform.getOS())) {
registerOnWindows();
} else if (Platform.OS_LINUX.equals(Platform.getOS())) {
registerOnLinux();
} else if (Platform.OS_MACOSX.equals(Platform.getOS())) {
registerOnMac();
}
}
public static void registerOnWindows() {
File protocolhandlerFolder = getProtocolHandlerFolder();
if (protocolhandlerFolder == null) {
return;
}
String eclipseLauncher = getEclipseLauncherPath();
if (eclipseLauncher == null) {
return;
}
eclipseLauncher = Matcher.quoteReplacement(eclipseLauncher);
File templateFile = new File(protocolhandlerFolder, "aptanaplugininstaller.reg.template"); //$NON-NLS-1$
if (templateFile.exists()) {
try {
File regFile = File.createTempFile("aptanaplugininstaller", ".reg"); //$NON-NLS-1$ //$NON-NLS-2$
IdeLog
.logInfo(
getPluginActivator(),
"aptanaplugininstaller: protocol registration file: " + regFile); //$NON-NLS-1$
try {
// Now copy from templateFile to regFile replacing @ECLIPSE.LAUNCHER@ with Product launcher path
BufferedReader br = new BufferedReader(new FileReader(templateFile));
PrintWriter pr = new PrintWriter(new FileWriter(regFile));
try {
String aLine;
while ((aLine = br.readLine()) != null) {
aLine = aLine.replaceAll(ECLIPSE_LAUNCHER_TOKEN, eclipseLauncher);
pr.println(aLine);
}
} finally {
pr.flush();
pr.close();
br.close();
}
if (PlatformUtils.isUserAdmin()) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(
"cmd" //$NON-NLS-1$
,"/C" //$NON-NLS-1$
,"regedit.exe" //$NON-NLS-1$
,"/s" //$NON-NLS-1$
,regFile.getAbsolutePath()
);
IdeLog.logInfo(getPluginActivator(), "Running : " + processBuilder); //$NON-NLS-1$
Process process = processBuilder.start();
try {
int exitStatus = process.waitFor();
if (exitStatus != 0) {
IdeLog
.logError(
getPluginActivator(),
processBuilder.toString()
+ " Exist status : " + exitStatus); //$NON-NLS-1$
}
} catch (InterruptedException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
} else {
PlatformUtils.runAsAdmin("cmd", //$NON-NLS-1$
new String[] {
"/C" //$NON-NLS-1$
,"regedit.exe" //$NON-NLS-1$
,"/s" //$NON-NLS-1$
,regFile.getAbsolutePath()});
}
} finally {
regFile.deleteOnExit();
}
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
}
}
public static void registerOnLinux() {
File protocolhandlerFolder = getProtocolHandlerFolder();
if (protocolhandlerFolder == null) {
return;
}
String eclipseLauncher = getEclipseLauncherPath();
if (eclipseLauncher == null) {
return;
}
File templateFile = new File(protocolhandlerFolder, "registeraptanaplugininstall.sh.template"); //$NON-NLS-1$
if (templateFile.exists()) {
try {
File regFile = File.createTempFile("registeraptanaplugininstall", ".sh"); //$NON-NLS-1$ //$NON-NLS-2$
IdeLog.logInfo(getPluginActivator(), "aptanaplugininstaller: protocol registration file: " + regFile); //$NON-NLS-1$
try {
// Now copy from templateFile to regFile replacing @ECLIPSE.LAUNCHER@ with Product launcher path
BufferedReader br = new BufferedReader(new FileReader(templateFile));
PrintWriter pr = new PrintWriter(new FileWriter(regFile));
try {
String aLine;
while ((aLine = br.readLine()) != null) {
aLine = aLine.replaceAll(ECLIPSE_LAUNCHER_TOKEN, eclipseLauncher);
pr.println(aLine);
}
} finally {
pr.flush();
pr.close();
br.close();
}
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(
"/bin/bash" //$NON-NLS-1$
, "--norc" //$NON-NLS-1$
, "--noprofile" //$NON-NLS-1$
,regFile.getAbsolutePath()
);
IdeLog.logInfo(getPluginActivator(), "Running : " + processBuilder); //$NON-NLS-1$
Process process;
try {
process = processBuilder.start();
int exitStatus = process.waitFor();
if (exitStatus != 0) {
IdeLog.logError(getPluginActivator(), processBuilder.toString() + " Exist status : " + exitStatus); //$NON-NLS-1$
}
} catch (InterruptedException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
} finally {
regFile.deleteOnExit();
}
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
}
}
public static void registerOnMac() {
File protocolhandlerFolder = getProtocolHandlerFolder();
if (protocolhandlerFolder == null) {
return;
}
String eclipseLauncher = getEclipseLauncherPath();
if (eclipseLauncher == null) {
return;
}
// unjar the protocol handler app
File protocolApp = new File(protocolhandlerFolder,
"AptanaStudio.app.jar"); //$NON-NLS-1$
IdeLog.logInfo(getPluginActivator(), MessageFormat.format(
Messages.ProtocolHandlerStartup_INF_UnjarringApp, protocolApp));
JarInputStream input = null;
try {
input = new JarInputStream(new FileInputStream(protocolApp));
// unjar the content
File contentFile;
JarEntry entry;
byte[] b = new byte[10000];
int nread;
while ((entry = input.getNextJarEntry()) != null) {
contentFile = new File(protocolhandlerFolder, entry.toString());
// creates the parent directory if it does not exist
// yet
if (!contentFile.getParentFile().exists()) {
contentFile.getParentFile().mkdirs();
}
if (entry.isDirectory()) {
contentFile.mkdir();
} else {
FileOutputStream out = null;
try {
out = new FileOutputStream(contentFile);
while ((nread = input.read(b, 0, b.length)) >= 0) {
out.write(b, 0, nread);
}
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
}
}
}
}
}
} catch (FileNotFoundException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
}
}
}
IdeLog.logInfo(getPluginActivator(), MessageFormat.format(
Messages.ProtocolHandlerStartup_INF_FinishedUnJar, protocolApp));
// modifies the proper executable permissions
(new SetExecutableBits(ProtocolHandlerActivator.getDefault().getBundle())).schedule();
File templateFile = new File(protocolhandlerFolder, "AptanaStudio.app/Contents/Resources/Scripts/API.sh.tmpl"); //$NON-NLS-1$
if (templateFile.exists()) {
try {
File regFile = new File(protocolhandlerFolder, "AptanaStudio.app/Contents/Resources/Scripts/AptanaPluginInstaller.sh"); //$NON-NLS-1$
IdeLog.logInfo(getPluginActivator(), "aptanaplugininstaller: protocol launcher file: " + regFile); //$NON-NLS-1$
// Now copy from templateFile to regFile replacing @ECLIPSE.LAUNCHER@ with Product launcher path
BufferedReader br = new BufferedReader(new FileReader(templateFile));
PrintWriter pr = new PrintWriter(new FileWriter(regFile));
try {
String aLine;
while ((aLine = br.readLine()) != null) {
aLine = aLine.replaceAll(ECLIPSE_LAUNCHER_TOKEN, eclipseLauncher);
pr.println(aLine);
}
} finally {
pr.flush();
pr.close();
br.close();
}
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
}
templateFile = new File(protocolhandlerFolder, "AptanaStudio.app/Contents/Resources/Scripts/AOF.sh.tmpl"); //$NON-NLS-1$
if (templateFile.exists()) {
try {
File regFile = new File(protocolhandlerFolder, "AptanaStudio.app/Contents/Resources/Scripts/AptanaOpenFiles.sh"); //$NON-NLS-1$
IdeLog.logInfo(getPluginActivator(), "file open handler file: " + regFile); //$NON-NLS-1$
// Now copy from templateFile to regFile replacing @ECLIPSE.LAUNCHER@ with Product launcher path
BufferedReader br = new BufferedReader(new FileReader(templateFile));
PrintWriter pr = new PrintWriter(new FileWriter(regFile));
try {
String aLine;
while ((aLine = br.readLine()) != null) {
aLine = aLine.replaceAll(ECLIPSE_LAUNCHER_TOKEN, eclipseLauncher);
pr.println(aLine);
}
} finally {
pr.flush();
pr.close();
br.close();
}
} catch (IOException e) {
IdeLog.logError(getPluginActivator(), e.getMessage(), e);
}
}
}
private static File getProtocolHandlerFolder() {
File protocolhandlerFolder = null;
URL protocolhandlerEntry = ProtocolHandlerActivator.getDefault().getBundle().getEntry("/protocolhandler"); //$NON-NLS-1$
try {
if (protocolhandlerEntry != null) {
String protocolhandlerEntryPath = FileLocator.toFileURL(protocolhandlerEntry).getFile();
if (protocolhandlerEntryPath != null) {
protocolhandlerFolder = new File(protocolhandlerEntryPath);
}
}
} catch (IOException el) {
}
if (protocolhandlerFolder == null || (protocolhandlerFolder.exists() && (!protocolhandlerFolder.isDirectory()))) {
IdeLog.logError(getPluginActivator(), Messages.ProtocolHandlerStartup_ERR_CannotLocateProtocolhandler);
return null;
}
return protocolhandlerFolder;
}
private static String getEclipseLauncherPath() {
String eclipseLauncher = System.getProperty("eclipse.launcher"); //$NON-NLS-1$
if (eclipseLauncher == null) {
IdeLog.logError(getPluginActivator(), Messages.ProtocolHandlerStartup_ERR_CannotLocateLauncher);
return null;
}
return Matcher.quoteReplacement(eclipseLauncher);
}
private static ProtocolHandlerActivator getPluginActivator() {
return ProtocolHandlerActivator.getDefault();
}
}