KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > core > translators > HTMLSupport


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.translators;
21
22 import java.awt.Image JavaDoc;
23 import java.io.*;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.text.DateFormat JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.ListIterator JavaDoc;
31 import javax.swing.table.TableColumn JavaDoc;
32 import javax.swing.table.TableColumnModel JavaDoc;
33 import org.netbeans.modules.tasklist.core.filter.Filter;
34 import org.netbeans.modules.tasklist.core.ColumnProperty;
35 import org.netbeans.modules.tasklist.core.TLUtils;
36 import org.netbeans.modules.tasklist.core.TaskListView;
37 import org.netbeans.modules.tasklist.core.TaskList;
38 import org.netbeans.modules.tasklist.core.Task;
39 import org.netbeans.modules.tasklist.core.TaskNode;
40 import org.netbeans.modules.tasklist.core.export.ExportImportFormat;
41 import org.netbeans.modules.tasklist.core.util.IconManager;
42 import org.openide.NotifyDescriptor;
43 import org.openide.ErrorManager;
44 import org.openide.NotifyDescriptor.Confirmation;
45 import org.openide.filesystems.FileObject;
46 import org.openide.filesystems.FileStateInvalidException;
47 import org.openide.nodes.Node;
48 import org.openide.util.NbBundle;
49 import org.openide.awt.HtmlBrowser.URLDisplayer;
50 import org.openide.awt.HtmlBrowser;
51 import org.openide.DialogDisplayer;
52 import org.openide.WizardDescriptor;
53
54
55 /**
56  * This class is not currently used.
57  *
58  * This class exports a given TaskListView to HTML, using the current
59  * visible columns, sorting column, etc.
60  *
61  * @author Tor Norbye
62  */

63 public abstract class HTMLSupport implements ExportImportFormat {
64     // these values are stored temporary during export
65
private ColumnProperty[] columns;
66     private String JavaDoc[] headers;
67     private Filter filter;
68     private TaskListView view;
69     private Writer writer;
70     private boolean sortAscending = true;
71     private boolean sortedByName = false;
72     private boolean noSorting = true;
73     private Node.Property sortedByProperty = null;
74     private IconManager iconMap = null;
75
76     public String JavaDoc getName() {
77         return NbBundle.getMessage(HTMLSupport.class, "HTML"); // NOI18N
78
}
79
80     public WizardDescriptor getWizard() {
81         // TODO return NbBundle.getMessage(HTMLSupport.class, "ExportHTML"); // NOI18N
82
return null;
83     }
84     
85     public boolean doExportImport(File dir,
86     boolean interactive, OutputStream out) throws IOException {
87         Writer writer = new OutputStreamWriter(out, "utf8"); // NOI18N
88
this.view = TaskListView.getCurrent();
89         if (view == null) {
90             return false;
91         }
92         this.filter = view.getFilter();
93         this.writer = writer;
94
95         if (interactive && (dir != null)) {
96             IconManager icm = new IconManager(dir);
97             // Show the result?
98
NotifyDescriptor nd = new NotifyDescriptor.Confirmation (
99                  NbBundle.getMessage(HTMLSupport.class,
100                                    "ExportIcons"), // NOI18N
101
NotifyDescriptor.YES_NO_OPTION
102             );
103             Object JavaDoc result = DialogDisplayer.getDefault().notify(nd);
104             if (NotifyDescriptor.YES_OPTION == result) {
105                 iconMap = icm;
106             }
107         }
108         
109         exportHTML();
110         writer.flush();
111
112         iconMap = null;
113         return true;
114     }
115
116     /**
117      * Creates CSS commands.
118      */

119     protected void writeCSS(Writer writer) throws IOException {
120         writer.write(
121             " body { background-color:white; color:black }\n" + // NOI18N
122
" td { text-align:left; vertical-align:text-top; background-color:#eeeeee }\n" + // NOI18N
123
" th { text-align:center; background-color:#222288; color:white }\n" + // NOI18N
124
" td.sum { text-align:left }\n" + // NOI18N
125
" td.sumdone { text-align:left; background-color:#cccccc }\n" + // NOI18N
126
" td.done { background-color:#cccccc }\n" + // NOI18N
127
" td.subhead { text-align:center; background-color:#ccccff }\n" + // NOI18N
128
" td.datehead { text-align:center; background-color:#ccccff }\n" + // NOI18N
129
" td.space { background-color:white }\n" + // NOI18N
130
" td.date { text-align:left }\n" + // NOI18N
131
" td.dateholiday { text-align:left; color:red }\n"); // NOI18N
132
}
133     
134     private void exportHTML() throws IOException {
135         TableColumnModel JavaDoc headerModel = view.getColumnModel();
136
137         // Based on Konqueror's output (KDE2's calendar app)
138
writer.write(
139             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"" + // NOI18N
140
" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" + // NOI18N
141
"<HTML><HEAD>\n <META http-equiv=\"Content-Type\"" + // NOI18N
142
" content=\"text/html; charset=UTF-8\">\n" + // NOI18N
143
" <TITLE>" + NbBundle.getMessage(HTMLSupport.class, "TaskListHeader") + "</TITLE>\n" + // NOI18N
144
" <style type=\"text/css\">\n"); // NOI18N
145
writeCSS(writer);
146         writer.write(
147             " </style>\n</HEAD><BODY>\n<H1>" + // NOI18N
148
NbBundle.getMessage(HTMLSupport.class, "TaskListHeader") + // NOI18N
149
"</H1>\n" + // NOI18N
150
"<TABLE WIDTH=\"100%\" BORDER=0 CELLPADDING=3 CELLSPACING=3>\n"); // NOI18N
151

152         // Write out header columns
153
int headercols = headerModel.getColumnCount();
154         writer.write("<TR>\n"); // NOI18N
155

156         // Compute total width of the table, so we can produce
157
// header proportion percentages
158
int width = 0;
159         for (int j = 0; j < headercols; j++) {
160             TableColumn JavaDoc column = headerModel.getColumn(j);
161             width += column.getWidth();
162         }
163         
164         headers = new String JavaDoc[headercols];
165
166         for (int j = 0; j < headercols; j++) {
167             TableColumn JavaDoc column = headerModel.getColumn(j);
168             int relativeWidth = column.getWidth()*100/width;
169             if (j == 0) {
170                 writer.write(" <TH WIDTH=\"" + relativeWidth + // NOI18N
171
"%\">"); // NOI18N
172
} else {
173                 writer.write(" <TH WIDTH=\"" + relativeWidth + // NOI18N
174
"%\">"); // NOI18N
175
}
176             headers[j] = column.getHeaderValue().toString();
177             writer.write(TLUtils.toHTML(headers[j]));
178             writer.write("</TH>\n"); // NOI18N
179
}
180         writer.write("</TR>\n"); // NOI18N
181

182         // Write out task items
183

184         // How do I generalize the case that some exporters
185
// want to nest subtasks, others want to put them at the
186
// end (or at the beginning) ???
187
// Perhaps task iteration should be left to each export
188
// filter... yeah, that's probably best. In that case the
189
// current methods can be viewed as a specific HTML export
190
// filter needing to be replaced by an export type registry
191
// abstraction
192

193         // Determine sorting properties
194
sortedByProperty = null;
195         sortAscending = true;
196         sortedByName = false;
197         noSorting = true;
198         
199         columns = view.getColumns();
200         
201         // Look up sorting column
202
for (int i = 0; i < columns.length; i++) {
203             Boolean JavaDoc sorting =
204                 (Boolean JavaDoc)columns[i].getValue( "SortingColumnTTV"); // NOI18N
205
if ((sorting != null) && (sorting.booleanValue())) {
206                 if (i == 0) {
207                     sortedByName = true;
208                 } else {
209                     sortedByProperty = columns[i];
210                 }
211                 Boolean JavaDoc desc = (Boolean JavaDoc)columns[i].
212                     getValue( "DescendingOrderTTV"); // NOI18N
213
sortAscending = ((desc == null) || !(desc.booleanValue()));
214             }
215         }
216         
217         // -1 == root node is hidden
218
Node n = view.getExplorerManager().getRootContext();
219         exportOneNode(n, -1);
220         
221         writer.write(
222             "</TR>\n</TABLE>\n<P>" + // NOI18N
223
NbBundle.getMessage(HTMLSupport.class, "PageCreatedBy", // NOI18N
224
"<A HREF=\"http://www.netbeans.org\">NetBeans</A> " + // NOI18N
225
"<A HREF=\"http://tasklist.netbeans.org\">tasklist</A></P>") + // NOI18N
226
DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG).
227                format(new Date JavaDoc()) +
228             "<P>\n</BODY></HTML>\n" // NOI18N
229
);
230
231     }
232     
233     /**
234      * Exports one node to HTML.
235      *
236      * @param n a task
237      * @param level indent level (negative levels will not be exported)
238      */

239     private void exportOneNode(Node n, int level)
240     throws IOException {
241       Task t = TaskNode.getTask(n);
242         if (t != null && filter != null && level != -1 && !filter.accept(t))
243             return;
244             
245         writer.write("<TR>\n"); // NOI18N
246

247         if (level >= 0) {
248             writeOneTask(n, level);
249         }
250         
251         List JavaDoc l = view.getSortedChildren(n, sortedByProperty, sortAscending,
252             sortedByName, noSorting);
253         
254         ListIterator JavaDoc it = l.listIterator();
255         while (it.hasNext()) {
256             Node node = (Node)it.next();
257             exportOneNode(node, level + 1);
258         }
259     }
260     
261     /**
262      * Exports one task to HTML (one row in the table).
263      *
264      * @param n a task
265      * @param level indent level >= 0
266      */

267     private void writeOneTask(Node n, int level)
268     throws IOException {
269         Boolean JavaDoc invisible = null;
270         for (int i = 0; i < headers.length; ++i) {
271             int colidx;
272
273             for (colidx = 0; colidx < columns.length; ++colidx) {
274                if (headers[i].equalsIgnoreCase(columns[colidx].getDisplayName())) {
275                   invisible = (Boolean JavaDoc)columns[colidx].getValue("InvisibleInTreeTableView"); // NOI18N
276
break;
277                }
278             }
279
280             if (colidx >= columns.length || (invisible != null && invisible.booleanValue())) {
281                 // XXX This should _never_ happen!!!!
282
// However, it does. The cause seems to be that the TreeTableView
283
// occasionally takes the VALUE of the display name of the
284
// root note, and sticks it in the table header for the tree
285
// column!! Thus, when this scenario occurs, we should simply
286
// use the display name/tree column
287
// OLD: System.out.println("Sorry but I did not find <" + headers[i] + ">"); // NOI18N
288
// OLD: writer.write(" <TD>ERROR</TD>\n"); // NOI18N
289
// OLD: continue;
290
colidx = 0;
291             }
292
293             // Map the node data...
294
Node.PropertySet[] propsets = n.getPropertySets();
295             for (int j = 0; j < propsets.length; ++j) {
296                 Node.Property[] props = propsets[j].getProperties();
297                 int k;
298
299                 for (k = 0; k < props.length; ++k) {
300                     String JavaDoc name = props[k].getName();
301
302                     // Locate the name among the columns
303
if (columns[colidx].getName().equals(name)) {
304                         break;
305                     }
306                 }
307
308                 if (k == props.length) {
309                     // Not found in this set, search next
310
break;
311                 }
312                 
313                 writeOneField(writer, j == 0, n, props[k], level);
314             }
315         }
316         writer.write("</TR>\n"); // NOI18N
317
}
318
319     /**
320      * Writes one field in the table.
321      *
322      * @param writer output stream
323      * @param prop this property should be written
324      * @param level indent level >= 0
325      */

326     protected void writeOneField(Writer writer, boolean first,
327                                  Node node, Node.Property prop, int level)
328     throws IOException {
329         // Only use a "sub" table when we have subtasks.
330
// The Swing HTML browser didn't handle these tables within
331
// tables well (all text is centered) so avoid it when
332
// it's not required. (As a side benefit, it makes the
333
// HTML document smaller and it renders faster.)
334
boolean subtable = level > 0;
335
336         if (prop.getName().equals(TaskListView.PROP_TASK_SUMMARY)) { // NOI18N
337
writer.write("<TD>\n"); // NOI18N
338
if (subtable) {
339                 writer.write("<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\" WIDTH=\"100%\">\n"); // NOI18N
340
writer.write("<TR>\n"); // NOI18N
341
writer.write("<TD WIDTH=\"" + 20 * level + "\"></TD>\n"); // NOI18N
342
writer.write("<TD CLASS=\"sum\">\n"); // NOI18N
343
}
344
345                             exportIcon(writer, first, node);
346                             try {
347                                 writer.write(TLUtils.toHTML(prop.getValue().toString()));
348                             } catch (java.lang.IllegalAccessException JavaDoc e) {
349                                 writer.write("ERROR"); // NOI18N
350
ErrorManager.getDefault().notify(e);
351                             } catch (InvocationTargetException JavaDoc e) {
352                                 writer.write("ERROR"); // NOI18N
353
ErrorManager.getDefault().notify(e);
354                             }
355             if (subtable) {
356                         writer.write("</TD>\n"); // NOI18N
357
writer.write("</TR>\n"); // NOI18N
358
writer.write("</TABLE>\n"); // NOI18N
359
}
360             writer.write("</TD>\n"); // NOI18N
361
} else {
362             writer.write("<TD>\n"); // NOI18N
363
try {
364                     Object JavaDoc value = prop.getValue();
365                     String JavaDoc s = value == null ? "" : value.toString(); // NOI18N
366
if (s == null) s = ""; // NOI18N
367
writer.write(TLUtils.toHTML(s));
368                 } catch (java.lang.IllegalAccessException JavaDoc e) {
369                     writer.write("ERROR"); // NOI18N
370
ErrorManager.getDefault().notify(e);
371                 } catch (InvocationTargetException JavaDoc e) {
372                     writer.write("ERROR"); // NOI18N
373
ErrorManager.getDefault().notify(e);
374                 }
375             writer.write("</TD>\n"); // NOI18N
376
}
377     }
378
379     /** Export an icon reference. Return false if that was not done,
380         either by user choice or IO fault. */

381     protected boolean exportIcon(Writer writer, boolean first,
382                                  Node node) throws IOException {
383         if (first && (iconMap != null)) {
384             Image JavaDoc icon = node.getIcon(java.beans.BeanInfo.ICON_COLOR_16x16);
385             String JavaDoc name = iconMap.getIcon(icon);
386             if (name != null) {
387                 writer.write("<IMG SRC=\"" + name + "\">&nbsp;\n"); // NOI18N
388
return true;
389             }
390         }
391         return false;
392     }
393 }
394
Popular Tags