org.mule.tools.npm.NPMModule.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.tools.npm.NPMModule.java

Source

/**
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 *
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */

package org.mule.tools.npm;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.archiver.tar.TarGZipUnArchiver;
import org.mule.tools.npm.version.VersionResolver;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class NPMModule {

    private String name;
    public String version;
    private Log log;
    private List<NPMModule> dependencies;
    private URL downloadURL;
    private String npmURL;

    public String getName() {
        return name;
    }

    public String getVerion() {
        return version;
    }

    public List<NPMModule> getDependencies() {
        return dependencies;
    }

    public void saveToFileWithDependencies(File file) throws MojoExecutionException {
        this.saveToFile(file);

        for (NPMModule dependency : dependencies) {
            dependency.saveToFileWithDependencies(file);
        }
    }

    public void saveToFile(File file) throws MojoExecutionException {
        URL dl;
        OutputStream os = null;
        InputStream is = null;
        File outputFolderFileTmp = new File(file, name + "_tmp");
        File outputFolderFile = new File(file, name);

        if (outputFolderFile.exists()) {
            //Already downloaded nothing to do
            return;
        }

        outputFolderFileTmp.mkdirs();

        File tarFile = new File(outputFolderFileTmp, name + "-" + version + ".tgz");
        ProgressListener progressListener = new ProgressListener(log);
        log.debug("Downloading " + this.name + ":" + this.version);

        try {
            os = new FileOutputStream(tarFile);
            is = getDownloadURL().openStream();

            DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
            dcount.setListener(progressListener);

            getDownloadURL().openConnection().getHeaderField("Content-Length");

            IOUtils.copy(is, dcount);

        } catch (FileNotFoundException e) {
            throw new MojoExecutionException(String.format("Error downloading module %s:%s", name, version), e);
        } catch (IOException e) {
            throw new MojoExecutionException(String.format("Error downloading module %s:%s", name, version), e);
        } finally {
            IOUtils.closeQuietly(os);
            IOUtils.closeQuietly(is);
        }

        final TarGZipUnArchiver ua = new TarGZipUnArchiver();
        ua.enableLogging(new LoggerAdapter(log));
        ua.setSourceFile(tarFile);
        ua.setDestDirectory(outputFolderFileTmp);
        ua.extract();

        FileUtils.deleteQuietly(tarFile);

        File fileToMove;

        File[] files = outputFolderFileTmp.listFiles();
        if (files != null && files.length == 1) {
            fileToMove = files[0];

        } else {
            File aPackage = new File(outputFolderFileTmp, "package");
            if (aPackage.exists() && aPackage.isDirectory()) {
                fileToMove = aPackage;
            } else {
                throw new MojoExecutionException(String.format(
                        "Only one file should be present at the folder when " + "unpacking module %s:%s: ", name,
                        version));
            }
        }

        try {
            FileUtils.moveDirectory(fileToMove, outputFolderFile);
        } catch (IOException e) {
            throw new MojoExecutionException(String.format(
                    "Error moving to the final folder when " + "unpacking module %s:%s: ", name, version), e);
        }

        try {
            FileUtils.deleteDirectory(outputFolderFileTmp);
        } catch (IOException e) {
            log.info("Error while deleting temporary folder: " + outputFolderFileTmp, e);
        }

    }

    private void downloadDependencies(Map dependenciesMap) throws IOException, MojoExecutionException {
        for (Object dependencyAsObject : dependenciesMap.entrySet()) {
            Map.Entry dependency = (Map.Entry) dependencyAsObject;
            String dependencyName = (String) dependency.getKey();

            String version = ((String) dependency.getValue());

            try {
                version = new VersionResolver(npmURL).getNextVersion(log, dependencyName, version);
                dependencies.add(fromNameAndVersion(npmURL, log, dependencyName, version));
            } catch (Exception e) {
                throw new RuntimeException(
                        "Error resolving dependency: " + dependencyName + ":" + version + " not found.", e);
            }

        }
    }

    public static Set downloadMetadataList(String npmURL, String name) throws IOException, JsonParseException {
        URL dl = new URL(String.format(npmURL, name, ""));
        ObjectMapper objectMapper = new ObjectMapper();
        Map allVersionsMetadata = objectMapper.readValue(dl, Map.class);
        return ((Map) allVersionsMetadata.get("versions")).keySet();
    }

    private Map downloadMetadata(String name, String version) throws IOException, JsonParseException {
        return downloadMetadata(new URL(String.format(npmURL, name, version != null ? version : "latest")));
    }

    public static Map downloadMetadata(URL dl) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.readValue(dl, Map.class);
        } catch (IOException e) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e1) {
            }
            return objectMapper.readValue(dl, Map.class);
        }
    }

    private void downloadModule() throws MojoExecutionException {

        try {
            Map jsonMap = downloadMetadata(name, version);

            Map distMap = (Map) jsonMap.get("dist");
            this.downloadURL = new URL((String) distMap.get("tarball"));
            this.version = (String) jsonMap.get("version");

            Map dependenciesMap = (Map) jsonMap.get("dependencies");

            if (dependenciesMap != null) {
                downloadDependencies(dependenciesMap);
            }

        } catch (MalformedURLException e) {
            throw new MojoExecutionException(String.format("Error downloading module info %s:%s", name, version),
                    e);
        } catch (JsonMappingException e) {
            throw new MojoExecutionException(String.format("Error downloading module info %s:%s", name, version),
                    e);
        } catch (JsonParseException e) {
            throw new MojoExecutionException(String.format("Error downloading module info %s:%s", name, version),
                    e);
        } catch (IOException e) {
            throw new MojoExecutionException(String.format("Error downloading module info %s:%s", name, version),
                    e);
        }
    }

    private NPMModule(String npmURL) {
        this.npmURL = npmURL;
    }

    public static NPMModule fromQueryString(String npmURL, Log log, String nameAndVersion)
            throws MojoExecutionException {
        String[] splitNameAndVersion = nameAndVersion.split(":");
        return fromNameAndVersion(npmURL, log, splitNameAndVersion[0], splitNameAndVersion[1]);
    }

    public static NPMModule fromNameAndVersion(String npmUrl, Log log, String name, String version)
            throws IllegalArgumentException, MojoExecutionException {
        NPMModule module = new NPMModule(npmUrl);
        module.log = log;
        module.name = name;

        if ("*".equals(version)) {
            throw new IllegalArgumentException();
        }

        module.version = version;
        module.dependencies = new ArrayList<NPMModule>();
        module.downloadModule();
        return module;
    }

    public URL getDownloadURL() {
        return downloadURL;
    }

    public static NPMModule fromName(String npmURL, Log log, String name) throws MojoExecutionException {
        return fromNameAndVersion(npmURL, log, name, null);
    }

}