KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > core > TLUtils


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.tasklist.core;
21
22 import java.io.File JavaDoc;
23 import javax.swing.text.*;
24
25 import java.net.URL JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.logging.ConsoleHandler JavaDoc;
29 import java.util.logging.Level JavaDoc;
30 import java.util.logging.Logger JavaDoc;
31 import java.awt.*;
32 import java.awt.event.FocusListener JavaDoc;
33 import java.awt.event.FocusEvent JavaDoc;
34 import java.io.FileInputStream JavaDoc;
35 import java.io.FileOutputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.nio.ByteBuffer JavaDoc;
38 import java.nio.channels.FileChannel JavaDoc;
39
40 import org.openide.cookies.LineCookie;
41 import org.openide.loaders.DataObject;
42 import org.openide.text.Line;
43 import org.openide.ErrorManager;
44 import org.openide.cookies.EditorCookie;
45 import org.openide.filesystems.URLMapper;
46 import org.openide.filesystems.FileObject;
47 import org.openide.nodes.Children;
48 import org.openide.nodes.Node;
49
50 /**
51  * Various utility methods shared by the various tasklist related modules
52  *
53  * @author Tor Norbye
54  */

55 public final class TLUtils {
56     /** Common logger for the core module */
57     public static final Logger JavaDoc LOGGER = TLUtils.getLogger(TLUtils.class);
58     
59     static {
60         LOGGER.setLevel(Level.FINE);
61     }
62
63     /**
64      * Convert a string to HTML, escaping &, <, >, etc
65      * Same as TLUtils.appendHTMLChar, but we don't want to
66      * translate ' ' into &nbsp;
67      *
68      * TODO: comment params
69      */

70     public static String JavaDoc toHTML(String JavaDoc text) {
71         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(2*text.length());
72         // Same as TLUtils.appendHTMLChar, but we don't want to
73
// translate ' ' into &nbsp;
74
int n = text.length();
75         for (int i = 0; i < n; i++) {
76             switch (text.charAt(i)) {
77             case '&': sb.append("&amp;"); break; // NOI18N
78
case '<': sb.append("&lt;"); break; // NOI18N
79
case '>': sb.append("&gt;"); break; // NOI18N
80
case '"': sb.append("&quot;"); break; // NOI18N
81
case '\n': sb.append("<br>"); break; // NOI18N
82
default: sb.append(text.charAt(i)); break;
83             }
84         }
85         return sb.toString();
86     }
87     
88     /**
89      * Creates a backup copy of a file.
90      * TODO: this function was not tested!
91      *
92      * @param f for this file a backup copy will be created
93      */

94     public static void createBackup(File JavaDoc f) throws IOException JavaDoc {
95         File JavaDoc dir = f.getParentFile();
96         File JavaDoc backup = new File JavaDoc(dir, f.getName() + "~"); // NOI18N
97
if (backup.exists()) {
98             if (!backup.delete())
99                 throw new IOException JavaDoc("Cannot delete the file"); // TODO: i18n
100
}
101         
102         FileInputStream JavaDoc fis = new FileInputStream JavaDoc(f);
103         try {
104             FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(backup);
105             
106             try {
107                 FileChannel JavaDoc ic = fis.getChannel();
108                 FileChannel JavaDoc oc = fos.getChannel();
109
110                 ByteBuffer JavaDoc bb = ByteBuffer.allocateDirect(16 * 1024);
111
112                 bb.clear(); // Prepare buffer for use
113
for (;;) {
114                     if (ic.read(bb) < 0 && !bb.hasRemaining())
115                         break; // No more bytes to transfer
116
bb.flip();
117                     oc.write(bb);
118                     bb.compact(); // In case of partial write
119
}
120             } finally {
121                 try {
122                     fos.close();
123                 } catch (IOException JavaDoc e) {
124                     ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
125                 }
126             }
127         } finally {
128             try {
129                 fis.close();
130             } catch (IOException JavaDoc e) {
131                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
132             }
133         }
134         
135     }
136     
137     /** Return the Line object for a particular line in a file
138      */

139     public static Line getLineByNumber(DataObject dobj, int lineno) {
140         // Go to the given line
141
try {
142             LineCookie lc = (LineCookie)dobj.getCookie(LineCookie.class);
143             if (lc != null) {
144                 Line.Set ls = lc.getLineSet();
145                 if (ls != null) {
146                     // I'm subtracting 1 because empirically I've discovered
147
// that the editor highlights whatever line I ask for plus 1
148
Line l = ls.getCurrent(lineno-1);
149                     return l;
150                 }
151             }
152         } catch (IndexOutOfBoundsException JavaDoc ex) {
153             // line was at the end of file and is deleted now
154

155         } catch (Exception JavaDoc e) {
156             ErrorManager.getDefault().log(ErrorManager.WARNING, "getLineByNumber - file " + dobj + " and lineno=" + lineno); // NOI18N
157
ErrorManager.getDefault().
158                 notify(ErrorManager.INFORMATIONAL, e);
159         }
160         return null;
161     }
162
163     /** Append a "window of text with the given line as the middle line.
164      * It will escape HTML characters.
165      * @param line The line we want to obtain a window for.
166      * @param currText If non null, use this line instead of the
167      * text on the current line.
168      */

169     public static void appendSurroundingLine(StringBuffer JavaDoc sb, Line line,
170                                              int offset) {
171         DataObject dobj = org.openide.text.DataEditorSupport.findDataObject (line);
172         try {
173             LineCookie lc = (LineCookie)dobj.getCookie(LineCookie.class);
174             if (lc == null) {
175                 return;
176             }
177             Line.Set ls = lc.getLineSet();
178             if (ls == null) {
179                 return;
180             }
181
182             int lineno = line.getLineNumber();
183             if (lineno+offset < 0) {
184                 // Trying to surround the first line - no "before" line
185
return;
186             }
187             Line before = ls.getCurrent(lineno+offset);
188             appendHTMLString(sb, before.getText());
189         } catch (Exception JavaDoc e) {
190             ErrorManager.getDefault().
191                 notify(ErrorManager.INFORMATIONAL, e);
192         }
193     }
194
195     /** Compute first difference position for two strings */
196     public static int firstDiff(String JavaDoc s1, String JavaDoc s2) {
197         int n1 = s1.length();
198         int n2 = s2.length();
199         int n;
200         if (n1 < n2) {
201             n = n1;
202         } else {
203             n = n2;
204         }
205         for (int i = 0; i < n; i++) {
206             if (s1.charAt(i) != s2.charAt(i)) {
207                 return i;
208             }
209         }
210         return n;
211     }
212
213     /** Compute last difference position for two strings. Returns
214         DISTANCE FROM THE END! */

215     public static int lastDiff(String JavaDoc s1, String JavaDoc s2) {
216         int n1 = s1.length()-1;
217         int n2 = s2.length()-1;
218         int i = 0;
219         while ((n2 >= 0) && (n1 >= 0)) {
220             if (s1.charAt(n1) != s2.charAt(n2)) {
221                 return i;
222             }
223             --n2;
224             --n1;
225             ++i;
226         }
227         return i;
228     }
229     
230     /** Append a character to a StringBuffer intended for HTML
231         display - it will escape <, >, etc. such that the char is
232         shown properly in HTML.
233     */

234     public static void appendHTMLChar(StringBuffer JavaDoc sb, char c) {
235         // See also HTMLSupport.toHTML if you modify this
236
switch (c) {
237         case '<': sb.append("&lt;"); break; // NOI18N
238
case '>': sb.append("&gt;"); break; // NOI18N
239
case '&': sb.append("&amp;"); break; // NOI18N
240
case '"': sb.append("&quot;"); break; // NOI18N
241
case ' ': sb.append("&nbsp;"); break; // NOI18N
242
case '\n': sb.append("<br>"); break; // NOI18N
243
default: sb.append(c);
244         }
245     }
246
247     /** Append a string to a StringBuffer intended for HTML
248         display - it will escape <, >, etc. such that they are
249         shown properly in HTML.
250     */

251     public static void appendHTMLString(StringBuffer JavaDoc sb, String JavaDoc s) {
252         int n = s.length();
253         for (int i = 0; i < n; i++) {
254             appendHTMLChar(sb, s.charAt(i));
255         }
256     }
257
258     /** Append the given string to the given string buffer,
259      * underlining from a starting index to an ending index.
260      * Also escape HTML characters.
261      */

262     public static void appendAttributed(StringBuffer JavaDoc sb,
263                                         String JavaDoc text,
264                                         int begin,
265                                         int end,
266                                         boolean underline,
267                                         boolean bold) {
268         if (begin != -1) {
269             for (int i = 0; i < begin; i++) {
270                 appendHTMLChar(sb, text.charAt(i));
271             }
272             if (underline) {
273                 sb.append("<u>"); // NOI18N
274
}
275             if (bold) {
276                 sb.append("<b>"); // NOI18N
277
}
278             for (int i = begin; i < end; i++) {
279                 appendHTMLChar(sb, text.charAt(i));
280             }
281             if (underline) {
282                 sb.append("</u>"); // NOI18N
283
}
284             if (bold) {
285                 sb.append("</b>"); // NOI18N
286
}
287             int nl = text.length();
288             for (int i = end; i < nl; i++) {
289                 appendHTMLChar(sb, text.charAt(i));
290             }
291         } else {
292             appendHTMLString(sb, text);
293         }
294     }
295
296     public static Element getElement(Document d, Line line) {
297     if (d == null) {
298             ErrorManager.getDefault().log(ErrorManager.USER, "d was null");
299             return null;
300     }
301
302         if (!(d instanceof StyledDocument)) {
303             ErrorManager.getDefault().log(ErrorManager.USER, "Not a styleddocument");
304             return null;
305         }
306             
307         StyledDocument doc = (StyledDocument)d;
308         Element e = doc.getParagraphElement(0).getParentElement();
309         if (e == null) {
310             // try default root (should work for text/plain)
311
e = doc.getDefaultRootElement ();
312         }
313         int lineNumber = line.getLineNumber();
314         Element elm = e.getElement(lineNumber);
315         return elm;
316     }
317
318     public static Document getDocument(Line line) {
319         DataObject dao = org.openide.text.DataEditorSupport.findDataObject (line);
320         if (!dao.isValid()) {
321             //ErrorManager.getDefault().log(ErrorManager.USER, "dataobject was not null");
322
return null;
323         }
324         return getDocument(dao);
325     }
326
327     public static Document getDocument(DataObject dao) {
328     final EditorCookie edit = (EditorCookie)dao.getCookie(EditorCookie.class);
329     if (edit == null) {
330             //ErrorManager.getDefault().log(ErrorManager.USER, "no editor cookie!");
331
return null;
332     }
333
334         Document d = edit.getDocument(); // Does not block
335
return d;
336     }
337
338     /** Remove a particular line. Make sure that the line begins with
339      * a given prefix, just in case.
340      * @param prefix A prefix that the line to be deleted must start with
341      */

342     public static boolean deleteLine(Line line, String JavaDoc prefix) {
343         Document doc = getDocument(line);
344         Element elm = getElement(doc, line);
345         if (elm == null) {
346             return false;
347         }
348         int offset = elm.getStartOffset();
349         int endOffset = elm.getEndOffset();
350
351         try {
352             String JavaDoc text = doc.getText(offset, endOffset-offset);
353             if (!text.startsWith(prefix)) {
354                 return false;
355             }
356             doc.remove(offset, endOffset-offset);
357         } catch (BadLocationException ex) {
358             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
359         }
360         return false;
361     }
362
363     /** Comment out a particular line (in a Java file). Make sure that
364      * the line begins with a given prefix, just in case.
365      * @param prefix A prefix that the line to be commented out must start with
366      */

367     public static boolean commentLine(Line line, String JavaDoc prefix) {
368         Document doc = getDocument(line);
369         Element elm = getElement(doc, line);
370         if (elm == null) {
371             return false;
372         }
373         int offset = elm.getStartOffset();
374         int endOffset = elm.getEndOffset();
375
376         try {
377             String JavaDoc text = doc.getText(offset, endOffset-offset);
378             if (!text.startsWith(prefix)) {
379                 return false;
380             }
381             doc.insertString(offset, "// ", null); // NOI18N
382
} catch (BadLocationException ex) {
383             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
384         }
385         return false;
386     }
387
388     /** Given a file object, produce a URL suitable for inclusion
389      * in a tasklist (e.g. it must be persistent, not based on some
390      * currently assigned webserver port etc.) */

391     public static String JavaDoc toURL(FileObject fo) {
392         // steal DirectURLMapper from Javadoc module
393
return URLMapper.findURL(fo, URLMapper.INTERNAL).toExternalForm();
394     }
395
396     /** Given a URL created by fileToURL, return a file object representing
397      * the given file. Returns null if the URL can (no longer) be resolved.
398      */

399     public static FileObject[] fromURL(String JavaDoc urlString) {
400         URL JavaDoc url;
401         try {
402             url = new URL JavaDoc(urlString);
403         } catch (MalformedURLException JavaDoc e) {
404             return null;
405         }
406         return URLMapper.findFileObjects(url);
407     }
408     
409     /**
410      * Counts all children nodes of the given node recursively.
411      *
412      * @return node a node or null
413      */

414     public static int getChildrenCountRecursively(Node node) {
415         if (node == null) return 0;
416         
417         Children children = node.getChildren();
418         if(children.getNodesCount() == 0) return 0;
419
420         int n = 0;
421         Node[] nodes = children.getNodes();
422         for (int i = 0; i < nodes.length; i++) {
423             n += getChildrenCountRecursively(nodes[i]) + 1;
424         }
425         return n;
426     }
427     
428     /**
429      * Gets a property descriptor for the specified property name.
430      *
431      * @param n a node
432      * @param prop name of a property
433      * @return found property or null
434      */

435     public static Node.Property getProperty(Node n, String JavaDoc prop) {
436         Node.PropertySet[] propsets = n.getPropertySets();
437         for (int j = 0; j < propsets.length; ++j) {
438             Node.Property[] props = propsets[j].getProperties();
439             for (int k = 0; k < props.length; ++k) {
440                 if (props[k].getName().equals(prop)) {
441                     return props[k];
442                 }
443             }
444         }
445         return null;
446     }
447
448
449     /**
450      * Creates a simple logger for the specified class.
451      * Category of the logger will be equals to the class name.
452      *
453      * @param clazz the name of the class will be used for the logger's category
454      * @return logger
455      */

456     public static Logger JavaDoc getLogger(Class JavaDoc clazz) {
457         // eliminate duplications. There are two console handlers somehow,
458
// the second one publishes also INFO messages
459
Logger JavaDoc logger = Logger.getLogger(clazz.getName());
460         logger.setUseParentHandlers(false);
461
462         ConsoleHandler JavaDoc ch = new ConsoleHandler JavaDoc();
463         ch.setLevel(Level.FINE);
464         logger.addHandler(ch);
465         logger.setLevel(Level.WARNING);
466         return logger;
467     }
468
469     /** For debugging purposes only */
470     public static void traceFocus(final Container c) {
471
472         c.addFocusListener(new FocusListener JavaDoc() {
473             public void focusGained(FocusEvent JavaDoc e) {
474                 System.err.println("Component " + c + " gained focus.");
475                 Thread.dumpStack();
476             }
477             public void focusLost(FocusEvent JavaDoc e) {
478                 System.err.println("Component " + c + " lost focus.");
479                 Thread.dumpStack();
480             }
481
482         });
483         Component[] cs = c.getComponents();
484         if (cs != null) {
485             for (int i = 0; i<cs.length; i++) {
486                 if (cs[i] instanceof Container) {
487                     traceFocus((Container)cs[i]);
488                 }
489             }
490         }
491     }
492
493     /** Recusrsively count all tasks in passed iterator. */
494     public static int recursiveCount(Iterator JavaDoc tasks) {
495         if (tasks == null) return 0;
496         int count = 0;
497         while (tasks.hasNext()) {
498             Task next = (Task) tasks.next();
499             count += next.getSubtaskCountRecursively() + 1;
500         }
501         return count;
502     }
503
504     /**
505      * Prints a tree of nodes.
506      *
507      * @param node root node
508      * @param depth maximal depth
509      */

510     public static void nodeRecursivePrint(Node node, int depth) {
511         if (depth > 20) { // probably invalid list
512
Thread.dumpStack();
513             return;
514         }
515         for (int i = 0; i < depth; i++) {
516             System.err.print(" "); // NOI18N
517
}
518         System.err.println(node.getDisplayName());
519         if ((node.getChildren() != null) &&
520                 (node.getChildren().getNodes() != null)) {
521             Node[] nodes = node.getChildren().getNodes();
522             for (int i = 0; i < nodes.length; i++) {
523                 nodeRecursivePrint(nodes[i], depth + 1);
524             }
525         }
526     }
527 }
528
Popular Tags