/******************************************************************************* * 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; } }