KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > webapp > data > PrintData


1 /*******************************************************************************
2  * Copyright (c) 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.help.internal.webapp.data;
12
13 import java.io.BufferedReader JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InputStreamReader JavaDoc;
17 import java.io.Reader JavaDoc;
18 import java.io.Writer JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20 import java.util.regex.Matcher JavaDoc;
21 import java.util.regex.Pattern JavaDoc;
22
23 import javax.servlet.ServletContext JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpServletResponse JavaDoc;
26
27 import org.eclipse.help.HelpSystem;
28 import org.eclipse.help.IToc;
29 import org.eclipse.help.ITopic;
30 import org.eclipse.help.internal.HelpPlugin;
31 import org.eclipse.help.internal.search.HTMLDocParser;
32 import org.eclipse.help.internal.webapp.HelpWebappPlugin;
33
34 /*
35  * Used by the print jsp to access print-related data.
36  */

37 public class PrintData extends RequestData {
38
39     // where to inject the section numbers
40
private static final Pattern JavaDoc PATTERN_HEADING = Pattern.compile("<body.*?>[\\s]*?([\\w])", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
41

42     // to normalize external links to new base href
43
private static final Pattern JavaDoc PATTERN_LINK = Pattern.compile("(src|href)=\"(.*?\")", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
44

45     /*
46      * Constructs the print data for the given request.
47      */

48     public PrintData(ServletContext JavaDoc context, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
49         super(context, request, response);
50     }
51
52     /*
53      * Returns the overall topic's title.
54      */

55     public String JavaDoc getTitle() {
56         return getTopic().getLabel();
57     }
58
59     /*
60      * Returns the href of the toc containing the topic(s) to print.
61      */

62     public String JavaDoc getTocHref() {
63         return getToc().getHref();
64     }
65     
66     /*
67      * Returns the href of the root topic to print.
68      */

69     public String JavaDoc getTopicHref() {
70         return getTopic().getHref();
71     }
72
73     /*
74      * Generates and outputs a table of contents div with links.
75      */

76     public void generateToc(Writer JavaDoc out) throws IOException JavaDoc {
77         out.write("<div id=\"toc\">"); //$NON-NLS-1$
78
out.write("<h1>"); //$NON-NLS-1$
79
out.write(getTitle());
80         out.write("</h1>"); //$NON-NLS-1$
81
out.write("<h2>"); //$NON-NLS-1$
82
out.write(ServletResources.getString("TocHeading", request)); //$NON-NLS-1$
83
out.write("</h2>"); //$NON-NLS-1$
84
out.write("<div id=\"toc_content\">"); //$NON-NLS-1$
85
ITopic topic = getTopic();
86         ITopic[] subtopics = topic.getSubtopics();
87         for (int i=0;i<subtopics.length;++i) {
88             generateToc(subtopics[i], String.valueOf(i + 1), out);
89         }
90         out.write("</div>"); //$NON-NLS-1$
91
out.write("</div>"); //$NON-NLS-1$
92
}
93
94     /*
95      * Auxiliary method for recursively generating table of contents div.
96      */

97     private void generateToc(ITopic topic, String JavaDoc sectionId, Writer JavaDoc out) throws IOException JavaDoc {
98         out.write("<div class=\"toc_" + (sectionId.length() > 2 ? "sub" : "") + "entry\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
99
out.write(sectionId + ". " + "<a HREF=\"#section" + sectionId + "\">" + topic.getLabel() + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
100
ITopic[] subtopics = topic.getSubtopics();
101         for (int i=0;i<subtopics.length;++i) {
102             String JavaDoc subsectionId = sectionId + "." + (i + 1); //$NON-NLS-1$
103
generateToc(subtopics[i], subsectionId, out);
104         }
105         out.write("</div>"); //$NON-NLS-1$
106
}
107
108     /*
109      * Generates the content to print (the merged topics).
110      */

111     public void generateContent(Writer JavaDoc out) throws IOException JavaDoc {
112         generateContent(getTopic(), null, out);
113     }
114     
115     /*
116      * Auxiliary method for recursively generating print content.
117      */

118     private void generateContent(ITopic topic, String JavaDoc sectionId, Writer JavaDoc out) throws IOException JavaDoc {
119         String JavaDoc href = topic.getHref();
120         if (href != null) {
121             // get the topic content
122
String JavaDoc pathHref = href.substring(0, href.lastIndexOf('/') + 1);
123             String JavaDoc baseHref = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/topic" + pathHref; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
124
String JavaDoc content = getContent(href, locale);
125             
126             // root topic doesn't have sectionId
127
if (sectionId != null) {
128                 content = injectHeading(content, sectionId);
129             }
130             content = normalizeHrefs(content, baseHref);
131             out.write(content);
132         }
133         ITopic[] subtopics = topic.getSubtopics();
134         for (int i=0;i<subtopics.length;++i) {
135             String JavaDoc subsectionId = (sectionId != null ? sectionId + "." : "") + (i + 1); //$NON-NLS-1$ //$NON-NLS-2$
136
generateContent(subtopics[i], subsectionId, out);
137         }
138     }
139
140     /*
141      * Injects the sectionId into the document heading.
142      */

143     private String JavaDoc injectHeading(String JavaDoc content, String JavaDoc sectionId) {
144         Matcher JavaDoc matcher = PATTERN_HEADING.matcher(content);
145         if (matcher.find()) {
146             String JavaDoc heading = "<a id=\"section" + sectionId + "\">" + sectionId + ". </a>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
147
return content.substring(0, matcher.start(1)) + heading + content.substring(matcher.start(1));
148         }
149         return content;
150     }
151     
152     /*
153      * Normalizes all external links since we're not at the same base href as the
154      * topics we're printing.
155      */

156     private String JavaDoc normalizeHrefs(String JavaDoc content, String JavaDoc baseHref) {
157         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
158         Matcher JavaDoc matcher = PATTERN_LINK.matcher(content);
159         int prev = 0;
160         while (matcher.find()) {
161             buf.append(content.substring(prev, matcher.start(2)));
162             buf.append(baseHref);
163             buf.append(matcher.group(2));
164             prev = matcher.end();
165         }
166         buf.append(content.substring(prev));
167         return buf.toString();
168     }
169     
170     /*
171      * Returns the string content of the referenced topic in UTF-8.
172      */

173     private String JavaDoc getContent(String JavaDoc href, String JavaDoc locale) {
174         InputStream JavaDoc in = HelpSystem.getHelpContent(href, locale);
175         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
176         if (in != null) {
177             try {
178                 String JavaDoc charset = HTMLDocParser.getCharsetFromHTML(in);
179                 if (charset == null) {
180                     charset = "UTF-8"; //$NON-NLS-1$
181
}
182                 in = HelpSystem.getHelpContent(href, locale);
183                 Reader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in, charset));
184                 char[] cbuf = new char[4096];
185                 int num;
186                 while ((num = reader.read(cbuf)) > 0) {
187                     buf.append(cbuf, 0, num);
188                 }
189             }
190             catch (Exception JavaDoc e) {
191                 String JavaDoc msg = "Error retrieving print preview content for " + href; //$NON-NLS-1$
192
HelpWebappPlugin.logError(msg, e);
193             }
194             finally {
195                 try {
196                     in.close();
197                 }
198                 catch (Exception JavaDoc e) {}
199             }
200         }
201         return buf.toString();
202     }
203
204     /*
205      * Returns the toc containing the selected topic(s).
206      */

207     private IToc getToc() {
208         String JavaDoc tocParam = request.getParameter("toc"); //$NON-NLS-1$
209
if (tocParam != null && tocParam.length() > 0) {
210             return HelpPlugin.getTocManager().getToc(tocParam, getLocale());
211         }
212         String JavaDoc topicParam = request.getParameter("topic"); //$NON-NLS-1$
213
if (topicParam != null && topicParam.length() > 0) {
214             if (topicParam.startsWith("/../nav/")) { //$NON-NLS-1$
215
String JavaDoc navPath = topicParam.substring(8);
216                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(navPath, "_"); //$NON-NLS-1$
217
int index = Integer.parseInt(tok.nextToken());
218                 return HelpPlugin.getTocManager().getTocs(getLocale())[index];
219             }
220             IToc[] tocs = HelpPlugin.getTocManager().getTocs(getLocale());
221             for (int i=0;i<tocs.length;++i) {
222                 if (tocs[i].getTopic(topicParam) != null) {
223                     return tocs[i];
224                 }
225             }
226         }
227         return null;
228     }
229
230     /*
231      * Returns the selected topic.
232      */

233     private ITopic getTopic() {
234         String JavaDoc topicParam = request.getParameter("topic"); //$NON-NLS-1$
235
if (topicParam != null && topicParam.length() > 0) {
236             if (topicParam.startsWith("/../nav/")) { //$NON-NLS-1$
237
String JavaDoc navPath = topicParam.substring(8);
238                 StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(navPath, "_"); //$NON-NLS-1$
239
int index = Integer.parseInt(tok.nextToken());
240                 ITopic topic = HelpPlugin.getTocManager().getTocs(getLocale())[index].getTopic(null);
241                 while (tok.hasMoreTokens()) {
242                     index = Integer.parseInt(tok.nextToken());
243                     topic = topic.getSubtopics()[index];
244                 }
245                 return topic;
246             }
247             else {
248                 IToc[] tocs = HelpPlugin.getTocManager().getTocs(getLocale());
249                 for (int i=0;i<tocs.length;++i) {
250                     ITopic topic = tocs[i].getTopic(topicParam);
251                     if (topic != null) {
252                         return topic;
253                     }
254                     // Test for root node as topic
255
topic = tocs[i].getTopic(null);
256                     if (topicParam.equals(topic.getHref())) {
257                         return topic;
258                     }
259                 }
260             }
261             return null;
262         }
263         return getToc().getTopic(null);
264     }
265 }
266
Popular Tags