Fixed: [ Issue 71 ] Changing project settings for proto doesn't trigger revalidation
https://code.google.com/p/protobuf-dt/issues/detail?id=71
Open editors are revalidated by default. User also is prompted to perform a full rebuild.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
index e5966fd..c5b5c80 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/PreferenceAndPropertyPage.java
@@ -219,9 +219,13 @@
@Override public final boolean performOk() {
preferenceBinder.saveValues();
+ okPerformed();
return true;
}
+ /** Method invoked after this page's values have been saved. By default this method does nothing. */
+ protected void okPerformed() {}
+
@Override protected final void performDefaults() {
preferenceBinder.applyDefaults();
updateContents();
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java
index 0449722..5ac4f8d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CodeGenerationEditor.java
@@ -9,7 +9,6 @@
package com.google.eclipse.protobuf.ui.preferences.pages.compiler;
import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.Messages.*;
-import static java.util.Collections.unmodifiableList;
import static org.eclipse.jface.window.Window.OK;
import java.util.*;
@@ -118,13 +117,9 @@
});
}
- public List<CodeGenerationSetting> codeGenerationOptions() {
- return unmodifiableList(settings);
- }
-
- public void codeGenerationSettings(List<CodeGenerationSetting> newSettings) {
+ public void codeGenerationSettings(CodeGenerationSettings newSettings) {
settings.clear();
- settings.addAll(newSettings);
+ settings.addAll(newSettings.allSettings());
updateTable();
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java
index 50b0976..797f57c 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/compiler/CompilerPreferencePage.java
@@ -169,7 +169,7 @@
private void checkState() {
boolean atLeastOneEnabled = false;
- for (CodeGenerationSetting option : codeGenerationEditor.codeGenerationOptions()) {
+ for (CodeGenerationSetting option : codeGenerationSettings.allSettings()) {
if (option.isEnabled()) {
atLeastOneEnabled = true;
break;
@@ -229,7 +229,7 @@
shouldEnableCompilerOptions = shouldEnableCompilerOptions && useProjectSettings;
}
enableCompilerOptions(shouldEnableCompilerOptions);
- codeGenerationEditor.codeGenerationSettings(codeGenerationSettings.allSettings());
+ codeGenerationEditor.codeGenerationSettings(codeGenerationSettings);
}
/** {@inheritDoc} */
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.java
index e24e4e9..a82b717 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.java
@@ -31,9 +31,11 @@
public static String importedFilesPathResolution;
public static String isWorkspacePathCheck;
public static String pathResolution;
+ public static String rebuildProjectNow;
public static String remove;
public static String selectFileSystemDirectory;
public static String selectWorkspaceDirectory;
+ public static String settingsChanged;
public static String up;
static {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.properties b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.properties
index 450ed3d..601cdf8 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.properties
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/Messages.properties
@@ -14,7 +14,9 @@
importedFilesPathResolution=Path resolution of imported files
isWorkspacePathCheck=Is a workspace path
pathResolution=Path Resolution
+rebuildProjectNow=By default, all open editors will be revalidated. In addition, a full rebuild may be necessary for changes to take effect on the whole project. Do the full build now?
remove=&Remove
selectFileSystemDirectory=Select a directory from file system:
selectWorkspaceDirectory=Select a directory from workspace:
+settingsChanged=Import Paths Settings Changed
up=Move Up
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
index 5d96567..30b919f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/paths/PathsPreferencePage.java
@@ -13,11 +13,17 @@
import static com.google.eclipse.protobuf.ui.swt.EventListeners.addSelectionListener;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;
+import static org.eclipse.core.resources.IncrementalProjectBuilder.FULL_BUILD;
+import static org.eclipse.core.runtime.Status.OK_STATUS;
+import static org.eclipse.core.runtime.jobs.Job.BUILD;
import static org.eclipse.xtext.util.Strings.*;
import java.util.*;
import java.util.List;
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
@@ -28,6 +34,7 @@
import com.google.eclipse.protobuf.ui.preferences.*;
import com.google.eclipse.protobuf.ui.preferences.binding.*;
import com.google.eclipse.protobuf.ui.preferences.pages.PreferenceAndPropertyPage;
+import com.google.eclipse.protobuf.ui.validation.ValidationTrigger;
import com.google.inject.Inject;
/**
@@ -37,7 +44,9 @@
*/
public class PathsPreferencePage extends PreferenceAndPropertyPage {
- private static final String COMMA_DELIMITER = ",";
+ private static Logger logger = Logger.getLogger(PathsPreferencePage.class);
+
+ private static final String COMMA_DELIMITER = ","; //$NON-NLS-1$
private static final String PREFERENCE_PAGE_ID = PathsPreferencePage.class.getName();
private Group grpResolutionOfImported;
@@ -46,6 +55,9 @@
private DirectoryPathsEditor directoryPathsEditor;
@Inject private PluginImageHelper imageHelper;
+ @Inject private ValidationTrigger validation;
+
+ private boolean stateChanged;
@Override protected Composite contentParent(Composite parent) {
Composite contents = new Composite(parent, SWT.NONE);
@@ -91,6 +103,7 @@
}
private void checkState() {
+ stateChanged = true;
if (directoryPathsEditor.isEnabled() && directoryPathsEditor.directoryPaths().isEmpty()) {
pageIsNowInvalid(errorNoDirectoryNames);
return;
@@ -104,10 +117,8 @@
@Override protected void setupBinding(PreferenceBinder preferenceBinder) {
RawPreferences preferences = new RawPreferences(getPreferenceStore());
- preferenceBinder.addAll(
- bindSelectionOf(btnOneDirectoryOnly).to(preferences.filesInOneDirectoryOnly()),
- bindSelectionOf(btnMultipleDirectories).to(preferences.filesInMultipleDirectories())
- );
+ preferenceBinder.addAll(bindSelectionOf(btnOneDirectoryOnly).to(preferences.filesInOneDirectoryOnly()),
+ bindSelectionOf(btnMultipleDirectories).to(preferences.filesInMultipleDirectories()));
final StringPreference directoryPaths = preferences.directoryPaths();
preferenceBinder.add(new Binding() {
public void applyPreferenceValueToTarget() {
@@ -126,7 +137,7 @@
private String directoryNames() {
List<DirectoryPath> paths = directoryPathsEditor.directoryPaths();
- if (paths.isEmpty()) return "";
+ if (paths.isEmpty()) return ""; //$NON-NLS-1$
List<String> pathsAsText = new ArrayList<String>();
for (DirectoryPath path : paths) {
pathsAsText.add(path.toString());
@@ -159,8 +170,41 @@
directoryPathsEditor.setEnabled(btnMultipleDirectories.getSelection() && enabled);
}
- /** {@inheritDoc} */
@Override protected String preferencePageId() {
return PREFERENCE_PAGE_ID;
}
+
+ @Override protected void okPerformed() {
+ // TODO check threading
+ if (!stateChanged) return;
+ stateChanged = false;
+ if (shouldRebuild()) {
+ rebuildProject();
+ return;
+ }
+ validation.validateOpenEditors(project());
+ }
+
+ private boolean shouldRebuild() {
+ MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText(settingsChanged);
+ messageBox.setMessage(rebuildProjectNow);
+ return messageBox.open() == SWT.YES;
+ }
+
+ private void rebuildProject() {
+ Job job = new Job("Rebuilding project") { //$NON-NLS-1$
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ project().build(FULL_BUILD, monitor);
+ } catch (CoreException e) {
+ logger.error(e.getMessage(), e);
+ return new Status(ERROR, "unknown", ERROR, e.getMessage(), e); //$NON-NLS-1$
+ }
+ return OK_STATUS;
+ }
+ };
+ job.setPriority(BUILD);
+ job.schedule(); // start as soon as possible
+ }
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
index bfa04d0..b4ca2e7 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
@@ -106,6 +106,23 @@
return (path != null) ? root.getFile(path) : null;
}
+ /**
+ * Returns the project owning the file displayed in the given editor.
+ * @param editor the given editor.
+ * @return the project owning the file displayed in the given editor.
+ */
+ public IProject project(IEditorPart editor) {
+ IResource resource = resourceFrom(editor);
+ return (resource == null) ? null : resource.getProject();
+ }
+
+ private IResource resourceFrom(IEditorPart editor) {
+ if (editor == null) return null;
+ Object adapter = editor.getEditorInput().getAdapter(IResource.class);
+ return (adapter == null) ? null : (IResource) adapter;
+ }
+
+
private IPath pathOf(URI uri) {
String platformUri = uri.toPlatformString(true);
return (platformUri != null) ? new Path(platformUri) : null;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
index 3593840..f4df0b7 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
@@ -9,27 +9,13 @@
*/
package com.google.eclipse.protobuf.ui.validation;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
-import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
-
-import java.util.List;
+import static com.google.eclipse.protobuf.ui.validation.Validation.*;
import org.eclipse.core.resources.IProject;
-import org.eclipse.emf.ecore.EObject;
import org.eclipse.ui.*;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.xtext.nodemodel.INode;
-import org.eclipse.xtext.resource.XtextResource;
-import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
-import org.eclipse.xtext.ui.editor.XtextEditor;
-import org.eclipse.xtext.ui.editor.model.*;
-import org.eclipse.xtext.util.concurrent.IUnitOfWork;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
import com.google.eclipse.protobuf.ui.preferences.pages.general.*;
-import com.google.eclipse.protobuf.util.ModelNodes;
-import com.google.inject.Injector;
+import com.google.eclipse.protobuf.ui.util.Resources;
/**
* Validates a .proto file when it is opened or activated.
@@ -38,84 +24,73 @@
*/
public class ValidateOnActivation implements IPartListener2 {
- private static final String LANGUAGE_NAME = "com.google.eclipse.protobuf.Protobuf";
-
- private final ModelNodes nodes = new ModelNodes();
-
+ /**
+ * Validates the active active editor in the given part that contains a .proto file in the Workspace.
+ * @param partRef the part that was activated.
+ */
public void partActivated(IWorkbenchPartReference partRef) {
- final XtextEditor editor = protoEditorFrom(partRef);
- if (editor == null) return;
- if (!shouldValidateEditor(editor.getResource().getProject())) return;
- validate(editor);
+ IEditorPart activeEditor = activeEditor(partRef);
+ IProject project = projectFrom(activeEditor);
+ if (project == null || !shouldValidateEditor(project)) return;
+ validate(activeEditor);
+ }
+
+ private IEditorPart activeEditor(IWorkbenchPartReference partRef) {
+ IWorkbenchPage page = partRef.getPage();
+ return (page == null) ? null : page.getActiveEditor();
+ }
+
+ private IProject projectFrom(IEditorPart editor) {
+ Resources resources = injector().getInstance(Resources.class);
+ return resources.project(editor);
}
private boolean shouldValidateEditor(IProject project) {
- Injector injector = ProtobufActivator.getInstance().getInjector(LANGUAGE_NAME);
- GeneralPreferencesFactory factory = injector.getInstance(GeneralPreferencesFactory.class);
+ GeneralPreferencesFactory factory = injector().getInstance(GeneralPreferencesFactory.class);
if (factory == null) return false;
GeneralPreferences preferences = factory.preferences(project);
return preferences.validateFilesOnActivation();
}
- private XtextEditor protoEditorFrom(IWorkbenchPartReference partRef) {
- XtextEditor editor = xtextEditorFrom(partRef);
- if (editor == null) return null;
- if (!LANGUAGE_NAME.equals(editor.getLanguageName())) return null;
- if (!(editor.getEditorInput() instanceof FileEditorInput)) return null;
- return editor;
- }
-
- private XtextEditor xtextEditorFrom(IWorkbenchPartReference partRef) {
- IWorkbenchPage page = partRef.getPage();
- if (page == null) return null;
- IEditorPart activeEditor = page.getActiveEditor();
- return (activeEditor instanceof XtextEditor) ? (XtextEditor) activeEditor : null;
- }
-
- private void validate(XtextEditor editor) {
- final IXtextDocument document = editor.getDocument();
- if (!(document instanceof XtextDocument)) return;
- document.readOnly(new IUnitOfWork<Void, XtextResource>() {
- public java.lang.Void exec(XtextResource resource) throws Exception {
- EObject root = resource.getParseResult().getRootASTElement();
- resetImports(root);
- resource.getLinker().linkModel(root, new ListBasedDiagnosticConsumer());
- ((XtextDocument) document).checkAndUpdateAnnotations();
- return null;
- }
- });
- }
-
- private void resetImports(EObject root) {
- List<Import> imports = getAllContentsOfType(root, Import.class);
- for (Import anImport : imports) resetUri(anImport);
- }
-
- private void resetUri(Import anImport) {
- String uri = uriAsEnteredInEditor(anImport);
- if (uri == null) return;
- anImport.setImportURI(uri);
- }
-
- private String uriAsEnteredInEditor(Import anImport) {
- INode node = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
- if (node == null) return null;
- String text = node.getText();
- if (text == null) return null;
- return text.substring(1, text.length() - 1);
- }
-
+ /**
+ * This method does nothing.
+ * @param partRef the part that was surfaced.
+ */
public void partBroughtToTop(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part that was closed.
+ */
public void partClosed(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part that was deactivated.
+ */
public void partDeactivated(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part that was opened.
+ */
public void partOpened(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part that was hidden.
+ */
public void partHidden(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part that is visible.
+ */
public void partVisible(IWorkbenchPartReference partRef) {}
+ /**
+ * This method does nothing.
+ * @param partRef the part whose input was changed.
+ */
public void partInputChanged(IWorkbenchPartReference partRef) {}
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java
new file mode 100644
index 0000000..a5b1205
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.validation;
+
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
+import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
+import org.eclipse.xtext.ui.editor.XtextEditor;
+import org.eclipse.xtext.ui.editor.model.*;
+import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.ui.internal.ProtobufActivator;
+import com.google.eclipse.protobuf.util.ModelNodes;
+import com.google.inject.Injector;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class Validation {
+
+ private static final String LANGUAGE_NAME = "com.google.eclipse.protobuf.Protobuf";
+
+ static void validate(IEditorPart editor) {
+ XtextEditor protoEditor = asProtoEditor(editor);
+ if (protoEditor == null) return;
+ validate(protoEditor);
+ }
+
+ private static XtextEditor asProtoEditor(IEditorPart editor) {
+ XtextEditor xtextEditor = asXtextEditor(editor);
+ if (xtextEditor == null) return null;
+ if (!LANGUAGE_NAME.equals(xtextEditor.getLanguageName())) return null;
+ return xtextEditor;
+ }
+
+ private static XtextEditor asXtextEditor(IEditorPart editor) {
+ if (!isXtextEditorContainingWorkspaceFile(editor)) return null;
+ return (XtextEditor) editor;
+ }
+
+ private static boolean isXtextEditorContainingWorkspaceFile(IEditorPart editor) {
+ return editor instanceof XtextEditor && editor.getEditorInput() instanceof FileEditorInput;
+ }
+
+ private static void validate(XtextEditor editor) {
+ final IXtextDocument document = editor.getDocument();
+ if (!(document instanceof XtextDocument)) return;
+ document.readOnly(new IUnitOfWork<Void, XtextResource>() {
+ public java.lang.Void exec(XtextResource resource) throws Exception {
+ EObject root = resource.getParseResult().getRootASTElement();
+ resetImports(root);
+ resource.getLinker().linkModel(root, new ListBasedDiagnosticConsumer());
+ ((XtextDocument) document).checkAndUpdateAnnotations();
+ return null;
+ }
+ });
+ }
+
+ private static void resetImports(EObject root) {
+ List<Import> imports = getAllContentsOfType(root, Import.class);
+ for (Import anImport : imports) resetUri(anImport);
+ }
+
+ private static void resetUri(Import anImport) {
+ String uri = uriAsEnteredInEditor(anImport);
+ if (uri == null) return;
+ anImport.setImportURI(uri);
+ }
+
+ private static String uriAsEnteredInEditor(Import anImport) {
+ INode node = nodes().firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
+ if (node == null) return null;
+ String text = node.getText();
+ if (text == null) return null;
+ return text.substring(1, text.length() - 1);
+ }
+
+ private static ModelNodes nodes() {
+ return injector().getInstance(ModelNodes.class);
+ }
+
+ static Injector injector() {
+ return ProtobufActivator.getInstance().getInjector(LANGUAGE_NAME);
+ }
+
+ private Validation() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java
new file mode 100644
index 0000000..9fc9f98
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * 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
+ */
+package com.google.eclipse.protobuf.ui.validation;
+
+import static com.google.eclipse.protobuf.ui.validation.Validation.validate;
+
+import java.net.URI;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.ui.*;
+
+import com.google.eclipse.protobuf.ui.util.Resources;
+import com.google.inject.*;
+
+/**
+ * Triggers validation of .proto files.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton
+public class ValidationTrigger {
+
+ private final String PROTO_EDITOR_ID = "com.google.eclipse.protobuf.Protobuf";
+
+ @Inject private Resources resources;
+
+ /**
+ * Triggers validation of all open .proto files belonging to the given project.
+ * @param project the given project.
+ */
+ public void validateOpenEditors(IProject project) {
+ for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ for (IWorkbenchPage page : window.getPages()) {
+ for (IEditorReference editorRef : page.getEditorReferences()) {
+ validateFileInEditor(editorRef, project);
+ }
+ }
+ }
+ }
+
+ private void validateFileInEditor(IEditorReference editorRef, IProject project) {
+ if (!PROTO_EDITOR_ID.equals(editorRef.getId())) return;
+ IEditorPart editor = editorRef.getEditor(true);
+ IProject fileProject = resources.project(editor);
+ if (fileProject == null || !haveEqualUris(project, fileProject)) return;
+ validate(editor);
+ }
+
+ private boolean haveEqualUris(IProject p1, IProject p2) {
+ if (p1 == null || p2 == null) return false;
+ URI uri1 = p1.getLocationURI();
+ URI uri2 = p2.getLocationURI();
+ return areEqual(uri1, uri2);
+ }
+
+ private boolean areEqual(URI uri1, URI uri2) {
+ if (uri1 == null) return false;
+ return uri1.equals(uri2);
+ }
+}