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); + } +}