KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > editor > text > XMLTextHover


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ant.internal.ui.editor.text;
12
13 import java.util.Iterator JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15
16 import org.apache.tools.ant.BuildException;
17 import org.apache.tools.ant.Project;
18 import org.apache.tools.ant.types.AbstractFileSet;
19 import org.apache.tools.ant.types.Path;
20 import org.apache.tools.ant.types.PatternSet;
21 import org.eclipse.ant.internal.ui.debug.model.AntProperty;
22 import org.eclipse.ant.internal.ui.debug.model.AntStackFrame;
23 import org.eclipse.ant.internal.ui.debug.model.AntValue;
24 import org.eclipse.ant.internal.ui.editor.AntEditor;
25 import org.eclipse.ant.internal.ui.editor.AntEditorSourceViewerConfiguration;
26 import org.eclipse.ant.internal.ui.model.AntElementNode;
27 import org.eclipse.ant.internal.ui.model.AntModel;
28 import org.eclipse.ant.internal.ui.model.AntPropertyNode;
29 import org.eclipse.ant.internal.ui.model.IAntModel;
30 import org.eclipse.core.runtime.IAdaptable;
31 import org.eclipse.debug.ui.DebugUITools;
32 import org.eclipse.jface.internal.text.html.HTMLPrinter;
33 import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
34 import org.eclipse.jface.text.BadLocationException;
35 import org.eclipse.jface.text.DefaultInformationControl;
36 import org.eclipse.jface.text.IDocument;
37 import org.eclipse.jface.text.IInformationControl;
38 import org.eclipse.jface.text.IInformationControlCreator;
39 import org.eclipse.jface.text.IRegion;
40 import org.eclipse.jface.text.ITextHover;
41 import org.eclipse.jface.text.ITextHoverExtension;
42 import org.eclipse.jface.text.ITextViewer;
43 import org.eclipse.jface.text.Position;
44 import org.eclipse.jface.text.Region;
45 import org.eclipse.jface.text.information.IInformationProviderExtension2;
46 import org.eclipse.jface.text.source.Annotation;
47 import org.eclipse.jface.text.source.IAnnotationModel;
48 import org.eclipse.jface.text.source.ISourceViewer;
49 import org.eclipse.swt.SWT;
50 import org.eclipse.swt.widgets.Shell;
51 import org.eclipse.ui.editors.text.EditorsUI;
52
53
54 public class XMLTextHover implements ITextHover, ITextHoverExtension, IInformationProviderExtension2 {
55
56     private AntEditor fEditor;
57     
58     public XMLTextHover(AntEditor editor) {
59         super();
60         fEditor = editor;
61     }
62     
63     /*
64      * Formats a message as HTML text.
65      * Expects the message to already be properly escaped
66      */

67     private String JavaDoc formatMessage(String JavaDoc message) {
68         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
69         HTMLPrinter.addPageProlog(buffer);
70         HTMLPrinter.addParagraph(buffer, message);
71         HTMLPrinter.addPageEpilog(buffer);
72         return buffer.toString();
73     }
74     
75     /*
76      * Formats a message as HTML text.
77      */

78     private String JavaDoc formatPathMessage(String JavaDoc[] list) {
79         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
80         HTMLPrinter.addPageProlog(buffer);
81         HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_4);
82         HTMLPrinter.startBulletList(buffer);
83         for (int i = 0; i < list.length; i++) {
84             HTMLPrinter.addBullet(buffer, list[i]);
85         }
86         HTMLPrinter.endBulletList(buffer);
87         HTMLPrinter.addPageEpilog(buffer);
88         return buffer.toString();
89     }
90     
91     /* (non-Javadoc)
92      * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
93      */

94     public String JavaDoc getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
95         
96         if (!(textViewer instanceof ISourceViewer)) {
97             return null;
98         }
99         
100         ISourceViewer sourceViewer= (ISourceViewer) textViewer;
101         IAnnotationModel model= sourceViewer.getAnnotationModel();
102         
103         if (model != null) {
104             String JavaDoc message= getAnnotationModelHoverMessage(model, hoverRegion);
105             if (message != null) {
106                 return message;
107             }
108         }
109         
110         AntModel antModel= fEditor.getAntModel();
111         if (antModel == null) { //the ant model has not been created yet
112
return null;
113         }
114         
115         return getAntModelHoverMessage(antModel, hoverRegion, textViewer);
116         
117     }
118     
119     private String JavaDoc getAntModelHoverMessage(AntModel antModel, IRegion hoverRegion, ITextViewer textViewer){
120         try {
121             IDocument document= textViewer.getDocument();
122             int offset= hoverRegion.getOffset();
123             int length= hoverRegion.getLength();
124             String JavaDoc text= document.get(offset, length);
125             String JavaDoc value;
126             AntElementNode node= antModel.getNode(offset, false);
127             if (document.get(offset - 2, 2).equals("${") || node instanceof AntPropertyNode) { //$NON-NLS-1$
128
AntStackFrame frame= getFrame();
129                 if (frame != null) {//active Ant debug session
130
AntProperty property= frame.findProperty(text);
131                     if (property != null) {
132                         return ((AntValue)property.getValue()).getValueString();
133                     }
134                 }
135                 value= antModel.getPropertyValue(text);
136                 if (value != null) {
137                     return formatMessage(HTMLPrinter.convertToHTMLContent(value));
138                 }
139             }
140             value= antModel.getTargetDescription(text);
141             if (value != null) {
142                 return formatMessage(HTMLPrinter.convertToHTMLContent(value));
143             }
144             Object JavaDoc referencedObject= antModel.getReferenceObject(text);
145             if (referencedObject != null) {
146                 if (referencedObject instanceof Path) {
147                     return formatPathMessage(((Path)referencedObject).list());
148                 } else if (referencedObject instanceof PatternSet) {
149                     return formatPatternSetMessage((PatternSet) referencedObject);
150                 } else if (referencedObject instanceof AbstractFileSet) {
151                     return formatFileSetMessage((AbstractFileSet)referencedObject);
152                 }
153             }
154         } catch (BadLocationException e) {
155         } catch (BuildException be) {
156             return be.getMessage();
157         }
158         
159         return null;
160     }
161     
162     private String JavaDoc getAnnotationModelHoverMessage(IAnnotationModel model, IRegion hoverRegion) {
163         Iterator JavaDoc e= model.getAnnotationIterator();
164         while (e.hasNext()) {
165             Annotation a= (Annotation) e.next();
166             if (a instanceof XMLProblemAnnotation) {
167                 Position p= model.getPosition(a);
168                 if (p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
169                     String JavaDoc msg= a.getText();
170                     if (msg != null && msg.trim().length() > 0) {
171                         return formatMessage(msg);
172                     }
173                 }
174             }
175         }
176         return null;
177     }
178     
179     private String JavaDoc formatFileSetMessage(AbstractFileSet set) {
180         FileScanner fileScanner= new FileScanner();
181         IAntModel antModel= fEditor.getAntModel();
182         Project project= antModel.getProjectNode().getProject();
183         set.setupDirectoryScanner(fileScanner, project);
184         String JavaDoc[] excludedPatterns= fileScanner.getExcludesPatterns();
185         String JavaDoc[] includesPatterns= fileScanner.getIncludePatterns();
186         return formatSetMessage(includesPatterns, excludedPatterns);
187     }
188
189     private String JavaDoc formatPatternSetMessage(PatternSet set) {
190         IAntModel antModel= fEditor.getAntModel();
191         Project project= antModel.getProjectNode().getProject();
192         String JavaDoc[] includes= set.getIncludePatterns(project);
193         String JavaDoc[] excludes= set.getExcludePatterns(project);
194         return formatSetMessage(includes, excludes);
195     }
196
197     private String JavaDoc formatSetMessage(String JavaDoc[] includes, String JavaDoc[] excludes) {
198         StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
199         HTMLPrinter.addPageProlog(buffer);
200         if (includes != null && includes.length > 0) {
201             HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_5);
202             for (int i = 0; i < includes.length; i++) {
203                 HTMLPrinter.addBullet(buffer, includes[i]);
204             }
205         }
206         HTMLPrinter.addParagraph(buffer, ""); //$NON-NLS-1$
207
HTMLPrinter.addParagraph(buffer, ""); //$NON-NLS-1$
208
if (excludes != null && excludes.length > 0) {
209             HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_6);
210             for (int i = 0; i < excludes.length; i++) {
211                 HTMLPrinter.addBullet(buffer, excludes[i]);
212             }
213         }
214         HTMLPrinter.addPageEpilog(buffer);
215         return buffer.toString();
216     }
217
218     /* (non-Javadoc)
219      * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
220      */

221     public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
222         if (textViewer != null) {
223             return getRegion(textViewer, offset);
224         }
225         return null;
226     }
227
228     public static IRegion getRegion(ITextViewer textViewer, int offset) {
229         IDocument document= textViewer.getDocument();
230         
231         int start= -1;
232         int end= -1;
233         IRegion region= null;
234         try {
235             int pos= offset;
236             char c;
237             
238             if (document.getChar(pos) == '"') {
239                 pos--;
240             }
241             while (pos >= 0) {
242                 c= document.getChar(pos);
243                 if (c != '.' && c != '-' && c != '/' && c != '\\' && c != ' ' && c != ')' && c != '('&& c != ':' && !Character.isJavaIdentifierPart(c) && pos != offset)
244                     break;
245                 --pos;
246             }
247             
248             start= pos;
249             
250             pos= offset;
251             int length= document.getLength();
252             
253             while (pos < length) {
254                 c= document.getChar(pos);
255                 if (c != '.' && c != '-' && c != '/' && c != '\\' && c != ' ' && c != ')' && c != '('&& c != ':' && !Character.isJavaIdentifierPart(c))
256                     break;
257                 if (c == '/' && (document.getLength() - 1) > (pos + 1) && document.getChar(pos + 1) == '>') {
258                    //e.g. <name/>
259
break;
260                 }
261                 ++pos;
262             }
263             
264             end= pos;
265             
266         } catch (BadLocationException x) {
267         }
268         
269         if (start > -1 && end > -1) {
270             if (start == offset && end == offset) {
271                 return new Region(offset, 0);
272             } else if (start == offset) {
273                 return new Region(start, end - start);
274             } else {
275                 try { //correct for spaces at beginning or end
276
while(document.getChar(start + 1) == ' ') {
277                         start++;
278                     }
279                     while(document.getChar(end - 1) == ' ') {
280                         end--;
281                     }
282                 } catch (BadLocationException e) {
283                 }
284                 region= new Region(start + 1, end - start - 1);
285             }
286         }
287         
288         if (region != null) {
289             try {
290                 char c= document.getChar(region.getOffset() - 1);
291                 if (c == '"') {
292                     if (document.get(offset, region.getLength()).indexOf(',') != -1) {
293                         region = cleanRegionForNonProperty(offset, document, region);
294                     }
295                 } else if (c != '{') {
296                     region = cleanRegionForNonProperty(offset, document, region);
297                 }
298             } catch (BadLocationException e) {
299             }
300         }
301             
302         return region;
303     }
304
305     private static IRegion cleanRegionForNonProperty(int offset, IDocument document, IRegion region) throws BadLocationException {
306         //do not allow spaces in region that is not a property
307
String JavaDoc text= document.get(region.getOffset(), region.getLength());
308         if (text.startsWith("/")) { //$NON-NLS-1$
309
text= text.substring(1);
310             region= new Region(region.getOffset() + 1, region.getLength() - 1);
311         }
312         StringTokenizer JavaDoc tokenizer= new StringTokenizer JavaDoc(text, " "); //$NON-NLS-1$
313
if (tokenizer.countTokens() != 1) {
314             while(tokenizer.hasMoreTokens()) {
315                 String JavaDoc token= tokenizer.nextToken();
316                 int index= text.indexOf(token);
317                 if (region.getOffset() + index <= offset && region.getOffset() + index + token.length() >= offset) {
318                     region= new Region(region.getOffset() + index, token.length());
319                     break;
320                 }
321             }
322         }
323         
324         return region;
325     }
326     
327     /* (non-Javadoc)
328      * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
329      */

330     public IInformationControlCreator getHoverControlCreator() {
331         return new IInformationControlCreator() {
332             public IInformationControl createInformationControl(Shell parent) {
333                 return new DefaultInformationControl(parent, SWT.NONE,
334                         new HTMLTextPresenter(true),
335                         EditorsUI.getTooltipAffordanceString());
336             }
337         };
338     }
339     
340     /**
341      * Returns the stack frame in which to search for properties, or <code>null</code>
342      * if none.
343      *
344      * @return the stack frame in which to search for properties, or <code>null</code>
345      * if none
346      */

347     private AntStackFrame getFrame() {
348         IAdaptable adaptable = DebugUITools.getDebugContext();
349         if (adaptable != null) {
350             return (AntStackFrame)adaptable.getAdapter(AntStackFrame.class);
351         }
352         return null;
353     }
354
355     /*
356      * @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
357      * @since 3.3
358      */

359     public IInformationControlCreator getInformationPresenterControlCreator() {
360         return AntEditorSourceViewerConfiguration.getInformationPresenterControlCreator();
361     }
362
363 }
364
Popular Tags