All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.wst.validation.internal.operations.ValidationBuilder Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2001, 2009 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.validation.internal.operations;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.wst.validation.ValidationFramework;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.InternalValidatorManager;
import org.eclipse.wst.validation.internal.ProjectConfiguration;
import org.eclipse.wst.validation.internal.ResourceConstants;
import org.eclipse.wst.validation.internal.ResourceHandler;
import org.eclipse.wst.validation.internal.Tracing;
import org.eclipse.wst.validation.internal.ValBuilderJob;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

/**
 * Validation Framework Builder.
 * 

* This builder is configured on J2EE IProjects automatically, and can be added to other types of * projects through the Properties page. It launches validation on the project if the project has * build validation enabled. *

*

* This launches a Job for the new V2 validators and also a Job for each of the Job based V1 * validators. If there are any "in-line" V1 validations they are done as part of this builder. * Because of all the jobs that this builder spawns, the build will usually be finished long before * all the validation has finished. *

*/ public class ValidationBuilder extends IncrementalProjectBuilder { /* * GRK - This class serves as a main entry point into the framework. There is one instance of this class for every * project that has a validation builder configured for it. Typically if you had ten projects in your workspace you would have * ten of these objects. They are created early in the life cycle of the workbench, and then are reused. * * My observation was that they are run serially by the same thread. */ public static final int NO_DELTA_CHANGE = -1; protected List referencedProjects; protected IWorkbenchContext workbenchContext = null; /** * All the jobs that the validation framework spawns will belong to this family. */ public static final Object FAMILY_VALIDATION_JOB = new Object(); public ValidationBuilder() { } private IProject[] getAllReferencedProjects(IProject project, Set visitedProjects) { if (visitedProjects == null)visitedProjects = new HashSet(); else if (visitedProjects.contains(project))return getReferencedProjects(); else visitedProjects.add(project); if (referencedProjects == null)referencedProjects = new ArrayList(); try { if (project.isAccessible()) { IProject[] refProjArray = project.getReferencedProjects(); collectReferecedProject(refProjArray); for (IProject refProject : refProjArray) { getAllReferencedProjects(refProject, visitedProjects); } } return getReferencedProjects(); } catch (CoreException e) { ValidationPlugin.getPlugin().handleException(e); } return null; } public IWorkbenchContext getWorkbenchContext() { if(workbenchContext == null) { workbenchContext = new WorkbenchContext(); workbenchContext.setProject(getProject()); } return workbenchContext; } /** * Add the projects from refProjArray to the list of referenced projects (if they are not * already in the list). * @param refProjArray */ private void collectReferecedProject(IProject[] refProjArray) { for (IProject project : refProjArray) { if (!referencedProjects.contains(project))referencedProjects.add(project); } } protected void clean(IProgressMonitor monitor) throws CoreException { IProject currentProject = getProject(); Tracing.log("ValidationBuilder-02 clean ", currentProject); //$NON-NLS-1$ newClean(monitor); if (currentProject == null || !currentProject.isAccessible())return; try { ProjectConfiguration prjp = ConfigurationManager.getManager().getProjectConfiguration(currentProject); ValidatorMetaData[] vmds = prjp.getValidators(); for (int i = 0; i < vmds.length; i++) { ValidatorMetaData vmd = vmds[i]; // For validators who aren't going to run, clear their messages from the task list. // Don't need to check for duplicate entries because each Validator must be unique. // The uniqueness of each Validator is checked by the plugin registry. WorkbenchReporter.removeAllMessages(currentProject, vmd.getValidatorNames(), null); } } catch (InvocationTargetException e) { ValidationPlugin.getPlugin().handleException(e); ValidationPlugin.getPlugin().handleException(e.getTargetException()); } } private IProject[] getReferencedProjects() { IProject[] refProjArray = new IProject[referencedProjects.size()]; return referencedProjects.toArray(refProjArray); } @SuppressWarnings("unchecked") public IProject[] build(int kind, Map parameters, IProgressMonitor monitor) { IResourceDelta delta = null; IProject project = getProject(); Tracing.log("ValidationBuilder-01 build ", kind, project); //$NON-NLS-1$ if (Tracing.isLogging(1)){ Tracing.logResourceDeltas(getDelta(project), 50); } // GRK I wonder why this builder needs to know about all the other referenced projects? // won't they have builders of their own. IProject[] referenced = getAllReferencedProjects(project, null); if (ValidationFramework.getDefault().isSuspended(project) || ValManager.getDefault().isDisabled(project))return referenced; try { newBuild(kind, monitor); ProjectConfiguration prjp = ConfigurationManager.getManager().getProjectConfiguration(project); delta = getDelta(project); boolean doFullBuild = (kind == FULL_BUILD); // It is possible for kind to == AUTO_BUILD while delta is null // (saw this when creating a project by copying another project.) // However, a "Rebuild Project" will invoke this builder with // kind==FULL_BUILD and a null delta, and validation should run in that case. if (!doFullBuild && delta == null) { if (isReferencedProjectInDelta(referenced)) { performFullBuildForReferencedProjectChanged(monitor, prjp); } else { String[] msgParms = new String[]{project.getName()}; monitor.subTask(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_STATUS_NULL_DELTA, msgParms)); // A null delta means that a full build must be performed, // but this builder was invoked with an incremental or automatic // build kind. Return without doing anything so that the user // doesn't have to wait forever. } return referenced; } if (doFullBuild) { cleanupReferencedProjectsMarkers(prjp, referenced); performFullBuild(monitor, prjp); } else { if (delta.getAffectedChildren().length == 0) { if (isReferencedProjectInDelta(referenced)){ cleanupReferencedProjectsMarkers(prjp, referenced); performFullBuildForReferencedProjectChanged(monitor, prjp); } return referenced; } EnabledIncrementalValidatorsOperation operation = new EnabledIncrementalValidatorsOperation(project, delta, true); operation.run(monitor); } return referenced; } catch (InvocationTargetException e) { ValidationPlugin.getPlugin().handleException(e); ValidationPlugin.getPlugin().handleException(e.getTargetException()); return referenced; } catch (Exception e) { ValidationPlugin.getPlugin().handleException(e); return referenced; } finally { referencedProjects = null; } } private void cleanupReferencedProjectsMarkers(final ProjectConfiguration prjp, IProject[] referenced){ //When a project references one or more project, performing a clean build on referenced //causes delta to be invoked on referencee, aka, parent. This causes following code to //be invoked. //The following code is trying to fix a case where Ejb project references a utility project, //and the clean build on utility project causes the code to come here, the ejb validator runs //on the ejb project due to performFullBuildForReferencedProjectChanged() below, but it also //causes marker to be generated for the util project, but the markers for util project are not //cleaned up. if( referenced == null || referenced.length == 0 )return; try{ ValidatorMetaData[] enabledValidators = prjp.getEnabledFullBuildValidators(true, false); Set set = new HashSet(); set.addAll( Arrays.asList( enabledValidators ) ); for (IProject p : referenced) { if (!p.isAccessible())continue; ProjectConfiguration refProjectCfg = ConfigurationManager.getManager().getProjectConfiguration(p); ValidatorMetaData[] refEnabledValidators = refProjectCfg.getEnabledFullBuildValidators(true, false); //remove from the set the validators which are also in child for(ValidatorMetaData vmd : refEnabledValidators)set.remove(vmd); for(ValidatorMetaData vmd : set)WorkbenchReporter.removeAllMessages(p, vmd.getValidator()); } }catch (Exception exc) { ValidationPlugin.getPlugin().logMessage(IStatus.ERROR, exc.toString()); } } private boolean isReferencedProjectInDelta(IProject[] referenced) { IProject p = null; for (int i = 0; i < referenced.length; i++) { p = referenced[i]; IResourceDelta delta = getDelta(p); if (delta != null && delta.getAffectedChildren().length > 0) return true; } return false; } private void performFullBuildForReferencedProjectChanged(IProgressMonitor monitor, ProjectConfiguration prjp) throws InvocationTargetException { performFullBuild(monitor, prjp, true); } private void performFullBuild(IProgressMonitor monitor, ProjectConfiguration prjp) throws InvocationTargetException { performFullBuild(monitor, prjp, false); } private void performFullBuild(IProgressMonitor monitor, ProjectConfiguration prjp, boolean onlyDependentValidators) throws InvocationTargetException { ValidatorMetaData[] enabledValidators = prjp.getEnabledFullBuildValidators(true, onlyDependentValidators); if ((enabledValidators != null) && (enabledValidators.length > 0)) { Set enabledValidatorsSet = InternalValidatorManager.wrapInSet(enabledValidators); EnabledValidatorsOperation op = new EnabledValidatorsOperation(getProject(), enabledValidatorsSet, true); op.run(monitor); } } /** * Run the new validation builder. This is a transition method, while we continue to have * the old and new validation builders. * * @param kind the kind of build * * @see IncrementalProjectBuilder#AUTO_BUILD * @see IncrementalProjectBuilder#CLEAN_BUILD * @see IncrementalProjectBuilder#FULL_BUILD * @see IncrementalProjectBuilder#INCREMENTAL_BUILD */ private void newBuild(int kind, IProgressMonitor monitor) throws CoreException { IResourceDelta delta = null; IProject project = getProject(); switch (kind){ case AUTO_BUILD: case INCREMENTAL_BUILD: delta = getDelta(project); break; } ValBuilderJob.validateProject(project, delta, kind); } /** * Run the new clean method. This is a transition method, while we continue to have * the old and new validation builders. */ private void newClean(IProgressMonitor monitor) throws CoreException { ValManager.getDefault().clean(getProject(), monitor); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy