Java tutorial
/** * Aptana Studio * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions). * Please see the license.html included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.aptana.portal.ui.dispatch.configurationProcessors; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.osgi.framework.Version; import com.aptana.configurations.processor.AbstractConfigurationProcessor; import com.aptana.configurations.processor.ConfigurationStatus; import com.aptana.core.logging.IdeLog; import com.aptana.core.util.InputStreamGobbler; import com.aptana.core.util.StringUtil; import com.aptana.core.util.VersionUtil; import com.aptana.ide.core.io.downloader.DownloadManager; import com.aptana.jetty.util.epl.ajax.JSON; import com.aptana.portal.ui.IPortalPreferences; import com.aptana.portal.ui.PortalUIPlugin; import com.aptana.ui.util.UIUtils; /** * Basic, abstract implementation, of a processor that deals with installing software. * * @author Shalom Gibly <sgibly@aptana.com> */ public abstract class InstallerConfigurationProcessor extends AbstractConfigurationProcessor { protected static final String APTANA_PROPERTIES_FILE_NAME = ".aptana"; //$NON-NLS-1$ protected static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ protected static final String INSTALL_DIR_ATTRIBUTE = "install_dir"; //$NON-NLS-1$ protected String[] downloadedPaths; /* * (non-Javadoc) * @see com.aptana.configurations.processor.AbstractConfigurationProcessor#computeStatus(org.eclipse.core.runtime. * IProgressMonitor, java.lang.Object) */ @Override public ConfigurationStatus computeStatus(IProgressMonitor progressMonitor, Object attributes) { // This one does nothing. We should compute the status in the generic VersionsConfigurationProcessor return configurationStatus; } /** * Returns the application's name. * * @return The application's name (e.g. XAMPP, Ruby) */ protected abstract String getApplicationName(); /** * Download the remote content and store it the temp directory. * * @param URLs * @param progressMonitor */ public IStatus download(String[] URLs, IProgressMonitor progressMonitor) { if (URLs.length == 0) { String err = Messages.InstallerConfigurationProcessor_missingDownloadTargets; applyErrorAttributes(err); IdeLog.logError(PortalUIPlugin.getDefault(), "We expected an array of URLs, but got an empty array.", //$NON-NLS-1$ new Exception(err)); return new Status(IStatus.ERROR, PortalUIPlugin.PLUGIN_ID, err); } downloadedPaths = null; DownloadManager downloadManager = new DownloadManager(); List<URL> urlsList = new ArrayList<URL>(URLs.length); for (int i = 0; i < URLs.length; i++) { try { urlsList.add(new URL(urls[i])); } catch (MalformedURLException mue) { IdeLog.logError(PortalUIPlugin.getDefault(), mue); } } try { downloadManager.addURLs(urlsList); IStatus status = downloadManager.start(progressMonitor); if (status.isOK()) { downloadedPaths = downloadManager.getContentsLocations(); } return status; } catch (Exception e) { IdeLog.logError(PortalUIPlugin.getDefault(), e); } return Status.CANCEL_STATUS; } /** * Cache the installed application location and version in the preferences. * * @param installDir * - The directory the application was installed to. * @param versionedFileLocation * - Can be the URL that we grabbed the installer from, or any other string that contains a version * information in a form of x.y.z. * @param appName * - The application name (e.g. xampp) */ @SuppressWarnings("unchecked") public void cacheVersion(String installDir, String versionedFileLocation, String appName) { IPreferenceStore preferenceStore = PortalUIPlugin.getDefault().getPreferenceStore(); String versions = preferenceStore.getString(IPortalPreferences.CACHED_VERSIONS_PROPERTY_NAME); Map<String, Map<String, String>> versionsMap = null; if (versions == null || versions.equals(StringUtil.EMPTY)) { versionsMap = new HashMap<String, Map<String, String>>(); } else { versionsMap = (Map<String, Map<String, String>>) JSON.parse(versions); } Map<String, String> appVersionMap = new HashMap<String, String>(); Version version = VersionUtil.parseVersion(versionedFileLocation); if (version != null) { appVersionMap.put(IPortalPreferences.CACHED_VERSION_PROPERTY, version.toString()); appVersionMap.put(IPortalPreferences.CACHED_LOCATION_PROPERTY, installDir); versionsMap.put(appName.toLowerCase(), appVersionMap); preferenceStore.setValue(IPortalPreferences.CACHED_VERSIONS_PROPERTY_NAME, JSON.toString(versionsMap)); } else { IdeLog.logError(PortalUIPlugin.getDefault(), MessageFormat.format( "Could not cache the location and version for {0}. Install dir: {1}, versionedFileLocation: {2}", //$NON-NLS-1$ appName, installDir, versionedFileLocation), new Exception()); } } /** * Extract the given zip file into the target folder on a Windows machine. * * @param sfxZip * Self extracting 7zip file. * @param targetFolder * @return The status of that extraction result. */ public static IStatus extractWin(String sfxZip, String targetFolder) { IStatus errorStatus = new Status(IStatus.ERROR, PortalUIPlugin.PLUGIN_ID, Messages.InstallerConfigurationProcessor_unableToExtractZip); if (!Platform.OS_WIN32.equals(Platform.getOS())) { IdeLog.logError(PortalUIPlugin.getDefault(), "Unable to extract the Zip file. A Windows OS extractor was called for a non-Windows platform.", //$NON-NLS-1$ new Exception()); return errorStatus; } if (sfxZip == null || targetFolder == null) { IdeLog.logError(PortalUIPlugin.getDefault(), "Undefined zip file or target folder", new Exception()); //$NON-NLS-1$ return errorStatus; } File destinationFolder = new File(targetFolder); if (!destinationFolder.exists() && !destinationFolder.mkdirs()) { IdeLog.logError(PortalUIPlugin.getDefault(), "Failed to create destination directory " + destinationFolder, new Exception()); //$NON-NLS-1$ return errorStatus; } ProcessBuilder processBuilder = new ProcessBuilder(sfxZip, "-o" + targetFolder, //$NON-NLS-1$ "-y", //$NON-NLS-1$ sfxZip); processBuilder.directory(destinationFolder); processBuilder.redirectErrorStream(true); String output = null; try { Process process = processBuilder.start(); InputStreamGobbler errorGobbler = new InputStreamGobbler(process.getErrorStream(), "\n", null); //$NON-NLS-1$ InputStreamGobbler outputGobbler = new InputStreamGobbler(process.getInputStream(), "\n", null); //$NON-NLS-1$ outputGobbler.start(); errorGobbler.start(); process.waitFor(); outputGobbler.interrupt(); errorGobbler.interrupt(); outputGobbler.join(); errorGobbler.join(); output = outputGobbler.getResult(); String errors = errorGobbler.getResult(); int exitVal = process.exitValue(); if (exitVal == 0) { return Status.OK_STATUS; } else { IdeLog.logError(PortalUIPlugin.getDefault(), "Zip extraction failed. The process returned " + exitVal, //$NON-NLS-1$ new Exception("Process output:\n" + errors)); //$NON-NLS-1$ return errorStatus; } } catch (Exception e) { IdeLog.logError(PortalUIPlugin.getDefault(), e); return errorStatus; } finally { if (output != null) { IdeLog.logInfo(PortalUIPlugin.getDefault(), output); } } } /** * Display a message dialog in a UI thread. * * @param kind * See {@link MessageDialog} for the types allowed. * @param title * @param message */ public void displayMessageInUIThread(final int kind, final String title, final String message) { UIUtils.showMessageDialogFromBgThread(kind, title, message, null); } /** * Finalize the installation. <br> * This implementation just marks to delete on exit any downaloaded file. * * @param installDir */ protected void finalizeInstallation(String installDir) { deleteDownloadedPaths(); // Cache the version and the location of the installed app. // We assume here that the version of app is specified in the install URL! if (installDir != null) { cacheVersion(installDir, urls[0], getApplicationName()); } } /** * Mark the downloaded paths to be deleted on exit. */ protected void deleteDownloadedPaths() { if (downloadedPaths != null) { for (String f : downloadedPaths) { File toDelete = new File(f); if (toDelete.exists()) { toDelete.deleteOnExit(); } } } } }