From ee478f28c2d4a3d0c85d9135716a12ec194c1fe6 Mon Sep 17 00:00:00 2001 From: "Donald J. Brown" Date: Sun, 1 Oct 2006 11:02:46 +0000 Subject: [PATCH] Added a view source capability to the showcase WW-1461 git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@451738 13f79535-47bb-0310-9956-ffa450edef68 --- apps/showcase/pom.xml | 28 ++- .../showcase/source/ViewSourceAction.java | 217 ++++++++++++++++++ apps/showcase/src/main/resources/struts.xml | 6 +- .../main/webapp/WEB-INF/decorators/main.jsp | 18 +- apps/showcase/src/main/webapp/WEB-INF/web.xml | 6 +- apps/showcase/src/main/webapp/viewSource.jsp | 53 +++++ 6 files changed, 321 insertions(+), 7 deletions(-) create mode 100644 apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java create mode 100644 apps/showcase/src/main/webapp/viewSource.jsp diff --git a/apps/showcase/pom.xml b/apps/showcase/pom.xml index 534164dd5..5ebfe74fc 100644 --- a/apps/showcase/pom.xml +++ b/apps/showcase/pom.xml @@ -47,7 +47,7 @@ struts2-sitemesh-plugin ${pom.version} - + org.apache.struts struts2-tiles-plugin @@ -61,6 +61,22 @@ provided + + + velocity + velocity + 1.4 + true + + + + velocity-tools + velocity-tools + 1.1 + true + + + opensymphony sitemesh @@ -128,5 +144,15 @@ + + + + src/main/java + + **/*.java + + + + diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java new file mode 100644 index 000000000..327bfe489 --- /dev/null +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java @@ -0,0 +1,217 @@ +/* + * $Id: CreatePerson.java 420385 2006-07-10 00:57:05Z mrdon $ + * + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.struts2.showcase.source; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContext; + +import org.apache.struts2.util.ServletContextAware; + +import com.opensymphony.xwork2.ActionSupport; +import com.opensymphony.xwork2.util.ClassLoaderUtil; + +/** + * Processes configuration, page, and action class paths to create snippets + * of the files for display. + */ +public class ViewSourceAction extends ActionSupport implements ServletContextAware { + + private String page; + private String className; + private String config; + + private List pageLines; + private List classLines; + private List configLines; + + private int configLine; + private int padding = 10; + + private ServletContext servletContext; + + public String execute() throws MalformedURLException, IOException { + + if (page != null) { + + InputStream in = ClassLoaderUtil.getResourceAsStream(page.substring(page.indexOf("//")+1), getClass()); + page = page.replace("//", "/"); + + if (in == null) { + in = servletContext.getResourceAsStream(page); + while (in == null && page.indexOf('/', 1) > 0) { + page = page.substring(page.indexOf('/', 1)); + in = servletContext.getResourceAsStream(page); + } + } + pageLines = read(in, -1); + } + + if (className != null) { + className = "/"+className.replace('.', '/') + ".java"; + InputStream in = getClass().getResourceAsStream(className); + if (in == null) { + in = servletContext.getResourceAsStream("/WEB-INF/src"+className); + } + classLines = read(in, -1); + } + + if (config != null) { + int pos = config.lastIndexOf(':'); + configLine = Integer.parseInt(config.substring(pos+1)); + config = config.substring(0, pos).replace("//", "/"); + configLines = read(new URL(config).openStream(), configLine); + } + return SUCCESS; + } + + /** + * @param className the className to set + */ + public void setClassName(String className) { + this.className = className; + } + + /** + * @param config the config to set + */ + public void setConfig(String config) { + this.config = config; + } + + /** + * @param page the page to set + */ + public void setPage(String page) { + this.page = page; + } + + /** + * @param padding the padding to set + */ + public void setPadding(int padding) { + this.padding = padding; + } + + + + /** + * @return the classLines + */ + public List getClassLines() { + return classLines; + } + + /** + * @return the configLines + */ + public List getConfigLines() { + return configLines; + } + + /** + * @return the pageLines + */ + public List getPageLines() { + return pageLines; + } + + /** + * @return the className + */ + public String getClassName() { + return className; + } + + /** + * @return the config + */ + public String getConfig() { + return config; + } + + /** + * @return the page + */ + public String getPage() { + return page; + } + + /** + * @return the configLine + */ + public int getConfigLine() { + return configLine; + } + + /** + * @return the padding + */ + public int getPadding() { + return padding; + } + + /** + * Reads in a strea, optionally only including the target line number + * and its padding + * + * @param in The input stream + * @param targetLineNumber The target line number, negative to read all + * @return A list of lines + */ + private List read(InputStream in, int targetLineNumber) { + List snippet = null; + if (in != null) { + snippet = new ArrayList(); + int startLine = 0; + int endLine = Integer.MAX_VALUE; + if (targetLineNumber > 0) { + startLine = targetLineNumber - padding; + endLine = targetLineNumber + padding; + } + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + + int lineno = 0; + String line; + while ((line = reader.readLine()) != null) { + lineno++; + if (lineno >= startLine && lineno <= endLine) { + snippet.add(line); + } + } + } catch (Exception ex) { + // ignoring as snippet not available isn't a big deal + } + } + return snippet; + } + + public void setServletContext(ServletContext arg0) { + this.servletContext = arg0; + } + + +} diff --git a/apps/showcase/src/main/resources/struts.xml b/apps/showcase/src/main/resources/struts.xml index 0a942327f..14e5a388b 100644 --- a/apps/showcase/src/main/resources/struts.xml +++ b/apps/showcase/src/main/resources/struts.xml @@ -8,8 +8,6 @@ - - @@ -57,6 +55,10 @@ showcase.jsp + + + viewSource.jsp + /date.jsp diff --git a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp index 37cf7d807..d80afbedf 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp +++ b/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp @@ -5,6 +5,18 @@ response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); + + // Calculate the view sources url + String sourceUrl = request.getContextPath()+"/viewSource.action"; + com.opensymphony.xwork2.ActionInvocation inv = com.opensymphony.xwork2.ActionContext.getContext().getActionInvocation(); + org.apache.struts2.dispatcher.mapper.ActionMapping mapping = org.apache.struts2.ServletActionContext.getActionMapping(); + if (inv != null) { + sourceUrl += "?config="+inv.getProxy().getConfig().getLocation().getURI()+":"+inv.getProxy().getConfig().getLocation().getLineNumber(); + sourceUrl += "&className="+inv.getProxy().getConfig().getClassName(); + sourceUrl += "&page="+mapping.getNamespace()+"/"+((org.apache.struts2.dispatcher.StrutsResultSupport)inv.getResult()).getLastFinalLocation(); + } else { + sourceUrl += "?page="+request.getServletPath(); + } %> <%@ taglib uri="sitemesh-decorator" prefix="decorator" %> @@ -89,7 +101,11 @@ - +
+

+ View Sources +

+
diff --git a/apps/showcase/src/main/webapp/WEB-INF/web.xml b/apps/showcase/src/main/webapp/WEB-INF/web.xml index 8cbb3c9b0..3f2a009d6 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/web.xml +++ b/apps/showcase/src/main/webapp/WEB-INF/web.xml @@ -1,6 +1,6 @@ - - - + + + Struts Showcase Application diff --git a/apps/showcase/src/main/webapp/viewSource.jsp b/apps/showcase/src/main/webapp/viewSource.jsp new file mode 100644 index 000000000..eac6c32ec --- /dev/null +++ b/apps/showcase/src/main/webapp/viewSource.jsp @@ -0,0 +1,53 @@ +<%@ taglib prefix="s" uri="/struts-tags" %> + + + View Sources + + + "> + "> + " media="print"> + + + + +

View Sources

+ + + +

${empty page ? "Unknown page" : page}

+
+
+${row.count}: 
+
+
+ +

${empty config ? "Unknown configuration" : config}

+
+
+
+${configLine - padding + row.count - 1}: 
+${configLine - padding + row.count - 1}: 
+
+
+ +

${empty className ? "Unknown or unavailable Action class" : className}

+
+
+${row.count}: 
+
+
+ +
+ + +