KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > webapp > servlet > IndexFragmentServlet


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.servlet;
12
13 import java.io.IOException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.WeakHashMap JavaDoc;
19
20 import javax.servlet.ServletException JavaDoc;
21 import javax.servlet.http.HttpServlet JavaDoc;
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24
25 import org.eclipse.help.IIndex;
26 import org.eclipse.help.IIndexEntry;
27 import org.eclipse.help.ITopic;
28 import org.eclipse.help.internal.HelpPlugin;
29 import org.eclipse.help.internal.base.BaseHelpSystem;
30 import org.eclipse.help.internal.webapp.WebappResources;
31 import org.eclipse.help.internal.webapp.data.ActivitiesData;
32 import org.eclipse.help.internal.webapp.data.EnabledTopicUtils;
33 import org.eclipse.help.internal.webapp.data.UrlUtil;
34
35 /*
36  * Creates xml representing selected parts of the index
37  * Parameter "start" represents the part of the index to start reading from
38  * Parameter "size" indicates the number of entries to read, no size parameter
39  * or a negatove size parameter indicates that all entries which match the start
40  * letters should be displayed.
41  * Parameter "offset" represents the starting point relative to the start
42  */

43 public class IndexFragmentServlet extends HttpServlet JavaDoc {
44     
45     private static final long serialVersionUID = 1L;
46     private static Map JavaDoc locale2Response = new WeakHashMap JavaDoc();
47     private String JavaDoc startParameter;
48     private String JavaDoc sizeParameter;
49     private String JavaDoc entryParameter;
50     private String JavaDoc modeParameter;
51     private String JavaDoc showAllParameter;
52     private int size;
53     private int entry;
54     private static final String JavaDoc NEXT = "next"; //$NON-NLS-1$
55
private static final String JavaDoc PREVIOUS = "previous"; //$NON-NLS-1$
56
private static final String JavaDoc SIZE = "size"; //$NON-NLS-1$
57
private static final String JavaDoc MODE = "mode"; //$NON-NLS-1$
58
private static final String JavaDoc ENTRY = "entry"; //$NON-NLS-1$
59
private static final String JavaDoc SHOW_ALL = "showAll"; //$NON-NLS-1$
60

61     protected void doGet(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc resp)
62             throws ServletException JavaDoc, IOException JavaDoc {
63         String JavaDoc locale = UrlUtil.getLocale(req, resp);
64         startParameter = req.getParameter("start"); //$NON-NLS-1$
65
if (startParameter != null) {
66             startParameter = startParameter.toLowerCase();
67         }
68
69         size = 30;
70         sizeParameter = req.getParameter(SIZE);
71         if (sizeParameter != null) {
72             try {
73                 size = Integer.parseInt(sizeParameter);
74             } catch (NumberFormatException JavaDoc n) {
75             }
76         }
77         
78         entry = -1;
79         entryParameter = req.getParameter(ENTRY);
80         if (entryParameter != null) {
81             try {
82                 entry = Integer.parseInt(entryParameter);
83             } catch (NumberFormatException JavaDoc n) {
84             }
85         }
86
87         modeParameter = req.getParameter(MODE);
88         showAllParameter = req.getParameter(SHOW_ALL);
89         if (showAllParameter != null) {
90             // Use activities data to toggle the show all state
91
new ActivitiesData(this.getServletContext(), req, resp);
92         }
93         
94         req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
95
resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
96
// Cache suppression required if not in infocenter mode because the set of disabled
97
// topics could change between requests
98
if (BaseHelpSystem.getMode() != BaseHelpSystem.MODE_INFOCENTER) {
99             resp.setHeader("Cache-Control","no-cache"); //$NON-NLS-1$//$NON-NLS-2$
100
resp.setHeader("Pragma","no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
101
resp.setDateHeader ("Expires", 0); //$NON-NLS-1$
102
}
103         Serializer serializer = new Serializer(locale);
104         String JavaDoc response = serializer.generateIndexXml();
105         locale2Response.put(locale, response);
106         resp.getWriter().write(response);
107     }
108     
109     /*
110      * Class which creates the xml file based upon the request parameters
111      */

112     private class Serializer {
113         
114         private IIndex index;
115         private StringBuffer JavaDoc buf;
116         private int count = 0;
117         private String JavaDoc locale;
118         private List JavaDoc entryList;
119         private IIndexEntry[] entries;
120         private boolean enablePrevious = true;
121         private boolean enableNext = true;
122
123         public Serializer(String JavaDoc locale) {
124             this.locale = locale;
125             index = HelpPlugin.getIndexManager().getIndex(locale);
126             buf = new StringBuffer JavaDoc();
127         }
128         
129         /*
130          * There are three modes of generation, current page, next page and previous page.
131          * Current page returns a screenful of entries starting at the startParameter.
132          * Next page returns a screenful of entries starting after but not including the start parameter.
133          * Previous page returns a screenful of entries going back from the start parameter
134          */

135         private String JavaDoc generateIndexXml() {
136             
137             entries = index.getEntries();
138             if (entries.length == 0) {
139                 generateEmptyIndexMessage();
140             } else {
141                 entryList = new ArrayList JavaDoc();
142                 int nextEntry = findFirstEntry(entries);
143                 if (PREVIOUS.equals(modeParameter)) {
144                     int remaining = getPreviousEntries(nextEntry, size);
145                     getNextEntries(nextEntry, remaining);
146                 } else {
147                     int remaining = getNextEntries(nextEntry, size);
148                     if (remaining == size) {
149                         // Generate just the last entry
150
size = 1;
151                         getPreviousEntries(nextEntry, 1);
152                     }
153                 }
154                 for (Iterator JavaDoc iter = entryList.iterator(); iter.hasNext();) {
155                     Integer JavaDoc entryId = (Integer JavaDoc)iter.next();
156                     generateEntry(entries[entryId.intValue()], 0, "e" + entryId.intValue()); //$NON-NLS-1$
157
}
158             }
159             String JavaDoc header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tree_data enableNext = \"" //$NON-NLS-1$
160
+ Boolean.toString(enableNext) + "\" enablePrevious = \"" + Boolean.toString(enablePrevious) + "\">\n"; //$NON-NLS-1$ //$NON-NLS-2$
161
buf.append("</tree_data>\n"); //$NON-NLS-1$
162
return header + buf.toString();
163         }
164         
165         private int getCategory(String JavaDoc keyword) {
166             if (keyword != null && keyword.length() > 0) {
167                 char c = keyword.charAt(0);
168                 if (Character.isDigit(c)) {
169                     return 2;
170                 } else if (Character.isLetter(c)) {
171                     return 3;
172                 }
173                 return 1;
174             }
175             return 4;
176         }
177         
178         private int compare (String JavaDoc left, String JavaDoc right) {
179             int catLeft = getCategory(left);
180             int catRight = getCategory(right);
181             if (catLeft != catRight) {
182                 return catLeft - catRight;
183             } else {
184                 return left.compareTo(right);
185             }
186         }
187
188         private int findFirstEntry(IIndexEntry[] entries) {
189             if (NEXT.equals(modeParameter)) {
190                 if (entry >= entries.length - 1) {
191                     return entries.length - 1;
192                 } else {
193                     return entry + 1;
194                 }
195             }
196             if (PREVIOUS.equals(modeParameter)) {
197                 if (entry <= 0) {
198                     return 0;
199                 } else {
200                     return entry - 1;
201                 }
202             }
203             if (startParameter == null) {
204                 return 0;
205             }
206             int nextEntry = 0;
207             while (nextEntry < entries.length) {
208                 String JavaDoc keyword = entries[nextEntry].getKeyword().toLowerCase();
209                 if (keyword != null) {
210                     if (compare(startParameter, keyword) <= 0) {
211                         break;
212                     }
213                 }
214                 nextEntry++;
215             }
216             return nextEntry;
217         }
218         
219         private int getNextEntries(int nextEntry, int remaining) {
220             while (nextEntry < entries.length) {
221                 int entrySize = enabledEntryCount(entries[nextEntry]);
222                 if (remaining == size || remaining > entrySize) {
223                     entryList.add(new Integer JavaDoc(nextEntry));
224                     setFlags(nextEntry);
225                     remaining -= entrySize;
226                 } else {
227                     break;
228                 }
229                 nextEntry++;
230             }
231             return remaining;
232         }
233
234         private int getPreviousEntries(int nextEntry, int remaining) {
235             nextEntry--;
236             while (nextEntry >= 0) {
237                 int entrySize = enabledEntryCount(entries[nextEntry]);
238                 if (remaining == size || remaining > entrySize) {
239                     entryList.add(0, new Integer JavaDoc(nextEntry));
240
241                     setFlags(nextEntry);
242                     remaining -= entrySize;
243                 } else {
244                     break;
245                 }
246                 nextEntry--;
247             }
248             return remaining;
249         }
250
251         private void setFlags(int nextEntry) {
252             if (nextEntry == 0) {
253                 enablePrevious = false;
254             }
255             if (nextEntry == entries.length - 1) {
256                 enableNext = false;
257             }
258         }
259         
260         private int enabledEntryCount(IIndexEntry entry) {
261             if (!EnabledTopicUtils.isEnabled(entry)) return 0;
262             if (entry.getKeyword() == null || entry.getKeyword().length() == 0) {
263                 return 0;
264             }
265             int count = 1;
266             ITopic[] topics = EnabledTopicUtils.getEnabled(entry.getTopics());
267             IIndexEntry[] subentries = EnabledTopicUtils.getEnabled(entry.getSubentries());
268             if (topics.length > 1) {
269                 count += topics.length;
270             }
271             for (int i=0;i<subentries.length;++i) {
272                 count += enabledEntryCount(subentries[i]);
273             }
274             return count;
275         }
276         
277         private void generateEmptyIndexMessage() {
278             buf.append("<node"); //$NON-NLS-1$
279
buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(WebappResources.getString("IndexEmpty", UrlUtil.getLocale(locale))) + '"'); //$NON-NLS-1$ //$NON-NLS-2$
280
buf.append('\n' + " id=\"no_index\""); //$NON-NLS-1$
281
buf.append(">\n"); //$NON-NLS-1$
282
buf.append("</node>\n"); //$NON-NLS-1$
283
enableNext = false;
284             enablePrevious = false;
285         }
286         
287         private void generateEntry(IIndexEntry entry, int level, String JavaDoc id) {
288             if (!EnabledTopicUtils.isEnabled(entry)) return;
289             if (entry.getKeyword() != null && entry.getKeyword().length() > 0) {
290                 ITopic[] topics = EnabledTopicUtils.getEnabled(entry.getTopics());
291                 IIndexEntry[] subentries = EnabledTopicUtils.getEnabled(entry.getSubentries());
292                 boolean multipleTopics = topics.length > 1;
293                 boolean singleTopic = topics.length == 1;
294                 
295                 buf.append("<node"); //$NON-NLS-1$
296
if (entry.getKeyword() != null) {
297                     buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(entry.getKeyword()) + '"'); //$NON-NLS-1$
298
}
299                 
300                 buf.append('\n' + " id=\"" + id + '"'); //$NON-NLS-1$
301

302                 String JavaDoc href;
303                 if (singleTopic) {
304                     href = UrlUtil.getHelpURL((entry.getTopics()[0]).getHref());
305                     buf.append('\n' + " HREF=\"" + //$NON-NLS-1$
306
XMLGenerator.xmlEscape(href) + "\""); //$NON-NLS-1$
307
}
308                 buf.append(">\n"); //$NON-NLS-1$
309

310                 if (multipleTopics || subentries.length > 0) {
311                     if (multipleTopics) generateTopicList(entry);
312                     generateSubentries(entry, level + 1);
313                 }
314                 
315                 buf.append("</node>\n"); //$NON-NLS-1$
316
}
317         }
318         
319         private void generateSubentries(IIndexEntry entry, int level) {
320             IIndexEntry[] subentries = entry.getSubentries();
321             for (int i=0;i<subentries.length;++i) {
322                 generateEntry(subentries[i], level, "s" + count++); //$NON-NLS-1$
323
}
324         }
325         
326         private void generateTopicList(IIndexEntry entry) {
327             ITopic[] topics = entry.getTopics();
328             
329             for (int i = 0; i < topics.length; ++i) {
330                 ITopic topic = (ITopic)topics[i];
331                 
332                 //
333
String JavaDoc label = UrlUtil.htmlEncode(topic.getLabel());
334                 if (label == null) {
335                     label = UrlUtil.htmlEncode(topic.getLabel());
336                 }
337                 
338             
339                 buf.append("<node"); //$NON-NLS-1$
340
if (entry.getKeyword() != null) {
341                     buf.append('\n' + " title=\"" + label + '"'); //$NON-NLS-1$
342
}
343                 
344                 count++;
345                 buf.append('\n' + " id=\"i" + count + '"'); //$NON-NLS-1$
346
String JavaDoc href = UrlUtil.getHelpURL(topic.getHref());
347                 buf.append('\n' + " HREF=\"" //$NON-NLS-1$
348
+ XMLGenerator.xmlEscape(href) + "\""); //$NON-NLS-1$
349
buf.append(">\n"); //$NON-NLS-1$
350
buf.append("</node>\n"); //$NON-NLS-1$
351

352             }
353         }
354     }
355
356 }
357
Popular Tags