1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.internal.ui.text;
14 import net.sourceforge.phpdt.core.ElementChangedEvent;
15 import net.sourceforge.phpdt.core.IElementChangedListener;
16 import net.sourceforge.phpdt.core.JavaCore;
17 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
19 import net.sourceforge.phpeclipse.ui.WebUI;
21 import org.eclipse.core.resources.IMarkerDelta;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.IResourceChangeEvent;
24 import org.eclipse.core.resources.IResourceChangeListener;
25 import org.eclipse.core.resources.IResourceDelta;
26 import org.eclipse.core.resources.IWorkspace;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.ITextViewer;
29 import org.eclipse.jface.text.reconciler.DirtyRegion;
30 import org.eclipse.jface.text.reconciler.MonoReconciler;
31 import org.eclipse.swt.events.ShellAdapter;
32 import org.eclipse.swt.events.ShellEvent;
33 import org.eclipse.swt.events.ShellListener;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Shell;
36 import org.eclipse.ui.IEditorInput;
37 import org.eclipse.ui.IFileEditorInput;
38 import org.eclipse.ui.IPartListener;
39 import org.eclipse.ui.IWorkbenchPart;
40 import org.eclipse.ui.IWorkbenchPartSite;
41 import org.eclipse.ui.IWorkbenchWindow;
42 import org.eclipse.ui.texteditor.ITextEditor;
45 * A reconciler that is also activated on editor activation.
47 public class JavaReconciler extends MonoReconciler {
50 * Internal part listener for activating the reconciler.
52 private class PartListener implements IPartListener {
55 * @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
57 public void partActivated(IWorkbenchPart part) {
58 if (part == fTextEditor && hasJavaModelChanged())
59 JavaReconciler.this.forceReconciling();
63 * @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
65 public void partBroughtToTop(IWorkbenchPart part) {
69 * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
71 public void partClosed(IWorkbenchPart part) {
75 * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
77 public void partDeactivated(IWorkbenchPart part) {
78 if (part == fTextEditor)
79 setJavaModelChanged(false);
83 * @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
85 public void partOpened(IWorkbenchPart part) {
90 * Internal Shell activation listener for activating the reconciler.
92 private class ActivationListener extends ShellAdapter {
94 private Control fControl;
96 public ActivationListener(Control control) {
101 * @see org.eclipse.swt.events.ShellListener#shellActivated(org.eclipse.swt.events.ShellEvent)
103 public void shellActivated(ShellEvent e) {
104 if (!fControl.isDisposed() && fControl.isVisible()
105 && hasJavaModelChanged())
106 JavaReconciler.this.forceReconciling();
110 * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
112 public void shellDeactivated(ShellEvent e) {
113 setJavaModelChanged(false);
118 * Internal Java element changed listener
122 private class ElementChangedListener implements IElementChangedListener {
124 * @see net.sourceforge.phpdt.core.IElementChangedListener#elementChanged(net.sourceforge.phpdt.core.ElementChangedEvent)
126 public void elementChanged(ElementChangedEvent event) {
127 setJavaModelChanged(true);
132 * Internal resource change listener.
136 class ResourceChangeListener implements IResourceChangeListener {
138 private IResource getResource() {
139 IEditorInput input = fTextEditor.getEditorInput();
140 if (input instanceof IFileEditorInput) {
141 IFileEditorInput fileInput = (IFileEditorInput) input;
142 return fileInput.getFile();
148 * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
150 public void resourceChanged(IResourceChangeEvent e) {
151 IResourceDelta delta = e.getDelta();
152 IResource resource = getResource();
153 if (delta != null && resource != null) {
154 IResourceDelta child = delta.findMember(resource.getFullPath());
156 IMarkerDelta[] deltas = child.getMarkerDeltas();
157 if (deltas.length > 0)
164 /** The reconciler's editor */
165 private ITextEditor fTextEditor;
167 /** The part listener */
168 private IPartListener fPartListener;
170 /** The shell listener */
171 private ShellListener fActivationListener;
174 * The mutex that keeps us from running multiple reconcilers on one editor.
175 * TODO remove once we have ensured that there is only one reconciler per
178 private Object fMutex;
181 * The Java element changed listener.
185 private IElementChangedListener fJavaElementChangedListener;
188 * Tells whether the Java model sent out a changed event.
192 private volatile boolean fHasJavaModelChanged = true;
195 * The resource change listener.
199 private IResourceChangeListener fResourceChangeListener;
201 private boolean fIninitalProcessDone = false;
204 * Creates a new reconciler.
206 public JavaReconciler(ITextEditor editor,
207 JavaCompositeReconcilingStrategy strategy, boolean isIncremental) {
208 super(strategy, isIncremental);
209 fTextEditor = editor;
211 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898
212 // when re-using editors, a new reconciler is set up by the source
214 // and the old one uninstalled. However, the old reconciler may still be
216 // To avoid having to reconcilers calling
217 // CompilationUnitEditor.reconciled,
218 // we synchronized on a lock object provided by the editor.
219 // The critical section is really the entire run() method of the
221 // thread, but synchronizing process() only will keep
222 // JavaReconcilingStrategy
223 // from running concurrently on the same editor.
224 // TODO remove once we have ensured that there is only one reconciler
226 if (editor instanceof PHPUnitEditor)
227 fMutex = ((PHPUnitEditor) editor).getReconcilerLock();
229 fMutex = new Object(); // Null Object
233 * @see org.eclipse.jface.text.reconciler.IReconciler#install(org.eclipse.jface.text.ITextViewer)
235 public void install(ITextViewer textViewer) {
236 super.install(textViewer);
238 fPartListener = new PartListener();
239 IWorkbenchPartSite site = fTextEditor.getSite();
240 IWorkbenchWindow window = site.getWorkbenchWindow();
241 window.getPartService().addPartListener(fPartListener);
243 fActivationListener = new ActivationListener(textViewer.getTextWidget());
244 Shell shell = window.getShell();
245 shell.addShellListener(fActivationListener);
247 fJavaElementChangedListener = new ElementChangedListener();
248 JavaCore.addElementChangedListener(fJavaElementChangedListener);
250 fResourceChangeListener = new ResourceChangeListener();
251 IWorkspace workspace = WebUI.getWorkspace();
252 workspace.addResourceChangeListener(fResourceChangeListener);
256 * @see org.eclipse.jface.text.reconciler.IReconciler#uninstall()
258 public void uninstall() {
260 IWorkbenchPartSite site = fTextEditor.getSite();
261 IWorkbenchWindow window = site.getWorkbenchWindow();
262 window.getPartService().removePartListener(fPartListener);
263 fPartListener = null;
265 Shell shell = window.getShell();
266 if (shell != null && !shell.isDisposed())
267 shell.removeShellListener(fActivationListener);
268 fActivationListener = null;
270 JavaCore.removeElementChangedListener(fJavaElementChangedListener);
271 fJavaElementChangedListener = null;
273 IWorkspace workspace = WebUI.getWorkspace();
274 workspace.removeResourceChangeListener(fResourceChangeListener);
275 fResourceChangeListener = null;
281 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#forceReconciling()
283 protected void forceReconciling() {
284 if (!fIninitalProcessDone)
287 super.forceReconciling();
288 JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
289 strategy.notifyListeners(false);
293 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#aboutToReconcile()
296 protected void aboutToBeReconciled() {
297 JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
298 strategy.aboutToBeReconciled();
302 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerReset()
304 protected void reconcilerReset() {
305 super.reconcilerReset();
306 JavaCompositeReconcilingStrategy strategy = (JavaCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
307 strategy.notifyListeners(true);
311 * @see org.eclipse.jface.text.reconciler.MonoReconciler#initialProcess()
313 protected void initialProcess() {
314 // TODO remove once we have ensured that there is only one reconciler
316 synchronized (fMutex) {
317 super.initialProcess();
319 fIninitalProcessDone = true;
323 * @see org.eclipse.jface.text.reconciler.MonoReconciler#process(org.eclipse.jface.text.reconciler.DirtyRegion)
325 protected void process(DirtyRegion dirtyRegion) {
326 // TODO remove once we have ensured that there is only one reconciler
328 synchronized (fMutex) {
329 super.process(dirtyRegion);
334 * Tells whether the Java Model has changed or not.
336 * @return <code>true</code> iff the Java Model has changed
339 private synchronized boolean hasJavaModelChanged() {
340 return fHasJavaModelChanged;
344 * Sets whether the Java Model has changed or not.
347 * <code>true</code> iff the java model has changed
350 private synchronized void setJavaModelChanged(boolean state) {
351 fHasJavaModelChanged = state;
355 // * A reconciler that is also activated on editor activation.
357 // public class JavaReconciler extends MonoReconciler {
360 // * Internal part listener for activating the reconciler.
362 // class PartListener implements IPartListener {
365 // * @see IPartListener#partActivated(IWorkbenchPart)
367 // public void partActivated(IWorkbenchPart part) {
368 // if (part == fTextEditor)
369 // JavaReconciler.this.forceReconciling();
373 // * @see IPartListener#partBroughtToTop(IWorkbenchPart)
375 // public void partBroughtToTop(IWorkbenchPart part) {
379 // * @see IPartListener#partClosed(IWorkbenchPart)
381 // public void partClosed(IWorkbenchPart part) {
385 // * @see IPartListener#partDeactivated(IWorkbenchPart)
387 // public void partDeactivated(IWorkbenchPart part) {
391 // * @see IPartListener#partOpened(IWorkbenchPart)
393 // public void partOpened(IWorkbenchPart part) {
398 // /** The reconciler's editor */
399 // private ITextEditor fTextEditor;
400 // /** The part listener */
401 // private IPartListener fPartListener;
405 // * Creates a new reconciler.
407 // public JavaReconciler(ITextEditor editor, IReconcilingStrategy strategy,
408 // boolean isIncremental) {
409 // super(strategy, isIncremental);
410 // fTextEditor= editor;
414 // * @see IReconciler#install(ITextViewer)
416 // public void install(ITextViewer textViewer) {
417 // super.install(textViewer);
419 // fPartListener= new PartListener();
420 // IWorkbenchPartSite site= fTextEditor.getSite();
421 // IWorkbenchWindow window= site.getWorkbenchWindow();
422 // window.getPartService().addPartListener(fPartListener);
426 // * @see IReconciler#uninstall()
428 // public void uninstall() {
430 // IWorkbenchPartSite site= fTextEditor.getSite();
431 // IWorkbenchWindow window= site.getWorkbenchWindow();
432 // window.getPartService().removePartListener(fPartListener);
433 // fPartListener= null;
435 // super.uninstall();
439 // * @see AbstractReconciler#forceReconciling()
441 // protected void forceReconciling() {
442 // super.forceReconciling();
443 // IReconcilingStrategy strategy=
444 // getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
445 // if (strategy instanceof JavaReconcilingStrategy) {
446 // JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy;
447 // java.notifyParticipants(false);
452 // * @see AbstractReconciler#reconcilerReset()
454 // protected void reconcilerReset() {
455 // super.reconcilerReset();
456 // IReconcilingStrategy strategy=
457 // getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
458 // if (strategy instanceof JavaReconcilingStrategy) {
459 // JavaReconcilingStrategy java= (JavaReconcilingStrategy) strategy;
460 // java.notifyParticipants(true);