KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > jsf > editor > jspel > JSFJSPHyperlinkProvider


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.web.jsf.editor.jspel;
21
22 import java.awt.Cursor JavaDoc;
23 import java.awt.Toolkit JavaDoc;
24 import java.beans.PropertyChangeEvent JavaDoc;
25 import java.beans.PropertyChangeListener JavaDoc;
26 import javax.swing.JEditorPane JavaDoc;
27 import javax.swing.text.BadLocationException JavaDoc;
28 import javax.swing.text.Document JavaDoc;
29 import javax.swing.text.JTextComponent JavaDoc;
30 import org.netbeans.api.lexer.Token;
31 import org.netbeans.api.lexer.TokenHierarchy;
32 import org.netbeans.api.lexer.TokenSequence;
33 import org.netbeans.editor.BaseDocument;
34 import org.netbeans.editor.SyntaxSupport;
35 import org.netbeans.editor.Utilities;
36 import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
37 import org.netbeans.modules.editor.NbEditorUtilities;
38 import org.netbeans.modules.el.lexer.api.ELTokenId;
39 import org.netbeans.modules.web.api.webmodule.WebModule;
40 import org.netbeans.modules.web.core.syntax.JspSyntaxSupport;
41 import org.netbeans.modules.web.core.syntax.deprecated.ELTokenContext;
42 import org.netbeans.modules.web.jsf.JSFConfigUtilities;
43 import org.netbeans.modules.web.jsf.api.ConfigurationUtils;
44 import org.netbeans.modules.web.jsf.editor.JSFEditorUtilities;
45 import org.openide.ErrorManager;
46 import org.openide.awt.StatusDisplayer;
47 import org.openide.cookies.EditorCookie;
48 import org.openide.filesystems.FileObject;
49 import org.openide.loaders.DataObject;
50 import org.openide.loaders.DataObjectNotFoundException;
51 import org.openide.util.NbBundle;
52
53 /**
54  * @author Tomasz.Slota@Sun.COM
55  * @author Petr Pisl
56  */

57 public class JSFJSPHyperlinkProvider implements HyperlinkProvider {
58     
59     /** Creates a new instance of JSFJSPHyperlinkProvider */
60     public JSFJSPHyperlinkProvider() {
61     }
62     
63     /**
64      * Should determine whether there should be a hyperlink on the given offset
65      * in the given document. May be called any number of times for given parameters.
66      * <br>
67      * This method is called from event dispatch thread.
68      * It should run very fast as it is called very often.
69      *
70      * @param doc document on which to operate.
71      * @param offset &gt;=0 offset to test (it generally should be offset &lt; doc.getLength(), but
72      * the implementations should not depend on it)
73      * @return true if the provided offset should be in a hyperlink
74      * false otherwise
75      */

76     public boolean isHyperlinkPoint(Document JavaDoc doc, int offset) {
77         if (!(doc instanceof BaseDocument))
78             return false;
79         
80         BaseDocument bdoc = (BaseDocument) doc;
81         bdoc.readLock();
82         try {
83         JTextComponent JavaDoc target = Utilities.getFocusedComponent();
84         
85         if (target == null || target.getDocument() != bdoc)
86             return false;
87         SyntaxSupport sup = bdoc.getSyntaxSupport();
88         JspSyntaxSupport jspSup = (JspSyntaxSupport)sup.get(JspSyntaxSupport.class);
89         
90         TokenHierarchy tokenHierarchy = TokenHierarchy.get(bdoc);
91         TokenSequence tokenSequence = tokenHierarchy.tokenSequence();
92         if(tokenSequence.move(offset) == Integer.MAX_VALUE) {
93             return false; //no token found
94
}
95         
96         if(!tokenSequence.moveNext()) {
97             return false; //no token
98
}
99         
100         Token token = tokenSequence.token();
101         TokenSequence elTokenSequence = tokenSequence.embedded(ELTokenId.language());
102         
103         if (elTokenSequence != null){
104             FileObject fObject = NbEditorUtilities.getFileObject(doc);
105             WebModule wm = WebModule.getWebModule(fObject);
106             
107             if (wm != null){
108                 JSFELExpression exp = new JSFELExpression(wm, (JspSyntaxSupport)bdoc.getSyntaxSupport());
109                 elTokenSequence.move(offset);
110                 if(!elTokenSequence.moveNext()) {
111                     return false; //no token
112
}
113                 
114                 if (elTokenSequence.token().id() == ELTokenId.DOT){
115                     return false;
116                 }
117                 
118                 int endOfEL = elTokenSequence.offset() + elTokenSequence.token().length();
119                 int res = exp.parse(endOfEL);
120                 
121                 if (res == JSFELExpression.EL_START){
122                     res = exp.parse(endOfEL + 1);
123                 }
124                 
125                 return res == JSFELExpression.EL_JSF_BEAN;
126             }
127         }
128         
129         } finally {
130             bdoc.readUnlock();
131         }
132         
133         return false;
134     }
135     
136     /**
137      * Should determine the span of hyperlink on given offset. Generally, if
138      * isHyperlinkPoint returns true for a given parameters, this class should
139      * return a valid span, but it is not strictly required.
140      * <br>
141      * This method is called from event dispatch thread.
142      * This method should run very fast as it is called very often.
143      *
144      * @param doc document on which to operate.
145      * @param offset &gt;=0 offset to test (it generally should be offset &lt; doc.getLength(), but
146      * the implementations should not depend on it)
147      * @return a two member array which contains starting and ending offset of a hyperlink
148      * that should be on a given offset
149      */

150     public int[] getHyperlinkSpan(Document JavaDoc doc, int offset) {
151         if (!(doc instanceof BaseDocument))
152             return null;
153         
154         BaseDocument bdoc = (BaseDocument) doc;
155         JTextComponent JavaDoc target = Utilities.getFocusedComponent();
156         
157         if (target == null || target.getDocument() != bdoc)
158             return null;
159         
160         SyntaxSupport sup = bdoc.getSyntaxSupport();
161         JspSyntaxSupport jspSup = (JspSyntaxSupport)sup.get(JspSyntaxSupport.class);
162         
163         TokenHierarchy tokenHierarchy = TokenHierarchy.get(bdoc);
164         TokenSequence tokenSequence = tokenHierarchy.tokenSequence();
165         if(tokenSequence.move(offset) == Integer.MAX_VALUE) {
166             return null; //no token found
167
}
168         if(!tokenSequence.moveNext()) {
169             return null; //no token
170
}
171         
172         Token token = tokenSequence.token();
173         
174         // is it a bean in EL ?
175
TokenSequence elTokenSequence = tokenSequence.embedded(ELTokenId.language());
176         
177         if (elTokenSequence != null){
178             FileObject fObject = NbEditorUtilities.getFileObject(doc);
179             WebModule wm = WebModule.getWebModule(fObject);
180             if (wm != null){
181                 JSFELExpression exp = new JSFELExpression(wm, (JspSyntaxSupport)bdoc.getSyntaxSupport());
182                 elTokenSequence.move(offset);
183                 if(!elTokenSequence.moveNext()) {
184                     return null; //no token
185
}
186                 
187                 int elEnd = elTokenSequence.offset() + elTokenSequence.token().length();
188                 
189                 int res = exp.parse(elEnd);
190                 if (res == JSFELExpression.EL_JSF_BEAN || res == JSFELExpression.EL_START )
191                     return new int[] {elTokenSequence.offset(), elEnd};
192             }
193         }
194         return null;
195     }
196     
197     /**
198      * The implementor should perform an action
199      * corresponding to clicking on the hyperlink on the given offset. The
200      * nature of the action is given by the nature of given hyperlink, but
201      * generally should open some resource or move cursor
202      * to certain place in the current document.
203      *
204      * @param doc document on which to operate.
205      * @param offset &gt;=0 offset to test (it generally should be offset &lt; doc.getLength(), but
206      * the implementations should not depend on it)
207      */

208     public void performClickAction(Document JavaDoc doc, int offset) {
209         
210         BaseDocument bdoc = (BaseDocument) doc;
211         JTextComponent JavaDoc target = Utilities.getFocusedComponent();
212         
213         if (target == null || target.getDocument() != bdoc)
214             return;
215         
216         SyntaxSupport sup = bdoc.getSyntaxSupport();
217         JspSyntaxSupport jspSup = (JspSyntaxSupport)sup.get(JspSyntaxSupport.class);
218         
219         TokenHierarchy tokenHierarchy = TokenHierarchy.get(bdoc);
220         TokenSequence tokenSequence = tokenHierarchy.tokenSequence();
221         if(tokenSequence.move(offset) == Integer.MAX_VALUE) {
222             return; //no token found
223
}
224         if(!tokenSequence.moveNext()) {
225             return ; //no token
226
}
227         
228         Token token = tokenSequence.token();
229         
230         // is it a bean in EL
231
TokenSequence elTokenSequence = tokenSequence.embedded(ELTokenId.language());
232         if (elTokenSequence != null){
233             FileObject fObject = NbEditorUtilities.getFileObject(doc);
234             WebModule wm = WebModule.getWebModule(fObject);
235             if (wm != null){
236                 JSFELExpression exp = new JSFELExpression(wm, (JspSyntaxSupport)bdoc.getSyntaxSupport());
237                 elTokenSequence.move(offset);
238                 if(!elTokenSequence.moveNext()) {
239                     return; //no token
240
}
241                 
242                 int res = exp.parse(elTokenSequence.offset() + elTokenSequence.token().length());
243                 if (res == JSFELExpression.EL_START ){
244                     (new OpenConfigFile(wm, elTokenSequence.token().text().toString())).run();
245                     return;
246                 }
247                 if (res == JSFELExpression.EL_JSF_BEAN){
248                     if (!exp.gotoPropertyDeclaration(exp.getObjectClass())){
249                         String JavaDoc msg = NbBundle.getBundle(JSFJSPHyperlinkProvider.class).getString("MSG_source_not_found");
250                         StatusDisplayer.getDefault().setStatusText(msg);
251                         Toolkit.getDefaultToolkit().beep();
252                     }
253                 }
254             }
255         }
256     }
257     
258     private static class OpenConfigFile implements Runnable JavaDoc {
259         private String JavaDoc beanName;
260         private WebModule wm;
261         
262         OpenConfigFile(WebModule wm, String JavaDoc beanName){
263             this.beanName = beanName;
264             this.wm = wm;
265         }
266         
267         public void run(){
268             if (wm == null) return;
269             
270             FileObject config = ConfigurationUtils.findFacesConfigForManagedBean(wm, beanName);
271             if (config != null){
272                 DataObject dobj = null;
273                 try{
274                     dobj = DataObject.find(config);
275                 } catch (DataObjectNotFoundException e){
276                     ErrorManager.getDefault().notify(e);
277                     return;
278                 }
279                 
280                 if (dobj != null){
281                     final EditorCookie.Observable ec = (EditorCookie.Observable)dobj.getCookie(EditorCookie.Observable.class);
282                     if (ec != null) {
283                         StatusDisplayer.getDefault().setStatusText(/*NbBundle.getMessage(JMIUtils.class, "opening-element", element instanceof NamedElement ? ((NamedElement)element).getName() : "")*/"otvirani"); // NOI18N
284
Utilities.runInEventDispatchThread(new Runnable JavaDoc() {
285                             public void run() {
286                                 JEditorPane JavaDoc[] panes = ec.getOpenedPanes();
287                                 if (panes != null && panes.length > 0) {
288                                     openPane(panes[0], beanName);
289                                     //ec.open();
290
} else {
291                                     ec.addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
292                                         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
293                                             if (EditorCookie.Observable.PROP_OPENED_PANES.equals(evt.getPropertyName())) {
294                                                 final JEditorPane JavaDoc[] panes = ec.getOpenedPanes();
295                                                 if (panes != null && panes.length > 0)
296                                                     openPane(panes[0], beanName);
297                                                 ec.removePropertyChangeListener(this);
298                                             }
299                                         }
300                                     });
301                                     // ec.open();
302
}
303                             }
304                         });
305                         ec.open();
306                     }
307                 }
308             }
309         }
310         
311         private void openPane(JEditorPane JavaDoc pane, String JavaDoc beanName){
312             final Cursor JavaDoc editCursor = pane.getCursor();
313             pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
314             int[] definition = JSFEditorUtilities.getManagedBeanDefinition((BaseDocument)pane.getDocument(), beanName);
315             if (definition [0] > -1)
316                 pane.setCaretPosition(definition[0]);
317             pane.setCursor(editCursor);
318             StatusDisplayer.getDefault().setStatusText(""); //NOI18N
319
}
320     }
321 }
322
Popular Tags