| /******************************************************************************* |
| * Copyright (c) 2007, 2011 IBM Corporation 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: |
| * IBM Corporation - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.server.core.internal; |
| |
| import java.io.BufferedInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.URL; |
| import java.util.zip.GZIPInputStream; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipInputStream; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.server.core.internal.tar.TarEntry; |
| import org.eclipse.wst.server.core.internal.tar.TarInputStream; |
| /** |
| * |
| */ |
| public class InstallableRuntime2 implements IInstallableRuntime { |
| private IConfigurationElement element; |
| private byte[] BUFFER = null; |
| |
| // Default sizes (infinite logarithmic progress will be used when default is employed) |
| private int DEFAULT_DOWNLOAD_SIZE = 10000000; |
| private int DEFAULT_FILE_COUNT = 1000; |
| |
| public InstallableRuntime2(IConfigurationElement element) { |
| super(); |
| this.element = element; |
| } |
| |
| /** |
| * |
| * @return the id |
| */ |
| public String getId() { |
| try { |
| return element.getAttribute("id"); |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| public String getName() { |
| return getArchivePath(); |
| } |
| |
| public String getArchiveUrl() { |
| try { |
| return element.getAttribute("archiveUrl"); |
| } catch (Exception e) { |
| // ignore |
| } |
| return null; |
| } |
| |
| public String getArchivePath() { |
| try { |
| return element.getAttribute("archivePath"); |
| } catch (Exception e) { |
| // ignore |
| } |
| return null; |
| } |
| |
| public int getArchiveSize() { |
| try { |
| String size = element.getAttribute("archiveSize"); |
| return Integer.parseInt(size); |
| } catch (Exception e) { |
| // ignore |
| } |
| return -1; |
| } |
| |
| public int getFileCount() { |
| try { |
| String size = element.getAttribute("fileCount"); |
| return Integer.parseInt(size); |
| } catch (Exception e) { |
| // ignore |
| } |
| return -1; |
| } |
| |
| public String getLicenseURL() { |
| try { |
| return element.getAttribute("licenseUrl"); |
| } catch (Exception e) { |
| // ignore |
| } |
| return null; |
| } |
| |
| /* |
| * @see IInstallableRuntime#getLicense(IProgressMonitor) |
| */ |
| public String getLicense(IProgressMonitor monitor) throws CoreException { |
| URL url = null; |
| ByteArrayOutputStream out = null; |
| try { |
| String licenseURL = getLicenseURL(); |
| if (licenseURL == null) |
| return null; |
| |
| url = new URL(licenseURL); |
| InputStream in = url.openStream(); |
| out = new ByteArrayOutputStream(); |
| copyWithSize(in, out, null, 0); |
| return new String(out.toByteArray()); |
| } catch (Exception e) { |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Error loading license", e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, |
| NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e)); |
| } finally { |
| try { |
| if (out != null) |
| out.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| |
| /* |
| * @see IInstallableRuntime#install(IPath) |
| */ |
| public void install(final IPath path) { |
| Job installRuntimeJob = new Job(Messages.jobInstallingRuntime) { |
| public boolean belongsTo(Object family) { |
| return ServerPlugin.PLUGIN_ID.equals(family); |
| } |
| |
| protected IStatus run(IProgressMonitor monitor) { |
| try { |
| install(path, monitor); |
| } catch (CoreException ce) { |
| return ce.getStatus(); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| |
| installRuntimeJob.schedule(); |
| } |
| |
| private void copyWithSize(InputStream in, OutputStream out, IProgressMonitor monitor, int size) throws IOException { |
| if (BUFFER == null) |
| BUFFER = new byte[8192]; |
| SubMonitor progress = SubMonitor.convert(monitor, size); |
| int r = in.read(BUFFER); |
| while (r >= 0) { |
| out.write(BUFFER, 0, r); |
| progress.worked(r); |
| r = in.read(BUFFER); |
| } |
| } |
| |
| private void download(InputStream in, OutputStream out, IProgressMonitor monitor, String name, int size) throws IOException { |
| if (BUFFER == null) |
| BUFFER = new byte[8192]; |
| |
| String msg = NLS.bind((size > 0) ? Messages.taskDownloadSizeKnown : Messages.taskDownloadSizeUnknown, |
| new Object [] { name, "{0}", Integer.toString(size / 1024) }); |
| SubMonitor progress = SubMonitor.convert(monitor, NLS.bind(msg, "0"), (size > 0) ? size : DEFAULT_DOWNLOAD_SIZE); |
| |
| int r = in.read(BUFFER); |
| int total = 0; |
| int lastTotal = 0; |
| while (r >= 0) { |
| out.write(BUFFER, 0, r); |
| total += r; |
| if (total >= lastTotal + 8192) { |
| lastTotal = total; |
| progress.subTask(NLS.bind(msg, Integer.toString(lastTotal / 1024))); |
| } |
| progress.worked(r); |
| // if size is not known, use infinite logarithmic progress |
| if (size <= 0) |
| progress.setWorkRemaining(DEFAULT_DOWNLOAD_SIZE); |
| |
| if (progress.isCanceled()) |
| break; |
| r = in.read(BUFFER); |
| } |
| } |
| |
| /* |
| * @see IInstallableRuntime#install(IPath, IProgressMonitor) |
| */ |
| public void install(IPath path, IProgressMonitor monitor) throws CoreException { |
| SubMonitor progress = SubMonitor.convert(monitor, 1000); |
| URL url = null; |
| File temp = null; |
| try { |
| url = new URL(getArchiveUrl()); |
| temp = File.createTempFile("runtime", ""); |
| temp.deleteOnExit(); |
| } catch (IOException e) { |
| if (monitor != null) |
| monitor.done(); |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Error creating url and temp file", e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, |
| NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e)); |
| } |
| String name = url.getPath(); |
| int slashIdx = name.lastIndexOf('/'); |
| if (slashIdx >= 0) |
| name = name.substring(slashIdx + 1); |
| |
| int archiveSize = getArchiveSize(); |
| |
| // download |
| FileOutputStream fout = null; |
| try { |
| InputStream in = url.openStream(); |
| fout = new FileOutputStream(temp); |
| download(in, fout, progress.newChild(500), name, archiveSize); |
| progress.setWorkRemaining(500); |
| } catch (Exception e) { |
| if (monitor != null) |
| monitor.done(); |
| if (Trace.WARNING) { |
| Trace.trace(Trace.STRING_WARNING, "Error downloading runtime", e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, |
| NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e)); |
| } finally { |
| try { |
| if (fout != null) |
| fout.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| if (progress.isCanceled()) |
| throw new CoreException(Status.CANCEL_STATUS); |
| |
| FileInputStream in = null; |
| try { |
| in = new FileInputStream(temp); |
| if (name.endsWith("zip")) |
| unzip(in, path, progress.newChild(500)); |
| else if (name.endsWith("tar")) |
| untar(in, path, progress.newChild(500)); |
| else if (name.endsWith("tar.gz")) { |
| File tarFile = File.createTempFile("runtime", ".tar"); |
| tarFile.deleteOnExit(); |
| String tarName = name; |
| if (slashIdx >= 0) |
| tarName = name.substring(0, name.length() - 3); |
| |
| progress.subTask(NLS.bind(Messages.taskUncompressing, tarName)); |
| int tempSize = Integer.MAX_VALUE; |
| if (temp.length() < Integer.MAX_VALUE) |
| tempSize = (int)temp.length(); |
| |
| ungzip(in, tarFile, progress.newChild(250), tempSize); |
| progress.setWorkRemaining(250); |
| if (!progress.isCanceled()) { |
| in = new FileInputStream(tarFile); |
| untar(in, path, progress.newChild(250)); |
| } |
| } |
| } catch (Exception e) { |
| if (Trace.SEVERE) { |
| Trace.trace(Trace.STRING_SEVERE, "Error uncompressing runtime", e); |
| } |
| throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, |
| NLS.bind(Messages.errorInstallingServer, e.getLocalizedMessage()), e)); |
| } finally { |
| try { |
| if (in != null) |
| in.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| progress.done(); |
| } |
| } |
| |
| /** |
| * Unzip the input stream into the given path. |
| * |
| * @param in |
| * @param path |
| * @param monitor |
| * @throws IOException |
| */ |
| private void unzip(InputStream in, IPath path, IProgressMonitor monitor) throws IOException { |
| int fileCnt = getFileCount(); |
| SubMonitor progress = SubMonitor.convert(monitor, (fileCnt > 0) ? fileCnt : DEFAULT_FILE_COUNT); |
| String archivePath = getArchivePath(); |
| BufferedInputStream bin = new BufferedInputStream(in); |
| ZipInputStream zin = new ZipInputStream(bin); |
| ZipEntry entry = zin.getNextEntry(); |
| while (entry != null) { |
| String name = entry.getName(); |
| progress.subTask(NLS.bind(Messages.taskUncompressing, name)); |
| if (archivePath != null && name.startsWith(archivePath)) { |
| name = name.substring(archivePath.length()); |
| if (name.length() > 1) |
| name = name.substring(1); |
| } |
| |
| if (name != null && name.length() > 0) { |
| if (entry.isDirectory()) |
| path.append(name).toFile().mkdirs(); |
| else { |
| FileOutputStream fout = new FileOutputStream(path.append(name).toFile()); |
| copyWithSize(zin, fout, progress.newChild(1), (int)entry.getSize()); |
| fout.close(); |
| // if count is not known, use infinite logarithmic progress |
| if (fileCnt <= 0) |
| progress.setWorkRemaining(DEFAULT_FILE_COUNT); |
| } |
| } |
| zin.closeEntry(); |
| entry = zin.getNextEntry(); |
| } |
| zin.close(); |
| } |
| |
| /** |
| * Untar the input stream into the given path. |
| * |
| * @param in |
| * @param path |
| * @param monitor |
| * @throws IOException |
| */ |
| protected void untar(InputStream in, IPath path, IProgressMonitor monitor) throws IOException { |
| int fileCnt = getFileCount(); |
| SubMonitor progress = SubMonitor.convert(monitor, (fileCnt > 0) ? fileCnt : 500); |
| String archivePath = getArchivePath(); |
| BufferedInputStream bin = new BufferedInputStream(in); |
| TarInputStream zin = new TarInputStream(bin); |
| TarEntry entry = zin.getNextEntry(); |
| while (entry != null) { |
| String name = entry.getName(); |
| progress.subTask(NLS.bind(Messages.taskUncompressing, name)); |
| if (archivePath != null && name.startsWith(archivePath)) { |
| name = name.substring(archivePath.length()); |
| if (name.length() > 1) |
| name = name.substring(1); |
| } |
| |
| if (name != null && name.length() > 0) { |
| if (entry.getFileType() == TarEntry.DIRECTORY) |
| path.append(name).toFile().mkdirs(); |
| else { |
| File dir = path.append(name).removeLastSegments(1).toFile(); |
| if (!dir.exists()) |
| dir.mkdirs(); |
| |
| FileOutputStream fout = new FileOutputStream(path.append(name).toFile()); |
| copyWithSize(zin, fout, progress.newChild(1), (int)entry.getSize()); |
| fout.close(); |
| if (fileCnt <= 0) |
| progress.setWorkRemaining(500); |
| } |
| } |
| entry = zin.getNextEntry(); |
| } |
| zin.close(); |
| } |
| |
| protected void ungzip(InputStream in, File tarFile, IProgressMonitor monitor, int size) throws IOException { |
| GZIPInputStream gzin = null; |
| FileOutputStream fout = null; |
| try { |
| gzin = new GZIPInputStream(in); |
| fout = new FileOutputStream(tarFile); |
| copyWithSize(gzin, fout, monitor, size); |
| } finally { |
| if (gzin != null) { |
| try { |
| gzin.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| if (fout != null) { |
| try { |
| fout.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| } |
| } |
| |
| public String toString() { |
| return "InstallableRuntime2[" + getId() + "]"; |
| } |
| } |