Package org.jnode.build

Source Code of org.jnode.build.InitJarBuilder$BuildPluginJar

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.build;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.GZip;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.taskdefs.Manifest;
import org.apache.tools.ant.types.FileSet;
import org.jnode.build.packager.PluginListInsertor;
import org.jnode.plugin.PluginDescriptor;
import org.jnode.plugin.PluginException;
import org.jnode.plugin.PluginPrerequisite;
import org.jnode.plugin.model.PluginJar;

/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public class InitJarBuilder extends AbstractPluginsTask {

    private File destDir;

    private File destFile;
   
    private PluginListInsertor insertor;

    public void execute() throws BuildException {

        final long start = System.currentTimeMillis();

        final PluginList piList;
        final PluginList systemPluginList;
        final long lmPI;
        try {
            piList = getPluginList();

            if (insertor != null) {
                insertor.insertInto(piList);
            }

            systemPluginList = getSystemPluginList();
            if ((destFile == null) && (destDir != null)) {
                destFile = new File(destDir, piList.getName() + ".jgz");
            }
            lmPI = Math.max(piList.lastModified(), systemPluginList.lastModified());
        } catch (PluginException ex) {
            throw new BuildException(ex);
        } catch (IOException ex) {
            throw new BuildException(ex);
        }

        final long lmDest = destFile.lastModified();
        final long lmPIL = getPluginListFile().lastModified();

        if ((lmPIL < lmDest) && (lmPI < lmDest)) {
            // No need to do anything, skip
            return;
        }
        destFile.delete();
        final File tmpFile = new File(destFile + ".tmp");
        tmpFile.delete();

        try {
            // Load the plugin descriptors
            /*
             * final PluginRegistry piRegistry; piRegistry = new
             * PluginRegistryModel(piList.getDescriptorUrlList());
             */

            final Jar jarTask = new Jar();
            jarTask.setProject(getProject());
            jarTask.setTaskName(getTaskName());
            jarTask.setDestFile(tmpFile);
            jarTask.setCompress(false);

            final Manifest mf = piList.getManifest();
            if (mf != null) {
                jarTask.addConfiguredManifest(mf);
            }

            final URL[] systemPlugins = systemPluginList.getPluginList();
            final ArrayList<PluginJar> pluginJars = new ArrayList<PluginJar>();
            for (URL url : systemPlugins) {
                final BuildPluginJar piJar = new BuildPluginJar(url);
                if (!piJar.getDescriptor().isSystemPlugin()) {
                    log("Non-system plugin " + piJar.getDescriptor().getId()
                        + " in plugin-list will be ignored",
                        Project.MSG_WARN);
                } else {
                    pluginJars.add(piJar);
                }
            }

            final URL[] pluginList = piList.getPluginList();
            for (URL url : pluginList) {
                final BuildPluginJar piJar = new BuildPluginJar(url);
                if (piJar.getDescriptor().isSystemPlugin()) {
                    log("System plugin " + piJar.getDescriptor().getId()
                        + " in plugin-list will be ignored",
                        Project.MSG_WARN);
                } else {
                    pluginJars.add(piJar);
                }
            }
            testPluginPrerequisites(pluginJars);
            final List<PluginJar> sortedPluginJars = sortPlugins(pluginJars);

            for (Iterator<PluginJar> i = sortedPluginJars.iterator(); i
                .hasNext();) {
                final BuildPluginJar piJar = (BuildPluginJar) i.next();
                if (!piJar.getDescriptor().isSystemPlugin()) {
//                    pluginJars.add(piJar);
                    final File f = new File(piJar.getPluginUrl().getPath());
                    final FileSet fs = new FileSet();
                    fs.setDir(f.getParentFile());
                    fs.setIncludes(f.getName());
                    jarTask.addFileset(fs);
                }
            }

            /*
             * for (Iterator i = piRegistry.getDescriptorIterator();
             * i.hasNext(); ) { final PluginDescriptor descr =
             * (PluginDescriptor)i.next(); final Runtime rt =
             * descr.getRuntime(); if (rt != null) { final Library[] libs =
             * rt.getLibraries(); for (int l = 0; l < libs.length; l++) {
             * processLibrary(jarTask, libs[l], fileSets, getPluginDir()); } }
             */

            // Now create the jar file
            jarTask.execute();

            // Now zip it
            final GZip gzipTask = new GZip();
            gzipTask.setProject(getProject());
            gzipTask.setTaskName(getTaskName());
            gzipTask.setSrc(tmpFile);
            gzipTask.setZipfile(destFile);
            gzipTask.execute();
            tmpFile.delete();

        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BuildException(ex);
        }
        final long end = System.currentTimeMillis();
        log("Building initjar took " + (end - start) + "ms");
    }

    /**
     * @param file
     */
    public void setDestFile(File file) {
        destFile = file;
    }

    /**
     * Ensure that all plugin prerequisites are met.
     *
     * @throws BuildException
     */
    protected void testPluginPrerequisites(List<PluginJar> pluginJars)
        throws BuildException {
        final Map<String, List<String>> idToVersions = new HashMap<String, List<String>>();
       
        // get all couples (id, version) in idToVersions
        for (PluginJar piJar : pluginJars) {
            final PluginDescriptor descr = piJar.getDescriptor();
           
            List<String> versions = idToVersions.get(descr.getId());
            if (versions == null) {
                versions = new ArrayList<String>();
                idToVersions.put(descr.getId(), versions);
            }
           
            versions.add(descr.getVersion().toString());
        }
       
        // now, check that each dependency is satisfied
        for (PluginJar piJar : pluginJars) {
            final PluginDescriptor descr = piJar.getDescriptor();
            final PluginPrerequisite[] prereqs = descr.getPrerequisites();
           
            for (int j = 0; j < prereqs.length; j++) {
                PluginPrerequisite required = prereqs[j];
                List<String> versions = idToVersions.get(required.getPluginReference().getId());
               
                boolean versionSpecified = (required.getPluginReference().getVersion() == null);

                boolean satisfied = false;
                if (versions != null) {
                    satisfied = !versionSpecified ||
                        versions.contains(required.getPluginReference().getVersion());
                }
               
                if (!satisfied) {
                    String reqVersionStr =  versionSpecified ? "" : " version " +
                            required.getPluginReference().getVersion();
                   
                    String versionStr =  (descr.getVersion()  == null) ? "" : " version " +
                            descr.getVersion();
                   
                    throw new BuildException("Cannot find plugin "
                        + required.getPluginReference().getId() + reqVersionStr
                        + ", which is required by " + descr.getId()
                        + versionStr);
                }
            }
        }
    }

    /**
     * Sort the plugins based on dependencies.
     *
     * @param pluginJars
     */
    protected List<PluginJar> sortPlugins(List<PluginJar> pluginJars) {
        final ArrayList<PluginJar> result = new ArrayList<PluginJar>(pluginJars.size());
        final HashSet<String> ids = new HashSet<String>();
        while (!pluginJars.isEmpty()) {
            boolean somethingRemoved = false;

            for (Iterator<PluginJar> i = pluginJars.iterator(); i.hasNext();) {
                final BuildPluginJar piJar = (BuildPluginJar) i.next();
                if (piJar.hasAllPrerequisitesInSet(ids)) {
                    log(piJar.getDescriptor().getId(), Project.MSG_VERBOSE);
                    result.add(piJar);
                    ids.add(piJar.getDescriptor().getId());
                    i.remove();
                    somethingRemoved = true;
                }
            }

            if (!somethingRemoved) {
                StringBuilder sb = new StringBuilder("cycle in plugin dependencies :\n");
                for (Iterator<PluginJar> i = pluginJars.iterator(); i.hasNext();) {
                    final BuildPluginJar piJar = (BuildPluginJar) i.next();
                    sb.append(piJar.getDescriptor().getId()).append('\n');
                }
                throw new BuildException(sb.toString());
            }
        }
        return result;
    }

    static class BuildPluginJar extends PluginJar {

        private final URL pluginUrl;

        /**
         * @param pluginUrl
         * @throws PluginException
         * @throws IOException
         */
        BuildPluginJar(URL pluginUrl) throws PluginException, IOException {
            super(null, pluginUrl);
            this.pluginUrl = pluginUrl;
        }

        /**
         * @return Returns the pluginUrl.
         */
        final URL getPluginUrl() {
            return this.pluginUrl;
        }

        public boolean hasAllPrerequisitesInSet(Set<String> ids) {
            final PluginDescriptor descr = getDescriptor();
            final PluginPrerequisite[] prereqs = descr.getPrerequisites();
            for (int j = 0; j < prereqs.length; j++) {
                if (!ids.contains(prereqs[j].getPluginReference().getId())) {
                    return false;
                }
            }
            return true;
        }
    }


    /**
     * @return Returns the destDir.
     */
    public final File getDestDir() {
        return destDir;
    }


    /**
     * @param destDir The destDir to set.
     */
    public final void setDestDir(File destDir) {
        this.destDir = destDir;
    }
       
    public void setPackager(PluginListInsertor insertor) {
        this.insertor = insertor;       
    }   
}
TOP

Related Classes of org.jnode.build.InitJarBuilder$BuildPluginJar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.