KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > editor > AntEditor


1 /*******************************************************************************
2  * Copyright (c) 2002, 2007 GEBIT Gesellschaft fuer EDV-Beratung
3  * und Informatik-Technologien mbH,
4  * Berlin, Duesseldorf, Frankfurt (Germany) and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
12  * IBM Corporation - bug fixes
13  * John-Mason P. Shackelford - bug 40255
14  * Mark Melvin - bug 93378
15  *******************************************************************************/

16
17 package org.eclipse.ant.internal.ui.editor;
18
19 import java.io.File JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.ResourceBundle JavaDoc;
25
26 import org.eclipse.ant.internal.ui.AntUIPlugin;
27 import org.eclipse.ant.internal.ui.AntUtil;
28 import org.eclipse.ant.internal.ui.ExternalHyperlink;
29 import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
30 import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
31 import org.eclipse.ant.internal.ui.editor.actions.FoldingActionGroup;
32 import org.eclipse.ant.internal.ui.editor.actions.OpenDeclarationAction;
33 import org.eclipse.ant.internal.ui.editor.actions.RenameInFileAction;
34 import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
35 import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
36 import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
37 import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
38 import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
39 import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
40 import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
41 import org.eclipse.ant.internal.ui.model.AntElementNode;
42 import org.eclipse.ant.internal.ui.model.AntModel;
43 import org.eclipse.ant.internal.ui.model.AntModelChangeEvent;
44 import org.eclipse.ant.internal.ui.model.AntModelCore;
45 import org.eclipse.ant.internal.ui.model.AntProjectNode;
46 import org.eclipse.ant.internal.ui.model.IAntModelListener;
47 import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
48 import org.eclipse.core.resources.IFile;
49 import org.eclipse.core.runtime.CoreException;
50 import org.eclipse.core.runtime.IProgressMonitor;
51 import org.eclipse.core.runtime.IStatus;
52 import org.eclipse.core.runtime.NullProgressMonitor;
53 import org.eclipse.core.runtime.Status;
54 import org.eclipse.core.runtime.jobs.Job;
55 import org.eclipse.debug.ui.actions.IRunToLineTarget;
56 import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
57 import org.eclipse.jdt.ui.JavaUI;
58 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
59 import org.eclipse.jface.action.IAction;
60 import org.eclipse.jface.action.IMenuManager;
61 import org.eclipse.jface.action.Separator;
62 import org.eclipse.jface.preference.IPreferenceStore;
63 import org.eclipse.jface.text.BadLocationException;
64 import org.eclipse.jface.text.DocumentEvent;
65 import org.eclipse.jface.text.IAutoEditStrategy;
66 import org.eclipse.jface.text.IDocument;
67 import org.eclipse.jface.text.IDocumentListener;
68 import org.eclipse.jface.text.IInformationControl;
69 import org.eclipse.jface.text.IInformationControlCreator;
70 import org.eclipse.jface.text.IRegion;
71 import org.eclipse.jface.text.ISelectionValidator;
72 import org.eclipse.jface.text.ISynchronizable;
73 import org.eclipse.jface.text.ITextInputListener;
74 import org.eclipse.jface.text.ITextSelection;
75 import org.eclipse.jface.text.ITextViewer;
76 import org.eclipse.jface.text.Position;
77 import org.eclipse.jface.text.link.LinkedModeModel;
78 import org.eclipse.jface.text.source.Annotation;
79 import org.eclipse.jface.text.source.IAnnotationModel;
80 import org.eclipse.jface.text.source.IAnnotationModelExtension;
81 import org.eclipse.jface.text.source.IOverviewRuler;
82 import org.eclipse.jface.text.source.ISourceViewer;
83 import org.eclipse.jface.text.source.IVerticalRuler;
84 import org.eclipse.jface.text.source.SourceViewerConfiguration;
85 import org.eclipse.jface.text.source.projection.IProjectionListener;
86 import org.eclipse.jface.text.source.projection.ProjectionSupport;
87 import org.eclipse.jface.text.source.projection.ProjectionViewer;
88 import org.eclipse.jface.util.PropertyChangeEvent;
89 import org.eclipse.jface.viewers.IPostSelectionProvider;
90 import org.eclipse.jface.viewers.ISelection;
91 import org.eclipse.jface.viewers.ISelectionChangedListener;
92 import org.eclipse.jface.viewers.ISelectionProvider;
93 import org.eclipse.jface.viewers.IStructuredSelection;
94 import org.eclipse.jface.viewers.SelectionChangedEvent;
95 import org.eclipse.swt.custom.StyledText;
96 import org.eclipse.swt.events.ShellAdapter;
97 import org.eclipse.swt.events.ShellEvent;
98 import org.eclipse.swt.graphics.Image;
99 import org.eclipse.swt.widgets.Composite;
100 import org.eclipse.swt.widgets.Shell;
101 import org.eclipse.ui.IEditorInput;
102 import org.eclipse.ui.IPageLayout;
103 import org.eclipse.ui.IPartService;
104 import org.eclipse.ui.IWorkbenchPage;
105 import org.eclipse.ui.IWorkbenchPart;
106 import org.eclipse.ui.IWorkbenchWindow;
107 import org.eclipse.ui.PartInitException;
108 import org.eclipse.ui.editors.text.TextEditor;
109 import org.eclipse.ui.ide.IDE;
110 import org.eclipse.ui.part.IShowInTargetList;
111 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
112 import org.eclipse.ui.texteditor.ContentAssistAction;
113 import org.eclipse.ui.texteditor.IDocumentProvider;
114 import org.eclipse.ui.texteditor.IEditorStatusLine;
115 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
116 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
117 import org.eclipse.ui.texteditor.TextOperationAction;
118 import org.eclipse.ui.views.contentoutline.ContentOutline;
119 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
120
121 /**
122  * The actual editor implementation for Eclipse's Ant integration.
123  */

124 public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
125     /**
126      * Updates the Ant outline page selection and this editor's range indicator.
127      *
128      * @since 3.0
129      */

130     private class EditorSelectionChangedListener implements ISelectionChangedListener {
131         
132         /**
133          * Installs this selection changed listener with the given selection provider. If
134          * the selection provider is a post selection provider, post selection changed
135          * events are the preferred choice, otherwise normal selection changed events
136          * are requested.
137          *
138          * @param selectionProvider
139          */

140         public void install(ISelectionProvider selectionProvider) {
141             if (selectionProvider == null || getAntModel() == null) {
142                 return;
143             }
144                 
145             if (selectionProvider instanceof IPostSelectionProvider) {
146                 IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
147                 provider.addPostSelectionChangedListener(this);
148             } else {
149                 selectionProvider.addSelectionChangedListener(this);
150             }
151         }
152
153         /**
154          * Removes this selection changed listener from the given selection provider.
155          *
156          * @param selectionProvider
157          */

158         public void uninstall(ISelectionProvider selectionProvider) {
159             if (selectionProvider == null || getAntModel() == null) {
160                 return;
161             }
162             
163             if (selectionProvider instanceof IPostSelectionProvider) {
164                 IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
165                 provider.removePostSelectionChangedListener(this);
166             } else {
167                 selectionProvider.removeSelectionChangedListener(this);
168             }
169         }
170         
171         /*
172          * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
173          */

174         public void selectionChanged(SelectionChangedEvent event) {
175             AntModel model= getAntModel();
176             ISelection selection= event.getSelection();
177             AntElementNode node= null;
178             if (selection instanceof ITextSelection) {
179                 ITextSelection textSelection= (ITextSelection)selection;
180                 int offset= textSelection.getOffset();
181                 node= model.getNode(offset, false);
182                 updateOccurrenceAnnotations(textSelection, model);
183             }
184         
185             if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {
186                 synchronizeOutlinePage(node, true);
187             }
188             setSelection(node, false);
189         }
190     }
191     
192     class StatusLineSourceViewer extends ProjectionViewer{
193         
194         public StatusLineSourceViewer(Composite composite, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, int styles) {
195             super(composite, verticalRuler, overviewRuler, isOverviewRulerVisible(), styles);
196         }
197
198         /* (non-Javadoc)
199          * @see org.eclipse.jface.text.ITextOperationTarget#doOperation(int)
200          */

201         public void doOperation(int operation) {
202             if (getTextWidget() == null || !redraws()) {
203                 return;
204             }
205
206             switch (operation) {
207                 case CONTENTASSIST_PROPOSALS:
208                     String JavaDoc msg= fContentAssistant.showPossibleCompletions();
209                     setStatusLineErrorMessage(msg);
210                     return;
211             }
212             
213             super.doOperation(operation);
214         }
215     }
216         
217     
218     /**
219      * Finds and marks occurrence annotations.
220      *
221      * @since 3.1
222      */

223     class OccurrencesFinderJob extends Job {
224         
225         private IDocument fDocument;
226         private ISelection fSelection;
227         private ISelectionValidator fPostSelectionValidator;
228         private boolean fCanceled= false;
229         private IProgressMonitor fProgressMonitor;
230         private List JavaDoc fPositions;
231         
232         public OccurrencesFinderJob(IDocument document, List JavaDoc positions, ISelection selection) {
233             super("Occurrences Marker"); //$NON-NLS-1$
234
fDocument= document;
235             fSelection= selection;
236             fPositions= positions;
237             
238             if (getSelectionProvider() instanceof ISelectionValidator)
239                 fPostSelectionValidator= (ISelectionValidator)getSelectionProvider();
240         }
241         
242         // cannot use cancel() because it is declared final
243
void doCancel() {
244             fCanceled= true;
245             cancel();
246         }
247         
248         private boolean isCanceled() {
249             return fCanceled || fProgressMonitor.isCanceled()
250                 || fPostSelectionValidator != null && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
251                 || LinkedModeModel.hasInstalledModel(fDocument);
252         }
253         
254         /*
255          * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
256          */

257         public IStatus run(IProgressMonitor progressMonitor) {
258             
259             fProgressMonitor= progressMonitor;
260             
261             if (isCanceled())
262                 return Status.CANCEL_STATUS;
263             
264             ITextViewer textViewer= getViewer();
265             if (textViewer == null)
266                 return Status.CANCEL_STATUS;
267             
268             IDocument document= textViewer.getDocument();
269             if (document == null)
270                 return Status.CANCEL_STATUS;
271             
272             IDocumentProvider documentProvider= getDocumentProvider();
273             if (documentProvider == null)
274                 return Status.CANCEL_STATUS;
275         
276             IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
277             if (annotationModel == null)
278                 return Status.CANCEL_STATUS;
279             
280             // Add occurrence annotations
281
int length= fPositions.size();
282             Map JavaDoc annotationMap= new HashMap JavaDoc(length);
283             for (int i= 0; i < length; i++) {
284                 
285                 if (isCanceled())
286                     return Status.CANCEL_STATUS;
287                 
288                 String JavaDoc message;
289                 Position position= (Position) fPositions.get(i);
290                 
291                 // Create & add annotation
292
try {
293                     message= document.get(position.offset, position.length);
294                 } catch (BadLocationException ex) {
295                     // Skip this match
296
continue;
297                 }
298                 annotationMap.put(
299                         new Annotation("org.eclipse.jdt.ui.occurrences", false, message), //$NON-NLS-1$
300
position);
301             }
302             
303             if (isCanceled()) {
304                 return Status.CANCEL_STATUS;
305             }
306             
307             Object JavaDoc lock= getLockObject(document);
308             if (lock == null) {
309                 updateAnnotations(annotationModel, annotationMap);
310             } else {
311                 synchronized (lock) {
312                     updateAnnotations(annotationModel, annotationMap);
313                 }
314             }
315
316             return Status.OK_STATUS;
317         }
318
319         private void updateAnnotations(IAnnotationModel annotationModel, Map JavaDoc annotationMap) {
320             if (annotationModel instanceof IAnnotationModelExtension) {
321                 ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap);
322             } else {
323                 removeOccurrenceAnnotations();
324                 Iterator JavaDoc iter= annotationMap.entrySet().iterator();
325                 while (iter.hasNext()) {
326                     Map.Entry JavaDoc mapEntry= (Map.Entry JavaDoc)iter.next();
327                     annotationModel.addAnnotation((Annotation)mapEntry.getKey(), (Position)mapEntry.getValue());
328                 }
329             }
330             fOccurrenceAnnotations= (Annotation[])annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
331         }
332     }
333     
334     /**
335      * Cancels the occurrences finder job upon document changes.
336      *
337      * @since 3.1
338      */

339     class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {
340
341         public void install() {
342             ISourceViewer sourceViewer= getSourceViewer();
343             if (sourceViewer == null)
344                 return;
345                 
346             StyledText text= sourceViewer.getTextWidget();
347             if (text == null || text.isDisposed())
348                 return;
349
350             sourceViewer.addTextInputListener(this);
351             
352             IDocument document= sourceViewer.getDocument();
353             if (document != null)
354                 document.addDocumentListener(this);
355         }
356         
357         public void uninstall() {
358             ISourceViewer sourceViewer= getSourceViewer();
359             if (sourceViewer != null)
360                 sourceViewer.removeTextInputListener(this);
361
362             IDocumentProvider documentProvider= getDocumentProvider();
363             if (documentProvider != null) {
364                 IDocument document= documentProvider.getDocument(getEditorInput());
365                 if (document != null)
366                     document.removeDocumentListener(this);
367             }
368         }
369                 
370
371         /*
372          * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
373          */

374         public void documentAboutToBeChanged(DocumentEvent event) {
375             if (fOccurrencesFinderJob != null)
376                 fOccurrencesFinderJob.doCancel();
377         }
378
379         /*
380          * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
381          */

382         public void documentChanged(DocumentEvent event) {
383         }
384
385         /*
386          * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
387          */

388         public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
389             if (oldInput == null)
390                 return;
391
392             oldInput.removeDocumentListener(this);
393         }
394
395         /*
396          * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
397          */

398         public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
399             if (newInput == null)
400                 return;
401             newInput.addDocumentListener(this);
402         }
403     }
404     
405     /**
406      * Internal activation listener.
407      * @since 3.1
408      */

409     private class ActivationListener extends ShellAdapter {
410         /*
411          * @see org.eclipse.swt.events.ShellAdapter#shellActivated(org.eclipse.swt.events.ShellEvent)
412          */

413         public void shellActivated(ShellEvent e) {
414             if (fMarkOccurrenceAnnotations && isActivePart()) {
415                 ISelection selection= getSelectionProvider().getSelection();
416                 if (selection instanceof ITextSelection) {
417                     fForcedMarkOccurrencesSelection= (ITextSelection) selection;
418                     updateOccurrenceAnnotations(fForcedMarkOccurrencesSelection, getAntModel());
419                 }
420             }
421         }
422         
423         /*
424          * @see org.eclipse.swt.events.ShellAdapter#shellDeactivated(org.eclipse.swt.events.ShellEvent)
425          */

426         public void shellDeactivated(ShellEvent e) {
427             if (fMarkOccurrenceAnnotations && isActivePart())
428                 removeOccurrenceAnnotations();
429         }
430     }
431
432     /**
433      * Selection changed listener for the outline view.
434      */

435     protected ISelectionChangedListener fSelectionChangedListener = new ISelectionChangedListener(){
436         public void selectionChanged(SelectionChangedEvent event) {
437             fSelectionSetFromOutline= false;
438             doSelectionChanged(event);
439             fSelectionSetFromOutline= true;
440         }
441     };
442     
443     private IAntModelListener fAntModelListener= new IAntModelListener() {
444         /* (non-Javadoc)
445          * @see org.eclipse.ant.internal.ui.editor.outline.IDocumentModelListener#documentModelChanged(org.eclipse.ant.internal.ui.editor.outline.DocumentModelChangeEvent)
446          */

447         public void antModelChanged(AntModelChangeEvent event) {
448             AntModel model= getAntModel();
449             if (event.getModel() == model) {
450                 if (event.isPreferenceChange()) {
451                     updateEditorImage(model);
452                 }
453                 if (fFoldingStructureProvider != null) {
454                     fFoldingStructureProvider.updateFoldingRegions(model);
455                 }
456             }
457         }
458     };
459     
460     /**
461      * The page that shows the outline.
462      */

463     protected AntEditorContentOutlinePage fOutlinePage;
464     
465     
466     private boolean fInitialReconcile= true;
467     
468     /**
469      * The editor selection changed listener.
470      *
471      * @since 3.0
472      */

473     private EditorSelectionChangedListener fEditorSelectionChangedListener;
474
475     private ProjectionSupport fProjectionSupport;
476     
477     private AntFoldingStructureProvider fFoldingStructureProvider;
478     
479     private boolean fSelectionSetFromOutline= false;
480
481     private FoldingActionGroup fFoldingGroup;
482     
483     /**
484      * Holds the current occurrence annotations.
485      * @since 3.1
486      */

487     private Annotation[] fOccurrenceAnnotations= null;
488
489     private OccurrencesFinderJob fOccurrencesFinderJob;
490     private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
491     
492     private ITextSelection fForcedMarkOccurrencesSelection;
493     /**
494      * The internal shell activation listener for updating occurrences.
495      * @since 3.1
496      */

497     private ActivationListener fActivationListener= new ActivationListener();
498     
499     private boolean fMarkOccurrenceAnnotations;
500     private boolean fStickyOccurrenceAnnotations;
501     
502     private AntModel fAntModel;
503   
504     public AntEditor() {
505         super();
506         setSourceViewerConfiguration(new AntEditorSourceViewerConfiguration(this));
507         setDocumentProvider(AntUIPlugin.getDefault().getDocumentProvider());
508         AntModelCore.getDefault().addAntModelListener(fAntModelListener);
509         
510         if (isFoldingEnabled()) {
511             fFoldingStructureProvider= new AntFoldingStructureProvider(this);
512         }
513     }
514
515
516     /* (non-Javadoc)
517      * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
518      */

519     protected void createActions() {
520         super.createActions();
521
522         ResourceBundle JavaDoc bundle = ResourceBundle.getBundle("org.eclipse.ant.internal.ui.editor.AntEditorMessages"); //$NON-NLS-1$
523
IAction action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$
524

525         // This action definition is associated with the accelerator Ctrl+Space
526
action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
527         setAction("ContentAssistProposal", action); //$NON-NLS-1$
528

529         action = new TextOperationAction(bundle, "ContentFormat.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
530
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.FORMAT);
531         setAction("ContentFormat", action); //$NON-NLS-1$
532

533         action = new OpenDeclarationAction(this);
534         setAction("OpenDeclaration", action); //$NON-NLS-1$
535

536         fFoldingGroup= new FoldingActionGroup(this, getViewer());
537         
538         action= new RenameInFileAction(this);
539         action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
540
setAction("renameInFile", action); //$NON-NLS-1$
541
}
542
543     /*
544      * (non-Javadoc)
545      * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
546      * Called from TextEditor.<init>
547      */

548     protected void initializeEditor() {
549         super.initializeEditor();
550         setPreferenceStore(AntUIPlugin.getDefault().getCombinedPreferenceStore());
551         setCompatibilityMode(false);
552         setHelpContextId(IAntUIHelpContextIds.ANT_EDITOR);
553         setRulerContextMenuId("org.eclipse.ant.internal.ui.editor.AntEditor.RulerContext"); //$NON-NLS-1$
554
setEditorContextMenuId("org.eclipse.ant.internal.ui.editor.AntEditor"); //$NON-NLS-1$
555
fMarkOccurrenceAnnotations= getPreferenceStore().getBoolean(AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES);
556         fStickyOccurrenceAnnotations= getPreferenceStore().getBoolean(AntEditorPreferenceConstants.EDITOR_STICKY_OCCURRENCES);
557     }
558    
559     /* (non-Javadoc)
560      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
561      */

562     public Object JavaDoc getAdapter(Class JavaDoc key) {
563         if (key.equals(IContentOutlinePage.class)) {
564             return getOutlinePage();
565         }
566         
567         if (fProjectionSupport != null) {
568             Object JavaDoc adapter= fProjectionSupport.getAdapter(getSourceViewer(), key);
569             if (adapter != null) {
570                 return adapter;
571             }
572         }
573
574         if (key == IShowInTargetList.class) {
575             return new IShowInTargetList() {
576                 public String JavaDoc[] getShowInTargetIds() {
577                     return new String JavaDoc[] { JavaUI.ID_PACKAGES, IPageLayout.ID_RES_NAV };
578                 }
579             };
580         }
581         
582         if (key == IToggleBreakpointsTarget.class) {
583             return new ToggleLineBreakpointAction();
584         }
585         
586         if (key == IRunToLineTarget.class) {
587             return new RunToLineAdapter();
588         }
589         
590         return super.getAdapter(key);
591     }
592
593     private AntEditorContentOutlinePage getOutlinePage() {
594         if (fOutlinePage == null) {
595             fOutlinePage= new AntEditorContentOutlinePage(AntModelCore.getDefault(), this);
596             fOutlinePage.addPostSelectionChangedListener(fSelectionChangedListener);
597             setOutlinePageInput();
598         }
599         return fOutlinePage;
600     }
601
602     private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
603         IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();
604
605         if (!isActivePart() && AntUIPlugin.getActivePage() != null) {
606             AntUIPlugin.getActivePage().bringToTop(this);
607         }
608         
609         AntElementNode selectedXmlElement = (AntElementNode)selection.getFirstElement();
610         if(selectedXmlElement != null) {
611             setSelection(selectedXmlElement, !isActivePart());
612         }
613     }
614
615     private boolean isActivePart() {
616         IWorkbenchPart part= getActivePart();
617         return part != null && part.equals(this);
618     }
619     
620     public void setSelection(AntElementNode reference, boolean moveCursor) {
621         if (fSelectionSetFromOutline) {
622             //the work has all just been done via a selection setting in the outline
623
fSelectionSetFromOutline= false;
624             return;
625         }
626         if (reference == null) {
627             if (moveCursor) {
628                  resetHighlightRange();
629                  markInNavigationHistory();
630             }
631             return;
632         }
633         
634         if (moveCursor) {
635             markInNavigationHistory();
636         }
637         
638         while (reference.getImportNode() != null) {
639             reference= reference.getImportNode();
640         }
641         if (reference.isExternal()) {
642             return;
643         }
644         
645         ISourceViewer sourceViewer= getSourceViewer();
646         if (sourceViewer == null) {
647             return;
648         }
649         StyledText textWidget= sourceViewer.getTextWidget();
650         if (textWidget == null) {
651             return;
652         }
653             
654         try {
655             int offset= reference.getOffset();
656             if (offset < 0) {
657                 return;
658             }
659             int length= reference.getSelectionLength();
660             int highLightLength= reference.getLength();
661                
662             textWidget.setRedraw(false);
663             
664             if (highLightLength > 0) {
665                 setHighlightRange(offset, highLightLength, moveCursor);
666             }
667             
668             if (!moveCursor) {
669                 return;
670             }
671                                         
672             if (offset > -1 && length > 0) {
673                 sourceViewer.revealRange(offset, length);
674                 // Selected region begins one index after offset
675
sourceViewer.setSelectedRange(offset, length);
676                 markInNavigationHistory();
677             }
678         } catch (IllegalArgumentException JavaDoc x) {
679             AntUIPlugin.log(x);
680         } finally {
681             textWidget.setRedraw(true);
682         }
683     }
684
685     /* (non-Javadoc)
686      * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(org.eclipse.jface.util.PropertyChangeEvent)
687      */

688     protected boolean affectsTextPresentation(PropertyChangeEvent event) {
689         return ((AntEditorSourceViewerConfiguration)getSourceViewerConfiguration()).affectsTextPresentation(event);
690     }
691     
692     /* (non-Javadoc)
693      * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
694      */

695     protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
696         String JavaDoc property= event.getProperty();
697         
698         if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
699             Object JavaDoc value= event.getNewValue();
700             StatusLineSourceViewer viewer= (StatusLineSourceViewer) getSourceViewer();
701             int newValue= -1;
702             if (value instanceof Integer JavaDoc) {
703                 newValue=((Integer JavaDoc) value).intValue();
704             } else if (value instanceof String JavaDoc) {
705                 newValue= Integer.parseInt((String JavaDoc) value);
706             }
707             if (newValue != -1) {
708                 viewer.getTextWidget().setTabs(newValue);
709             }
710             return;
711         }
712         
713         if (AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
714             boolean newBooleanValue= Boolean.valueOf(event.getNewValue().toString()).booleanValue();
715             if (newBooleanValue != fMarkOccurrenceAnnotations) {
716                 fMarkOccurrenceAnnotations= newBooleanValue;
717                 if (fMarkOccurrenceAnnotations) {
718                     installOccurrencesFinder();
719                 } else {
720                     uninstallOccurrencesFinder();
721                 }
722             }
723             return;
724         }
725         if (AntEditorPreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) {
726             boolean newBooleanValue= Boolean.valueOf(event.getNewValue().toString()).booleanValue();
727             fStickyOccurrenceAnnotations= newBooleanValue;
728             return;
729         }
730
731         AntEditorSourceViewerConfiguration sourceViewerConfiguration= (AntEditorSourceViewerConfiguration)getSourceViewerConfiguration();
732         if (sourceViewerConfiguration != null) {
733             if (affectsTextPresentation(event)) {
734                 sourceViewerConfiguration.adaptToPreferenceChange(event);
735             }
736
737             sourceViewerConfiguration.changeConfiguration(event);
738         }
739         super.handlePreferenceStoreChanged(event);
740     }
741     
742     /*
743      * @see org.eclipse.ui.editors.text.TextEditor#doSetInput(org.eclipse.ui.IEditorInput)
744      */

745     protected void doSetInput(IEditorInput input) throws CoreException {
746         fAntModel= null;
747         super.doSetInput(input);
748         setOutlinePageInput();
749         if (fFoldingStructureProvider != null) {
750             fFoldingStructureProvider.setDocument(getDocumentProvider().getDocument(input));
751         }
752     }
753
754     private void setOutlinePageInput() {
755         if (fOutlinePage != null) {
756             fOutlinePage.setPageInput(getAntModel());
757         }
758     }
759     
760     /**
761      * Returns the Ant model for the current editor input of this editor.
762      * @return the Ant model for this editor or <code>null</code>
763      */

764     public AntModel getAntModel() {
765         if (fAntModel == null) {
766             IDocumentProvider provider= getDocumentProvider();
767             if (provider instanceof AntEditorDocumentProvider) {
768                 AntEditorDocumentProvider documentProvider= (AntEditorDocumentProvider) provider;
769                 fAntModel= documentProvider.getAntModel(getEditorInput());
770             }
771         }
772         return fAntModel;
773     }
774     
775     /* (non-Javadoc)
776      * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
777      */

778     protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
779         fOverviewRuler= createOverviewRuler(getSharedColors());
780         ISourceViewer viewer= new StatusLineSourceViewer(parent, ruler, getOverviewRuler(), styles);
781         //ensure decoration support has been created and configured.
782
getSourceViewerDecorationSupport(viewer);
783         return viewer;
784     }
785     
786     /**
787      * Set the given message as error message to this editor's status line.
788      * @param msg message to be set
789      */

790     protected void setStatusLineErrorMessage(String JavaDoc msg) {
791         IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
792         if (statusLine != null)
793             statusLine.setMessage(true, msg, null);
794     }
795
796     public void openReferenceElement() {
797         ISelection selection= getSelectionProvider().getSelection();
798         Object JavaDoc target= null;
799         if (selection instanceof ITextSelection) {
800             ITextSelection textSelection= (ITextSelection)selection;
801             ISourceViewer viewer= getSourceViewer();
802             int textOffset= textSelection.getOffset();
803             IRegion region= XMLTextHover.getRegion(viewer, textOffset);
804             target= findTarget(region);
805         }
806         
807         openTarget(target);
808     }
809     
810     protected void openTarget(Object JavaDoc node) {
811         String JavaDoc errorMessage= null;
812         if (node instanceof AntElementNode) {
813             errorMessage= openNode((AntElementNode) node);
814             if (errorMessage == null) {
815                 return;
816             }
817         } else if (node instanceof String JavaDoc){
818             errorMessage= openInEditor((String JavaDoc) node, getAntModel().getEditedFile());
819             if (errorMessage == null) {
820                 return;
821             }
822         }
823         if (errorMessage == null || errorMessage.length() == 0) {
824             errorMessage= AntEditorMessages.getString("AntEditor.3"); //$NON-NLS-1$
825
}
826         setStatusLineErrorMessage(errorMessage);
827         getSite().getShell().getDisplay().beep();
828     }
829
830     /**
831      * @param region The region to find the navigation target
832      * @return the navigation target at the specified region
833      */

834     public Object JavaDoc findTarget(IRegion region) {
835         ISourceViewer viewer = getSourceViewer();
836         AntElementNode node= null;
837        
838         if (region != null) {
839             IDocument document= viewer.getDocument();
840             String JavaDoc text= null;
841             try {
842                 text= document.get(region.getOffset(), region.getLength());
843             } catch (BadLocationException e) {
844             }
845             if (text != null && text.length() > 0) {
846                 AntModel model= getAntModel();
847                 if (model == null) {
848                     return null;
849                 }
850                 node= model.getReferenceNode(text);
851                 if (node == null) {
852                     node= model.getTargetNode(text);
853                     if (node == null) {
854                         node= model.getPropertyNode(text);
855                         if (node == null) {
856                             String JavaDoc path= model.getPath(text, region.getOffset());
857                             if (path != null) {
858                                 return path;
859                             }
860                             
861                             node= model.getDefininingTaskNode(text);
862                             if (node == null) {
863                                 node= model.getMacroDefAttributeNode(text);
864                             }
865                         }
866                     }
867                 }
868             }
869         }
870         return node;
871     }
872
873
874     private String JavaDoc openNode(AntElementNode node) {
875         String JavaDoc errorMessage= null;
876         if (node.isExternal()) {
877             String JavaDoc path= node.getFilePath();
878             errorMessage= openInEditor(path, null);
879         } else {
880             setSelection(node, true);
881         }
882         return errorMessage;
883     }
884     
885     private String JavaDoc openInEditor(String JavaDoc path, File JavaDoc buildFile) {
886         File JavaDoc buildFileParent= null;
887         if (buildFile != null) {
888             buildFileParent= buildFile.getParentFile();
889         }
890         IFile file= AntUtil.getFileForLocation(path, buildFileParent);
891         if (file != null && file.exists()) {
892             try {
893                 IWorkbenchPage p= getEditorSite().getPage();
894                 if (p != null) {
895                     IDE.openEditor(p, file, isActivePart());
896                 }
897                 return null;
898             } catch (PartInitException e) {
899                 return e.getLocalizedMessage();
900             }
901         }
902         File JavaDoc externalFile= new File JavaDoc(path);
903         if (externalFile.exists()) {
904             new ExternalHyperlink(externalFile, -1).linkActivated();
905             return null;
906         }
907         
908         return ""; //$NON-NLS-1$
909
}
910     
911     /* (non-Javadoc)
912      * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
913      */

914     public void editorContextMenuAboutToShow(IMenuManager menu) {
915         super.editorContextMenuAboutToShow(menu);
916         
917         if (getAntModel() != null) {
918             IAction action= getAction("OpenDeclaration"); //$NON-NLS-1$
919
if (action != null) {
920                 String JavaDoc openGroup = "group.open"; //$NON-NLS-1$
921
menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, new Separator(openGroup));
922                 menu.appendToGroup(openGroup, action);
923             }
924             
925             action= getAction("renameInFile"); //$NON-NLS-1$
926
String JavaDoc editGroup = "group.edit"; //$NON-NLS-1$
927
menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, new Separator(editGroup));
928             menu.appendToGroup(editGroup, action);
929             
930             action= getAction("ContentFormat"); //$NON-NLS-1$
931
menu.appendToGroup(editGroup, action);
932         }
933     }
934     
935     /* (non-Javadoc)
936      * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
937      */

938     public void createPartControl(Composite parent) {
939         super.createPartControl(parent);
940         
941         ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer();
942         createFoldingSupport(projectionViewer);
943         if (isFoldingEnabled()) {
944             projectionViewer.doOperation(ProjectionViewer.TOGGLE);
945         }
946         
947         if (fMarkOccurrenceAnnotations) {
948             installOccurrencesFinder();
949         }
950         getEditorSite().getShell().addShellListener(fActivationListener);
951         
952         fEditorSelectionChangedListener= new EditorSelectionChangedListener();
953         fEditorSelectionChangedListener.install(getSelectionProvider());
954     }
955     
956     private void createFoldingSupport(ProjectionViewer projectionViewer) {
957         fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
958         fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
959             public IInformationControl createInformationControl(Shell shell) {
960                 return new AntSourceViewerInformationControl(shell);
961             }
962         });
963         fProjectionSupport.install();
964         ((ProjectionViewer)getViewer()).addProjectionListener(this);
965         
966     }
967
968
969     private boolean isFoldingEnabled() {
970         IPreferenceStore store= getPreferenceStore();
971         return store.getBoolean(AntEditorPreferenceConstants.EDITOR_FOLDING_ENABLED);
972     }
973
974     /*
975      * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled()
976      * @since 3.3
977      */

978     protected boolean isTabsToSpacesConversionEnabled() {
979         return super.isTabsToSpacesConversionEnabled(); //provide package visibility
980
}
981     
982     /* (non-Javadoc)
983      * @see org.eclipse.ui.IWorkbenchPart#dispose()
984      */

985     public void dispose() {
986         if (fEditorSelectionChangedListener != null) {
987             fEditorSelectionChangedListener.uninstall(getSelectionProvider());
988             fEditorSelectionChangedListener= null;
989         }
990         
991         ((ProjectionViewer)getViewer()).removeProjectionListener(this);
992         if (fProjectionSupport != null) {
993             fProjectionSupport.dispose();
994             fProjectionSupport= null;
995         }
996         
997         uninstallOccurrencesFinder();
998         
999         if (fActivationListener != null) {
1000            Shell shell= getEditorSite().getShell();
1001            if (shell != null && !shell.isDisposed()) {
1002                shell.removeShellListener(fActivationListener);
1003            }
1004            fActivationListener= null;
1005        }
1006        
1007        AntModelCore.getDefault().removeAntModelListener(fAntModelListener);
1008        fAntModel= null;
1009        super.dispose();
1010    }
1011    
1012    /* (non-Javadoc)
1013     * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
1014     */

1015    public void doSave(IProgressMonitor monitor) {
1016        super.doSave(monitor);
1017        AntModel model= getAntModel();
1018        model.updateMarkers();
1019        updateEditorImage(model);
1020    }
1021    
1022    private void updateEditorImage(AntModel model) {
1023        Image titleImage= getTitleImage();
1024        if (titleImage == null) {
1025            return;
1026        }
1027        AntProjectNode node= model.getProjectNode();
1028        if (node != null) {
1029            postImageChange(node);
1030        }
1031    }
1032    
1033    private void updateForInitialReconcile() {
1034        IDocumentProvider provider= getDocumentProvider();
1035        if (provider == null) {//disposed
1036
return;
1037        }
1038        if (getAntModel() == null) {
1039            return;
1040        }
1041        IDocument doc= provider.getDocument(getEditorInput());
1042        if (doc == null) {
1043            return; //disposed
1044
}
1045        Object JavaDoc lock= getLockObject(doc);
1046        //ensure to synchronize so that the AntModel is not nulled out underneath in the AntEditorDocumentProvider
1047
//when the editor/doc provider are disposed
1048
if (lock == null) {
1049            updateModelForInitialReconcile();
1050        } else {
1051            synchronized (lock) {
1052                updateModelForInitialReconcile();
1053            }
1054        }
1055    }
1056    
1057    private void updateModelForInitialReconcile() {
1058        AntModel model= getAntModel();
1059        if (model == null) {
1060            return;
1061        }
1062
1063        fInitialReconcile= false;
1064        updateEditorImage(model);
1065        model.updateForInitialReconcile();
1066    }
1067    
1068    private Object JavaDoc getLockObject(IDocument doc) {
1069        Object JavaDoc lock= null;
1070        if (doc instanceof ISynchronizable) {
1071            lock= ((ISynchronizable) doc).getLockObject();
1072        } else {
1073            lock= getAntModel();
1074        }
1075        return lock;
1076    }
1077    
1078    private void postImageChange(final AntElementNode node) {
1079        Shell shell= getSite().getShell();
1080        if (shell != null && !shell.isDisposed()) {
1081            shell.getDisplay().asyncExec(new Runnable JavaDoc() {
1082                public void run() {
1083                    if (getSite().getShell() == null || getSite().getShell().isDisposed()) {
1084                        return;
1085                    }
1086                    Image titleImage= getTitleImage();
1087                    Image newImage= node.getImage();
1088                    if (titleImage != newImage) {
1089                        setTitleImage(newImage);
1090                    }
1091                }
1092            });
1093        }
1094    }
1095
1096    public void synchronizeOutlinePage(boolean checkIfOutlinePageActive) {
1097        if (getSelectionProvider() == null) {
1098            return;
1099        }
1100        AntElementNode node= getNode();
1101        synchronizeOutlinePage(node, checkIfOutlinePageActive);
1102        
1103    }
1104    
1105    protected void synchronize(boolean checkIfOutlinePageActive) {
1106        if (getSelectionProvider() == null) {
1107            return;
1108        }
1109        AntElementNode node= getNode();
1110        if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {
1111            synchronizeOutlinePage(node, checkIfOutlinePageActive);
1112        }
1113        setSelection(node, false);
1114        
1115    }
1116    
1117    private AntElementNode getNode() {
1118        AntModel model= getAntModel();
1119        if (model == null) {
1120            return null;
1121        }
1122        AntElementNode node= null;
1123        ISelection selection= getSelectionProvider().getSelection();
1124        if (selection instanceof ITextSelection) {
1125            ITextSelection textSelection= (ITextSelection)selection;
1126            int offset= textSelection.getOffset();
1127            node= model.getNode(offset, false);
1128        }
1129        return node;
1130    }
1131    
1132    protected void synchronizeOutlinePage(AntElementNode node, boolean checkIfOutlinePageActive) {
1133        if (fOutlinePage != null && !(checkIfOutlinePageActive && isAntOutlinePageActive())) {
1134            fOutlinePage.removePostSelectionChangedListener(fSelectionChangedListener);
1135            fOutlinePage.select(node);
1136            fOutlinePage.addPostSelectionChangedListener(fSelectionChangedListener);
1137        }
1138    }
1139    
1140    /* (non-Javadoc)
1141     * @see org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant#reconciled()
1142     */

1143    public void reconciled() {
1144        if (fInitialReconcile) {
1145            updateForInitialReconcile();
1146        }
1147        
1148        SourceViewerConfiguration config= getSourceViewerConfiguration();
1149        if (config == null) {
1150            return; //editor has been disposed.
1151
}
1152        IAutoEditStrategy[] strategies= config.getAutoEditStrategies(getViewer(), null);
1153        for (int i = 0; i < strategies.length; i++) {
1154            IAutoEditStrategy strategy = strategies[i];
1155            if (strategy instanceof AntAutoEditStrategy) {
1156                ((AntAutoEditStrategy)strategy).reconciled();
1157            }
1158        }
1159        
1160        Shell shell= getSite().getShell();
1161        if (shell != null && !shell.isDisposed()) {
1162            shell.getDisplay().asyncExec(new Runnable JavaDoc() {
1163                public void run() {
1164                    if (getSite().getShell() == null || getSite().getShell().isDisposed()) {
1165                        return;
1166                    }
1167                    synchronize(true);
1168                }
1169            });
1170        }
1171    }
1172    
1173    private boolean isAntOutlinePageActive() {
1174        IWorkbenchPart part= getActivePart();
1175        return part instanceof ContentOutline && ((ContentOutline)part).getCurrentPage() == fOutlinePage;
1176    }
1177
1178    private IWorkbenchPart getActivePart() {
1179        IWorkbenchWindow window= getSite().getWorkbenchWindow();
1180        IPartService service= window.getPartService();
1181        return service.getActivePart();
1182    }
1183    
1184    /* (non-Javadoc)
1185     * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(org.eclipse.jface.viewers.ISelection)
1186     */

1187    protected void doSetSelection(ISelection selection) {
1188        super.doSetSelection(selection);
1189        synchronizeOutlinePage(true);
1190    }
1191
1192    /**
1193     * Returns the viewer associated with this editor
1194     * @return The viewer associated with this editor
1195     */

1196    public ISourceViewer getViewer() {
1197        return getSourceViewer();
1198    }
1199
1200    protected FoldingActionGroup getFoldingActionGroup() {
1201        return fFoldingGroup;
1202    }
1203
1204    /* (non-Javadoc)
1205     * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
1206     */

1207    public void projectionEnabled() {
1208        fFoldingStructureProvider= new AntFoldingStructureProvider(this);
1209        fFoldingStructureProvider.setDocument(getDocumentProvider().getDocument(getEditorInput()));
1210        fFoldingStructureProvider.updateFoldingRegions(getAntModel());
1211    }
1212
1213    /* (non-Javadoc)
1214     * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
1215     */

1216    public void projectionDisabled() {
1217        fFoldingStructureProvider= null;
1218    }
1219    
1220    /* (non-Javadoc)
1221     * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
1222     */

1223    protected void initializeKeyBindingScopes() {
1224        setKeyBindingScopes(new String JavaDoc[] { "org.eclipse.ant.ui.AntEditorScope" }); //$NON-NLS-1$
1225
}
1226    
1227    protected IPreferenceStore getEditorPreferenceStore() {
1228        return getPreferenceStore();
1229    }
1230    
1231    /* (non-Javadoc)
1232     * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
1233     * @since 3.1
1234     */

1235    protected String JavaDoc[] collectContextMenuPreferencePages() {
1236        String JavaDoc[] ids= super.collectContextMenuPreferencePages();
1237        String JavaDoc[] more= new String JavaDoc[ids.length + 6];
1238        more[0]= "org.eclipse.ant.ui.AntEditorPreferencePage"; //$NON-NLS-1$
1239
more[1]= "org.eclipse.ant.ui.AntCodeFormatterPreferencePage"; //$NON-NLS-1$
1240
more[2]= "org.eclipse.ant.ui.AntCodeAssistPreferencePage"; //$NON-NLS-1$
1241
more[3]= "org.eclipse.ant.ui.TemplatesPreferencePage"; //$NON-NLS-1$
1242
more[4]= "org.eclipse.ant.ui.AntPreferencePage"; //$NON-NLS-1$
1243
more[5]= "org.eclipse.ant.ui.AntRuntimePreferencePage"; //$NON-NLS-1$
1244
System.arraycopy(ids, 0, more, 6, ids.length);
1245        return more;
1246    }
1247    
1248    /**
1249     * Updates the occurrences annotations based
1250     * on the current selection.
1251     *
1252     * @param selection the text selection
1253     * @param antModel the model for the buildfile
1254     * @since 3.1
1255     */

1256    protected void updateOccurrenceAnnotations(ITextSelection selection, AntModel antModel) {
1257
1258        if (fOccurrencesFinderJob != null)
1259            fOccurrencesFinderJob.cancel();
1260
1261        if (!fMarkOccurrenceAnnotations) {
1262            return;
1263        }
1264        
1265        if (selection == null || antModel == null) {
1266            return;
1267        }
1268        
1269        IDocument document= getSourceViewer().getDocument();
1270        if (document == null) {
1271            return;
1272        }
1273        
1274        List JavaDoc positions= null;
1275        
1276        OccurrencesFinder finder= new OccurrencesFinder(this, antModel, document, selection.getOffset());
1277        positions= finder.perform();
1278        
1279        if (positions == null || positions.size() == 0) {
1280            if (!fStickyOccurrenceAnnotations) {
1281                removeOccurrenceAnnotations();
1282            }
1283            return;
1284        }
1285            
1286        fOccurrencesFinderJob= new OccurrencesFinderJob(document, positions, selection);
1287        fOccurrencesFinderJob.run(new NullProgressMonitor());
1288    }
1289    
1290    private void removeOccurrenceAnnotations() {
1291        IDocumentProvider documentProvider= getDocumentProvider();
1292        if (documentProvider == null) {
1293            return;
1294        }
1295        
1296        IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
1297        if (annotationModel == null || fOccurrenceAnnotations == null) {
1298            return;
1299        }
1300
1301        IDocument document= documentProvider.getDocument(getEditorInput());
1302        Object JavaDoc lock= getLockObject(document);
1303        if (lock == null) {
1304            updateAnnotationModelForRemoves(annotationModel);
1305        } else {
1306            synchronized (lock) {
1307                updateAnnotationModelForRemoves(annotationModel);
1308            }
1309        }
1310    }
1311
1312
1313    private void updateAnnotationModelForRemoves(IAnnotationModel annotationModel) {
1314        if (annotationModel instanceof IAnnotationModelExtension) {
1315            ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, null);
1316        } else {
1317            for (int i= 0, length= fOccurrenceAnnotations.length; i < length; i++) {
1318                annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
1319            }
1320        }
1321        fOccurrenceAnnotations= null;
1322    }
1323
1324    protected void installOccurrencesFinder() {
1325        fMarkOccurrenceAnnotations= true;
1326        
1327        if (getSelectionProvider() != null) {
1328            ISelection selection= getSelectionProvider().getSelection();
1329            if (selection instanceof ITextSelection) {
1330                fForcedMarkOccurrencesSelection= (ITextSelection) selection;
1331                updateOccurrenceAnnotations(fForcedMarkOccurrencesSelection, getAntModel());
1332            }
1333        }
1334        if (fOccurrencesFinderJobCanceler == null) {
1335            fOccurrencesFinderJobCanceler= new OccurrencesFinderJobCanceler();
1336            fOccurrencesFinderJobCanceler.install();
1337        }
1338    }
1339    
1340    protected void uninstallOccurrencesFinder() {
1341        fMarkOccurrenceAnnotations= false;
1342        
1343        if (fOccurrencesFinderJob != null) {
1344            fOccurrencesFinderJob.cancel();
1345            fOccurrencesFinderJob= null;
1346        }
1347
1348        if (fOccurrencesFinderJobCanceler != null) {
1349            fOccurrencesFinderJobCanceler.uninstall();
1350            fOccurrencesFinderJobCanceler= null;
1351        }
1352        
1353        removeOccurrenceAnnotations();
1354    }
1355    
1356    public boolean isMarkingOccurrences() {
1357        return fMarkOccurrenceAnnotations;
1358    }
1359
1360
1361    /**
1362     * The editor has entered or exited linked mode.
1363     * @param inLinkedMode whether an enter or exit has occurred
1364     * @param effectsOccurrences whether to change the state of the occurrences finder
1365     */

1366    public void setInLinkedMode(boolean inLinkedMode, boolean effectsOccurrences) {
1367        if (inLinkedMode) {
1368            getAntModel().setShouldReconcile(false);
1369            if (effectsOccurrences) {
1370                uninstallOccurrencesFinder();
1371            }
1372        } else {
1373            getAntModel().setShouldReconcile(true);
1374            if (effectsOccurrences) {
1375                installOccurrencesFinder();
1376            }
1377        }
1378    }
1379}
Popular Tags