Source Viewer : WEB-INF/classes/org/apache/click/examples/page/SourceViewer.java
package org.apache.click.examples.page; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.click.Page; import org.apache.click.util.ClickUtils; import org.apache.click.util.HtmlStringBuffer; import org.apache.commons.lang.StringUtils; /** * Provides a Java source code, HTML and XML examples rendering page. */ public class SourceViewer extends BorderPage { private static final long serialVersionUID = 1L; private static final String[] JAVA_KEYWORDS = { "package", "import", "class", "public", "protected", "private", "extends", "implements", "return", "if", "while", "for", "do", "else", "try", "new", "void", "catch", "throws", "throw", "static", "final", "break", "continue", "super", "finally", "true", "false", "true;", "false;", "null", "boolean", "int", "char", "long", "float", "double", "short", "super", "this," }; private static final String[] JAVASCRIPT_KEYWORDS = { "break", "continue", "do", "else", "for", "if", "return", "while", "auto", "case", "char", "const", "default", "double", "enum", "extern", "float", "goto", "int", "long", "register", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "catch", "class", "delete", "false", "import", "new", "operator", "private", "protected", "public", "this", "throw", "true", "try", "debugger", "eval", "export", "function", "get", "null", "set", "undefined", "var", "with", "Infinity", "NaN" }; private static final String[] HTML_KEYWORDS = { "html", "head", "style", "script", "title", "link", "body", "h1", "h2", "h3", "h4", "h5", "h6", "p", "hr", "br", "span", "table", "tr", "th", "td", "a", "b", "i", "u", "ul", "ol", "li", "form", "div", "input", "fieldset", "pre", "tt", "ajax-response", "response", "%@", "%@taglib", "jsp:include", "c:forEach", "c:choose", "c:when", "c:otherwise", "fmt:formatNumber", "fmt:formatDate", "center" }; private static final String[] XML_KEYWORDS = { "click-app", "pages", "page", "excludes", "headers", "header", "format", "mode", "type", "filter-name", "filter-class", "filter-mapping", "filter", "web-app", "display-name", "description", "servlet-mapping", "servlet-name", "servlet-class", "init-param", "param-name", "param-value", "servlet", "load-on-startup", "security-constraint", "web-resource-collection", "auth-constraint", "role-name", "login-config", "auth-method", "realm-name", "security-role", "url-pattern", "welcome-file-list", "welcome-file", "Context", "ResourceLink", "menu", "?xml", "controls", "control", "listener-class", "listener", "beans", "bean", "context-param", "context:component-scan", "property", "constructor-arg", "list", "value", "ref", "beans:beans", "beans:bean", "http", "intercept-url", "form-login", "logout", "beans:property", "beans:list", "beans:ref", "authentication-provider"}; private static final String[] VELOCITY_KEYWORDS = { "#if", "#if(", "#elseif", "#elseif(", "#else", "#else(", "#end", "#set", "#set(", "#include", "#include(", "#parse", "#parse(", "#stop", "#macro", "#macro(", "#foreach", "#foreach(", "##", "#*", "*#", "#" }; private boolean isJava = false; private boolean isJavaScript = false; private boolean javaMultilineComment = false; private boolean isXml = false; private boolean isHtml = false; /** * @see Page#onGet() */ @Override public void onGet() { HttpServletRequest request = getContext().getRequest(); String filename = request.getParameter("filename"); if (filename != null) { loadFilename(filename); getModel().put("title", "Source Viewer : " + filename); } else { addModel("error", "filename not defined"); } } private void loadFilename(String filename) { ServletContext context = getContext().getServletContext(); // Orion server requires '/' prefix to find resources String resourceFilename = (filename.charAt(0) != '/') ? "/" + filename : filename; InputStream in = null; try { in = context.getResourceAsStream(resourceFilename); if (in == null && filename.endsWith(".htm")) { resourceFilename = resourceFilename.substring(0, resourceFilename.length() - 4) + ".jsp"; in = context.getResourceAsStream(resourceFilename); } if (in != null) { loadResource(in, filename); } else { addModel("error", "File " + resourceFilename + " not found"); } } catch (IOException e) { addModel("error", "Could not read " + resourceFilename); } finally { ClickUtils.close(in); } } private void loadResource(InputStream inputStream, String name) throws IOException { isJava = name.endsWith(".java"); isJavaScript = name.endsWith(".js"); isXml = name.endsWith(".xml"); isHtml = name.endsWith(".htm"); if (!isHtml) { isHtml = name.endsWith(".html"); } if (!isHtml) { isHtml = name.endsWith(".vm"); } if (!isHtml) { isHtml = name.endsWith(".jsp"); } BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); HtmlStringBuffer buffer = new HtmlStringBuffer(); // Filter out the license from displaying skipLicense(reader, buffer); String line = reader.readLine(); while (line != null) { buffer.append(getEncodedLine(line)); buffer.append("\n"); line = reader.readLine(); } addModel("source", buffer.toString()); addModel("name", name); } private void skipLicense(BufferedReader reader, HtmlStringBuffer buffer) throws IOException { // Mark reader so we can undo the read in case no license is found reader.mark(500); String line = reader.readLine(); if (line == null) { return; } line = line.trim(); // Check for license start tokens if (line.startsWith("/*") || line.startsWith("<!--")) { line = reader.readLine(); while (line != null) { line = line.trim(); // Check for license end tokens if (line.startsWith("*/") || line.startsWith("-->")) { // Move the reader past the end of license token line = reader.readLine(); break; } line = reader.readLine(); } } else { // undo the read reader.reset(); line = null; } // Gobble whitespace while (line != null) { if (!"".equals(line.trim())) { // If the line is not empty, write it to buffer and break loop buffer.append(getEncodedLine(line)); buffer.append("\n"); break; } line = reader.readLine(); } } private String getEncodedLine(String line) { if (isJava) { line = ClickUtils.escapeHtml(line); // Check if line is part of multiline comment if (isMultilineComment(line)) { line = renderComment(line); } else { // Check if line contains singleline comment String comment = ""; if (hasComment(line)) { comment = getComment(line); comment = renderComment(comment); line = removeComment(line); } if (StringUtils.isNotBlank(line)) { for (int i = 0; i < JAVA_KEYWORDS.length; i++) { String keyword = JAVA_KEYWORDS[i]; line = renderJavaKeywords(line, keyword); } } line = line + comment; } } else if (isJavaScript) { line = ClickUtils.escapeHtml(line); // Check if line is part of multiline comment if (isMultilineComment(line)) { line = renderComment(line); } else { // Check if line contains singleline comment String comment = ""; if (hasComment(line)) { comment = getComment(line); comment = renderComment(comment); line = removeComment(line); } if (StringUtils.isNotBlank(line)) { for (int i = 0; i < JAVASCRIPT_KEYWORDS.length; i++) { String keyword = JAVASCRIPT_KEYWORDS[i]; // Reuse renderJavaKeywords method line = renderJavaKeywords(line, keyword); } } line = line + comment; } } else if (isHtml) { line = ClickUtils.escapeHtml(line); for (int i = 0; i < HTML_KEYWORDS.length; i++) { String keyword = HTML_KEYWORDS[i]; line = renderHtmlKeywords(line, keyword); } for (int i = 0; i < VELOCITY_KEYWORDS.length; i++) { String keyword = VELOCITY_KEYWORDS[i]; line = renderVelocityKeywords(line, keyword); } String renderedDollar = "<font color=\"red\">$</font>"; line = StringUtils.replace(line, "$", renderedDollar); } else if (isXml) { line = ClickUtils.escapeHtml(line); for (int i = 0; i < XML_KEYWORDS.length; i++) { String keyword = XML_KEYWORDS[i]; line = renderXmlKeywords(line, keyword); } } else { line = ClickUtils.escapeHtml(line); } return line; } private String renderJavaKeywords(String line, String token) { String markupToken = renderJavaToken(token); line = StringUtils.replace (line, " " + token + " ", " " + markupToken + " "); if (line.startsWith(token)) { line = markupToken + line.substring(token.length()); } if (line.endsWith(token)) { line = line.substring(0, line.length() - token.length()) + markupToken; } return line; } private boolean hasComment(String line) { return line.indexOf("//") != -1; } private String removeComment(String line) { int lineCommentStart = line.indexOf("//"); if (lineCommentStart != -1) { line = line.substring(0, lineCommentStart); } return line; } private String getComment(String line) { int lineCommentStart = line.indexOf("//"); if (lineCommentStart != -1) { return line.substring(lineCommentStart); } return ""; } private boolean isMultilineComment(String line) { boolean isComment = false; line = line.trim(); if (line.startsWith("/*")) { isComment = true; javaMultilineComment = true; } if (line.endsWith("*/")) { isComment = true; javaMultilineComment = false; } if (javaMultilineComment && line.startsWith("*")) { isComment = true; } return isComment; } private String renderVelocityKeywords(String line, String token) { String markupToken = renderVelocityToken(token); line = StringUtils.replace (line, " " + token + " ", " " + markupToken + " "); if (line.startsWith(token)) { line = markupToken + line.substring(token.length()); } if (line.endsWith(token)) { line = line.substring(0, line.length() - token.length()) + markupToken; } return line; } private String renderHtmlKeywords(String line, String token) { String markupToken = "<" + token + ">"; String renderedToken = "<" + renderHtmlToken(token) + ">"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "<" + token + "/>"; renderedToken = "<" + renderHtmlToken(token) + "/>"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "</" + token + ">"; renderedToken = "</" + renderHtmlToken(token) + ">"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "<" + token + " "; renderedToken = "<" + renderHtmlToken(token) + " "; line = StringUtils.replace(line, markupToken, renderedToken); return line; } private String renderXmlKeywords(String line, String token) { String markupToken = "<" + token + ">"; String renderedToken = "<" + renderXmlToken(token) + ">"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "<" + token + "/>"; renderedToken = "<" + renderXmlToken(token) + "/>"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "</" + token + ">"; renderedToken = "</" + renderXmlToken(token) + ">"; line = StringUtils.replace(line, markupToken, renderedToken); markupToken = "<" + token + " "; renderedToken = "<" + renderXmlToken(token) + " "; line = StringUtils.replace(line, markupToken, renderedToken); return line; } private String renderHtmlToken(String token) { return "<font color=\"#00029F\">" + token + "</font>"; } private String renderXmlToken(String token) { return "<font color=\"#00029F\">" + token + "</font>"; } private String renderVelocityToken(String token) { return "<font color=\"red\">" + token + "</font>"; } private String renderJavaToken(String token) { return "<font color=\"#7f0055\"><b>" + token + "</b></font>"; } private String renderComment(String comment) { return "<font color=\"#3F7F5F\">" + comment + "</font>"; } }