fr.inria.atlanmod.neo4emf.neo4jresolver.runtimes.internal.Neo4jZippedInstaller.java Source code

Java tutorial

Introduction

Here is the source code for fr.inria.atlanmod.neo4emf.neo4jresolver.runtimes.internal.Neo4jZippedInstaller.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Atlanmod INRIA LINA Mines Nantes
 * 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:
 *     Atlanmod INRIA LINA Mines Nantes - initial API and implementation
 *******************************************************************************/
package fr.inria.atlanmod.neo4emf.neo4jresolver.runtimes.internal;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;

import fr.inria.atlanmod.neo4emf.neo4jresolver.runtimes.AbstractNeo4jRuntimeInstaller;

/**
 * @author abelgomez
 *
 */
public class Neo4jZippedInstaller extends AbstractNeo4jRuntimeInstaller {

    protected static final int TIMEOUT = 10000;
    private String id;
    private String name;
    private String description;
    private String licenseText;
    private URL url;
    private String version;
    private List<String> jarFiles = new ArrayList<String>();
    private static final int ERROR = -1;
    private static final int UNDEFINED = -2;
    private volatile int size = UNDEFINED;

    public Neo4jZippedInstaller() {
        Thread checkSizeThread = new Thread() {
            @Override
            public void run() {
                try {
                    URLConnection connection = getUrl().openConnection();
                    connection.setConnectTimeout(1000);
                    connection.setReadTimeout(1000);
                    size = connection.getContentLength();
                } catch (Exception e) {
                    size = ERROR;
                }
                notifyListeners();
            }
        };
        checkSizeThread.start();
    }

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the version
     */
    public String getVersion() {
        return version;
    }

    /**
     * @param version the version to set
     */
    public void setVersion(String version) {
        this.version = version;
    }

    /**
     * @return the licenseText
     */
    public String getLicenseText() {
        return licenseText;
    }

    /**
     * @param licenseText the licenseText to set
     */
    public void setLicenseText(String licenseText) {
        this.licenseText = licenseText;
    }

    /**
     * @return the url
     */
    public URL getUrl() {
        return url;
    }

    /**
     * @param url the url to set
     */
    public void setUrl(URL url) {
        this.url = url;
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return getDescriptionText();
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @return the jarFiles
     */
    public List<String> getJarFiles() {
        return jarFiles;
    }

    public String getDescriptionText() {
        StringBuilder builder = new StringBuilder();
        builder.append(description);
        int size = getSize();
        builder.append("\n");
        builder.append("URL: ");
        builder.append(getUrl().toString());
        builder.append("\n");
        builder.append("Download size: ");
        if (size >= 0) {
            builder.append(FileUtils.byteCountToDisplaySize(size));
        } else if (size == UNDEFINED) {
            builder.append(NLS.bind("Connecting to {0} to get the size...", getUrl().toString()));
        } else if (size == ERROR) {
            builder.append(NLS.bind("Unknown (unable to connect to {0})", getUrl().toString()));
        }
        return builder.toString();
    }

    protected int getSize() {
        return size;
    }

    /* (non-Javadoc)
     * @see fr.inria.atlanmod.neo4emf.neo4jresolver.installer.INeo4jInstallerHandler#install(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    public void performInstall(IProgressMonitor monitor, IPath dirPath) throws IOException {
        if (monitor == null) {
            monitor = new NullProgressMonitor();
        }

        InputStream urlStream = null;
        try {
            URL url = getUrl();
            URLConnection connection = url.openConnection();
            connection.setConnectTimeout(TIMEOUT);
            connection.setReadTimeout(TIMEOUT);

            int length = connection.getContentLength();
            monitor.beginTask(NLS.bind("Reading from {1}", getVersion(), getUrl().toString()),
                    length >= 0 ? length : IProgressMonitor.UNKNOWN);

            urlStream = connection.getInputStream();
            ZipInputStream zipStream = new ZipInputStream(urlStream);
            byte[] buffer = new byte[1024 * 8];
            long start = System.currentTimeMillis();
            int total = length;
            int totalRead = 0;
            ZipEntry entry;
            float kBps = -1;
            while ((entry = zipStream.getNextEntry()) != null) {
                if (monitor.isCanceled())
                    break;
                String fullFilename = entry.getName();
                IPath fullFilenamePath = new Path(fullFilename);
                int secsRemaining = (int) ((total - totalRead) / 1024 / kBps);
                String textRemaining = secsToText(secsRemaining);
                monitor.subTask(NLS.bind("{0} remaining. Reading {1}",
                        textRemaining.length() > 0 ? textRemaining : "unknown time", StringUtils
                                .abbreviateMiddle(fullFilenamePath.removeFirstSegments(1).toString(), "...", 45)));
                int entrySize = (int) entry.getCompressedSize();
                OutputStream output = null;
                try {
                    int len = 0;
                    int read = 0;
                    String action = null;
                    if (jarFiles.contains(fullFilename)) {
                        action = "Copying";
                        String filename = FilenameUtils.getName(fullFilename);
                        output = new FileOutputStream(dirPath.append(filename).toOSString());
                    } else {
                        action = "Skipping";
                        output = new NullOutputStream();
                    }
                    int secs = (int) ((System.currentTimeMillis() - start) / 1000);
                    kBps = (float) totalRead / 1024 / secs;

                    while ((len = zipStream.read(buffer)) > 0) {
                        if (monitor.isCanceled())
                            break;
                        read += len;
                        monitor.subTask(NLS.bind("{0} remaining. {1} {2} at {3}KB/s ({4}KB / {5}KB)",
                                new Object[] {
                                        String.format("%s",
                                                textRemaining.length() > 0 ? textRemaining : "unknown time"),
                                        action,
                                        StringUtils.abbreviateMiddle(
                                                fullFilenamePath.removeFirstSegments(1).toString(), "...", 45),
                                        String.format("%,.1f", kBps), String.format("%,.1f", (float) read / 1024),
                                        String.format("%,.1f", (float) entry.getSize() / 1024) }));
                        output.write(buffer, 0, len);
                    }
                    totalRead += entrySize;
                    monitor.worked(entrySize);
                } finally {
                    IOUtils.closeQuietly(output);
                }
            }
        } finally {
            IOUtils.closeQuietly(urlStream);
            monitor.done();
        }
    }

    /**
     * @param secsRemaining
     * @return
     */
    private String secsToText(int secsRemaining) {
        if (secsRemaining < 0)
            return "";
        int mins = secsRemaining / 60;
        int secs = secsRemaining % 60;
        StringBuilder builder = new StringBuilder();
        if (mins > 0)
            builder.append(NLS.bind("{0}min ", mins));
        if (mins > 0 && secs > 0)
            builder.append("and ");
        if (secs > 0)
            builder.append(NLS.bind("{0}s", secs));
        return builder.toString();
    }

}