Package org.apache.felix.sigil.eclipse.internal.builders

Source Code of org.apache.felix.sigil.eclipse.internal.builders.SigilIncrementalProjectBuilder

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.felix.sigil.eclipse.internal.builders;

import java.io.File;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.felix.sigil.common.bnd.BundleBuilder;
import org.apache.felix.sigil.common.config.IBldProject;
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsoleStream;

public class SigilIncrementalProjectBuilder extends IncrementalProjectBuilder
{
    @Override
    protected IProject[] build(int kind, @SuppressWarnings("unchecked") Map args,
        IProgressMonitor monitor) throws CoreException
    {
        IProject project = getProject();

        if (checkOk(project))
        {
            switch (kind)
            {
                case CLEAN_BUILD:
                case FULL_BUILD:
                    fullBuild(project, monitor);
                    break;
                case AUTO_BUILD:
                case INCREMENTAL_BUILD:
                    autoBuild(project, monitor);
                    break;
            }
        }

        return null;
    }

    /**
     * @param install
     * @param project
     * @param monitor
     * @throws CoreException
     */
    private void autoBuild(IProject project, IProgressMonitor monitor)
        throws CoreException
    {
        IResourceDelta delta = getDelta(project);
        final boolean[] changed = new boolean[1];
        ISigilProjectModel sigil = SigilCore.create(project);
        final IPath bldRoot = sigil.findBundleLocation().removeLastSegments(1);

        delta.accept(new IResourceDeltaVisitor()
        {
            public boolean visit(IResourceDelta delta) throws CoreException
            {
                if (!changed[0])
                {
                    IResource res = delta.getResource();
                    if (res.getType() == IResource.FILE)
                    {
                        changed[0] = !bldRoot.isPrefixOf(res.getLocation());
                    }
                }
                return !changed[0];
            }
        });

        if (changed[0])
        {
            doBuild(project, monitor);
        }
    }

    /**
     * @param install
     * @param project
     * @param monitor
     * @throws CoreException
     */
    private void fullBuild(IProject project, IProgressMonitor monitor)
        throws CoreException
    {
        doBuild(project, monitor);
    }

    private boolean checkOk(IProject project) throws CoreException
    {
        IMarker[] markers = project.findMarkers(
            IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);

        for (IMarker m : markers)
        {
            Integer s = (Integer) m.getAttribute(IMarker.SEVERITY);
            if (s != null && s.equals(IMarker.SEVERITY_ERROR))
            {
                SigilCore.log("Skipping " + project.getName()
                    + " build due to unresolved errors");
                return false;
            }
        }

        return true;
    }

    private void doBuild(IProject project, IProgressMonitor monitor) throws CoreException
    {
        ISigilProjectModel sigil = SigilCore.create(project);
        IBldProject bld = sigil.getBldProject();

        File[] classpath = buildClasspath(sigil, monitor);

        String destPattern = buildDestPattern(sigil);

        Properties env = new Properties();

        BundleBuilder bb = new BundleBuilder(bld, classpath, destPattern, env);

        for (IBldProject.IBldBundle bundle : bld.getBundles())
        {
            String id = bundle.getId();
            loginfo("creating bundle: " + id);
            int nWarn = 0;
            int nErr = 0;
            String msg = "";

            try
            {
                boolean modified = bb.createBundle(bundle, false, new BundleBuilder.Log()
                {
                    public void warn(String msg)
                    {
                        logwarn(msg);
                    }

                    public void verbose(String msg)
                    {
                        loginfo(msg);
                    }
                });
                nWarn = bb.warnings().size();
                if (!modified)
                {
                    msg = " (not modified)";
                }
            }
            catch (Exception e)
            {
                List<String> errors = bb.errors();
                if (errors != null)
                {
                    nErr = errors.size();
                    for (String err : errors)
                    {
                        logerror(err);
                    }
                }
                // FELIX-1690 - error is already logged no need to throw error as this
                // results in noisy error dialog box
                //throw SigilCore.newCoreException( "Failed to create: " + id + ": " + e, e );
            }
            finally
            {
                loginfo(id + ": " + count(nErr, "error") + ", " + count(nWarn, "warning")
                    + msg);
            }
        }
    }

    private static void loginfo(String message)
    {
        log("INFO: " + message);
    }

    private static void logwarn(String message)
    {
        log("WARN: " + message);
    }

    private static void logerror(String message)
    {
        log("ERROR: " + message);
    }

    private static void log(final String message)
    {
        // do this in background to avoid deadlock with ui
        Job job = new Job("log")
        {
            @Override
            protected IStatus run(IProgressMonitor arg0)
            {
                BuildConsole console = findConsole();
                MessageConsoleStream stream = console.getMessageStream();
                stream.println(message);
                return Status.OK_STATUS;
            }
        };
        job.schedule();
    }

    private static BuildConsole findConsole()
    {
        BuildConsole console = null;

        IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();

        for (IConsole c : manager.getConsoles())
        {
            if (c instanceof BuildConsole)
            {
                console = (BuildConsole) c;
                break;
            }
        }

        if (console == null)
        {
            console = new BuildConsole();
            manager.addConsoles(new IConsole[] { console });
        }

        return console;
    }

    private String buildDestPattern(ISigilProjectModel sigil) throws CoreException
    {
        IPath loc = sigil.findBundleLocation().removeLastSegments(1);

        loc.toFile().mkdirs();

        return loc.toOSString() + File.separator + "[name].jar";
    }

    private File[] buildClasspath(ISigilProjectModel sigil, IProgressMonitor monitor)
        throws CoreException
    {
        LinkedList<File> files = new LinkedList<File>();
        if (sigil.getBundle().getClasspathEntrys().isEmpty())
        {
            IClasspathEntry[] entries = sigil.getJavaModel().getResolvedClasspath(true);
            for (IClasspathEntry cp : entries)
            {
                convert(cp, sigil, files);
            }
        }
        else
        {
            buildLocalClasspath(sigil, files);
            buildExternalClasspath(sigil, files, monitor);
        }
        return files.toArray(new File[files.size()]);
    }

    private void buildExternalClasspath(ISigilProjectModel sigil, List<File> files,
        IProgressMonitor monitor) throws CoreException
    {
        Collection<IClasspathEntry> entries = sigil.findExternalClasspath(monitor);

        for (IClasspathEntry cp : entries)
        {
            convert(cp, sigil, files);
        }
    }

    private void buildLocalClasspath(ISigilProjectModel sigil, List<File> files)
        throws CoreException
    {
        Collection<IClasspathEntry> entries = JavaHelper.findClasspathEntries(sigil.getBundle());
        for (IClasspathEntry cp : entries)
        {
            convert(cp, sigil, files);
        }
    }

    private void convert(IClasspathEntry cp, ISigilProjectModel sigil, List<File> files)
        throws CoreException
    {
        switch (cp.getEntryKind())
        {
            case IClasspathEntry.CPE_PROJECT:
            {
                convertProject(cp, files);
                break;
            }
            case IClasspathEntry.CPE_SOURCE:
            {
                convertSource(sigil, cp, files);
                break;
            }
            case IClasspathEntry.CPE_LIBRARY:
            {
                convertLibrary(sigil, cp, files);
                break;
            }
            case IClasspathEntry.CPE_VARIABLE:
                convertVariable(cp, files);
                break;
        }
    }

    private void convertVariable(IClasspathEntry cp, List<File> files)
    {
        cp = JavaCore.getResolvedClasspathEntry(cp);
        if (cp != null)
        {
            IPath p = cp.getPath();
            files.add(p.toFile());
        }
    }

    private void convertLibrary(ISigilProjectModel sigil, IClasspathEntry cp,
        List<File> files)
    {
        IPath p = cp.getPath();

        IProject project = sigil.getProject().getWorkspace().getRoot().getProject(
            p.segment(0));
        if (project.exists())
        {
            p = project.getLocation().append(p.removeFirstSegments(1));
        }

        files.add(p.toFile());
    }

    private void convertSource(ISigilProjectModel sigil, IClasspathEntry cp,
        List<File> files) throws JavaModelException
    {
        IPath path = cp.getOutputLocation() == null ? sigil.getJavaModel().getOutputLocation()
            : cp.getOutputLocation();
        IFolder buildFolder = sigil.getProject().getFolder(path.removeFirstSegments(1));
        if (buildFolder.exists())
        {
            files.add(buildFolder.getLocation().toFile());
        }
    }

    private void convertProject(IClasspathEntry cp, List<File> files)
        throws CoreException
    {
        IProject p = findProject(cp.getPath());
        ISigilProjectModel project = SigilCore.create(p);
        if (project.getBundle().getClasspathEntrys().isEmpty())
        {
            // ew this is pretty messy - if a dependent bundle specifies it's dependencies
            // via package statements vs source directories then we need to add
            // the classpath path of that bundle
            for (IClasspathEntry rp : project.getJavaModel().getResolvedClasspath(true))
            {
                convert(rp, project, files);
            }
        }
        else
        {
            for (String scp : project.getBundle().getClasspathEntrys())
            {
                IClasspathEntry jcp = project.getJavaModel().decodeClasspathEntry(scp);
                convert(jcp, project, files);
            }
        }
    }

    private IProject findProject(IPath path) throws CoreException
    {
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        for (IProject p : root.getProjects())
        {
            IPath projectPath = p.getFullPath();
            if (projectPath.equals(path))
            {
                return p;
            }
        }

        throw SigilCore.newCoreException("No such project " + path, null);
    }

    private String count(int count, String msg)
    {
        return count + " " + msg + (count == 1 ? "" : "s");
    }
}
TOP

Related Classes of org.apache.felix.sigil.eclipse.internal.builders.SigilIncrementalProjectBuilder

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.