KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > languages > html > HTML


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.languages.html;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Stack JavaDoc;
28 import javax.swing.text.BadLocationException JavaDoc;
29 import javax.swing.text.Document JavaDoc;
30 import javax.swing.text.StyledDocument JavaDoc;
31 import org.netbeans.api.languages.ASTItem;
32 import org.netbeans.api.lexer.Token;
33 import org.netbeans.api.lexer.TokenSequence;
34 import org.netbeans.api.languages.Context;
35 import org.netbeans.api.languages.SyntaxContext;
36 import org.netbeans.api.languages.ASTNode;
37 import org.netbeans.api.languages.ASTToken;
38 import org.netbeans.api.languages.LibrarySupport;
39 import org.netbeans.api.languages.support.CompletionSupport;
40 import org.openide.ErrorManager;
41 import org.openide.text.NbDocument;
42
43
44 /**
45  *
46  * @author Jan Jancura
47  */

48 public class HTML {
49     
50 // private static final String HTML40DOC = "modules/ext/html40.zip";
51
private static final String JavaDoc HTML401 = "org/netbeans/modules/languages/html/HTML401.xml";
52     
53     
54     // tag completion ..........................................................
55

56     public static String JavaDoc complete (Context context) {
57         TokenSequence ts = context.getTokenSequence ();
58         ts.moveNext ();
59         Token t = ts.token ();
60         if (t == null) return null;
61         String JavaDoc identifier = t.text ().toString ();
62         if (!identifier.equals (">")) return null;
63         do {
64             if (!ts.movePrevious ()) return null;
65         } while (!t.id ().name ().equals ("html_element_name"));
66         String JavaDoc et = getLibrary ().getProperty ("TAG", identifier, "endTag");
67         if (!ts.movePrevious ()) return null;
68         if (!ts.token ().text ().toString ().equals ("<")) return null;
69         return "</" + identifier + ">";
70     }
71     
72     
73     // indent ..................................................................
74

75     public static void indent (Context context) {
76         TokenSequence ts = context.getTokenSequence ();
77         Document JavaDoc doc = context.getDocument ();
78         int indent;
79         Token t;
80         do {
81             ts.movePrevious ();
82             t = ts.token ();
83         } while (t.text ().toString ().trim ().length () == 0);
84         String JavaDoc text = t.text ().toString ();
85         String JavaDoc type = t.id ().name ();
86         int ln = NbDocument.findLineNumber ((StyledDocument JavaDoc) doc, ts.offset ());
87         int start = NbDocument.findLineOffset ((StyledDocument JavaDoc) doc, ln);
88         if (text.equals (">") || text.equals ("/>")) {
89             do {
90                 if (!ts.movePrevious ()) break;
91                 t = ts.token ();
92             } while (!t.text ().toString ().equals ("<"));
93             indent = getIndent (ts, doc);
94         } else
95         if (type.equals ("html_attribute_value") ||
96             type.equals ("html_attribute_name") ||
97             type.equals ("html_element_name") ||
98             type.equals ("html_operator")
99         ) {
100             do {
101                 if (!ts.movePrevious ()) break;
102                 t = ts.token ();
103             } while (
104                 !t.text ().toString ().equals ("<") &&
105                 ts.offset () > start
106             );
107             if (t.text ().toString ().equals ("<"))
108                 indent = getIndent (ts, doc) + 4;
109             else {
110                 ts.moveNext ();
111                 indent = getIndent (ts, doc);
112             }
113         } else
114         if (text.equals ("<")) {
115             indent = getIndent (ts, doc) + 4;
116         } else
117             indent = getIndent (ts, doc);
118         indent (doc, context.getJTextComponent ().getCaret ().getDot (), indent);
119     }
120     
121     private static int getIndent (TokenSequence ts, Document JavaDoc doc) {
122         int ln = NbDocument.findLineNumber ((StyledDocument JavaDoc) doc, ts.offset ());
123         int start = NbDocument.findLineOffset ((StyledDocument JavaDoc) doc, ln);
124         ts.move (start);
125         ts.moveNext ();
126         if (ts.token ().text ().toString ().trim ().length () == 0)
127             ts.moveNext ();
128         return ts.offset () - start;
129     }
130     
131     private static void indent (Document JavaDoc doc, int offset, int i) {
132         StringBuilder JavaDoc sb = new StringBuilder JavaDoc ();
133         while (i > 0) {
134             sb.append (' ');i--;
135         }
136         try {
137             doc.insertString (offset, sb.toString (), null);
138         } catch (BadLocationException JavaDoc ex) {
139             ErrorManager.getDefault ().notify (ex);
140         }
141     }
142     
143 // public static Runnable hyperlink (PTPath path) {
144
// ASTToken t = (ASTToken) path.getLeaf ();
145
// String s = t.getIdentifier ();
146
// s = s.substring (1, s.length () - 1).trim ();
147
// if (!s.endsWith (")")) return null;
148
// s = s.substring (0, s.length () - 1).trim ();
149
// if (!s.endsWith ("(")) return null;
150
// s = s.substring (0, s.length () - 1).trim ();
151
// final Line l = (Line) DatabaseManager.get (s);
152
// if (l != null)
153
// return new Runnable () {
154
// public void run () {
155
// l.show (l.SHOW_SHOW);
156
// }
157
// };
158
// return null;
159
// }
160

161     
162     // completion ..............................................................
163

164     public static List JavaDoc tags (Context context) {
165         if (context instanceof SyntaxContext) return Collections.EMPTY_LIST;
166         List JavaDoc tags = getLibrary ().getItems ("TAG");
167         List JavaDoc items = new ArrayList JavaDoc (tags.size ());
168         Iterator JavaDoc it = tags.iterator ();
169         while (it.hasNext ()) {
170             String JavaDoc tag = (String JavaDoc) it.next ();
171             String JavaDoc description = getLibrary ().getProperty
172                 ("TAG", tag, "description");
173             items.add (CompletionSupport.createCompletionItem (
174                 tag,
175                 "<html><b><font color=blue>" + tag.toUpperCase () +
176                 ": </font></b><font color=black> " +
177                 description + "</font></html>"
178             ));
179         }
180         return items;
181     }
182
183     public static List JavaDoc attributes (Context context) {
184         if (context instanceof SyntaxContext) return Collections.EMPTY_LIST;
185         String JavaDoc tagName = tagName (context.getTokenSequence ());
186         if (tagName == null) return Collections.EMPTY_LIST;
187         List JavaDoc r = getLibrary ().getItems (tagName);
188         if (r == null) return Collections.EMPTY_LIST;
189         //S ystem.out.println("attributes " + r);
190
List JavaDoc items = new ArrayList JavaDoc (r.size ());
191         Iterator JavaDoc it = r.iterator ();
192         while (it.hasNext ()) {
193             String JavaDoc tag = (String JavaDoc) it.next ();
194             String JavaDoc description = getLibrary ().getProperty
195                 (tagName, tag, "description");
196             items.add (CompletionSupport.createCompletionItem (
197                 tag,
198                 "<html><b><font color=blue>" + tag.toUpperCase () +
199                 ": </font></b><font color=black> " +
200                 description + "</font></html>"
201             ));
202         }
203         //S ystem.out.println("attributeDescriptions " + attributeDescriptions);
204
return items;
205     }
206     
207
208     // marks ...................................................................
209

210     public static boolean isDeprecatedAttribute (Context context) {
211         TokenSequence ts = context.getTokenSequence ();
212         String JavaDoc attribName = ts.token ().text ().toString ().toLowerCase ();
213         String JavaDoc tagName = tagName (context.getTokenSequence ());
214         if (tagName == null) return false;
215         return "true".equals (getLibrary ().getProperty (tagName, attribName, "deprecated"));
216     }
217
218     public static boolean isDeprecatedTag (Context context) {
219         Token t = context.getTokenSequence ().token ();
220         String JavaDoc tagName = t.text ().toString ().toLowerCase ();
221         return "true".equals (getLibrary ().getProperty ("TAG", tagName, "deprecated"));
222     }
223
224     public static boolean isEndTagRequired (Context context) {
225         Token t = context.getTokenSequence ().token ();
226         return isEndTagRequired (t.id ().name ().toLowerCase ());
227     }
228
229     static boolean isEndTagRequired (String JavaDoc tagName) {
230         String JavaDoc v = getLibrary ().getProperty ("TAG", tagName, "endTag");
231         return !"O".equals (v) && !"F".equals (v);
232     }
233     
234     public static ASTNode process (SyntaxContext context) {
235         ASTNode n = (ASTNode) context.getASTPath ().getRoot ();
236         List JavaDoc l = new ArrayList JavaDoc ();
237         resolve (n, new Stack JavaDoc (), l, true);
238         return ASTNode.create (n.getMimeType (), n.getNT (), l, n.getOffset ());
239     }
240     
241     
242     // private methods .........................................................
243

244     private static String JavaDoc tagName (TokenSequence ts) {
245         while (!ts.token ().id ().name ().equals ("html_element_name"))
246             if (!ts.movePrevious ()) break;
247         if (!ts.token ().id ().name ().equals ("html_element_name"))
248             return null;
249         return ts.token ().text ().toString ().toLowerCase ();
250     }
251     
252     private static LibrarySupport library;
253     
254     private static LibrarySupport getLibrary () {
255         if (library == null)
256             library = LibrarySupport.create (HTML401);
257         return library;
258     }
259     
260     private static ASTNode clone (String JavaDoc mimeType, String JavaDoc nt, int offset, List JavaDoc children) {
261         Iterator JavaDoc it = children.iterator ();
262         List JavaDoc l = new ArrayList JavaDoc ();
263         while (it.hasNext ()) {
264             Object JavaDoc o = it.next ();
265             if (o instanceof ASTToken)
266                 l.add (clone ((ASTToken) o));
267             else
268                 l.add (clone ((ASTNode) o));
269         }
270         return ASTNode.create (mimeType, nt, l, offset);
271     }
272     
273     private static ASTNode clone (ASTNode n) {
274         return clone (n.getMimeType (), n.getNT (), n.getOffset (), n.getChildren ());
275     }
276     
277     private static ASTToken clone (ASTToken token) {
278         List JavaDoc<ASTItem> children = new ArrayList JavaDoc ();
279         Iterator JavaDoc<ASTItem> it = token.getChildren ().iterator ();
280         while (it.hasNext ()) {
281             ASTItem item = it.next ();
282             if (item instanceof ASTNode)
283                 children.add (clone ((ASTNode) item));
284             else
285                 children.add (clone ((ASTToken) item));
286         }
287         return ASTToken.create (
288             token.getMimeType (),
289             token.getType (),
290             token.getIdentifier (),
291             token.getOffset (),
292             token.getLength (),
293             children
294         );
295     }
296     
297     private static ASTNode clone (ASTNode n, String JavaDoc nt) {
298         return clone (n.getMimeType (), nt, n.getOffset (), n.getChildren ());
299     }
300     
301     private static void resolve (ASTNode n, Stack JavaDoc s, List JavaDoc l, boolean findUnpairedTags) {
302         Iterator JavaDoc<ASTItem> it = n.getChildren ().iterator ();
303         while (it.hasNext ()) {
304             ASTItem item = it.next ();
305             if (item instanceof ASTToken) {
306                 l.add (clone ((ASTToken) item));
307                 continue;
308             }
309             ASTNode node = (ASTNode) item;
310             if (node.getNT ().equals ("startTag")) {
311                 if (node.getTokenType ("html_end_element_end") != null) {
312                     l.add (clone (node, "simpleTag"));
313                 } else {
314                     String JavaDoc name = node.getTokenTypeIdentifier ("html_element_name");
315                     if (name == null)
316                         name = "";
317                     else
318                         name = name.toLowerCase ();
319                     s.add (name);
320                     s.add (new Integer JavaDoc (l.size ()));
321                     if (findUnpairedTags && isEndTagRequired (name))
322                         l.add (clone (node, "unpairedStartTag"));
323                     else
324                         l.add (clone (node, "startTag"));
325                 }
326                 continue;
327             } else
328             if (node.getNT ().equals ("endTag")) {
329                 String JavaDoc name = node.getTokenTypeIdentifier ("html_element_name");
330                 if (name == null)
331                     name = "";
332                 else
333                     name = name.toLowerCase ();
334                 int indexS = s.lastIndexOf (name);
335                 if (indexS >= 0) {
336                     int indexL = ((Integer JavaDoc) s.get (indexS + 1)).intValue ();
337                     List JavaDoc ll = l.subList (indexL, l.size ());
338                     ll.set (0, clone ((ASTNode) ll.get (0), "startTag"));
339                     List JavaDoc ll1 = new ArrayList JavaDoc (ll);
340                     ll1.add (node);
341                     ASTNode tag = clone (
342                         node.getMimeType (),
343                         "tag",
344                         ((ASTNode) ll1.get (0)).getOffset (),
345                         ll1
346                     );
347                     ll.clear ();
348                     s.subList (indexS, s.size ()).clear ();
349                     l.add (tag);
350                 } else
351                     l.add (clone (node, "unpairedEndTag"));
352                 continue;
353             } else
354             if (node.getNT ().equals ("tags")) {
355                 resolve (node, s, l, findUnpairedTags);
356                 continue;
357             }
358             l.add (clone (node));
359         }
360     }
361 }
362
363
Popular Tags