blob: d9ee3a285fcf0070e8f59c06e1b23b0a3661a87a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 GianMaria Romanato
* 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:
* GianMaria Romanato - initial API and implementation
*******************************************************************************/
package org.eclipse.virgo.ide.pde.core;
import static org.eclipse.virgo.ide.pde.core.Constants.META_INF;
import static org.eclipse.virgo.ide.pde.core.Helper.DEBUG;
import java.util.Map;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
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.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.JavaModelException;
/**
* A custom build command that ensures that the content of META-INF is copied to the binary folder of the plug-in
* project so that Virgo Server can find it via classpath.
* <p>
* Additionally the builder parsers the MANIFEST.MF and copies to bin folder any nested JAR (Bundle-ClassPath header)
* <p>
*
*
*/
public class Builder extends IncrementalProjectBuilder {
private abstract class Predicate<T> {
public abstract boolean accept(T t);
}
public Builder() {
super();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
@SuppressWarnings("rawtypes")
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
Helper.forcePDEEditor(getProject());
IPath outputLocation = Helper.getOutputLocation(getProject());
if (DEBUG) {
String typeStr = "UNKNOWN"; //$NON-NLS-1$
switch (kind) {
case INCREMENTAL_BUILD:
typeStr = "INCREMENTAL"; //$NON-NLS-1$
break;
case AUTO_BUILD:
typeStr = "AUTO"; //$NON-NLS-1$
break;
case CLEAN_BUILD:
typeStr = "CLEAN"; //$NON-NLS-1$
break;
case FULL_BUILD:
typeStr = "FULL"; //$NON-NLS-1$
break;
}
debug("Build type " + typeStr + " output location: " + outputLocation.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
if (kind == CLEAN_BUILD) {
if (DEBUG) {
debug("Doing nothing"); //$NON-NLS-1$
}
return null;
}
if (kind == FULL_BUILD) {
fullBuild(outputLocation, monitor);
} else {
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
if (DEBUG) {
debug("Incremental build was requested but delta is null, performing full build"); //$NON-NLS-1$
}
fullBuild(outputLocation, monitor);
return null;
}
if (!Helper.checkMETAINFFolder(getProject())) {
if (DEBUG) {
debug("Incremental build was requested but META-INF folder is missing from output location, performing full build"); //$NON-NLS-1$
}
fullBuild(outputLocation, monitor);
return null;
}
if (!Helper.checkLibraries(getProject())) {
if (DEBUG) {
debug("Incremental build was requested but some classpath libraries are missing from output location, performing full build"); //$NON-NLS-1$
}
fullBuild(outputLocation, monitor);
return null;
}
if (DEBUG) {
debug("Incremental build"); //$NON-NLS-1$
}
incrementalBuild(outputLocation, delta, monitor);
return null;
}
return null;
}
private void incrementalBuild(IPath outputLocation, final IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
monitor.beginTask(Messages.Builder_IncrementalBuildMessage, 2);
if (delta.findMember(new Path(META_INF)) != null) {
buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
} else {
monitor.worked(1);
}
buildLibraries(new Predicate<String>() {
@Override
public boolean accept(String t) {
return delta.findMember(new Path(t)) != null;
}
}, outputLocation, new SubProgressMonitor(monitor, 1));
monitor.done();
}
private void fullBuild(IPath outputLocation, IProgressMonitor monitor) throws CoreException {
if (DEBUG) {
debug("Full build, output location: " + outputLocation.toOSString()); //$NON-NLS-1$
}
monitor.beginTask(Messages.Builder_FullBuildMessage, 2);
buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
buildLibraries(null, outputLocation, new SubProgressMonitor(monitor, 1));
monitor.done();
}
private void buildLibraries(Predicate<String> predicate, IPath outputLocation, IProgressMonitor monitor) throws CoreException {
IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
binFolder.refreshLocal(IResource.DEPTH_ONE, null);
java.util.List<String> toCopy = Helper.getLibraryEntries(getProject());
monitor.beginTask(Messages.Builder_copy_libraries, toCopy.size());
for (String path : toCopy) {
if (predicate == null || predicate.accept(path)) {
Helper.copyLibraryToBin(getProject(), path);
}
monitor.worked(1);
}
monitor.done();
}
private void buildMetaInf(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
IProject project = getProject();
IFolder metaInf = project.getFolder(META_INF);
if (!metaInf.exists()) {
error("META-INF folder not found for project: " + getProject().getName()); //$NON-NLS-1$
return;
}
IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
if (!binFolder.exists()) {
binFolder.create(true, true, null);
} else {
binFolder.refreshLocal(IResource.DEPTH_ONE, null);
}
IFolder binaryMetaInf = binFolder.getFolder(META_INF);
if (!binaryMetaInf.exists()) {
binaryMetaInf.create(true, true, null);
} else {
binaryMetaInf.refreshLocal(IResource.DEPTH_ONE, null);
}
SubProgressMonitor sub = new SubProgressMonitor(monitor, 1);
IResource[] children = metaInf.members();
sub.beginTask(Messages.Builder_CopyMetaInfContent, children.length);
for (IResource iResource : children) {
if (!iResource.isTeamPrivateMember() && !iResource.isDerived()) {
IPath target = binaryMetaInf.getFullPath().append(iResource.getName());
IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(target);
if (res != null && res.exists()) {
if (DEBUG) {
debug(res.getFullPath().toString() + " exists, deleting"); //$NON-NLS-1$
}
res.refreshLocal(IResource.DEPTH_INFINITE, null);
res.delete(true, null);
if (DEBUG) {
debug(res.getFullPath().toString() + " deleted"); //$NON-NLS-1$
}
}
iResource.copy(target, true, null);
if (DEBUG) {
debug("Copied " + iResource.getFullPath().toString() + " to " + target.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
sub.worked(1);
}
monitor.done();
}
private void debug(String string) {
Helper.debug(getProject().getName() + " - " + string); //$NON-NLS-1$
}
private void error(String string) {
Helper.error(getProject().getName() + " - " + string); //$NON-NLS-1$
}
}