You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2009/03/07 00:31:05 UTC
svn commit: r751135 [2/3] - in /incubator/jspwiki/trunk: ./ src/WebContent/
src/WebContent/WEB-INF/ src/WebContent/WEB-INF/classes/
src/WebContent/WEB-INF/classes/templates/ src/WebContent/scripts/
src/WebContent/templates/default/ src/WebContent/templ...
Modified: incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default_zh_CN.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default_zh_CN.properties?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default_zh_CN.properties (original)
+++ incubator/jspwiki/trunk/src/WebContent/WEB-INF/classes/templates/default_zh_CN.properties Fri Mar 6 23:31:03 2009
@@ -43,10 +43,6 @@
diff.goback=\u8fd4\u56de {0} \u6216 {1}
diff.versionhistory={0} \u9875\u9762\u4fe1\u606f
diff.nodiff=\u6ca1\u6709\u5dee\u5f02\u3002
-# EditContent.jsp
-
-edit.locked=\u7528\u6237 <strong>{0}</strong> \u5df2\u5f00\u59cb\u7f16\u8f91\u8be5\u9875\u9762\uff0c\u4f46\u8fd8\u672a\u4fdd\u5b58\u3002\u6211\u4e0d\u4f1a\u963b\u6b62\u60a8\u7f16\u8f91\u8be5\u9875\u9762\uff0c\u4f46\u662f\u8981\u77e5\u9053\u5176\u4ed6\u4eba\u53ef\u80fd\u4f1a\u5f88\u70e6\u3002\u7b49\u5f85\u9501\u5b9a\u8fc7\u671f\u6216\u522b\u4eba\u505c\u6b62\u7f16\u8f91\uff0c\u8fd9\u6837\u4f1a\u6bd4\u8f83\u793c\u8c8c\u3002\u9501\u5b9a\u4f1a\u5728 {1} \u5206\u949f\u540e\u8fc7\u671f\u3002
-edit.restoring=\u5c06\u6062\u590d\u7248\u672c {0}\u3002\u5355\u51fb\u201c\u4fdd\u5b58\u201d\u6765\u8fdb\u884c\u6062\u590d\u3002\u4e5f\u53ef\u4ee5\u5728\u6062\u590d\u9875\u9762\u524d\u8fdb\u884c\u7f16\u8f91\u3002
edit.tab.attachments=\u9644\u4ef6
edit.tab.help=\u5e2e\u52a9
edit.tab.edit=\u7f16\u8f91
@@ -98,8 +94,8 @@
group.tab=\u67e5\u770b\u7ec4
#replaced by grp.deletegroup.confirm
-#group.areyousure=Are you sure you want to permanently delete group "{0}"? \
-# Users might not be able to access pages whose ACLS contain this group. \\n\\n \
+#group.areyousure=Are you sure you want to permanently delete group "{0}"? \
+# Users might not be able to access pages whose ACLS contain this group. \\n\\n \
# If you click OK, the group will be removed immediately.
group.doesnotexist=\u8be5\u7ec4\u4e0d\u5b58\u5728\u3002
group.createsuggestion=\u4e3a\u4ec0\u4e48\u4e0d {0}
@@ -376,18 +372,10 @@
# 0 : Application Name
# 1 : Page name
view.title.view={0}\uff1a{1}
-# The built-in editors also have their localized strings in this file.
-
-editor.plain.name=\u60a8\u7684\u540d\u79f0(<span class='accesskey'>N</span>)
-editor.plain.remember=\u662f\u5426\u8bb0\u4f4f\u6211\u7684\u4fe1\u606f\uff1f
editor.plain.email=\u4e3b\u9875\u6216\u7535\u5b50\u90ae\u4ef6(<span class='accesskey'>M</span>)
-editor.plain.save.submit=\u4fdd\u5b58
editor.plain.save.title=\u4fdd\u5b58 [ s ]
-editor.plain.preview.submit=\u9884\u89c8
editor.plain.preview.title=\u9884\u89c8 [ v ]
-editor.plain.cancel.submit=\u53d6\u6d88
editor.plain.cancel.title=\u53d6\u6d88\u7f16\u8f91\u3002\u60a8\u6240\u505a\u7684\u66f4\u6539\u5c06\u4e22\u5931\u3002[ q ]
-editor.plain.changenote=\u66f4\u6539\u6ce8\u91ca
editor.commentsignature=\u6ce8\u91ca\u7b7e\u540d
editor.plain.toolbar=\u5de5\u5177\u680f
editor.plain.find=\u67e5\u627e
@@ -407,9 +395,6 @@
editor.plain.smartpairs.title=\u81ea\u52a8\u8f93\u5165\u6210\u5bf9\u7684\u7b26\u53f7 () [] {} <> "" ''
editor.plain.tabcompletion=Tab \u5b8c\u6210\uff08\u5173\u952e\u5b57 + Tab\uff09
editor.plain.tabcompletion.title=\u5c06\u5173\u952e\u5b57\u81ea\u52a8\u6269\u5c55\u4e3a Wiki \u6807\u8bb0
-#editor.plain.editassist=Edit Assist
-#editor.plain.editassist.title=Toggle Edit Assist buttons
-editor.plain.sneakpreview=\u62a2\u5148\u9884\u89c8
editor.plain.sneakpreview.title=\u62a2\u5148\u9884\u89c8\u3002\u5728\u6587\u672c\u6846\u5916\u9762\u70b9\u51fb\u53ef\u4ee5\u5237\u65b0\u62a2\u5148\u9884\u89c8\u533a\u57df\u3002
editor.plain.tbLink.title=\u94fe\u63a5 - \u63d2\u5165 Wiki \u94fe\u63a5
editor.plain.tbH1.title=h1 - \u63d2\u5165\u6807\u9898\u6837\u5f0f1
Modified: incubator/jspwiki/trunk/src/WebContent/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/WEB-INF/web.xml?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/WEB-INF/web.xml (original)
+++ incubator/jspwiki/trunk/src/WebContent/WEB-INF/web.xml Fri Mar 6 23:31:03 2009
@@ -96,13 +96,6 @@
This is new in 2.4. This defines a servlet filter which filters all requests.
-->
- <!--
- <filter>
- <filter-name>WikiJSPFilter</filter-name>
- <filter-class>org.apache.wiki.ui.WikiJSPFilter</filter-class>
- </filter>
- -->
-
<filter-mapping>
<filter-name>WikiServletFilter</filter-name>
<url-pattern>/attach/*</url-pattern>
@@ -147,17 +140,6 @@
</filter-mapping>
<!--
- <filter-mapping>
- <filter-name>WikiJSPFilter</filter-name>
- <url-pattern>/wiki/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>WikiJSPFilter</filter-name>
- <url-pattern>*.jsp</url-pattern>
- </filter-mapping>
- -->
-
- <!--
HttpSessionListener used for managing WikiSessions.
-->
<listener>
Modified: incubator/jspwiki/trunk/src/WebContent/Wiki.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/Wiki.jsp?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/Wiki.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/Wiki.jsp Fri Mar 6 23:31:03 2009
@@ -1,8 +1,15 @@
<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
<s:useActionBean beanclass="org.apache.wiki.action.ViewActionBean" event="view" executeResolution="true" id="wikiActionBean" />
-<s:layout-render name="/templates/default/ViewLayout.jsp">
+<s:layout-render name="/templates/default/DefaultLayout.jsp">
+ <%-- If wiki page is current, allow search engines to spider it --%>
+ <wiki:CheckVersion mode="latest">
+ <s:layout-component name="head.meta.robots">
+ <meta name="robots" content="index,follow" />
+ </s:layout-component>
+ </wiki:CheckVersion>
+
<s:layout-component name="content">
<wiki:NoSuchPage>
<fmt:message key="common.nopage">
Modified: incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-edit.js
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-edit.js?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-edit.js (original)
+++ incubator/jspwiki/trunk/src/WebContent/scripts/jspwiki-edit.js Fri Mar 6 23:31:03 2009
@@ -496,7 +496,7 @@
var ta = this.textarea,
isOn = checkbox.checked;
- $('sneakpreview').empty();
+ $('livepreview').empty();
ta.removeEvents('preview');
Wiki.prefs.set('autopreview',isOn);
@@ -506,7 +506,7 @@
},
refreshPreview: function(){
- var preview = $('sneakpreview');
+ var preview = $('livepreview');
$('previewSpin').show();
new Ajax( Wiki.TemplateUrl + "/AJAXPreview.jsp?page="+Wiki.PageName, {
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/AttachmentTab.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/AttachmentTab.jsp?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/AttachmentTab.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/AttachmentTab.jsp Fri Mar 6 23:31:03 2009
@@ -27,7 +27,7 @@
<div id="addattachment">
<h3><fmt:message key="attach.add" /></h3>
<wiki:Permission permission="upload">
- <s:form beanclass="org.apache.wiki.action.ViewActionBean" class="wikiform" id="uploadform" acceptcharset="UTF-8">
+ <s:form beanclass="org.apache.wiki.action.UploadActionBean" class="wikiform" id="uploadform" acceptcharset="UTF-8">
<s:param name="progressid" value="<%=progressId%>" />
<s:param name="page" value="${wikiActionBean.page.name}" />
<table>
@@ -35,8 +35,13 @@
<td colspan="2"><div class="formhelp"><fmt:message key="attach.add.info" /></div></td>
</tr>
<tr>
+ <td span="2"><s:errors field="newAttachments" /></td>
+ </tr>
+ <tr>
<td><s:label for="attachfile0" name="attach.add.selectfile" /></td>
- <td><s:file name="newAttachments[0]" id="attachfile0" /></td>
+ <td><s:file name="newAttachments[0]" id="attachfile0" /><br/>
+ <s:file name="newAttachments[1]" id="attachfile1" /><br/>
+ <s:file name="newAttachments[2]" id="attachfile2" /></td>
</tr>
<tr>
<td><s:label for="attachnote" name="attach.add.changenote" /></td>
@@ -53,7 +58,6 @@
</table>
</s:form>
- <wiki:Messages div="error" />
</wiki:Permission>
<wiki:Permission permission="!upload">
<div class="formhelp"><fmt:message key="attach.add.permission" /></div>
Copied: incubator/jspwiki/trunk/src/WebContent/templates/default/DefaultLayout.jsp (from r746887, incubator/jspwiki/trunk/src/WebContent/templates/default/ViewLayout.jsp)
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/DefaultLayout.jsp?p2=incubator/jspwiki/trunk/src/WebContent/templates/default/DefaultLayout.jsp&p1=incubator/jspwiki/trunk/src/WebContent/templates/default/ViewLayout.jsp&r1=746887&r2=751135&rev=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/ViewLayout.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/DefaultLayout.jsp Fri Mar 6 23:31:03 2009
@@ -1,29 +1,144 @@
<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
+<%@ page import="org.apache.wiki.WikiContext" %>
+<%@ page import="org.apache.wiki.action.WikiContextFactory" %>
+<%--
+ This file contains the default layout used by all JSPWiki 3 pages.
+ The default layout contains the HTML doctype declaration, header,
+ and page layout. It can be customized in the following ways:
+
+ 1) Top-level JSPs can define default components, as defined by
+ Stripes <s:layout-component name="foo"> elements. Named components
+ that can be overridden include:
+
+ head.title : The HTML page title, which will be rendered
+ in the <title> element. Default=wiki: pagename
+ stylesheet : Link tags to external stylesheets. Default=blank
+ inlinecss : Inline stylesheets. Default=blank
+ script : JavaScript <script> elements. Default=blank
+ jslocalizedstrings : Localized scripts for JavaScript
+ functions. Default=blank
+ jsfunction : JavaScript functions. Default=blank
+ head.meta.robots : Search engine options. Default=noindex,nofollow
+ content : The page contents. Default=blank
+
+ 2) DefaultLayout injects additional JSPs that are meant to be
+ customized. These include:
+
+ commonheader.jsp : A "local header" that can contain company logos
+ or other markup. Default=blank
+
+--%>
<s:layout-definition>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
+ <%--
+
+ Title: by default, use the "view page" title
+ --%>
+ <s:layout-component name="head.title">
<fmt:message key="view.title.view">
<fmt:param><wiki:Variable var="ApplicationName" /></fmt:param>
<fmt:param><wiki:PageName/></fmt:param>
</fmt:message>
+ </s:layout-component>
</title>
- <wiki:Include page="commonheader.jsp" />
- <wiki:CheckVersion mode="notlatest">
- <meta name="robots" content="noindex,nofollow" />
- </wiki:CheckVersion>
- <wiki:CheckRequestContext context="diff|info">
- <meta name="robots" content="noindex,nofollow" />
- </wiki:CheckRequestContext>
- <wiki:CheckRequestContext context="!view">
- <meta name="robots" content="noindex,follow" />
+ <%--
+
+ CSS stylesheets
+ --%>
+ <link rel="stylesheet" media="screen, projection, print" type="text/css" href="<wiki:Link format='url' templatefile='jspwiki.css' />" />
+ <%-- put this at the top, to avoid double load when not yet cached --%>
+ <link rel="stylesheet" type="text/css" media="print" href="<wiki:Link format='url' templatefile='jspwiki_print.css' />" />
+ <link rel="alternate stylesheet" type="text/css" href="<wiki:Link format='url' templatefile='jspwiki_print.css' />" title="Print friendly" />
+ <link rel="alternate stylesheet" type="text/css" href="<wiki:Link format='url' templatefile='jspwiki.css' />" title="Standard" />
+ <s:layout-component name="stylesheet" />
+ <s:layout-component name="inlinecss" />
+ <%--
+
+ Links to favicon and common pages
+ --%>
+ <link rel="search" href="<wiki:LinkTo format='url' page='FindPage' />" title='Search ${wikiEngine.applicationName}' />
+ <link rel="help" href="<wiki:LinkTo format='url' page='TextFormattingRules' />" title="Help" />
+ <link rel="start" href="<wiki:LinkTo format='url' page='${wikiEngine.frontPage}' />" title="Front page" />
+ <link rel="shortcut icon" type="image/x-icon" href="<wiki:Link format='url' jsp='images/favicon.ico' />" />
+ <%-- ie6 needs next line --%>
+ <link rel="icon" type="image/x-icon" href="<wiki:Link format='url' jsp='images/favicon.ico' />" />
+ <%--
+
+ Support for the universal edit button
+ (www.universaleditbutton.org)
+ --%>
+ <wiki:CheckRequestContext context='view|info|diff|upload'>
+ <wiki:Permission permission="edit">
+ <wiki:PageType type="page">
+ <link rel="alternate" type="application/x-wiki" href="<wiki:EditLink format='url' />" title="<fmt:message key='actions.edit.title' />" />
+ </wiki:PageType>
+ </wiki:Permission>
</wiki:CheckRequestContext>
+ <%--
+
+ Skins: extra stylesheets, extra javascript
+ --%>
+ <c:if test='${(!empty prefs.Skin) && (prefs.Skin!="PlainVanilla") }'>
+ <link rel="stylesheet" type="text/css" media="screen, projection, print" href="<wiki:Link format='url' templatefile='skins/${prefs.Skin}/skin.css' />" />
+ <script type="text/javascript" src="<wiki:Link format='url' templatefile='skins/${prefs.Skin}/skin.js' />"></script>
+ </c:if>
+ <%--
+
+ JavaScript
+ --%>
+ <script type="text/javascript" src="<wiki:Link format='url' jsp='scripts/mootools.js' />"></script>
+ <script type="text/javascript" src="<wiki:Link format='url' jsp='scripts/prettify.js' />"></script>
+ <script type="text/javascript" src="<wiki:Link format='url' jsp='scripts/jspwiki-common.js' />"></script>
+ <script type="text/javascript" src="<wiki:Link format='url' jsp='scripts/jspwiki-commonstyles.js' />"></script>
+ <s:layout-component name="script" />
+ <%--
+
+ JavaScript: localized strings and functions
+ --%>
+ <script type="text/javascript">//<![CDATA[
+ /* Localized javascript strings: LocalizedStrings[] */
+ <s:layout-component name="jslocalizedstrings" />
+ <s:layout-component name="jsfunction" />
+ //]]></script>
+ <%--
+
+ Meta tags
+ --%>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="wikiContext" content='${wikiContext.requestContext}' />
+ <meta name="wikiBaseUrl" content='<wiki:BaseURL/>' />
+ <meta name="wikiPageUrl" content='<wiki:Link format="url" page="#$%" />' />
+ <meta name="wikiEditUrl" content='<wiki:EditLink format="url" />' />
+ <meta name="wikiJsonUrl" content='<%= WikiContextFactory.findContext(pageContext).getURL( WikiContext.NONE, "JSON-RPC" ) %>' /><%--unusual pagename--%>
+ <meta name="wikiPageName" content='<wiki:Variable var="pagename" />' /><%--pagename without blanks--%>
+ <meta name="wikiUserName" content='<wiki:UserName/>' />
+ <meta name="wikiTemplateUrl" content='<wiki:Link format="url" templatefile="" />' />
+ <meta name="wikiApplicationName" content='${wikiEngine.applicationName}' />
+ <%--
+
+ Search engines: by default, page is not indexed or followed
+ --%>
+ <s:layout-component name="head.meta.robots">
+ <meta name="robots" content="noindex,nofollow" />
+ </s:layout-component>
+ <%--
+
+ RSS Feed discovery
+ --%>
+ <wiki:FeedDiscovery/>
+
+ <wiki:Include page="localheader.jsp" />
+
+
</head>
- <body class="view">
+ <body class="${wikiContext.requestContext}">
<div id="wikibody" class="${prefs.Orientation}">
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/EditContent.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/EditContent.jsp?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/EditContent.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/EditContent.jsp Fri Mar 6 23:31:03 2009
@@ -1,7 +1,8 @@
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
+<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
<%@ page import="org.apache.wiki.*" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
<%@ page import="org.apache.wiki.action.WikiContextFactory" %>
<%
@@ -11,51 +12,28 @@
if( attCount != 0 ) attTitle += " (" + attCount + ")";
%>
-<wiki:TabbedSection defaultTab="editcontent">
+<wiki:TabbedSection defaultTab="editcontent">
+
<wiki:Tab id="editcontent" titleKey="edit.tab.edit" accesskey="e">
- <wiki:CheckLock mode="locked" id="lock">
- <div class="error">
- <fmt:message key="edit.locked">
- <fmt:param><c:out value="${lock.locker}" /></fmt:param>
- <fmt:param><c:out value="${lock.timeLeft}" /></fmt:param>
- </fmt:message>
- </div>
- </wiki:CheckLock>
-
- <wiki:CheckVersion mode="notlatest">
- <div class="warning">
- <fmt:message key="edit.restoring">
- <fmt:param><wiki:PageVersion/></fmt:param>
- </fmt:message>
- </div>
- </wiki:CheckVersion>
-
- <wiki:Editor/>
-
-</wiki:Tab>
+ <s:errors />
+ <s:messages />
+ <wiki:Editor/>
+ </wiki:Tab>
<wiki:PageExists>
-
- <wiki:Tab id="attach" title="<%= attTitle %>" accesskey="a">
- <wiki:Include page="AttachmentTab.jsp" />
- </wiki:Tab>
-
- <wiki:Tab id="info" titleKey="info.tab"
- url="<%=c.getURL(WikiContext.INFO, c.getPage().getName())%>"
- accesskey="i" >
- </wiki:Tab>
-
+ <wiki:Tab id="attach" title="<%= attTitle %>" accesskey="a" url="Attachments.jsp?page=${wikiActionBean.page.name}" />
+ <wiki:Tab id="info" titleKey="info.tab" url="PageInfo.jsp?page=${wikiActionBean.page.name}" accesskey="i" />
</wiki:PageExists>
-
+
<wiki:Tab id="edithelp" titleKey="edit.tab.help" accesskey="h">
- <wiki:InsertPage page="EditPageHelp" />
- <wiki:NoSuchPage page="EditPageHelp">
- <div class="error">
- <fmt:message key="comment.edithelpmissing">
- <fmt:param><wiki:EditLink page="EditPageHelp">EditPageHelp</wiki:EditLink></fmt:param>
- </fmt:message>
- </div>
- </wiki:NoSuchPage>
+ <wiki:InsertPage page="EditPageHelp" />
+ <wiki:NoSuchPage page="EditPageHelp">
+ <div class="error">
+ <fmt:message key="comment.edithelpmissing">
+ <fmt:param><wiki:EditLink page="EditPageHelp">EditPageHelp</wiki:EditLink></fmt:param>
+ </fmt:message>
+ </div>
+ </wiki:NoSuchPage>
</wiki:Tab>
</wiki:TabbedSection>
\ No newline at end of file
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/PreviewContent.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/PreviewContent.jsp?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/PreviewContent.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/PreviewContent.jsp Fri Mar 6 23:31:03 2009
@@ -1,24 +1,51 @@
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
+<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
+<%@ page import="org.apache.wiki.filters.SpamFilter" %>
<%@ page import="org.apache.wiki.ui.EditorManager" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.*" %>
-<%-- Inserts page content for preview. --%>
<wiki:TabbedSection>
-<wiki:Tab id="previewcontent" titleKey="preview.tab">
-
- <div class="information">
- <fmt:message key="preview.info" />
- <wiki:Editor/>
- </div>
-
- <div class="previewcontent">
- <wiki:Translate><%=EditorManager.getEditedText(pageContext)%></wiki:Translate>
- </div>
-
- <div class="information">
- <fmt:message key="preview.info" />
- </div>
+ <wiki:Tab id="previewcontent" titleKey="preview.tab">
+
+ <div class="information">
+ <fmt:message key="preview.info" />
+ </div>
+ <s:errors />
+ <s:messages />
-</wiki:Tab>
+ <s:form beanclass="org.apache.wiki.action.EditActionBean" method="post" acceptcharset="UTF-8"
+ class="wikiform" id="editform" enctype="application/x-www-form-urlencoded">
+
+ <p>
+ <%-- Edit.jsp & Comment.jsp rely on these being found. So be careful, if you make changes. --%>
+ <s:hidden name="author" />
+ <s:hidden name="changenote" />
+ <s:hidden name="link" />
+ <s:hidden name="page" value="${wikiActionBean.page.name}" />
+ <s:hidden name="remember" />
+ <s:hidden name="text" />
+ <s:hidden name="<%=SpamFilter.getHashFieldName(request)%>"><c:out value="${lastchange}" /></s:hidden>
+ </p>
+ <div id="submitbuttons">
+ <c:set var="editTitle"><fmt:message key="editor.preview.edit.title"/></c:set>
+ <s:submit name="edit" accesskey="e" title="${editTitle}"><fmt:message key="editor.preview.edit.submit" /></s:submit>
+ <c:set var="saveTitle"><fmt:message key='editor.preview.save.title'/></c:set>
+ <s:submit name="save" accesskey="s" title="${saveTitle}" />
+ <c:set var="cancelTitle"><fmt:message key='editor.preview.cancel.title'/></c:set>
+ <s:submit name="cancel" accesskey="q" title="${cancelTitle}" />
+ </div>
+
+ </s:form>
+
+ <div class="previewcontent">
+ <wiki:Translate>${wikiActionBean.text}</wiki:Translate>
+ </div>
+
+ <div class="information">
+ <fmt:message key="preview.info" />
+ </div>
+
+ </wiki:Tab>
</wiki:TabbedSection>
\ No newline at end of file
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/editors/plain.jsp
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/editors/plain.jsp?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/editors/plain.jsp (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/editors/plain.jsp Fri Mar 6 23:31:03 2009
@@ -1,220 +1,163 @@
-<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
-<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
-<%@ page import="org.apache.wiki.*" %>
-<%@ page import="org.apache.wiki.auth.*" %>
-<%@ page import="org.apache.wiki.auth.permissions.*" %>
-<%@ page import="org.apache.wiki.tags.*" %>
-<%@ page import="org.apache.wiki.filters.SpamFilter" %>
-<%@ page import="org.apache.wiki.ui.*" %>
-<%@ page import="org.apache.wiki.rpc.*" %>
-<%@ page import="org.apache.wiki.rpc.json.*" %>
-<%@ page import="org.apache.wiki.api.WikiPage" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="stripes" %>
-<%@ page import="org.apache.wiki.action.WikiContextFactory" %>
+<%@ taglib uri="http://jakarta.apache.org/jspwiki.tld" prefix="wiki" %>
+<%@ taglib uri="http://stripes.sourceforge.net/stripes.tld" prefix="s" %>
+<%@ page import="org.apache.wiki.filters.SpamFilter" %>
<%@ page import="org.apache.wiki.util.TextUtil" %>
<%--
This is a plain editor for JSPWiki.
--%>
-<%
- WikiContext context = WikiContextFactory.findContext( pageContext );
- WikiEngine engine = context.getEngine();
-
- String contextPath = request.getContextPath();
-
- TemplateManager.addResourceRequest( context, "script", contextPath + "/scripts/jspwiki-edit.js" );
- TemplateManager.addResourceRequest( context, "script", contextPath + "/scripts/posteditor.js" );
- String usertext = EditorManager.getEditedText( pageContext );
-%>
-<wiki:CheckRequestContext context="edit">
-<wiki:NoSuchPage> <%-- this is a new page, check if we're cloning --%>
-<%
- String clone = request.getParameter( "clone" );
- if( clone != null )
- {
- WikiPage p = engine.getPage( clone );
- if( p != null )
- {
- AuthorizationManager mgr = engine.getAuthorizationManager();
- PagePermission pp = new PagePermission( p, PagePermission.VIEW_ACTION );
-
- try
- {
- if( mgr.checkPermission( context.getWikiSession(), pp ) )
- {
- usertext = engine.getPureText( p );
- }
- }
- catch( Exception e ) { /*log.error( "Accessing clone page "+clone, e );*/ }
- }
- }
-%>
-</wiki:NoSuchPage>
-<%
- if( usertext == null )
- {
- usertext = engine.getPureText( context.getPage() );
- }
-%>
-</wiki:CheckRequestContext>
-<% if( usertext == null ) usertext = ""; %>
-
-
<div style="width:100%"> <%-- Required for IE6 on Windows --%>
-
-<form action="<wiki:CheckRequestContext
- context='edit'><wiki:EditLink format='url'/></wiki:CheckRequestContext><wiki:CheckRequestContext
- context='comment'><wiki:CommentLink format='url'/></wiki:CheckRequestContext>"
- class="wikiform"
- id="editform"
- onsubmit="return Wiki.submitOnce(this);"
- method="post" accept-charset="<wiki:ContentEncoding/>"
- enctype="application/x-www-form-urlencoded" >
-
- <%-- Edit.jsp relies on these being found. So be careful, if you make changes. --%>
- <p id="submitbuttons">
- <input name="page" type="hidden" value="<wiki:Variable var='pagename' />" />
- <input name="action" type="hidden" value="save" />
- <%=SpamFilter.insertInputFields( pageContext )%>
- <input name="<%=SpamFilter.getHashFieldName(request)%>" type="hidden" value="<c:out value='${lastchange}' />" />
- <input type="submit" name="ok" value="<fmt:message key='editor.plain.save.submit'/>"
- accesskey="s"
- title="<fmt:message key='editor.plain.save.title'/>" />
- <input type="submit" name="preview" value="<fmt:message key='editor.plain.preview.submit'/>"
- accesskey="v"
- title="<fmt:message key='editor.plain.preview.title'/>" />
- <input type="submit" name="cancel" value="<fmt:message key='editor.plain.cancel.submit'/>"
- accesskey="q"
- title="<fmt:message key='editor.plain.cancel.title'/>" />
- </p>
- <%-- This following field is only for the SpamFilter to catch bots which are just randomly filling all fields and submitting.
- Normal user should never see this field, nor type anything in it. --%>
- <div style="display:none;">Authentication code: <input type="text" name="<%=SpamFilter.getBotFieldName()%>" id="<%=SpamFilter.getBotFieldName()%>" value="" /></div>
- <table>
-<%--FIXME
- <wiki:Permission permission="rename">
- <tr>
- <td><label for="renameto"><fmt:message key='editor.renameto'/></label></td>
- <td><input type="text" name="renameto" value="<wiki:Variable var='pagename' />" size="40" />
-
- <input type="checkbox" name="references" checked="checked" />
- <fmt:message key="info.updatereferrers"/>
- FIXME</td>
- </tr>
- </wiki:Permission>
---%>
- <tr>
- <td><label for="changenote"><fmt:message key='editor.plain.changenote' /></label></td>
- <td><input type="text" name="changenote" id="changenote" size="80" maxlength="80" value="<c:out value='${changenote}' />" /></td>
- </tr>
- </table>
- <div id="tools">
+ <s:form beanclass="org.apache.wiki.action.EditActionBean" class="wikiform"
+ id="editform" method="post" acceptcharset="UTF-8" enctype="application/x-www-form-urlencoded" >
+
+ <%-- Edit.jsp relies on these being found. So be careful, if you make changes. --%>
+ <p id="submitbuttons">
+ <s:hidden name="page"><wiki:Variable var='pagename' /></s:hidden>
+ <s:hidden name="<%=SpamFilter.getHashFieldName(request)%>"><c:out value="${lastchange}" /></s:hidden>
+ <%=SpamFilter.insertInputFields( pageContext )%>
+ <c:set var="saveTitle" scope="page"><fmt:message key="editor.plain.save.title" /></c:set>
+ <wiki:CheckRequestContext context='edit'>
+ <s:submit name="save" accesskey="s" title="${saveTitle}" />
+ </wiki:CheckRequestContext>
+ <wiki:CheckRequestContext context='comment'>
+ <s:submit name="comment" accesskey="s" title="${saveTitle}"><fmt:message key="editor.plain.save.submit"/></s:submit>
+ </wiki:CheckRequestContext>
+
+ <c:set var="previewTitle" scope="page"><fmt:message key="editor.plain.preview.title" /></c:set>
+ <s:submit name="preview" accesskey="v" title="${previewTitle}" />
+
+ <c:set var="cancelTitle" scope="page"><fmt:message key="editor.plain.cancel.title" /></c:set>
+ <s:submit name="cancel" accesskey="q" title="${cancelTitle}" />
+ </p>
+
+ <%-- This following field is only for the SpamFilter to catch bots which are just
+ randomly filling all fields and submitting. Normal user should never see this field,
+ nor type anything in it. --%>
+ <div style="display:none;">Authentication code: <input type="text" name="<%=SpamFilter.getBotFieldName()%>" id="<%=SpamFilter.getBotFieldName()%>" value="" /></div>
+
+ <%-- Fields for changenote, renaming etc. --%>
+ <table>
+ <tr>
+ <td>
+ <s:label for="changenote" name="changenote" />
+ </td>
+ <td>
+ <s:text name="changenote" id="changenote" size="80" maxlength="80" />
+ </td>
+ </tr>
+ </table>
+
+ <%-- Toolbar --%>
+ <div id="tools">
<h4><fmt:message key='editor.plain.toolbar' /></h4>
<div id="toolbuttons">
- <span>
- <a href="#" class="tool" rel="" id="tbLink" title="<fmt:message key='editor.plain.tbLink.title' />">link</a>
- <a href="#" class="tool" rel="break" id="tbH1" title="<fmt:message key='editor.plain.tbH1.title' />">h1</a>
- <a href="#" class="tool" rel="break" id="tbH2" title="<fmt:message key='editor.plain.tbH2.title' />">h2</a>
- <a href="#" class="tool" rel="break" id="tbH3" title="<fmt:message key='editor.plain.tbH3.title' />">h3</a>
- </span>
- <span>
- <a href="#" class="tool" rel="" id="tbB" title="<fmt:message key='editor.plain.tbB.title' />">bold</a>
- <a href="#" class="tool" rel="" id="tbI" title="<fmt:message key='editor.plain.tbI.title' />">italic</a>
- <a href="#" class="tool" rel="" id="tbMONO" title="<fmt:message key='editor.plain.tbMONO.title' />">mono</a>
- <a href="#" class="tool" rel="" id="tbSUP" title="<fmt:message key='editor.plain.tbSUP.title' />">sup</a>
- <a href="#" class="tool" rel="" id="tbSUB" title="<fmt:message key='editor.plain.tbSUB.title' />">sub</a>
- <a href="#" class="tool" rel="" id="tbSTRIKE" title="<fmt:message key='editor.plain.tbSTRIKE.title' />">strike</a>
- </span>
- <span>
- <a href="#" class="tool" rel="" id="tbBR" title="<fmt:message key='editor.plain.tbBR.title' />">br</a>
- <a href="#" class="tool" rel="break" id="tbHR" title="<fmt:message key='editor.plain.tbHR.title' />">hr</a>
- <a href="#" class="tool" rel="break" id="tbPRE" title="<fmt:message key='editor.plain.tbPRE.title' />">pre</a>
- <a href="#" class="tool" rel="break" id="tbCODE" title="<fmt:message key='editor.plain.tbCODE.title' />">code</a>
- <a href="#" class="tool" rel="break" id="tbDL" title="<fmt:message key='editor.plain.tbDL.title' />">dl</a>
- </span>
- <span>
- <a href="#" class="tool" rel="break" id="tbTOC" title="<fmt:message key='editor.plain.tbTOC.title' />">toc</a>
- <a href="#" class="tool" rel="break" id="tbTAB" title="<fmt:message key='editor.plain.tbTAB.title' />">tab</a>
- <a href="#" class="tool" rel="break" id="tbTABLE" title="<fmt:message key='editor.plain.tbTABLE.title' />">table</a>
- <a href="#" class="tool" rel="" id="tbIMG" title="<fmt:message key='editor.plain.tbIMG.title' />">img</a>
- <a href="#" class="tool" rel="break" id="tbQUOTE" title="<fmt:message key='editor.plain.tbQUOTE.title' />">quote</a>
- <a href="#" class="tool" rel="break" id="tbSIGN" title="<fmt:message key='editor.plain.tbSIGN.title' />">sign</a>
- </span>
- <span>
- <a href="#" class="tool" rel="break" id="tbUNDO" title="<fmt:message key='editor.plain.undo.title' />"><fmt:message key='editor.plain.undo.submit' /></a>
- </span>
- <span>
- <a href="#" class="tool" rel="break" id="tbREDO" title="<fmt:message key='editor.plain.redo.title' />"><fmt:message key='editor.plain.redo.submit' /></a>
- </span>
- </div>
-
- <div id="toolextra" class="clearbox" style="display:none;">
- <span>
- <input type="checkbox" name="tabcompletion" id="tabcompletion" <%=TextUtil.isPositive((String)session.getAttribute("tabcompletion")) ? "checked='checked'" : ""%> />
- <label for="tabcompletion" title="<fmt:message key='editor.plain.tabcompletion.title' />"><fmt:message key="editor.plain.tabcompletion" /></label>
- </span>
- <span>
- <input type="checkbox" name="smartpairs" id="smartpairs" <%=TextUtil.isPositive((String)session.getAttribute("smartpairs")) ? "checked='checked'" : ""%> />
- <label for="smartpairs" title="<fmt:message key='editor.plain.smartpairs.title' />"><fmt:message key="editor.plain.smartpairs" /></label>
- </span>
- </div>
-
- <div id="searchbar">
- <span>
- <label for="tbFIND"><fmt:message key="editor.plain.find" /></label>
- <input type="text" name="tbFIND" id="tbFIND" size="16" />
- <label for="tbREPLACE"><fmt:message key="editor.plain.replace" /></label>
- <input type="text" name="tbREPLACE" id="tbREPLACE" size="16" />
- <input type="button" name="doreplace" id="doreplace" value="<fmt:message key='editor.plain.find.submit' />" />
- </span>
- <span>
- <input type="checkbox" name="tbMatchCASE" id="tbMatchCASE" />
- <label for="tbMatchCASE"><fmt:message key="editor.plain.matchcase" /></label>
- </span>
- <span>
- <input type="checkbox" name="tbREGEXP" id="tbREGEXP" />
- <label for="tbREGEXP"><fmt:message key="editor.plain.regexp" /></label>
- </span>
- <span>
- <input type="checkbox" name="tbGLOBAL" id="tbGLOBAL" checked="checked" />
- <label for="tbGLOBAL"><fmt:message key="editor.plain.global" /></label>
- </span>
- </div>
- <div class="clearbox"></div>
- </div>
-
- <div>
- <textarea id="editorarea" name="<%=EditorManager.REQ_EDITEDTEXT%>"
- class="editor"
- rows="20" cols="80"><%=TextUtil.replaceEntities(usertext)%></textarea>
- <div class="clearbox" ></div>
- </div>
-
- <wiki:CheckRequestContext context="comment">
- <fieldset>
- <legend><fmt:message key="editor.commentsignature" /></legend>
- <p>
- <label for="authorname" accesskey="n"><fmt:message key="editor.plain.name" /></label>
- <input type="text" name="author" id="authorname" value="<c:out value='${sessionScope.author}' />" />
- <input type="checkbox" name="remember" id="rememberme" <%=TextUtil.isPositive((String)session.getAttribute("remember")) ? "checked='checked'" : ""%> />
- <label for="rememberme"><fmt:message key="editor.plain.remember" /></label>
- </p>
- <p>
- <label for="link" accesskey="m"><fmt:message key="editor.plain.email" /></label>
- <input type="text" name="link" id="link" size="24" value="<c:out value='${sessionScope.link}' />" />
- </p>
- </fieldset>
- </wiki:CheckRequestContext>
-
-</form>
-
-<div id="sneakpreviewheader">
- <input type="checkbox" name="autopreview" id="autopreview" <%=TextUtil.isPositive((String)session.getAttribute("autopreview")) ? "checked='checked'" : ""%> />
- <label for="autopreview" title="<fmt:message key='editor.plain.sneakpreview.title' />"><fmt:message key="editor.plain.sneakpreview" /></label>
- <span id="previewSpin" class="spin" style="position:absolute;display:none;"></span>
-</div>
-<div id="sneakpreview"></div>
+ <span>
+ <a href="#" class="tool" rel="" id="tbLink" title="<fmt:message key='editor.plain.tbLink.title' />">link</a>
+ <a href="#" class="tool" rel="break" id="tbH1" title="<fmt:message key='editor.plain.tbH1.title' />">h1</a>
+ <a href="#" class="tool" rel="break" id="tbH2" title="<fmt:message key='editor.plain.tbH2.title' />">h2</a>
+ <a href="#" class="tool" rel="break" id="tbH3" title="<fmt:message key='editor.plain.tbH3.title' />">h3</a>
+ </span>
+ <span>
+ <a href="#" class="tool" rel="" id="tbB" title="<fmt:message key='editor.plain.tbB.title' />">bold</a>
+ <a href="#" class="tool" rel="" id="tbI" title="<fmt:message key='editor.plain.tbI.title' />">italic</a>
+ <a href="#" class="tool" rel="" id="tbMONO" title="<fmt:message key='editor.plain.tbMONO.title' />">mono</a>
+ <a href="#" class="tool" rel="" id="tbSUP" title="<fmt:message key='editor.plain.tbSUP.title' />">sup</a>
+ <a href="#" class="tool" rel="" id="tbSUB" title="<fmt:message key='editor.plain.tbSUB.title' />">sub</a>
+ <a href="#" class="tool" rel="" id="tbSTRIKE" title="<fmt:message key='editor.plain.tbSTRIKE.title' />">strike</a>
+ </span>
+ <span>
+ <a href="#" class="tool" rel="" id="tbBR" title="<fmt:message key='editor.plain.tbBR.title' />">br</a>
+ <a href="#" class="tool" rel="break" id="tbHR" title="<fmt:message key='editor.plain.tbHR.title' />">hr</a>
+ <a href="#" class="tool" rel="break" id="tbPRE" title="<fmt:message key='editor.plain.tbPRE.title' />">pre</a>
+ <a href="#" class="tool" rel="break" id="tbCODE" title="<fmt:message key='editor.plain.tbCODE.title' />">code</a>
+ <a href="#" class="tool" rel="break" id="tbDL" title="<fmt:message key='editor.plain.tbDL.title' />">dl</a>
+ </span>
+ <span>
+ <a href="#" class="tool" rel="break" id="tbTOC" title="<fmt:message key='editor.plain.tbTOC.title' />">toc</a>
+ <a href="#" class="tool" rel="break" id="tbTAB" title="<fmt:message key='editor.plain.tbTAB.title' />">tab</a>
+ <a href="#" class="tool" rel="break" id="tbTABLE" title="<fmt:message key='editor.plain.tbTABLE.title' />">table</a>
+ <a href="#" class="tool" rel="" id="tbIMG" title="<fmt:message key='editor.plain.tbIMG.title' />">img</a>
+ <a href="#" class="tool" rel="break" id="tbQUOTE" title="<fmt:message key='editor.plain.tbQUOTE.title' />">quote</a>
+ <a href="#" class="tool" rel="break" id="tbSIGN" title="<fmt:message key='editor.plain.tbSIGN.title' />">sign</a>
+ </span>
+ <span>
+ <a href="#" class="tool" rel="break" id="tbUNDO" title="<fmt:message key='editor.plain.undo.title' />"><fmt:message key='editor.plain.undo.submit' /></a>
+ </span>
+ <span>
+ <a href="#" class="tool" rel="break" id="tbREDO" title="<fmt:message key='editor.plain.redo.title' />"><fmt:message key='editor.plain.redo.submit' /></a>
+ </span>
+ </div>
+
+ <%-- Toolbar extras --%>
+ <div id="toolextra" class="clearbox" style="display:none;">
+ <span>
+ <input type="checkbox" name="tabcompletion" id="tabcompletion" <%=TextUtil.isPositive((String)session.getAttribute("tabcompletion")) ? "checked='checked'" : ""%> />
+ <label for="tabcompletion" title="<fmt:message key='editor.plain.tabcompletion.title' />"><fmt:message key="editor.plain.tabcompletion" /></label>
+ </span>
+ <span>
+ <input type="checkbox" name="smartpairs" id="smartpairs" <%=TextUtil.isPositive((String)session.getAttribute("smartpairs")) ? "checked='checked'" : ""%> />
+ <label for="smartpairs" title="<fmt:message key='editor.plain.smartpairs.title' />"><fmt:message key="editor.plain.smartpairs" /></label>
+ </span>
+ </div>
+
+ <%-- Search bar --%>
+ <div id="searchbar">
+ <span>
+ <label for="tbFIND"><fmt:message key="editor.plain.find" /></label>
+ <input type="text" name="tbFIND" id="tbFIND" size="16" />
+ <label for="tbREPLACE"><fmt:message key="editor.plain.replace" /></label>
+ <input type="text" name="tbREPLACE" id="tbREPLACE" size="16" />
+ <input type="button" name="doreplace" id="doreplace" value="<fmt:message key='editor.plain.find.submit' />" />
+ </span>
+ <span>
+ <input type="checkbox" name="tbMatchCASE" id="tbMatchCASE" />
+ <label for="tbMatchCASE"><fmt:message key="editor.plain.matchcase" /></label>
+ </span>
+ <span>
+ <input type="checkbox" name="tbREGEXP" id="tbREGEXP" />
+ <label for="tbREGEXP"><fmt:message key="editor.plain.regexp" /></label>
+ </span>
+ <span>
+ <input type="checkbox" name="tbGLOBAL" id="tbGLOBAL" checked="checked" />
+ <label for="tbGLOBAL"><fmt:message key="editor.plain.global" /></label>
+ </span>
+ </div>
+ <div class="clearbox"></div>
+ </div>
+
+ <%-- You knew this would be here somewhere. Yes, it's the textarea where the user
+ actually edits stuff. --%>
+ <div>
+ <s:textarea id="editorarea" name="text" class="editor" rows="20" cols="80" />
+ <div class="clearbox" ></div>
+ </div>
+
+ <wiki:CheckRequestContext context="comment">
+ <fieldset>
+ <legend><fmt:message key="editor.commentsignature" /></legend>
+ <p>
+ <s:label for="author" accesskey="n" name="author" />
+ <s:text id="author" name="author" />
+ <s:checkbox id="remember" name="remember" />
+ <s:label for="remember" name="remember" />
+ </p>
+ <p>
+ <s:label for="link" accesskey="m" name="editor.plain.email" />
+ <s:text id="link" name="link" size="24" />
+ </p>
+ </fieldset>
+ </wiki:CheckRequestContext>
+
+ <div id="livepreviewheader">
+ <s:checkbox id="livePreview" name="livePreview" />
+ <c:set var="livePreviewTitle" scope="page"><fmt:message key="editor.plain.livepreview.title"/></c:set>
+ <s:label for="livePreview" title="${livePreviewTitle}" name="livePreview" />
+ <span id="previewSpin" class="spin" style="position:absolute;display:none;"></span>
+ </div>
+ <div id="livepreview"></div>
+ </s:form>
+
</div>
\ No newline at end of file
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/jspwiki.css
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/jspwiki.css?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/jspwiki.css (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/jspwiki.css Fri Mar 6 23:31:03 2009
@@ -1177,14 +1177,14 @@
/* +++ 475 PreviewContent - "This is a preview" comment +++ */
-#sneakpreviewheader {
+#livepreviewheader {
clear:both;
font-size:110%;
background-color:#ddd;
padding:0.5em;
margin:0.5em 0;
}
-#sneakpreview {
+#livepreview {
}
#previewcontent {
}
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/skins/OrderedList/skin.css
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/skins/OrderedList/skin.css?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/skins/OrderedList/skin.css (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/skins/OrderedList/skin.css Fri Mar 6 23:31:03 2009
@@ -350,10 +350,10 @@
}
/* +++ 475 PageContent.jsp +++ */
-#sneakpreviewheader {
+#livepreviewheader {
background-color:#3f464a;
}
-#sneakpreview {
+#livepreview {
background:transparent !important;
}
/* +++ 475 PreviewContent - "This is a preview" comment +++ */
Modified: incubator/jspwiki/trunk/src/WebContent/templates/default/skins/Smart/skin.css
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/WebContent/templates/default/skins/Smart/skin.css?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/WebContent/templates/default/skins/Smart/skin.css (original)
+++ incubator/jspwiki/trunk/src/WebContent/templates/default/skins/Smart/skin.css Fri Mar 6 23:31:03 2009
@@ -275,7 +275,7 @@
color:white;
padding:0.5em 0.25em;
}
-#sneakpreviewheader {
+#livepreviewheader {
background-color:#fff7c0;
}
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/AbstractPageActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/AbstractPageActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/AbstractPageActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/AbstractPageActionBean.java Fri Mar 6 23:31:03 2009
@@ -30,10 +30,9 @@
* process {@link org.apache.wiki.api.WikiPage} objects bound to the
* <code>page</code> request parameter. In particular, this subclass contains
* special processing logic that ensures that, the <code>page</code>
- * properties of this object and its related
- * {@link org.apache.wiki.WikiContext} are set to the same value. When
- * {@link #setPage(WikiPage)} is called by, for example, the Stripes controller,
- * the underlying
+ * properties of this object and its related {@link org.apache.wiki.WikiContext}
+ * are set to the same value. When {@link #setPage(WikiPage)} is called by, for
+ * example, the Stripes controller, the underlying
* {@link org.apache.wiki.ui.stripes.WikiActionBeanContext#setPage(WikiPage)}
* method is called also.
*/
@@ -55,10 +54,14 @@
* Sets the WikiPage property for this ActionBean, and also sets the
* WikiActionBeanContext's page property to the same value by calling
* {@link org.apache.wiki.ui.stripes.WikiActionBeanContext#setPage(WikiPage)}.
+ * Note that because of the {@link Validate} annotation, the
+ * <code>page</code> field will be required by any executing event handler
+ * method. To change this property, subclasses should override this method
+ * and supply a <code>Validate( required = false )</code> annotation.
*
* @param page the wiki page.
*/
- @Validate( required = false )
+ @Validate( required = true )
public void setPage( WikiPage page )
{
m_page = page;
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/DeleteActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/DeleteActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/DeleteActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/DeleteActionBean.java Fri Mar 6 23:31:03 2009
@@ -108,15 +108,6 @@
}
/**
- * {@inheritDoc}
- */
- @Validate( required = true )
- public void setPage( WikiPage page )
- {
- super.setPage( page );
- }
-
- /**
* Sets the version to delete. If not set, all versions of the page or
* attachment will be deleted.
*
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/EditActionBean.java Fri Mar 6 23:31:03 2009
@@ -21,26 +21,88 @@
package org.apache.wiki.action;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
-import org.apache.wiki.WikiContext;
+import net.sourceforge.stripes.action.*;
+import net.sourceforge.stripes.controller.LifecycleStage;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidationErrors;
+
+import org.apache.wiki.*;
+import org.apache.wiki.api.WikiException;
+import org.apache.wiki.api.WikiPage;
import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.filters.RedirectException;
import org.apache.wiki.filters.SpamFilter;
-import org.apache.wiki.ui.EditorManager;
+import org.apache.wiki.htmltowiki.HtmlStringToWikiTranslator;
+import org.apache.wiki.log.Logger;
+import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.ui.stripes.HandlerPermission;
+import org.apache.wiki.ui.stripes.WikiActionBeanContext;
import org.apache.wiki.ui.stripes.WikiRequestContext;
-
-import net.sourceforge.stripes.action.*;
-
+import org.apache.wiki.workflow.DecisionRequiredException;
+import org.jdom.JDOMException;
@HttpCache( allow = false )
-@UrlBinding( "/Edit.jsp" )
public class EditActionBean extends AbstractPageActionBean
{
- @HandlesEvent("comment")
- @HandlerPermission(permissionClass=PagePermission.class, target="${page.qualifiedName}", actions=PagePermission.COMMENT_ACTION)
- @WikiRequestContext("comment")
+ private static final Logger log = LoggerFactory.getLogger( EditActionBean.class );
+
+ private String m_author = null;
+
+ private String m_spamhash = null;
+
+ private String m_text = null;
+
+ private String m_changeNote = null;
+
+ private boolean m_append = false;
+
+ private boolean m_captcha = false;
+
+ private boolean m_remember = true;
+
+ private String m_htmlPageText = null;
+
+ private boolean m_livePreview = false;
+
+ private String m_link = null;
+
+ /**
+ * Event handler method that cancels any locks the user possesses for the current wiki page,
+ * and redirects the user to the {@link ViewActionBean} "view" handler.
+ * @return the redirect
+ */
+ @DontValidate
+ @HandlesEvent( "cancel" )
+ @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.EDIT_ACTION )
+ @WikiRequestContext( "cancel" )
+ public Resolution cancel()
+ {
+ String pagereq = m_page.getName();
+ log.debug( "Cancelled editing " + pagereq );
+
+ // Cancel page lock
+ HttpSession session = getContext().getRequest().getSession();
+ WikiEngine engine = getContext().getEngine();
+ PageLock lock = (PageLock) session.getAttribute( "lock-" + pagereq );
+ if( lock != null )
+ {
+ engine.getPageManager().unlockPage( lock );
+ session.removeAttribute( "lock-" + pagereq );
+ }
+ return new RedirectResolution( ViewActionBean.class ).addParameter( "page", pagereq );
+ }
+
+ @HandlesEvent( "comment" )
+ @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.COMMENT_ACTION )
+ @WikiRequestContext( "comment" )
public Resolution comment()
{
return null;
@@ -61,17 +123,176 @@
}
@DefaultHandler
+ @DontValidate
@HandlesEvent( "edit" )
@HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.EDIT_ACTION )
@WikiRequestContext( "edit" )
public Resolution edit()
{
- return null;
+ WikiActionBeanContext wikiContext = getContext();
+ HttpServletRequest request = wikiContext.getRequest();
+ HttpSession session = request.getSession();
+ Principal user = wikiContext.getCurrentUser();
+ String pagereq = m_page.getName();
+
+ log.info( "Editing page " + pagereq + ". User=" + user.getName() + ", host=" + request.getRemoteAddr() );
+
+ // If page is locked, make sure we tell the user
+ List<Message> messages = wikiContext.getMessages();
+ WikiEngine engine = wikiContext.getEngine();
+ PageManager mgr = engine.getPageManager();
+ PageLock lock = mgr.getCurrentLock( m_page );
+ if( lock != null )
+ {
+ messages.add( new LocalizableMessage( "edit.locked", lock.getLocker(), lock.getTimeLeft() ) );
+ }
+
+ // If user is not editing the latest one, tell user also
+ ValidationErrors errors = getContext().getValidationErrors();
+ WikiPage latest = engine.getPage( m_page.getName() );
+ if( latest.getVersion() != m_page.getVersion() )
+ {
+ errors.addGlobalError( new LocalizableError( "edit.restoring", m_page.getVersion() ) );
+ }
+
+ // Attempt to lock the page.
+ lock = mgr.lockPage( m_page, user.getName() );
+ if( lock != null )
+ {
+ session.setAttribute( "lock-" + pagereq, lock );
+ }
+
+ // Load the page text
+ m_text = engine.getPureText( m_page );
+
+ return new ForwardResolution( "/Edit.jsp" );
+ }
+
+ /**
+ * Returns whether the edited text should be appended to the page.
+ *
+ * @return <code>true</code> if text should be appended;
+ * <code>false</code> otherwise (the default).
+ */
+ public boolean getAppend()
+ {
+ return m_append;
+ }
+
+ /**
+ * Returns the author.
+ *
+ * @return the author
+ */
+ public String getAuthor()
+ {
+ return m_author;
+ }
+
+ /**
+ * Returns whether a CAPTCHA is being used for editing.
+ *
+ * @return <code>true</code> if a CAPTCHA is in use; <code>false</code>
+ * otherwise.
+ */
+ public boolean getCaptcha()
+ {
+ return m_captcha;
+ }
+
+ /*
+ * Returns the changenote for this upload.
+ */
+ public String getChangenote()
+ {
+ return m_changeNote;
+ }
+
+ /**
+ * Returns the HTML page text.
+ *
+ * @return the HTML page text
+ */
+ public String getHtmlPageText()
+ {
+ return m_htmlPageText;
+ }
+
+ /**
+ * Returns the link.
+ *
+ * @return the link
+ */
+ public String getLink()
+ {
+ return m_link;
+ }
+
+ /**
+ * Returns <code>true</code> if the "live preview" feature is turned on;
+ * <code>false</code> otherwise
+ *
+ * @return the "live preview" setting
+ */
+ public boolean getLivePreview()
+ {
+ return m_livePreview;
+ }
+
+ /**
+ * Returns the flag indicating whether the author name should be remembered.
+ *
+ * @return the remember-me flag
+ */
+ public boolean getRemember()
+ {
+ return m_remember;
}
/**
- * Event that extracts the current state of the edited page from the HTTP
- * session and redirects the user to the previewer JSP.
+ * Returns the edited text.
+ *
+ * @return the text
+ */
+ public String getText()
+ {
+ return m_text;
+ }
+
+ /**
+ * Initializes default values. Also looks up the correct spam hash field, as determined by
+ * {@link SpamFilter#getHashFieldName(HttpServletRequest)}.
+
+ */
+ @After( stages = LifecycleStage.BindingAndValidation )
+ public void initDefaultValues()
+ {
+ HttpServletRequest request = getContext().getRequest();
+
+ // Look up and set spam hash field name for this particular edit
+ String hashParam = SpamFilter.getHashFieldName( request );
+ m_spamhash = request.getParameter( hashParam );
+ if( m_spamhash != null )
+ {
+ m_spamhash = m_spamhash.trim();
+ }
+
+ // Set author: prefer authenticated/asserted principals first
+ WikiSession wikiSession = getContext().getWikiSession();
+ if( wikiSession.isAsserted() || wikiSession.isAuthenticated() )
+ {
+ m_author = wikiSession.getUserPrincipal().getName();
+ }
+
+ // Otherwise, if author not bound, check session
+ else if( m_author == null )
+ {
+ m_author = wikiSession.getUserPrincipal().getName();
+ }
+ }
+
+ /**
+ * Event that the user to the preview display JSP.
*
* @return a forward resolution back to the preview page.
*/
@@ -80,15 +301,202 @@
@WikiRequestContext( "preview" )
public Resolution preview()
{
- WikiContext context = getContext();
- HttpServletRequest request = context.getHttpRequest();
+ log.debug( "Previewing " + m_page.getName() );
+ return new ForwardResolution( "/Preview.jsp" );
+ }
+
+ @HandlesEvent( "save" )
+ @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.EDIT_ACTION )
+ @WikiRequestContext( "save" )
+ public Resolution save() throws WikiException
+ {
+ WikiSession wikiSession = getContext().getWikiSession();
+ HttpServletRequest request = getContext().getHttpRequest();
HttpSession session = request.getSession();
+ WikiContext wikiContext = getContext();
+ WikiEngine engine = getContext().getEngine();
+ String pagereq = m_page.getName();
+
+ log.info( "Saving page " + m_page.getName() + ". UserPrincipal=" + wikiSession.getUserPrincipal().getName() + ", Author="
+ + m_author + ", Host=" + getContext().getRequest().getRemoteAddr() );
+
+ // Check for session expiration
+ Resolution r = SpamFilter.checkHash( this );
+ if( r != null )
+ {
+ return r;
+ }
+
+ // FIXME: I am not entirely sure if the JSP page is the
+ // best place to check for concurrent changes. It certainly
+ // is the best place to show errors, though.
+ String h = SpamFilter.getSpamHash( m_page, request );
+
+ // Someone changed the page while we were editing it!
+ if( !h.equals( m_spamhash ) )
+ {
+ log.info( "Page changed, warning user." );
+ return new RedirectResolution( PageModifiedActionBean.class, "conflict" ).addParameter( "page", pagereq );
+ }
+
+ //
+ // We expire ALL locks at this moment, simply because someone has
+ // already broken it.
+ //
+ PageLock lock = engine.getPageManager().getCurrentLock( m_page );
+ engine.getPageManager().unlockPage( lock );
+ session.removeAttribute( "lock-" + pagereq );
+
+ // Set author information and other metadata
+ WikiPage modifiedPage = (WikiPage) wikiContext.getPage().clone();
+ modifiedPage.setAuthor( m_author );
+
+ // If this is an append, add it to the page.
+ // If a full edit, replace the previous contents.
+ try
+ {
+ wikiContext.setPage( modifiedPage );
+
+ if( m_captcha )
+ {
+ wikiContext.setVariable( "captcha", Boolean.TRUE );
+ session.removeAttribute( "captcha" );
+ }
+
+ if( m_append )
+ {
+ StringBuffer pageText = new StringBuffer( engine.getText( pagereq ) );
+ pageText.append( m_text );
+ engine.saveText( wikiContext, pageText.toString() );
+ }
+ else
+ {
+ engine.saveText( wikiContext, m_text );
+ }
+ }
+ catch( DecisionRequiredException ex )
+ {
+ return new RedirectResolution( ViewActionBean.class, "view" ).addParameter( "page", "ApprovalRequiredForPageChanges" );
+ }
+ catch( RedirectException ex )
+ {
+ // Should work, but doesn't
+ wikiContext.getWikiSession().addMessage( ex.getMessage() ); // FIXME:
+ session.setAttribute( "message", ex.getMessage() );
+ session.setAttribute( SpamFilter.getHashFieldName( request ), m_spamhash );
+ return new RedirectResolution( ex.getRedirect() ).flash( this );
+ }
- request.setAttribute( EditorManager.ATTR_EDITEDTEXT, session.getAttribute( EditorManager.REQ_EDITEDTEXT ) );
+ return new RedirectResolution( ViewActionBean.class, "view" ).addParameter( "page", pagereq );
+ }
- String lastchange = SpamFilter.getSpamHash( context.getPage(), request );
- request.setAttribute( "lastchange", lastchange );
+ /**
+ * Sets a flag indicating that new page text should be appended to the old
+ * text.
+ *
+ * @param <code>true</code> if text should be appended; <code>false</code>
+ * otherwise (the default).
+ */
+ @Validate( required = false )
+ public void setAppend( boolean append )
+ {
+ m_append = append;
+ }
- return new ForwardResolution( "/Preview.jsp" );
+ /**
+ * Sets the author.
+ *
+ * @param author the author
+ */
+ @Validate( required = false )
+ public void setAuthor( String author )
+ {
+ m_author = author;
}
+
+ /**
+ * Sets a flag indicating that CAPTCHA should be used for editing.
+ *
+ * @param captcha <code>true</code> if a CAPTCHA is in use;
+ * <code>false</code> otherwise.
+ */
+ @Validate( required = false )
+ public void setCaptcha( boolean captcha )
+ {
+ m_captcha = captcha;
+ }
+
+ /**
+ * Sets the changenote for this upload; usually a short comment.
+ *
+ * @param changenote the change note
+ */
+ @Validate( required = false )
+ public void setChangenote( String changenote )
+ {
+ m_changeNote = changenote;
+ }
+
+ /**
+ * Sets the HTML page text, which will be translated into wiki text by
+ * {@link HtmlStringToWikiTranslator}. Calling this method causes
+ * {@link #setText(String)} to be called, with the translated text supplied.
+ *
+ * @param the HTML to translate
+ * @throws JDOMException if the HTML cannot be translated
+ * @throws IOException if the HtmlStringToWikiTranslator cannot translated
+ * the text
+ */
+ @Validate( required = false )
+ public void setHtmlPageText( String html ) throws IOException, JDOMException
+ {
+ m_htmlPageText = html;
+ m_text = new HtmlStringToWikiTranslator().translate( html, getContext() );
+ }
+
+ /**
+ * Sets the link.
+ *
+ * @param link the link
+ */
+ @Validate( required = false )
+ public void setLink( String link )
+ {
+ m_link = link;
+ }
+
+ /**
+ * Returns <code>true</code> if the "live preview" feature is turned on;
+ * <code>false</code> otherwise
+ *
+ * @param livePreview the "live preview" setting
+ */
+ @Validate( required = false )
+ public void setLivePreview( boolean livePreview )
+ {
+ m_livePreview = livePreview;
+ }
+
+ /**
+ * Sets the flag indicating that the author name should be remembered.
+ *
+ * @param remember the remember-me flag
+ */
+ @Validate( required = false )
+ public void setRemember( boolean remember )
+ {
+ m_remember = remember;
+ }
+
+ /**
+ * Sets the edited text.
+ *
+ * @param text the text
+ */
+ @Validate( required = true )
+ public void setText( String text )
+ {
+ m_text = text;
+ }
+
}
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/RenameActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/RenameActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/RenameActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/RenameActionBean.java Fri Mar 6 23:31:03 2009
@@ -23,21 +23,23 @@
import javax.servlet.http.HttpServletRequest;
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.RedirectResolution;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.UrlBinding;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidationErrors;
+import net.sourceforge.stripes.validation.ValidationMethod;
+
import org.apache.wiki.WikiEngine;
import org.apache.wiki.api.WikiException;
-import org.apache.wiki.api.WikiPage;
import org.apache.wiki.auth.permissions.PagePermission;
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.ui.stripes.HandlerPermission;
import org.apache.wiki.ui.stripes.WikiRequestContext;
-import net.sourceforge.stripes.action.HandlesEvent;
-import net.sourceforge.stripes.action.RedirectResolution;
-import net.sourceforge.stripes.action.Resolution;
-import net.sourceforge.stripes.action.UrlBinding;
-import net.sourceforge.stripes.validation.*;
-
/**
* <p>
@@ -138,16 +140,6 @@
}
/**
- * Sets the page.
- * @param page the wiki page.
- */
- @Validate( required = true )
- public void setPage( WikiPage page )
- {
- super.setPage( page );
- }
-
- /**
* Sets the new name for the page, which will be set when the
* {@link #rename()} handler is executed.
*
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UploadActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UploadActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UploadActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/UploadActionBean.java Fri Mar 6 23:31:03 2009
@@ -21,26 +21,52 @@
package org.apache.wiki.action;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
import java.util.List;
+import net.sourceforge.stripes.action.FileBean;
+import net.sourceforge.stripes.action.HandlesEvent;
+import net.sourceforge.stripes.action.RedirectResolution;
+import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.validation.LocalizableError;
+import net.sourceforge.stripes.validation.Validate;
+import net.sourceforge.stripes.validation.ValidationErrors;
+import net.sourceforge.stripes.validation.ValidationMethod;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.WikiException;
+import org.apache.wiki.api.WikiPage;
+import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.attachment.AttachmentManager;
import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.content.WikiName;
+import org.apache.wiki.i18n.InternationalizationManager;
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
+import org.apache.wiki.providers.ProviderException;
import org.apache.wiki.ui.stripes.HandlerPermission;
import org.apache.wiki.ui.stripes.WikiRequestContext;
-import net.sourceforge.stripes.action.FileBean;
-import net.sourceforge.stripes.action.HandlesEvent;
-import net.sourceforge.stripes.action.Resolution;
-import net.sourceforge.stripes.action.UrlBinding;
-
-@UrlBinding( "/Upload.jsp" )
-public class UploadActionBean extends AbstractActionBean
+public class UploadActionBean extends AbstractPageActionBean
{
- private Logger log = LoggerFactory.getLogger( UploadActionBean.class );
+ private static final Logger log = LoggerFactory.getLogger( UploadActionBean.class );
private List<FileBean> m_newAttachments;
+ private String m_changeNote = null;
+
+ /**
+ * Returns the new attachments uploaded by the user.
+ * @return the new files to attach
+ */
+ public List<FileBean> getNewAttachments()
+ {
+ return m_newAttachments;
+ }
+
/**
* Sets the set of new attachments that should be saved when the
* {@link #upload()} event is executed.
@@ -53,17 +79,157 @@
}
/**
+ * Sets the changenote for this upload; usually a short comment.
+ *
+ * @param changenote the change note
+ */
+ @Validate( required = false )
+ public void setChangenote( String changenote )
+ {
+ m_changeNote = changenote;
+ }
+
+ /*
+ * Returns the changenote for this upload.
+ */
+ public String getChangenote()
+ {
+ return m_changeNote;
+ }
+
+ /**
* Handler method that uploads a new attachment to the ViewActionBean.
*
- * @return {@link Resolution}
+ * @return
*/
@HandlesEvent( "upload" )
- @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.VIEW_ACTION )
+ @HandlerPermission( permissionClass = PagePermission.class, target = "${page.qualifiedName}", actions = PagePermission.UPLOAD_ACTION )
@WikiRequestContext( "upload" )
- public Resolution upload()
+ public Resolution upload() throws Exception
+ {
+ for( FileBean attachment : m_newAttachments )
+ {
+ if ( attachment != null )
+ {
+ executeUpload( attachment );
+ log.debug( "Executed upload; " + m_newAttachments.size() + " attachments found." );
+ }
+ }
+
+ return new RedirectResolution( ViewActionBean.class, "attachments" ).addParameter( "page", m_page.getName() );
+ }
+
+ @ValidationMethod
+ public void validateFileType( ValidationErrors errors )
{
- log.debug( "Executed upload; " + m_newAttachments.size() + " attachments found." );
- return null;
+ AttachmentManager mgr = getContext().getEngine().getAttachmentManager();
+ for ( FileBean attachment : m_newAttachments )
+ {
+ if ( attachment != null )
+ {
+ // Clean the file name before validating
+ String filename = attachment.getFileName();
+ try
+ {
+ filename = AttachmentManager.cleanFileName( filename );
+ }
+ catch( WikiException e )
+ {
+ // Error message returns the i18n key name
+ errors.add( "newAttachments", new LocalizableError( e.getMessage(), filename ) );
+ }
+
+ if ( !mgr.isFileTypeAllowed( filename ) )
+ {
+ errors.add( "newAttachments", new LocalizableError( "attach.bad.filetype", filename ) );
+ }
+ }
+ }
+ }
+
+ /**
+ * Uploads a single FileBean to the AttachmentManager. This method assumes
+ * that the user has permissions to do so; handler method callers should use
+ * the {@link HandlerPermission} annotation to force permission checks.
+ *
+ * @param filebean the FileBean containing the file to be uploaded
+ * @return <code>true</code> if upload results in the creation of a new
+ * page; <code>false</code> otherwise
+ * @throws IOException If there is a problem in the upload.
+ * @throws ProviderException If there is a problem in the backend.
+ */
+ private boolean executeUpload( FileBean filebean ) throws Exception
+ {
+ boolean created = false;
+ WikiContext context = getContext();
+ WikiEngine engine = context.getEngine();
+ AttachmentManager mgr = engine.getAttachmentManager();
+
+ // Get the file name, size etc from the FileBean
+ InputStream data = filebean.getInputStream();
+ String filename = filebean.getFileName();
+ int contentLength = (int)filebean.getSize();
+
+ // Cleanse the file name
+ filename = AttachmentManager.cleanFileName( filename );
+ log.debug( "file=" + filename );
+
+ // Get the name of the user uploading the file
+ Principal user = context.getCurrentUser();
+
+ //
+ // Check whether we already have this kind of a page.
+ // If the "page" parameter already defines an attachment
+ // name for an update, then we just use that file.
+ // Otherwise we create a new attachment, and use the
+ // filename given. Incidentally, this will also mean
+ // that if the user uploads a file with the exact
+ // same name than some other previous attachment,
+ // then that attachment gains a new version.
+ //
+
+ Attachment att = mgr.getAttachmentInfo( context.getPage().getName() );
+
+ if( att == null )
+ {
+ String contentType = "application/octet-stream"; // FIXME: This is not a good guess
+ WikiName path = context.getPage().getQualifiedName().resolve(filename);
+ att = engine.getContentManager().addPage( path, contentType );
+ created = true;
+ }
+ att.setSize( contentLength );
+
+ if( user != null )
+ {
+ att.setAuthor( user.getName() );
+ }
+
+ if( m_changeNote != null && m_changeNote.length() > 0 )
+ {
+ att.setAttribute( WikiPage.CHANGENOTE, m_changeNote );
+ }
+
+ try
+ {
+ engine.getAttachmentManager().storeAttachment( att, data );
+ }
+ catch( ProviderException pe )
+ {
+ // this is a kludge, the exception that is caught here contains
+ // the i18n key
+ // here we have the context available, so we can
+ // internationalize it properly :
+ throw new ProviderException( context.getBundle( InternationalizationManager.CORE_BUNDLE )
+ .getString( pe.getMessage() ) );
+ }
+
+ // Close the stream and delete the filebean, since we're done with it
+ data.close();
+ filebean.delete();
+
+ log.info( "User " + user + " uploaded attachment to " + m_page.getName() + " called " + filename + ", size " + att.getSize() );
+
+ return created;
}
}
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/action/ViewActionBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/action/ViewActionBean.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/action/ViewActionBean.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/action/ViewActionBean.java Fri Mar 6 23:31:03 2009
@@ -23,6 +23,7 @@
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
+import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationError;
import net.sourceforge.stripes.validation.ValidationErrors;
@@ -192,6 +193,17 @@
}
/**
+ * {@inheritDoc}. This method overrides the superclass method
+ * by disabling validation of the <code>page</code> field.
+ */
+ @Override
+ @Validate( required = false )
+ public void setPage( WikiPage page )
+ {
+ super.setPage( page );
+ }
+
+ /**
* Sets the name to rename the page to
*
* @param renameTo the page name to use
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/Attachment.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/Attachment.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/Attachment.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/Attachment.java Fri Mar 6 23:31:03 2009
@@ -20,8 +20,6 @@
*/
package org.apache.wiki.attachment;
-import java.io.InputStream;
-
import org.apache.wiki.api.WikiPage;
/**
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentManager.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentManager.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentManager.java Fri Mar 6 23:31:03 2009
@@ -40,6 +40,7 @@
import org.apache.wiki.log.Logger;
import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.providers.ProviderException;
+import org.apache.wiki.util.TextUtil;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.NeedsRefreshException;
@@ -80,6 +81,16 @@
private WikiEngine m_engine;
/**
+ * List of attachment types which are allowed.
+ */
+ private String[] m_allowedPatterns;
+
+ /**
+ * List of attachment types which are forbidden.
+ */
+ private String[] m_forbiddenPatterns;
+
+ /**
* Creates a new AttachmentManager. Note that creation will never fail,
* but it's quite likely that attachments do not function.
* <p>
@@ -96,6 +107,7 @@
public AttachmentManager( WikiEngine engine, Properties props )
{
m_engine = engine;
+ initFileRestrictions();
}
/**
@@ -376,7 +388,7 @@
* disabled.
* @throws ProviderException If the provider fails for some reason.
*/
- public List getVersionHistory( String attachmentName )
+ public List<WikiPage> getVersionHistory( String attachmentName )
throws ProviderException
{
return m_engine.getContentManager().getVersionHistory( WikiName.valueOf(attachmentName) );
@@ -407,14 +419,14 @@
}
/**
- * Validates the filename and makes sure it is legal. It trims and splits
- * and replaces bad characters.
+ * Cleans an attachment filename by trimming and replacing bad characters.
+ * If a file path is supplied, only the trailing file name will be returned.
*
- * @param filename
+ * @param filename the filename to cleanse
* @return A validated name with annoying characters replaced.
* @throws WikiException If the filename is not legal (e.g. empty)
*/
- static String validateFileName( String filename )
+ public static String cleanFileName( String filename )
throws WikiException
{
if( filename == null || filename.trim().length() == 0 )
@@ -457,4 +469,69 @@
return filename;
}
+
+ /**
+ * Determines whether a supplied attachment is allowed to be
+ * uploaded, based on the file name. The list of files types allowed for uploading
+ * are contained in <code>jspwiki.properties</code> property
+ * {@link #PROP_ALLOWEDEXTENSIONS}. The list of denied file types are
+ * contained in {@link #PROP_FORDBIDDENEXTENSIONS}. If an extension is
+ * included in both lists, the forbidden list wins.
+ * @param name the proposed file name
+ * @return <code>true</code> if a supplied attachment file name is
+ * allowed to be uploaded; <code>false</code> otherwise.
+ */
+ public boolean isFileTypeAllowed( String name )
+ {
+ if( name == null || name.length() == 0 ) return false;
+
+ name = name.toLowerCase();
+
+ for( int i = 0; i < m_forbiddenPatterns.length; i++ )
+ {
+ if( name.endsWith(m_forbiddenPatterns[i]) && m_forbiddenPatterns[i].length() > 0 )
+ return false;
+ }
+
+ for( int i = 0; i < m_allowedPatterns.length; i++ )
+ {
+ if( name.endsWith(m_allowedPatterns[i]) && m_allowedPatterns[i].length() > 0 )
+ return true;
+ }
+
+ return m_allowedPatterns.length == 0;
+ }
+
+ private void initFileRestrictions()
+ {
+ Properties props = m_engine.getWikiProperties();
+
+ String allowed = TextUtil.getStringProperty( props,
+ AttachmentManager.PROP_ALLOWEDEXTENSIONS,
+ null );
+
+ if( allowed != null && allowed.length() > 0 )
+ {
+ m_allowedPatterns = allowed.toLowerCase().split("\\s");
+ }
+ else
+ {
+ m_allowedPatterns = new String[0];
+ }
+
+ String forbidden = TextUtil.getStringProperty( props,
+ AttachmentManager.PROP_FORDBIDDENEXTENSIONS,
+ null );
+
+ if( forbidden != null && forbidden.length() > 0 )
+ {
+ m_forbiddenPatterns = forbidden.toLowerCase().split("\\s");
+ }
+ else
+ {
+ m_forbiddenPatterns = new String[0];
+ }
+
+ log.debug( "AttachmentManager initialized with allowed/denied file patterns." );
+ }
}
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentServlet.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentServlet.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentServlet.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/attachment/AttachmentServlet.java Fri Mar 6 23:31:03 2009
@@ -666,7 +666,7 @@
try
{
- filename = AttachmentManager.validateFileName( filename );
+ filename = AttachmentManager.cleanFileName( filename );
}
catch( WikiException e )
{
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/filters/SpamFilter.java Fri Mar 6 23:31:03 2009
@@ -32,11 +32,15 @@
import javax.servlet.jsp.PageContext;
import net.sf.akismet.Akismet;
+import net.sourceforge.stripes.action.RedirectResolution;
+import net.sourceforge.stripes.action.Resolution;
import org.apache.commons.jrcs.diff.*;
import org.apache.commons.jrcs.diff.myers.MyersDiff;
import org.apache.commons.lang.time.StopWatch;
import org.apache.wiki.*;
+import org.apache.wiki.action.ViewActionBean;
+import org.apache.wiki.action.WikiActionBean;
import org.apache.wiki.action.WikiContextFactory;
import org.apache.wiki.api.ModuleData;
import org.apache.wiki.api.WikiPage;
@@ -46,6 +50,7 @@
import org.apache.wiki.log.LoggerFactory;
import org.apache.wiki.providers.ProviderException;
import org.apache.wiki.ui.EditorManager;
+import org.apache.wiki.ui.stripes.WikiActionBeanContext;
import org.apache.wiki.util.FileUtil;
import org.apache.wiki.util.TextUtil;
@@ -1111,6 +1116,39 @@
return hash != null ? hash : c_hashName;
}
+ /**
+ * <p>This method checks if the hash value is still valid, i.e. if it exists at all. This
+ * can occur in two cases: either this is a spam bot which is not adaptive, or it is
+ * someone who has been editing one page for too long, and their session has expired.</p>
+ * <p>If the hash is not valid, this method returns a Stripes
+ * {@link net.sourceforge.stripes.action.RedirectResolution} that directs
+ * users to wiki page "SessionExpired" and logs the incident in the spam log
+ * (it may or may not be spam, but it's rather likely that it is).</p>
+ * <p>If the hash is valid, this method simply returns <code>null</code>.</p>
+ * <p>Other than the differences in the method parameters and return syntax, this
+ * method operates in every other respect identically to
+ * {@link #checkHash(WikiContext, PageContext)}</p>
+ *
+ * @param actionBean the WikiActionBean representing the editing activity and page.
+ * @return <code>null</code> if hash is okay, or a RedirectResolution if not.
+ * @since 3.0
+ */
+ public static final Resolution checkHash( WikiActionBean actionBean )
+ {
+ WikiActionBeanContext context = actionBean.getContext();
+ String hashName = getHashFieldName( context.getRequest() );
+
+ if( context.getRequest().getParameter(hashName) == null )
+ {
+ Change change = getChange( context, EditorManager.getEditedText( context.getRequest() ) );
+
+ log( context, REJECT, "MissingHash", change.m_change );
+
+ return new RedirectResolution( ViewActionBean.class, "view" ).addParameter( "name", "SessionExpired");
+ }
+
+ return null;
+ }
/**
* This method checks if the hash value is still valid, i.e. if it exists at all. This
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IncludeResourcesTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IncludeResourcesTag.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IncludeResourcesTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/IncludeResourcesTag.java Fri Mar 6 23:31:03 2009
@@ -28,7 +28,7 @@
* tiny marker into the stream, and then a ServletFilter will take
* care of the actual inclusion.
*
- *
+* @deprecated use the Stripes <code>layout-component</code> tags instead
*/
public class IncludeResourcesTag extends WikiTagBase
{
Modified: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/RequestResourceTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/RequestResourceTag.java?rev=751135&r1=751134&r2=751135&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/RequestResourceTag.java (original)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/RequestResourceTag.java Fri Mar 6 23:31:03 2009
@@ -27,6 +27,7 @@
* any of the request types defined there.
*
* @see TemplateManager
+ * @deprecated use the Stripes <code>layout-component</code> tags instead
*/
public class RequestResourceTag extends WikiTagBase
{