| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.ui.javaeditor; |
| |
| import org.eclipse.ui.IPartListener2; |
| import org.eclipse.ui.IWindowListener; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.ITypeRoot; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.manipulation.CoreASTProvider; |
| |
| import org.eclipse.jdt.internal.corext.dom.IASTSharedValues; |
| |
| import org.eclipse.jdt.ui.JavaUI; |
| |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| |
| |
| /** |
| * Provides a shared AST for clients. The shared AST is |
| * the AST of the active Java editor's input element. |
| * |
| * @since 3.0 |
| */ |
| public final class ASTProvider implements IASTSharedValues { |
| |
| private static final CoreASTProvider INSTANCE= CoreASTProvider.getInstance(); |
| |
| /** |
| * Internal activation listener. |
| * |
| * @since 3.0 |
| */ |
| private class ActivationListener implements IPartListener2, IWindowListener { |
| |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partActivated(IWorkbenchPartReference ref) { |
| if (isJavaEditor(ref) && !isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partBroughtToTop(IWorkbenchPartReference ref) { |
| if (isJavaEditor(ref) && !isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partClosed(IWorkbenchPartReference ref) { |
| if (isActiveEditor(ref)) { |
| if (JavaPlugin.DEBUG_AST_PROVIDER) |
| System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "closed active editor: " + ref.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| activeJavaEditorChanged(null); |
| } |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partDeactivated(IWorkbenchPartReference ref) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partOpened(IWorkbenchPartReference ref) { |
| if (isJavaEditor(ref) && !isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partHidden(IWorkbenchPartReference ref) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partVisible(IWorkbenchPartReference ref) { |
| if (isJavaEditor(ref) && !isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partInputChanged(IWorkbenchPartReference ref) { |
| if (isJavaEditor(ref) && isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) |
| */ |
| @Override |
| public void windowActivated(IWorkbenchWindow window) { |
| IWorkbenchPartReference ref= window.getPartService().getActivePartReference(); |
| if (isJavaEditor(ref) && !isActiveEditor(ref)) |
| activeJavaEditorChanged(ref.getPart(true)); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) |
| */ |
| @Override |
| public void windowDeactivated(IWorkbenchWindow window) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) |
| */ |
| @Override |
| public void windowClosed(IWorkbenchWindow window) { |
| if (fActiveEditor != null && fActiveEditor.getSite() != null && window == fActiveEditor.getSite().getWorkbenchWindow()) { |
| if (JavaPlugin.DEBUG_AST_PROVIDER) |
| System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "closed active editor: " + fActiveEditor.getTitle()); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| activeJavaEditorChanged(null); |
| } |
| window.getPartService().removePartListener(this); |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) |
| */ |
| @Override |
| public void windowOpened(IWorkbenchWindow window) { |
| window.getPartService().addPartListener(this); |
| } |
| |
| private boolean isActiveEditor(IWorkbenchPartReference ref) { |
| return ref != null && isActiveEditor(ref.getPart(false)); |
| } |
| |
| private boolean isActiveEditor(IWorkbenchPart part) { |
| return part != null && (part == fActiveEditor); |
| } |
| |
| private boolean isJavaEditor(IWorkbenchPartReference ref) { |
| if (ref == null) |
| return false; |
| |
| String id= ref.getId(); |
| |
| // The instanceof check is not need but helps clients, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84862 |
| return JavaUI.ID_CF_EDITOR.equals(id) || JavaUI.ID_CU_EDITOR.equals(id) || ref.getPart(false) instanceof JavaEditor; |
| } |
| } |
| |
| private ActivationListener fActivationListener; |
| private IWorkbenchPart fActiveEditor; |
| |
| /** |
| * Returns the Java plug-in's AST provider. |
| * |
| * @return the AST provider |
| * @since 3.2 |
| */ |
| public static ASTProvider getASTProvider() { |
| return JavaPlugin.getDefault().getASTProvider(); |
| } |
| |
| /** |
| * Creates a new AST provider. |
| */ |
| public ASTProvider() { |
| install(); |
| } |
| |
| /** |
| * Installs this AST provider. |
| */ |
| void install() { |
| // Create and register activation listener |
| fActivationListener= new ActivationListener(); |
| PlatformUI.getWorkbench().addWindowListener(fActivationListener); |
| |
| // Ensure existing windows get connected |
| IWorkbenchWindow[] windows= PlatformUI.getWorkbench().getWorkbenchWindows(); |
| for (IWorkbenchWindow window : windows) |
| window.getPartService().addPartListener(fActivationListener); |
| } |
| |
| void activeJavaEditorChanged(IWorkbenchPart editor) { |
| |
| ITypeRoot javaElement= null; |
| if (editor instanceof JavaEditor) |
| javaElement= ((JavaEditor)editor).getInputJavaElement(); |
| |
| synchronized (this) { |
| fActiveEditor= editor; |
| INSTANCE.setActiveJavaElement(javaElement); |
| INSTANCE.cache(null, javaElement); |
| } |
| |
| if (JavaPlugin.DEBUG_AST_PROVIDER) |
| System.out.println(CoreASTProvider.getThreadName() + " - " + CoreASTProvider.DEBUG_PREFIX + "active editor is: " + INSTANCE.toString(javaElement)); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| if ((INSTANCE.isReconciling() && (INSTANCE.getReconcilingJavaElement() == null || !INSTANCE.getReconcilingJavaElement().equals(javaElement))) |
| || (javaElement == null)) { |
| INSTANCE.clearReconciliation(); |
| } |
| } |
| |
| /** |
| * Returns whether the given compilation unit AST is |
| * cached by this AST provided. |
| * |
| * @param ast the compilation unit AST |
| * @return <code>true</code> if the given AST is the cached one |
| */ |
| public boolean isCached(CompilationUnit ast) { |
| return ast != null && INSTANCE.getCachedAST() == ast; |
| } |
| |
| /** |
| * Returns whether this AST provider is active on the given |
| * compilation unit. |
| * |
| * @param cu the compilation unit |
| * @return <code>true</code> if the given compilation unit is the active one |
| * @since 3.1 |
| */ |
| public synchronized boolean isActive(ICompilationUnit cu) { |
| return cu != null && cu.equals(INSTANCE.getActiveJavaElement()); |
| } |
| |
| /** |
| * Disposes this AST provider. |
| */ |
| public void dispose() { |
| |
| // Dispose activation listener |
| PlatformUI.getWorkbench().removeWindowListener(fActivationListener); |
| fActivationListener= null; |
| |
| INSTANCE.disposeAST(); |
| INSTANCE.waitLockNotifyAll(); |
| |
| } |
| |
| } |
| |