/*******************************************************************************
* Copyright (c) 2007-2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.validation;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.wst.validation.internal.operations.WorkbenchContext;
import org.eclipse.wst.validation.internal.operations.WorkbenchReporter;
import org.jboss.tools.common.CommonPlugin;
/**
* Helper for Validators that use Validator Context.
* @author Alexey Kazakov
*/
public class ContextValidationHelper extends WorkbenchContext {
private static Storage initializedResourceRegistrators = new Storage();
protected IValidationContextManager validationContextManager;
protected TextFileDocumentProvider documentProvider = new TextFileDocumentProvider();
private static class Storage {
Set<ContextValidationHelper> registrators = new HashSet<ContextValidationHelper>();
synchronized boolean add(ContextValidationHelper helper) {
return registrators.add(helper);
}
synchronized void clear() {
registrators.clear();
}
}
/*
* (non-Javadoc)
* @see org.eclipse.wst.validation.internal.operations.WorkbenchContext#initialize()
*/
@Override
public void initialize() {
super.initialize();
cleanup();
}
/*
* (non-Javadoc)
* @see org.eclipse.wst.validation.internal.operations.WorkbenchContext#deleting()
*/
@Override
public void deleting() {
super.deleting();
cleanup();
}
/*
* (non-Javadoc)
* @see org.eclipse.wst.validation.internal.operations.WorkbenchContext#cleanup(org.eclipse.wst.validation.internal.operations.WorkbenchReporter)
*/
@Override
public void cleanup(WorkbenchReporter reporter) {
super.cleanup(reporter);
cleanup();
}
public void cleanup() {
if(validationContextManager!=null) {
validationContextManager.setValidationResourceRegisters(null);
}
validationContextManager = null;
initializedResourceRegistrators.clear();
}
/*
* (non-Javadoc)
* @see org.eclipse.wst.validation.internal.operations.WorkbenchContext#registerResource(org.eclipse.core.resources.IResource)
*/
@Override
public void registerResource(IResource resource) {
if(resource instanceof IFile) {
IFile file = (IFile)resource;
if(file.isDerived(IResource.CHECK_ANCESTORS)) {
return;
}
if(initializedResourceRegistrators.add(this)) {
// We should reinitialize validationContextManager if this helper is starting
// to collect changed resources after previous validation session.
// See https://issues.jboss.org/browse/JBIDE-15662
validationContextManager = null;
}
if(validationContextManager == null) {
validationContextManager = new ValidationContext(file.getProject());
} else if(validationContextManager.isObsolete()) {
validationContextManager.init(file.getProject()); // https://issues.jboss.org/browse/JBIDE-8726
}
validationContextManager.addProject(file.getProject());
if(!file.exists()) {
validationContextManager.addRemovedFile(file);
} else {
validationContextManager.registerFile(file);
}
}
}
/**
* @return Set of changed resources
*/
public Set<IFile> getChangedFiles() {
Set<IFile> result = new HashSet<IFile>();
String[] uris = getURIs();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
Set<IProject> projects = getAllProjects();
for (int i = 0; i < uris.length; i++) {
if(uris[i].endsWith(".jar") || uris[i].endsWith(".classpath")) continue;
IFile currentFile = root.getFile(new Path(uris[i]));
if(projects.contains(currentFile.getProject())
&& !currentFile.isDerived(IResource.CHECK_ANCESTORS)) {
result.add(currentFile);
}
}
Set<IFile> removedFiles = getValidationContextManager().getRemovedFiles();
for (IFile file : removedFiles) {
if(projects.contains(file.getProject())) {
result.add(file);
}
}
return result;
}
public boolean isClasspathAffected() {
String[] uris = getURIs();
for (String uri: uris) {
if(uri.endsWith(".jar") || uri.endsWith(".classpath")) {
return true;
}
}
return false;
}
public Set<IFile> getProjectSetRegisteredFiles() {
Set<IFile> result = new HashSet<IFile>();
Set<IFile> files = getValidationContextManager().getRegisteredFiles();
Set<IProject> projects = getAllProjects();
for (IFile file : files) {
if(projects.contains(file.getProject())) {
result.add(file);
}
}
return result;
}
private Set<IProject> getAllProjects() {
IProject project = getProject();
if(!project.isAccessible()) {
return Collections.emptySet();
}
List<IValidator> validators = getValidationContextManager().getValidators();
Set<IProject> projects = new HashSet<IProject>();
for (IValidator validator : validators) {
IValidatingProjectTree tree = validator.getValidatingProjects(project);
if(tree == null) {
CommonPlugin.getDefault().logError(new IllegalStateException(MessageFormat.format(ValidationMessages.ERR_ILLIGAL_VALIDATION_STATE,validator,getProject(),getProject().exists()))); //$NON-NLS-1$
} else {
projects.addAll(tree.getAllProjects());
}
}
return projects;
}
public IValidationContextManager getValidationContextManager() {
return getValidationContextManager(true);
}
public IValidationContextManager getValidationContextManager(boolean initialize) {
if(!initialize) {
return validationContextManager;
}
if(validationContextManager==null) {
validationContextManager = new ValidationContext(getProject());
}
return validationContextManager;
}
public void setValidationContextManager(IValidationContextManager context) {
validationContextManager = context;
}
public TextFileDocumentProvider getDocumentProvider() {
return documentProvider;
}
}