1 11 package org.eclipse.help.internal.webapp.servlet; 12 13 import java.io.IOException ; 14 import java.util.Locale ; 15 import java.util.Map ; 16 import java.util.WeakHashMap ; 17 18 import javax.servlet.ServletException ; 19 import javax.servlet.http.HttpServlet ; 20 import javax.servlet.http.HttpServletRequest ; 21 import javax.servlet.http.HttpServletResponse ; 22 23 import org.eclipse.help.IToc; 24 import org.eclipse.help.ITopic; 25 import org.eclipse.help.internal.webapp.WebappResources; 26 import org.eclipse.help.internal.webapp.data.EnabledTopicUtils; 27 import org.eclipse.help.internal.webapp.data.TocData; 28 import org.eclipse.help.internal.webapp.data.UrlUtil; 29 30 36 public class TocFragmentServlet extends HttpServlet { 37 38 private static final long serialVersionUID = 1L; 39 private static Map locale2Response = new WeakHashMap (); 40 41 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 42 throws ServletException , IOException { 43 String locale = UrlUtil.getLocale(req, resp); 44 req.setCharacterEncoding("UTF-8"); resp.setContentType("application/xml; charset=UTF-8"); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); resp.setDateHeader ("Expires", 0); TocData data = new TocData(this.getServletContext(), req, resp); 50 Serializer serializer = new Serializer(data, req.getLocale()); 51 String response = serializer.generateTreeXml(); 52 locale2Response.put(locale, response); 53 resp.getWriter().write(response); 54 } 55 56 59 private class Serializer { 60 61 private TocData tocData; 62 private StringBuffer buf; 63 private int requestKind; 64 private Locale locale; 65 private static final int REQUEST_SHOW_IN_TOC = 1; private static final int REQUEST_SHOW_TOCS = 2; private static final int REQUEST_SHOW_CHILDREN = 3; 69 public Serializer(TocData data, Locale locale) { 70 tocData = data; 71 buf = new StringBuffer (); 72 this.locale = locale; 73 if (tocData.getTopicHref() != null) { 74 requestKind = REQUEST_SHOW_IN_TOC; 75 } else if (tocData.getSelectedToc() == -1) { 76 requestKind = REQUEST_SHOW_TOCS; 77 } else { 78 requestKind = REQUEST_SHOW_CHILDREN; 79 } 80 } 81 82 public String generateTreeXml() { 83 buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); buf.append("<tree_data>\n"); 86 87 if (tocData.isRemoteHelpError()) { 88 addError(WebappResources.getString("remoteHelpErrorMessage", locale)); } 90 91 if (requestKind == REQUEST_SHOW_IN_TOC && tocData.getTopicPath() == null) { 93 addError(WebappResources.getString("CannotSync", locale)); } else { 95 serializeTocs(); 96 } 97 buf.append("</tree_data>\n"); return buf.toString(); 99 } 100 101 private void addError(String message) { 102 buf.append("<error>"); buf.append(XMLGenerator.xmlEscape(message)); 104 buf.append("</error>"); } 106 107 private void serializeTocs() { 108 ITopic[] topicPath = tocData.getTopicPath(); 109 110 int selectedToc = tocData.getSelectedToc(); 111 for (int toc=0; toc< tocData.getTocCount(); toc++) { 114 boolean shouldLoad = requestKind == REQUEST_SHOW_TOCS || toc == selectedToc; 115 if(!tocData.isEnabled(toc)){ 116 shouldLoad = false; 117 } 118 if (shouldLoad) { 119 boolean isSelected = false; if (requestKind == REQUEST_SHOW_TOCS) { 121 isSelected = toc == 0; 122 } else if (requestKind == REQUEST_SHOW_CHILDREN) { 123 isSelected = tocData.getRootPath() == null; 124 } 125 serializeToc(tocData.getTocs()[toc], toc, topicPath, isSelected); 126 } 127 } 128 } 129 130 private void serializeToc(IToc toc, int tocIndex, ITopic[] topicPath, boolean isSelected) { 131 ITopic[] topics = EnabledTopicUtils.getEnabled(toc.getTopics()); 132 if (topics.length <= 0) { 133 return; 135 } 136 137 if (requestKind == REQUEST_SHOW_CHILDREN) { 138 topicPath = getTopicPathFromRootPath(toc); 139 } 140 141 buf.append("<node"); if (toc.getLabel() != null) { 143 buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(toc.getLabel()) + '"'); } 145 buf.append('\n' + " id=\"" + XMLGenerator.xmlEscape(toc.getHref()) + "\""); 147 String href = toc.getTopic(null).getHref(); 148 if (href == null) { 149 href = "/../nav/" + tocIndex; } 151 buf.append('\n' + " HREF=\"" + XMLGenerator.xmlEscape(UrlUtil.getHelpURL(href)) + "\""); 153 buf.append('\n' + " image=\"toc_closed\""); 155 boolean serializeChildren = true; 156 if (requestKind == REQUEST_SHOW_TOCS) { 157 serializeChildren = false; 158 } 159 if (requestKind == REQUEST_SHOW_IN_TOC && topicPath.length == 0) { 160 serializeChildren = false; 161 buf.append('\n' + " is_selected=\"true\"" ); buf.append('\n' + " is_highlighted=\"true\"" ); } 164 buf.append(">\n"); if (serializeChildren) { 166 serializeChildTopics(topics, topicPath, "", isSelected); } 168 buf.append("</node>\n"); 170 } 171 172 private ITopic[] getTopicPathFromRootPath(IToc toc) { 173 ITopic[] topicPath; 174 int[] rootPath = tocData.getRootPath(); 176 if (rootPath == null) { 177 return null; 178 } 179 int pathLength = rootPath.length; 180 topicPath = new ITopic[pathLength]; 181 ITopic[] children = EnabledTopicUtils.getEnabled(toc.getTopics()); 182 for (int i = 0; i < pathLength; i++) { 183 int index = rootPath[i]; 184 if (index < children.length) { 185 topicPath[i] = children[index]; 186 children = EnabledTopicUtils.getEnabled(topicPath[i].getSubtopics()); 187 } else { 188 return null; } 190 } 191 return topicPath; 192 } 193 194 private void serializeTopic(ITopic topic, ITopic[] topicPath, boolean isSelected, String parentPath) { 195 ITopic[] subtopics = EnabledTopicUtils.getEnabled(topic.getSubtopics()); 196 buf.append("<node"); if (topic.getLabel() != null) { 198 buf.append('\n' + " title=\"" + XMLGenerator.xmlEscape(topic.getLabel()) + '"'); } 200 201 buf.append('\n' + " id=\"" + parentPath + "\""); 203 String href = topic.getHref(); 204 if (href == null) { 205 href = "/../nav/" + tocData.getSelectedToc() + '_' + parentPath; } 207 buf.append('\n' + " HREF=\"" + XMLGenerator.xmlEscape( UrlUtil.getHelpURL(href)) + '"'); 209 if (subtopics.length == 0 ) { 210 buf.append('\n' + " is_leaf=\"true\"" ); } 212 if (isSelected && requestKind == REQUEST_SHOW_IN_TOC) { 213 buf.append('\n' + " is_selected=\"true\"" ); buf.append('\n' + " is_highlighted=\"true\"" ); } 216 String icon; 217 if (subtopics.length == 0) { 218 icon = "topic"; } else if (topic.getHref() == null) { 220 icon = "container_obj"; } else { 222 icon = "container_topic"; } 224 buf.append('\n' + " image=\"" + icon + "\""); 226 buf.append(">\n"); serializeChildTopics(subtopics, topicPath, parentPath, isSelected); 228 buf.append("</node>\n"); } 230 231 private void serializeChildTopics(ITopic[] childTopics, ITopic[] topicPath, String parentPath, boolean parentIsSelected) { 232 if (parentIsSelected && requestKind == REQUEST_SHOW_CHILDREN) { 233 for (int subtopic = 0; subtopic < childTopics.length; subtopic++) { 235 serializeTopic(childTopics[subtopic], null, false, addSuffix(parentPath, subtopic)); 236 } 237 } else if (topicPath != null) { 238 for (int subtopic = 0; subtopic < childTopics.length; subtopic++) { 239 if (topicPath[0].getLabel().equals(childTopics[subtopic].getLabel())) { 240 ITopic[] newPath = null; 241 if (topicPath.length > 1) { 242 newPath = new ITopic[topicPath.length - 1]; 243 System.arraycopy(topicPath, 1, newPath, 0, topicPath.length - 1); 244 } 245 serializeTopic(childTopics[subtopic], newPath, topicPath.length == 1, addSuffix(parentPath, subtopic)); 246 } else { 247 serializeTopic(childTopics[subtopic], null, false, addSuffix(parentPath, subtopic)); 248 } 249 } 250 } 251 } 252 253 private String addSuffix(String parentPath, int subtopic) { 254 if (parentPath.length() == 0) { 255 return parentPath + subtopic; 256 } 257 return parentPath + '_' + subtopic; 258 } 259 } 260 261 } 262 | Popular Tags |