blob: 76a88a394ff764ff1107a5a0a50547547bb3f6ec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.internal.core.builder;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.wst.jsdt.core.IJavaScriptModelMarker;
import org.eclipse.wst.jsdt.core.compiler.CharOperation;
import org.eclipse.wst.jsdt.core.compiler.ValidationParticipant;
import org.eclipse.wst.jsdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
import org.eclipse.wst.jsdt.internal.core.JavaProject;
import org.eclipse.wst.validation.internal.operations.ValidationBuilder;
@SuppressWarnings("restriction")
public class JavaBuilder extends ValidationBuilder {
IProject currentProject;
JavaProject javaProject;
IWorkspaceRoot workspaceRoot;
ValidationParticipant[] participants;
NameEnvironment nameEnvironment;
SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary resources (output folders, class folders, zip/jar files)
public State lastState;
BuildNotifier notifier;
char[][] extraResourceFileFilters;
String[] extraResourceFolderFilters;
public static final String SOURCE_ID = "JSDT"; //$NON-NLS-1$
public static boolean DEBUG = false;
public static IMarker[] getProblemsFor(IResource resource) {
try {
if (resource != null && resource.exists()) {
IMarker[] markers = resource.findMarkers(IJavaScriptModelMarker.JAVASCRIPT_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
Set markerTypes = JavaModelManager.getJavaModelManager().validationParticipants.managedMarkerTypes();
if (markerTypes.isEmpty()) return markers;
ArrayList markerList = new ArrayList(5);
for (int i = 0, length = markers.length; i < length; i++) {
markerList.add(markers[i]);
}
Iterator iterator = markerTypes.iterator();
while (iterator.hasNext()) {
markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
for (int i = 0, length = markers.length; i < length; i++) {
markerList.add(markers[i]);
}
}
IMarker[] result;
markerList.toArray(result = new IMarker[markerList.size()]);
return result;
}
} catch (CoreException e) {
// assume there are no problems
}
return new IMarker[0];
}
public static IMarker[] getTasksFor(IResource resource) {
try {
if (resource != null && resource.exists())
return resource.findMarkers(IJavaScriptModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
// assume there are no tasks
}
return new IMarker[0];
}
/**
* Hook allowing to initialize some static state before a complete build iteration.
* This hook is invoked during PRE_AUTO_BUILD notification
*/
public static void buildStarting() {
// build is about to start
}
/**
* Hook allowing to reset some static state after a complete build iteration.
* This hook is invoked during POST_AUTO_BUILD notification
*/
public static void buildFinished() {
BuildNotifier.resetProblemCounters();
}
public static void removeProblemsFor(IResource resource) {
try {
if (resource != null && resource.exists()) {
resource.deleteMarkers(IJavaScriptModelMarker.JAVASCRIPT_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
// delete managed markers
Set markerTypes = JavaModelManager.getJavaModelManager().validationParticipants.managedMarkerTypes();
if (markerTypes.size() == 0) return;
Iterator iterator = markerTypes.iterator();
while (iterator.hasNext())
resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
}
} catch (CoreException e) {
// assume there were no problems
}
}
public static void removeTasksFor(IResource resource) {
try {
if (resource != null && resource.exists())
resource.deleteMarkers(IJavaScriptModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
// assume there were no problems
}
}
public static void removeProblemsAndTasksFor(IResource resource) {
try {
if (resource != null && resource.exists()) {
resource.deleteMarkers(IJavaScriptModelMarker.JAVASCRIPT_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
resource.deleteMarkers(IJavaScriptModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
// delete managed markers
Set markerTypes = JavaModelManager.getJavaModelManager().validationParticipants.managedMarkerTypes();
if (markerTypes.size() == 0) return;
Iterator iterator = markerTypes.iterator();
while (iterator.hasNext())
resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
}
} catch (CoreException e) {
// assume there were no problems
}
}
public static State readState(IProject project, DataInputStream in) throws IOException {
return State.read(project, in);
}
public static void writeState(Object state, DataOutputStream out) throws IOException {
((State) state).write(out);
}
private static final IProject[] EMPTY_PROJECTS = new IProject[0];
public IProject[] build(int kind, Map ignored, IProgressMonitor monitor) {
// We shouldn't run the validation builder again if validation builder exists on a project.
if (!isValidationBuilderDefined()) {
// Simply rely on the ValidationBuilder behavior
return super.build(kind, ignored, monitor);
}
return EMPTY_PROJECTS;
}
private static final String VALIDATION_BUILDER = "org.eclipse.wst.validation.validationbuilder"; //$NON-NLS-1$
private boolean isValidationBuilderDefined() {
try {
ICommand[] spec = getProject().getDescription().getBuildSpec();
if (spec != null) {
for (ICommand cmd : spec) {
if(VALIDATION_BUILDER.equals(cmd.getBuilderName())) {
return true;
}
}
}
} catch (CoreException e) {
// Cannot obtain description for the project - skip it
return true;
}
return false;
}
protected void clean(IProgressMonitor monitor) throws CoreException {
super.clean(monitor);
}
boolean filterExtraResource(IResource resource) {
if (extraResourceFileFilters != null) {
char[] name = resource.getName().toCharArray();
for (int i = 0, l = extraResourceFileFilters.length; i < l; i++)
if (CharOperation.match(extraResourceFileFilters[i], name, true))
return true;
}
if (extraResourceFolderFilters != null) {
IPath path = resource.getProjectRelativePath();
String pathName = path.toString();
int count = path.segmentCount();
if (resource.getType() == IResource.FILE) count--;
for (int i = 0, l = extraResourceFolderFilters.length; i < l; i++)
if (pathName.indexOf(extraResourceFolderFilters[i]) != -1)
for (int j = 0; j < count; j++)
if (extraResourceFolderFilters[i].equals(path.segment(j)))
return true;
}
return false;
}
public State getLastState(IProject project) {
return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, notifier.monitor);
}
boolean hasBuildpathErrors() throws CoreException {
// IMarker[] markers = this.currentProject.findMarkers(IJavaScriptModelMarker.JAVASCRIPT_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
// for (int i = 0, l = markers.length; i < l; i++)
// if (markers[i].getAttribute(IJavaScriptModelMarker.CATEGORY_ID, -1) == CategorizedProblem.CAT_BUILDPATH)
// return true;
return false;
}
/*
* Instruct the build manager that this project is involved in a cycle and
* needs to propagate structural changes to the other projects in the cycle.
*/
void mustPropagateStructuralChanges() {
HashSet cycleParticipants = new HashSet(3);
javaProject.updateCycleParticipants(new ArrayList(), cycleParticipants, workspaceRoot, new HashSet(3), null);
IPath currentPath = javaProject.getPath();
Iterator i= cycleParticipants.iterator();
while (i.hasNext()) {
IPath participantPath = (IPath) i.next();
if (participantPath != currentPath) {
IProject project = workspaceRoot.getProject(participantPath.segment(0));
if (hasBeenBuilt(project)) {
if (DEBUG)
System.out.println("Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$
+ " has not yet seen some structural changes"); //$NON-NLS-1$
needRebuild();
return;
}
}
}
}
/**
* String representation for debugging purposes
*/
public String toString() {
return currentProject == null
? "JavaBuilder for unknown project" //$NON-NLS-1$
: "JavaBuilder for " + currentProject.getName(); //$NON-NLS-1$
}
}