Author: christian.bauer(a)jboss.com
Date: 2008-06-06 20:25:03 -0400 (Fri, 06 Jun 2008)
New Revision: 8348
Added:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiServletListener.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryDisplayPositionComparator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryNameComparator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiURLRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiFormattedTextValidator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextPreview.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextValidator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLink.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLinkResolver.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiTextParser.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/DefaultWikiTextRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/MacroWikiTextRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/NullWikiTextRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/WikiTextRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroComponentHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroIncludeTextRenderer.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIMacro.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIWikiFormattedText.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/WikiFormattedTextHandler.java
trunk/examples/wiki/view/includes/admin/sessionManager.xhtml
trunk/examples/wiki/view/includes/onlineUsers.xhtml
Removed:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/renderer/
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/MacroComponentHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIMacro.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextEditor.java
Modified:
trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml
trunk/examples/wiki/src/etc/WEB-INF/components.xml
trunk/examples/wiki/src/etc/WEB-INF/faces-config.xml
trunk/examples/wiki/src/etc/WEB-INF/web.xml
trunk/examples/wiki/src/etc/i18n/messages_en.properties
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DefaultWikiLinkResolver.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Help.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/captcha/WikiCaptchaValidator.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedDAO.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedEntryManager.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/LinkProtocol.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/UserProfile.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiFile.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/NestedSetNodeInfo.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/query/NestedSetNodeWrapper.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/Plugin.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginInfo.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginModule.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/preferences/template/WriteProtectedAreaTemplate.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearchSupport.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFaceletsResourceResolver.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiRedirect.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/UploadHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/WikiUploadImageHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirMenu.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirTocQuery.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DocPager.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/LastModifiedDocuments.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/faqBrowser/templates/faqQuestionForm.xhtml
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQuery.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ReplyHome.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/lastTopicPost.xhtml
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/replyForm.xhtml
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Linking.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java
trunk/examples/wiki/view/adminHome_d.xhtml
trunk/examples/wiki/view/docEdit_d.xhtml
trunk/examples/wiki/view/includes/commentForm.xhtml
trunk/examples/wiki/view/includes/wikiTextEditor.xhtml
trunk/examples/wiki/view/includes/wikiTextPreview.xhtml
trunk/examples/wiki/view/themes/default/css/template.css
trunk/examples/wiki/view/themes/default/template.xhtml
trunk/examples/wiki/view/themes/inrelationto/css/inrelationto.css
trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css
trunk/examples/wiki/view/themes/sfwkorg/template.xhtml
trunk/examples/wiki/view/userHome_d.xhtml
Log:
New session monitor, improved wiki text editor, minor optimizations
Modified: trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml
===================================================================
--- trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -37,6 +37,31 @@
</function>
<function>
+ <function-name>toDate</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>java.util.Date
toDate(java.lang.Long)</function-signature>
+ </function>
+
+ <function>
+ <function-name>getTimeDifference</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>java.lang.String
getTimeDifference(java.util.Date,java.util.Date)</function-signature>
+ </function>
+
+ <function>
+ <function-name>getTimeDifferenceToCurrent</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>java.lang.String
getTimeDifferenceToCurrent(java.util.Date)</function-signature>
+ </function>
+
+ <function>
+ <function-name>currentDate</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>java.util.Date
currentDate()</function-signature>
+ </function>
+
+
+ <function>
<function-name>concat</function-name>
<function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
<function-signature>java.lang.String
concat(java.lang.String,java.lang.String)</function-signature>
@@ -85,12 +110,6 @@
</function>
<function>
- <function-name>hasMessage</function-name>
- <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
- <function-signature>boolean
hasMessage(java.lang.String,java.lang.String)</function-signature>
- </function>
-
- <function>
<function-name>escapeJSMessage</function-name>
<function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
<function-signature>java.lang.String
escapeJSMessage(java.lang.String)</function-signature>
@@ -139,6 +158,12 @@
</function>
<function>
+ <function-name>isGuestOrAdminUsername</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>boolean
isGuestOrAdminUsername(java.lang.String)</function-signature>
+ </function>
+
+ <function>
<function-name>isLastItemInList</function-name>
<function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
<function-signature>boolean
isLastItemInList(java.util.List,java.lang.Object)</function-signature>
@@ -152,7 +177,7 @@
<tag>
<tag-name>formattedText</tag-name>
- <handler-class>org.jboss.seam.wiki.core.ui.WikiFormattedTextHandler</handler-class>
+ <handler-class>org.jboss.seam.wiki.core.wikitext.renderer.jsf.WikiFormattedTextHandler</handler-class>
</tag>
<tag>
@@ -166,8 +191,8 @@
<tag>
<tag-name>plugin</tag-name>
<component>
- <component-type>org.jboss.seam.wiki.core.ui.UIMacro</component-type>
-
<handler-class>org.jboss.seam.wiki.core.ui.MacroComponentHandler</handler-class>
+
<component-type>org.jboss.seam.wiki.core.wikitext.renderer.jsf.UIMacro</component-type>
+
<handler-class>org.jboss.seam.wiki.core.wikitext.renderer.jsf.MacroComponentHandler</handler-class>
</component>
</tag>
Modified: trunk/examples/wiki/src/etc/WEB-INF/components.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/components.xml 2008-06-07 00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/etc/WEB-INF/components.xml 2008-06-07 00:25:03 UTC (rev 8348)
@@ -18,7 +18,7 @@
http://jboss.com/products/seam/components
http://jboss.com/products/seam/components-2.1.xsd">
<!-- Conversation timeout: 20 minutes -->
- <core:manager concurrent-request-timeout="2000"
+ <core:manager concurrent-request-timeout="4000"
conversation-timeout="1200000"
conversation-id-parameter="cid"/>
@@ -86,7 +86,9 @@
<!-- Misc Settings -->
+ <!-- TODO: Disabled, see
http://jira.jboss.com/jira/browse/JBSEAM-3070
<web:context-filter regex-url-pattern="/(service|servlets)/.+"/>
+ -->
<web:redirect-filter disabled="true"/> <!-- Messes up
into-conversation-redirect and is not needed -->
<component name="wikiUrlRewriteFilter"
class="org.jboss.seam.wiki.core.ui.WikiUrlRewriteFilter"
precedence="30">
Modified: trunk/examples/wiki/src/etc/WEB-INF/faces-config.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/faces-config.xml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/src/etc/WEB-INF/faces-config.xml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -10,8 +10,8 @@
<!-- Needed because WikiFormattedTextHandler instantiates these, asking the JSF
infrastructure -->
<component>
- <component-type>org.jboss.seam.wiki.core.ui.UIMacro</component-type>
-
<component-class>org.jboss.seam.wiki.core.ui.UIMacro</component-class>
+
<component-type>org.jboss.seam.wiki.core.wikitext.renderer.jsf.UIMacro</component-type>
+
<component-class>org.jboss.seam.wiki.core.wikitext.renderer.jsf.UIMacro</component-class>
</component>
<!-- We map this to <wiki:loadStyle src="..."/> in Facelets
-->
Modified: trunk/examples/wiki/src/etc/WEB-INF/web.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/web.xml 2008-06-07 00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/etc/WEB-INF/web.xml 2008-06-07 00:25:03 UTC (rev 8348)
@@ -4,6 +4,11 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
+ <!-- LaceWiki administration -->
+ <listener>
+
<listener-class>org.jboss.seam.wiki.admin.WikiServletListener</listener-class>
+ </listener>
+
<!--
(This resolves the not-thrown ViewExpiredException on session timeout and JSF
POSTback.)
I have got a lot of times to understand JSF 1.2 implementation code. As I guess
from code,
@@ -143,7 +148,7 @@
<!-- Session timeout,can be extended for authenticated users in components.xml!
-->
<session-config>
- <session-timeout>10</session-timeout>
+ <session-timeout>30</session-timeout>
</session-config>
</web-app>
Modified: trunk/examples/wiki/src/etc/i18n/messages_en.properties
===================================================================
--- trunk/examples/wiki/src/etc/i18n/messages_en.properties 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/src/etc/i18n/messages_en.properties 2008-06-07 00:25:03 UTC (rev
8348)
@@ -232,8 +232,14 @@
lacewiki.msg.wikiTextEditor.FormatHeadline2=Headline 2
lacewiki.msg.wikiTextEditor.FormatHeadline3=Headline 3
lacewiki.msg.wikiTextEditor.FormatHeadline4=Headline 4
-lacewiki.button.wikiTextEditor.UpdatePreview=Update Pre<u>v</u>iew
-lacewiki.button.wikiTextEditor.UpdatePreview.accesskey=V
+lacewiki.button.wikiTextEditor.EnablePreview=Pre<u>v</u>iew On
+lacewiki.button.wikiTextEditor.EnablePreview.accesskey=V
+lacewiki.button.wikiTextEditor.DisablePreview=Pre<u>v</u>iew Off
+lacewiki.button.wikiTextEditor.DisablePreview.accesskey=V
+lacewiki.button.wikiTextEditor.Validate=<u>C</u>heck
+lacewiki.button.wikiTextEditor.Validate.accesskey=C
+lacewiki.msg.wikiTextValidator.InvalidWikiText=Invalid wiki text, please click HELP for
formatting instructions.
+lacewiki.msg.wikiTextValidator.EmptyWikiText=Please enter wiki text, field can not be
empty.
# Document Display
Added: trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.admin;
+
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.wiki.core.model.User;
+import org.jboss.seam.wiki.core.model.Role;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Logger;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.security.Restrict;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.security.Identity;
+
+import javax.servlet.http.HttpSession;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author Christian Bauer
+ */
+@Name("wikiHttpSessionManager")
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class WikiHttpSessionManager implements Serializable {
+
+ protected static final String SESSION_ATTR_IDENTITY =
"org.jboss.seam.security.identity";
+ protected static final String SESSION_ATTR_ACCESSLVL =
"currentAccessLevel";
+
+ @Logger
+ private Log log;
+
+ transient private Map<String, Boolean> selectedSessions = new
HashMap<String,Boolean>();
+ transient private Map<String, Long> sessionsSize = new
HashMap<String,Long>();
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public Map<String, Boolean> getSelectedSessions() { return selectedSessions; }
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public Map<String, Long> getSessionsSize() { return sessionsSize; }
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public List<HttpSession> getSessions() {
+ return new ArrayList(WikiServletListener.getSessions().values());
+ }
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public HttpSession getSession(String id) {
+ return WikiServletListener.getSessions().get(id);
+ }
+
+ /**
+ * Calculate the size of an HttpSession using serialization.
+ * <p>
+ * This is extremely crude and a guesstimate, especially because this ignores any
+ * serialization errors.
+ * </p>
+ *
+ * @param id the identifier of th HttpSession
+ * @return size in bytes
+ */
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public long getSessionSize(String id) {
+ HttpSession session = WikiServletListener.getSessions().get(id);
+ long sessionSize = 0;
+ if (session != null) {
+ Enumeration elem = session.getAttributeNames();
+ while (elem.hasMoreElements()) {
+ String attName = (String)elem.nextElement();
+ log.debug("serializing session attribute: " + attName);
+ ByteArrayOutputStream bos = null;
+ try {
+ bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(
+ session.getAttribute(attName)
+ );
+ out.close();
+ } catch (Exception ex) {
+ // Just swallow that
+ log.warn("error during serialization, ignoring: " + ex);
+ }
+ if (bos != null) {
+ byte[] buf = bos.toByteArray();
+ sessionSize = sessionSize + buf.length;
+ }
+ }
+ }
+ return sessionSize;
+ }
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public String getUsername(String id) {
+ log.debug("trying to get username of Http session: " + id);
+ HttpSession session = WikiServletListener.getSessions().get(id);
+ String username = User.GUEST_USERNAME;
+ if (session != null) {
+ Identity identity = (Identity)session.getAttribute(SESSION_ATTR_IDENTITY);
+ if (identity != null && identity.getPrincipal() != null)
+ username = identity.getPrincipal().getName();
+ }
+ return username;
+ }
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public void calculateSelectedSessionsSize() {
+ sessionsSize.clear();
+ for (Map.Entry<String, Boolean> entry : selectedSessions.entrySet()) {
+ if (entry.getValue()) {
+ log.debug("calculating size of Http session: " +
entry.getKey());
+ sessionsSize.put(
+ entry.getKey(),
+ getSessionSize( entry.getKey() )
+ );
+ }
+ }
+ selectedSessions.clear();
+ }
+
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public void refresh() {
+ selectedSessions.clear();
+ }
+
+ /* TODO: The way Seam handles sessions conflicts with "destroying" it from
the "outside"
+ @Restrict("#{s:hasPermission('User', 'isAdmin',
currentUser)}")
+ public void invalidateSelectedSessions() {
+ for (Map.Entry<String, Boolean> entry : selectedSessions.entrySet()) {
+ if (entry.getValue()) {
+ HttpSession s = getSession(entry.getKey());
+ if (s != null) {
+ log.debug("########### invalidating Http session: " +
entry.getKey());
+ Session seamSession =
(Session)s.getAttribute("org.jboss.seam.web.session");
+ seamSession.invalidate();
+ }
+ }
+ }
+ selectedSessions.clear();
+ }
+ */
+
+ public long getNumberOfOnlineMembers() {
+ Collection<HttpSession> sessions =
WikiServletListener.getSessions().values();
+
+ long loggedInUsers = 0l;
+ for (HttpSession session : sessions) {
+ Integer userLevel = (Integer)session.getAttribute(SESSION_ATTR_ACCESSLVL);
+ if (userLevel != null && userLevel > Role.GUESTROLE_ACCESSLEVEL)
{
+ loggedInUsers++;
+ }
+ }
+ return loggedInUsers;
+
+ }
+
+ public long getNumberOfOnlineGuests() {
+ return WikiServletListener.getSessions().values().size() -
getNumberOfOnlineMembers();
+ }
+
+
+}
Added: trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiServletListener.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiServletListener.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiServletListener.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.admin;
+
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Christian Bauer
+ */
+public class WikiServletListener implements HttpSessionListener {
+
+ private static final LogProvider log =
Logging.getLogProvider(WikiServletListener.class);
+
+ // Thread-safe read/write and non-blocking reads (snapshot reads)
+ private static ConcurrentHashMap<String, HttpSession> sessions =
+ new ConcurrentHashMap<String, HttpSession>();
+
+ public void sessionCreated(HttpSessionEvent event) {
+ log.debug("starting monitoring of Http session: " +
event.getSession().getId());
+ sessions.put(event.getSession().getId(), event.getSession());
+ }
+
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ log.debug("stopping monitoring of Http session: " +
event.getSession().getId());
+ sessions.remove(event.getSession().getId());
+ }
+
+ public static ConcurrentHashMap<String, HttpSession> getSessions() {
+ return sessions;
+ }
+}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -17,8 +17,8 @@
import org.jboss.seam.wiki.core.action.prefs.UserManagementPreferences;
import org.jboss.seam.wiki.core.dao.UserDAO;
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
-import org.jboss.seam.wiki.core.renderer.MacroWikiTextRenderer;
-import org.jboss.seam.wiki.core.renderer.WikiURLRenderer;
+import org.jboss.seam.wiki.core.wikitext.renderer.MacroWikiTextRenderer;
+import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
import org.jboss.seam.wiki.core.model.*;
import org.jboss.seam.wiki.core.model.Role;
import org.jboss.seam.wiki.util.Hash;
@@ -181,23 +181,6 @@
return "loggedOut";
}
- /**
- * Assigns the Guest user to 'currentUser' when 'currentUser' is
first referenced. If a
- * user actually logs in, the 'currentUser' is reset.
- */
- @Factory(value = "currentUser", autoCreate = true)
- public void setGuestUser() {
- Contexts.getSessionContext().set("currentUser",
Component.getInstance("guestUser"));
- }
-
- /**
- * Assigns the context variable 'currentAccessLevel' when no user is logged
in.
- */
- @Factory(value = "currentAccessLevel", autoCreate = true)
- public void setGuestAccessLevel() {
- Contexts.getSessionContext().set("currentAccessLevel",
Role.GUESTROLE_ACCESSLEVEL);
- }
-
@Observer("org.jboss.seam.security.loginSuccessful")
public void extendSessionTime() {
// Store the regular session timeout value, so we can set it back later on
logout
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -22,13 +22,11 @@
import org.jboss.seam.wiki.core.action.prefs.CommentsPreferences;
import org.jboss.seam.wiki.core.exception.InvalidWikiRequestException;
import org.jboss.seam.wiki.core.ui.WikiRedirect;
-import org.jboss.seam.wiki.core.engine.WikiFormattedTextValidator;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.util.WikiUtil;
import static org.jboss.seam.international.StatusMessage.Severity.INFO;
-import static org.jboss.seam.international.StatusMessage.Severity.WARN;
-import javax.faces.validator.ValidatorException;
import java.util.Date;
@Name("commentHome")
@@ -115,9 +113,6 @@
@Override
public String persist() {
-
- if (!validateContent()) return null;
-
String outcome = super.persist();
if (outcome != null) {
@@ -209,23 +204,6 @@
/* -------------------------- Internal Methods ------------------------------ */
- // TODO: Why again are we using a different validator here for the text editor?
- protected boolean validateContent() {
- WikiFormattedTextValidator validator = new WikiFormattedTextValidator();
- try {
- validator.validate(null, null, getInstance().getContent());
- } catch (ValidatorException e) {
- // TODO: Needs to use resource bundle, how?
- StatusMessages.instance().addToControl(
- getTextAreaId(),
- WARN,
- e.getFacesMessage().getSummary()
- );
- return false;
- }
- return true;
- }
-
protected void endConversation() {
showForm = false;
Conversation.instance().end();
@@ -267,10 +245,33 @@
return quoted.toString();
}
- protected String getTextAreaId() {
- return "commentTextArea";
+ @Override
+ protected WikiTextValidator.ValidationCommand[] getPersistValidationCommands() {
+ return new WikiTextValidator.ValidationCommand[] {
+ new WikiTextValidator.ValidationCommand() {
+ public String getKey() {
+ return "comment";
+ }
+
+ public String getWikiTextValue() {
+ return getInstance().getContent();
+ }
+
+ public boolean getWikiTextRequired() {
+ return true;
+ }
+ }
+ };
}
+ protected String getValidationRequiredWikiTextEditorId() {
+ return "comment";
+ }
+
+ protected String getValidationRequiredWikiText() {
+ return getInstance().getContent();
+ }
+
/* -------------------------- Public Features ------------------------------ */
public boolean isShowForm() {
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DefaultWikiLinkResolver.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DefaultWikiLinkResolver.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DefaultWikiLinkResolver.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -7,8 +7,8 @@
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
import org.jboss.seam.wiki.core.model.*;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
-import org.jboss.seam.wiki.core.engine.WikiLink;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
import org.jboss.seam.wiki.util.WikiUtil;
import java.util.Map;
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -19,13 +19,14 @@
import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
import org.jboss.seam.wiki.core.feeds.FeedDAO;
import org.jboss.seam.wiki.core.feeds.FeedEntryManager;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
-import org.jboss.seam.wiki.core.renderer.MacroWikiTextRenderer;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.renderer.MacroWikiTextRenderer;
import org.jboss.seam.wiki.core.model.*;
import org.jboss.seam.wiki.core.exception.InvalidWikiRequestException;
import org.jboss.seam.wiki.core.template.TemplateRegistry;
import org.jboss.seam.wiki.core.template.WikiDocumentTemplate;
import org.jboss.seam.wiki.core.template.WikiDocumentEditorDefaults;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.preferences.Preferences;
import org.hibernate.validator.Length;
@@ -52,7 +53,6 @@
private Boolean minorRevision;
private String formContent;
private Set<WikiFile> linkTargets;
- private boolean enabledPreview = false;
private boolean pushOnFeeds = false;
private boolean pushOnSiteFeed = false;
private boolean isOnSiteFeed = false;
@@ -255,6 +255,34 @@
return (DocumentNodeRemover)Component.getInstance(DocumentNodeRemover.class);
}
+ @Override
+ protected WikiTextValidator.ValidationCommand[] getPersistValidationCommands() {
+ return getValidationCommands();
+ }
+
+ protected WikiTextValidator.ValidationCommand[] getUpdateValidationCommands() {
+ return getValidationCommands();
+ }
+
+ private WikiTextValidator.ValidationCommand[] getValidationCommands() {
+ return new WikiTextValidator.ValidationCommand[] {
+ new WikiTextValidator.ValidationCommand() {
+ public String getKey() {
+ return "content";
+ }
+
+ public String getWikiTextValue() {
+ return getFormContent();
+ }
+
+ public boolean getWikiTextRequired() {
+ return true;
+ }
+ }
+ };
+ }
+
+
/* -------------------------- Messages ------------------------------ */
@Override
@@ -398,15 +426,6 @@
}
public void setMinorRevision(boolean minorRevision) { this.minorRevision =
minorRevision; }
- public boolean isEnabledPreview() {
- return enabledPreview;
- }
-
- public void setEnabledPreview(boolean enabledPreview) {
- this.enabledPreview = enabledPreview;
- syncFormContentToInstance(getParentNode());
- }
-
public boolean isOnSiteFeed() {
return isOnSiteFeed;
}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Help.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Help.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Help.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -19,9 +19,6 @@
@Logger
Log log;
- @In
- WikiNodeDAO wikiNodeDAO;
-
@In("#{preferences.get('Wiki')}")
WikiPreferences wikiPreferences;
@@ -29,7 +26,7 @@
@Create
public void create() {
- helpAreaRoot =
wikiNodeDAO.findArea(WikiUtil.convertToWikiName(wikiPreferences.getHelpArea()));
+ helpAreaRoot =
WikiNodeDAO.instance().findArea(WikiUtil.convertToWikiName(wikiPreferences.getHelpArea()));
}
WikiDocument selectedHelpDoc;
@@ -41,7 +38,7 @@
public void selectDocumentByName(String documentName) {
log.debug("Searching for help document with wiki name in area: " +
helpAreaRoot.getAreaNumber() + ", " +
WikiUtil.convertToWikiName(documentName));
selectedHelpDoc =
- wikiNodeDAO.findWikiDocumentInArea(
+ WikiNodeDAO.instance().findWikiDocumentInArea(
helpAreaRoot.getAreaNumber(),
WikiUtil.convertToWikiName(documentName)
);
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -7,6 +7,7 @@
package org.jboss.seam.wiki.core.action;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.Component;
import org.jboss.seam.annotations.*;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
@@ -14,6 +15,7 @@
import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetNodeWrapper;
import org.jboss.seam.wiki.core.cache.PageFragmentCache;
+import org.jboss.seam.wiki.preferences.Preferences;
import java.io.Serializable;
@@ -35,15 +37,6 @@
Log log;
@In
- WikiDirectory wikiRoot;
-
- @In
- WikiNodeDAO wikiNodeDAO;
-
- @In("#{preferences.get('Wiki')}")
- WikiPreferences wikiPreferences;
-
- @In
Integer currentAccessLevel;
NestedSetNodeWrapper<WikiDirectory> root;
@@ -57,8 +50,9 @@
@Observer(value = { "Node.updated", "Node.removed",
"PersistenceContext.filterReset" }, create = false)
public void refreshRoot() {
log.debug("Loading menu items tree");
- root = wikiNodeDAO.findMenuItemTree(
- wikiRoot,
+ WikiPreferences wikiPreferences =
Preferences.instance().get(WikiPreferences.class);
+ root = WikiNodeDAO.instance().findMenuItemTree(
+ (WikiDirectory)Component.getInstance("wikiRoot"),
wikiPreferences.getMainMenuDepth(),
wikiPreferences.getMainMenuLevels(),
wikiPreferences.isMainMenuShowAdminOnly()
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -19,6 +19,7 @@
import org.jboss.seam.wiki.core.model.*;
import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
import org.jboss.seam.wiki.core.exception.InvalidWikiRequestException;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.util.WikiUtil;
import org.jboss.seam.wiki.preferences.Preferences;
import org.jboss.seam.international.StatusMessages;
@@ -36,6 +37,9 @@
*/
public abstract class NodeHome<N extends WikiNode, P extends WikiNode> extends
EntityHome<N> {
+ // TODO: This is a performance optimization, our EM is always already joined (SMPC)
+ protected void joinTransaction() {}
+
/* -------------------------- Context Wiring ------------------------------ */
@In
@@ -48,12 +52,15 @@
protected User currentUser;
@In
protected List<Role.AccessLevel> accessLevelsList;
+ @In
+ protected WikiTextValidator wikiTextValidator;
public WikiNodeDAO getWikiNodeDAO() { return wikiNodeDAO; }
public UserDAO getUserDAO() { return userDAO; }
public WikiDirectory getWikiRoot() { return wikiRoot; }
public User getCurrentUser() { return currentUser; }
public List<Role.AccessLevel> getAccessLevelsList() { return accessLevelsList;
}
+ public WikiTextValidator getWikiTextValidator() { return wikiTextValidator; }
/* -------------------------- Request Wiring ------------------------------ */
@@ -214,6 +221,8 @@
public String persist() {
checkPersistPermissions();
+ if (!validateWikiTexts(getPersistValidationCommands())) return null;
+
if (!preparePersist()) return null;
getLog().trace("linking new node with its parent node: " +
getParentNode());
@@ -247,6 +256,8 @@
public String update() {
checkUpdatePermissions();
+ if (!validateWikiTexts(getUpdateValidationCommands())) return null;
+
if (!prepareUpdate()) return null;
// Modification metadata
@@ -407,6 +418,25 @@
return Identity.instance().hasPermission("Node", "edit",
node);
}
+ protected boolean validateWikiTexts(WikiTextValidator.ValidationCommand[]
validationCommands) {
+ if (validationCommands == null) return true;
+
+ boolean allValid = true;
+ for (WikiTextValidator.ValidationCommand validationCommand : validationCommands)
{
+ getWikiTextValidator().validate(validationCommand);
+ allValid = getWikiTextValidator().isValid(validationCommand.getKey());
+ }
+ return allValid;
+ }
+
+ protected WikiTextValidator.ValidationCommand[] getUpdateValidationCommands() {
+ return null;
+ }
+
+ protected WikiTextValidator.ValidationCommand[] getPersistValidationCommands() {
+ return null;
+ }
+
/* -------------------------- Optional Subclass Callbacks
------------------------------ */
protected boolean isPageRootController() { return true; }
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -28,6 +28,7 @@
import org.jboss.seam.wiki.core.model.WikiUploadImage;
import org.jboss.seam.wiki.core.upload.Uploader;
import org.jboss.seam.wiki.core.exception.InvalidWikiRequestException;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.preferences.PreferenceVisibility;
import org.jboss.seam.wiki.preferences.Preferences;
import org.jboss.seam.wiki.preferences.PreferenceProvider;
@@ -47,6 +48,9 @@
@Scope(ScopeType.CONVERSATION)
public class UserHome extends EntityHome<User> {
+ // TODO: This is a performance optimization, our EM is always already joined (SMPC)
+ //protected void joinTransaction() {}
+
@In
private StatusMessages statusMessages;
@@ -153,7 +157,8 @@
public String persist() {
// Validate
- if (!isUniqueUsername() ||
+ if (!validateWikiTextEditors() ||
+ !isUniqueUsername() ||
!passwordAndControlNotNull() ||
!passwordMatchesRegex() ||
!passwordMatchesControl()) {
@@ -213,6 +218,10 @@
@Restrict("#{s:hasPermission('User', 'edit',
userHome.instance)}")
public String update() {
+ if (!validateWikiTextEditors()) {
+ return null;
+ }
+
if (uploader.hasData()) {
uploader.uploadNewInstance();
if (WikiUploadImage.class.isAssignableFrom(uploader.getUpload().getClass()))
{
@@ -339,7 +348,17 @@
);
}
+ protected boolean validateWikiTextEditors() {
+ WikiTextValidator wikiTextValidator =
+ (WikiTextValidator) Component.getInstance(WikiTextValidator.class);
+ wikiTextValidator.validate("bio", getInstance().getProfile().getBio(),
false);
+ wikiTextValidator.validate("signature",
getInstance().getProfile().getSignature(), false);
+
+ return wikiTextValidator.isValid("bio") &&
wikiTextValidator.isValid("signature");
+ }
+
+
/* -------------------------- Messages ------------------------------ */
@Override
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -19,8 +19,6 @@
import org.jboss.seam.security.Identity;
import org.jboss.seam.wiki.core.model.*;
-import javax.security.auth.login.LoginException;
-
/**
* Need this until Drools fixes bugs and becomes usable/debuggable.
*
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/captcha/WikiCaptchaValidator.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/captcha/WikiCaptchaValidator.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/captcha/WikiCaptchaValidator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -16,6 +16,7 @@
import javax.faces.validator.ValidatorException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
+import java.io.Serializable;
/**
* I don't trust the built-in validator with @CaptchaResponse.
@@ -28,7 +29,7 @@
*/
@Name("wikiCaptchaValidator")
@Validator(id = "wikiCaptchaValidator")
-public class WikiCaptchaValidator implements javax.faces.validator.Validator {
+public class WikiCaptchaValidator implements javax.faces.validator.Validator,
Serializable {
public static final String VERIFICATION_MSG_EXPR =
"#{messages['lacewiki.label.VerificationError']}";
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -6,9 +6,7 @@
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.wiki.core.model.Role;
import org.jboss.seam.wiki.core.model.User;
import org.jboss.seam.Component;
import org.hibernate.criterion.Order;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -19,6 +19,18 @@
@In
EntityManager entityManager;
+ // Anonymous (not logged-in) user
+ @Factory(value = "currentUser", scope = ScopeType.SESSION, autoCreate =
true)
+ public User getCurrentUser() {
+ return getGuestUser();
+ }
+
+ // Anonymous (not logged-in) user's access level
+ @Factory(value = "currentAccessLevel", scope = ScopeType.SESSION,
autoCreate = true)
+ public Integer getCurrentAccessLevel() {
+ return Role.GUESTROLE_ACCESSLEVEL;
+ }
+
@Factory(value = "guestUser", scope = ScopeType.SESSION)
public User getGuestUser() {
try {
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -559,9 +559,12 @@
public NestedSetNodeWrapper<WikiDirectory> findMenuItemTree(WikiDirectory
startDir, Long maxDepth, Long flattenToLevel, boolean showAdminOnly) {
- NestedSetNodeWrapper<WikiDirectory> startNodeWrapper = new
NestedSetNodeWrapper<WikiDirectory>(startDir, getComparatorDisplayPosition());
+ NestedSetNodeWrapper<WikiDirectory> startNodeWrapper =
+ new NestedSetNodeWrapper<WikiDirectory>(startDir, new
WikiDirectoryDisplayPositionComparator());
+
NestedSetResultTransformer<WikiDirectory> transformer =
- new NestedSetResultTransformer<WikiDirectory>(startNodeWrapper,
flattenToLevel);
+ new NestedSetResultTransformer<WikiDirectory>(startNodeWrapper,
flattenToLevel);
+
transformer.getAdditionalProjections().put("displayPosition",
"m.displayPosition");
// Make hollow copies for menu display so that changes to the model in the
persistence context don't appear
@@ -586,10 +589,16 @@
return findWikiDirectoryTree(startDir, null, 0l, false);
}
- public NestedSetNodeWrapper<WikiDirectory> findWikiDirectoryTree(WikiDirectory
startDir, Long maxDepth, Long flattenToLevel, boolean showAdminOnly) {
+ public NestedSetNodeWrapper<WikiDirectory> findWikiDirectoryTree(WikiDirectory
startDir,
+ Long maxDepth, Long
flattenToLevel,
+ boolean
showAdminOnly) {
- NestedSetNodeWrapper<WikiDirectory> startNodeWrapper = new
NestedSetNodeWrapper<WikiDirectory>(startDir, getComparatorWikiDirectoryName());
- NestedSetResultTransformer<WikiDirectory> transformer = new
NestedSetResultTransformer<WikiDirectory>(startNodeWrapper, flattenToLevel);
+ NestedSetNodeWrapper<WikiDirectory> startNodeWrapper =
+ new NestedSetNodeWrapper<WikiDirectory>(startDir, new
WikiDirectoryNameComparator());
+
+ NestedSetResultTransformer<WikiDirectory> transformer =
+ new NestedSetResultTransformer<WikiDirectory>(startNodeWrapper,
flattenToLevel);
+
appendNestedSetNodes(transformer, maxDepth, showAdminOnly, null);
return startNodeWrapper;
@@ -650,45 +659,6 @@
nestedSetQuery.list(); // Append all children hierarchically to the transformers
rootWrapper
}
- public Comparator<NestedSetNodeWrapper<WikiDirectory>>
getComparatorWikiDirectoryName() {
- // Needs to be equals() safe (SortedSet):
- // - compare by name, if equal
- // - compare by id
- return
- new Comparator<NestedSetNodeWrapper<WikiDirectory>>() {
- public int compare(NestedSetNodeWrapper<WikiDirectory> o1,
NestedSetNodeWrapper<WikiDirectory> o2) {
- WikiDirectory node1 = o1.getWrappedNode();
- WikiDirectory node2 = o2.getWrappedNode();
- if (node1.getName().compareTo(node2.getName()) != 0) {
- return node1.getName().compareTo(node2.getName());
- }
- return node1.getId().compareTo(node2.getId());
- }
- };
- }
-
- public Comparator<NestedSetNodeWrapper<WikiDirectory>>
getComparatorDisplayPosition() {
- // Needs to be equals() safe (SortedSet):
- // - compare by display position, if equal
- // - compare by name, if equal
- // - compare by id
- return
- new Comparator<NestedSetNodeWrapper<WikiDirectory>>() {
- public int compare(NestedSetNodeWrapper<WikiDirectory> o1,
NestedSetNodeWrapper<WikiDirectory> o2) {
- WikiDirectory node1 = o1.getWrappedNode();
- Long node1DisplayPosition =
(Long)o1.getAdditionalProjections().get("displayPosition");
- WikiDirectory node2 = o2.getWrappedNode();
- Long node2DisplayPosition =
(Long)o2.getAdditionalProjections().get("displayPosition");
- if (node1DisplayPosition.compareTo(node2DisplayPosition) != 0) {
- return node1DisplayPosition.compareTo(node2DisplayPosition);
- } else if (node1.getName().compareTo(node2.getName()) != 0) {
- return node1.getName().compareTo(node2.getName());
- }
- return node1.getId().compareTo(node2.getId());
- }
- };
- }
-
private Session getSession(boolean restricted) {
if (restricted) {
return ((Session)((org.jboss.seam.persistence.EntityManagerProxy)
restrictedEntityManager).getDelegate());
@@ -697,4 +667,8 @@
}
}
+ public static WikiNodeDAO instance() {
+ return (WikiNodeDAO)Component.getInstance(WikiNodeDAO.class);
+ }
+
}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedDAO.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedDAO.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedDAO.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -13,7 +13,7 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.model.*;
-import org.jboss.seam.wiki.core.renderer.WikiURLRenderer;
+import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedEntryManager.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedEntryManager.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/feeds/FeedEntryManager.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -14,14 +14,14 @@
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
-import org.jboss.seam.wiki.core.engine.WikiLink;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
-import org.jboss.seam.wiki.core.engine.WikiTextParser;
-import org.jboss.seam.wiki.core.engine.WikiFormattedTextValidator;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiTextParser;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiFormattedTextValidator;
+import org.jboss.seam.wiki.core.wikitext.renderer.DefaultWikiTextRenderer;
import org.jboss.seam.wiki.core.model.FeedEntry;
import org.jboss.seam.wiki.core.model.WikiTextMacro;
-import org.jboss.seam.wiki.core.renderer.DefaultWikiTextRenderer;
-import org.jboss.seam.wiki.core.renderer.WikiURLRenderer;
+import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
/**
* @author Christian Bauer
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/LinkProtocol.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/LinkProtocol.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/LinkProtocol.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -11,10 +11,11 @@
import javax.persistence.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
+import java.io.Serializable;
@Entity
@Table(name = "LINK_PROTOCOL")
-public class LinkProtocol {
+public class LinkProtocol implements Serializable {
@Id
@GeneratedValue(generator = "wikiSequenceGenerator")
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/UserProfile.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/UserProfile.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/UserProfile.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -10,11 +10,12 @@
import javax.persistence.*;
import java.util.Date;
+import java.io.Serializable;
@Entity
@Table(name = "USER_PROFILE")
@org.hibernate.annotations.BatchSize(size = 20)
-public class UserProfile {
+public class UserProfile implements Serializable {
@Id
@GeneratedValue(generator = "wikiSequenceGenerator")
Added:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryDisplayPositionComparator.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryDisplayPositionComparator.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryDisplayPositionComparator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.model;
+
+import org.jboss.seam.wiki.core.nestedset.query.NestedSetNodeWrapper;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Needs to be equals() safe (SortedSet): compare by display position, if equal compare
by name,
+ * if equal compare by id.
+ *
+ * @author Christian Bauer
+ */
+public class WikiDirectoryDisplayPositionComparator
+ implements Comparator<NestedSetNodeWrapper<WikiDirectory>>,
Serializable {
+
+ public int compare(NestedSetNodeWrapper<WikiDirectory> o1,
NestedSetNodeWrapper<WikiDirectory> o2) {
+ WikiDirectory node1 = o1.getWrappedNode();
+ Long node1DisplayPosition =
(Long)o1.getAdditionalProjections().get("displayPosition");
+ WikiDirectory node2 = o2.getWrappedNode();
+ Long node2DisplayPosition =
(Long)o2.getAdditionalProjections().get("displayPosition");
+ if (node1DisplayPosition.compareTo(node2DisplayPosition) != 0) {
+ return node1DisplayPosition.compareTo(node2DisplayPosition);
+ } else if (node1.getName().compareTo(node2.getName()) != 0) {
+ return node1.getName().compareTo(node2.getName());
+ }
+ return node1.getId().compareTo(node2.getId());
+ }
+
+}
Added:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryNameComparator.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryNameComparator.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectoryNameComparator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.model;
+
+import org.jboss.seam.wiki.core.nestedset.query.NestedSetNodeWrapper;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Needs to be equals() safe (SortedSet), compare by name, if equal compare by id.
+ *
+ * @author Christian Bauer
+ */
+public class WikiDirectoryNameComparator
+ implements Comparator<NestedSetNodeWrapper<WikiDirectory>>,
Serializable {
+
+ public int compare(NestedSetNodeWrapper<WikiDirectory> o1,
NestedSetNodeWrapper<WikiDirectory> o2) {
+ WikiDirectory node1 = o1.getWrappedNode();
+ WikiDirectory node2 = o2.getWrappedNode();
+ if (node1.getName().compareTo(node2.getName()) != 0) {
+ return node1.getName().compareTo(node2.getName());
+ }
+ return node1.getId().compareTo(node2.getId());
+ }
+
+}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiFile.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiFile.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiFile.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -2,12 +2,13 @@
import javax.persistence.*;
import java.util.*;
+import java.io.Serializable;
@Entity
@Table(name = "WIKI_FILE")
@org.hibernate.annotations.ForeignKey(name = "FK_WIKI_FILE_NODE_ID")
//TODO: @org.hibernate.annotations.OnDelete(action =
org.hibernate.annotations.OnDeleteAction.CASCADE)
-public abstract class WikiFile<N extends WikiFile> extends WikiNode<N> {
+public abstract class WikiFile<N extends WikiFile> extends WikiNode<N>
implements Serializable {
@org.hibernate.annotations.CollectionOfElements(fetch = FetchType.LAZY)
@JoinTable(name = "WIKI_TAG", joinColumns = @JoinColumn(name =
"FILE_ID"))
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/NestedSetNodeInfo.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/NestedSetNodeInfo.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/NestedSetNodeInfo.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -4,9 +4,10 @@
import javax.persistence.Embeddable;
import javax.persistence.Column;
+import java.io.Serializable;
@Embeddable
-public class NestedSetNodeInfo<N extends NestedSetNode> {
+public class NestedSetNodeInfo<N extends NestedSetNode> implements Serializable {
@Parent
private N owner;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/query/NestedSetNodeWrapper.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/query/NestedSetNodeWrapper.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/nestedset/query/NestedSetNodeWrapper.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -9,6 +9,7 @@
import org.jboss.seam.wiki.core.nestedset.NestedSetNode;
import java.util.*;
+import java.io.Serializable;
/**
* Wraps a {@link org.jboss.seam.wiki.core.nestedset.NestedSetDelegate} and links it into
a read-only tree of parent and children.
@@ -43,7 +44,7 @@
*
* @author Christian Bauer
*/
-public class NestedSetNodeWrapper<N extends NestedSetNode> {
+public class NestedSetNodeWrapper<N extends NestedSetNode> implements Serializable
{
N wrappedNode;
NestedSetNodeWrapper<N> wrappedParent;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/Plugin.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/Plugin.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/Plugin.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -8,17 +8,17 @@
import org.jboss.seam.Component;
import org.jboss.seam.wiki.core.exception.InvalidWikiConfigurationException;
-import org.jboss.seam.wiki.core.plugin.metamodel.PluginModule;
import java.util.ArrayList;
import java.util.List;
+import java.io.Serializable;
/**
* Plugin metadata.
*
* @author Christian Bauer
*/
-public class Plugin {
+public class Plugin implements Serializable {
// Some constants that represent the sub-package layout of a plugin package
public static final String PACKAGE_I18N = "i18n";
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginInfo.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginInfo.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginInfo.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -6,17 +6,19 @@
*/
package org.jboss.seam.wiki.core.plugin.metamodel;
+import java.io.Serializable;
+
/**
* @author Christian Bauer
*/
-public class PluginInfo {
+public class PluginInfo implements Serializable {
private String description;
private String version;
private ApplicationVersion applicationVersion;
private Vendor vendor;
- public class ApplicationVersion {
+ public class ApplicationVersion implements Serializable {
private String min;
private String max;
@@ -34,7 +36,7 @@
}
}
- public class Vendor {
+ public class Vendor implements Serializable {
private String name;
private String url;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginModule.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginModule.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/plugin/metamodel/PluginModule.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -10,11 +10,12 @@
import org.jboss.seam.wiki.core.exception.InvalidWikiConfigurationException;
import java.util.*;
+import java.io.Serializable;
/**
* @author Christian Bauer
*/
-public abstract class PluginModule {
+public abstract class PluginModule implements Serializable {
private Plugin plugin;
private String key;
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/preferences/template/WriteProtectedAreaTemplate.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/preferences/template/WriteProtectedAreaTemplate.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/preferences/template/WriteProtectedAreaTemplate.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -18,17 +18,15 @@
public class WriteProtectedAreaTemplate implements PreferenceValueTemplate, Serializable
{
@In
- WikiNodeDAO wikiNodeDAO;
-
- @In
WikiDirectory wikiRoot;
private List<String> areaNames;
public List<String> getTemplateValues() {
if (areaNames == null) {
- areaNames = new ArrayList<String>();
- List<WikiNode> areas = wikiNodeDAO.findChildren(wikiRoot,
WikiNode.SortableProperty.name, false, 0, Integer.MAX_VALUE);
+ areaNames = new ArrayList<String>();
+ List<WikiNode> areas =
+ WikiNodeDAO.instance().findChildren(wikiRoot,
WikiNode.SortableProperty.name, false, 0, Integer.MAX_VALUE);
for (WikiNode area : areas) {
if (area.isWriteProtected()) {
areaNames.add(area.getName());
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearchSupport.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearchSupport.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearchSupport.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -5,7 +5,7 @@
import org.jboss.seam.wiki.core.model.WikiComment;
import org.jboss.seam.wiki.core.search.metamodel.SearchSupport;
import org.jboss.seam.wiki.core.search.metamodel.SearchableEntityHandler;
-import org.jboss.seam.wiki.core.renderer.WikiURLRenderer;
+import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
import org.jboss.seam.Component;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.*;
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -10,6 +10,8 @@
import com.sun.syndication.io.SyndFeedOutput;
import com.sun.syndication.io.FeedException;
import org.jboss.seam.Component;
+import org.jboss.seam.servlet.ContextualHttpServletRequest;
+import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.international.Messages;
import org.jboss.seam.wiki.core.feeds.FeedDAO;
import org.jboss.seam.wiki.core.model.*;
@@ -76,17 +78,29 @@
// Allow unit testing
public FeedServlet() {}
- // TODO: All data access in this method runs with auto-commit mode, see
http://jira.jboss.com/jira/browse/JBSEAM-957
@Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ protected void doGet(final HttpServletRequest request, final HttpServletResponse
response)
throws ServletException, IOException {
+ new ContextualHttpServletRequest(request) {
+ @Override
+ public void process() throws Exception {
+ doWork(request, response);
+ }
+ }.run();
+ }
+ // TODO: All data access in this method runs with auto-commit mode, see
http://jira.jboss.com/jira/browse/JBSEAM-957
+ protected void doWork(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
String feedIdParam = request.getParameter("feedId");
String areaNameParam = request.getParameter("areaName");
String nodeNameParam = request.getParameter("nodeName");
String aggregateParam = request.getParameter("aggregate");
log.debug(">>> feed request id: '" + feedIdParam +
"' area name: '" + areaNameParam + "' node name: '" +
nodeNameParam + "'");
+ Contexts.getSessionContext().set("LAST_ACCESS_ACTION", "Feed:
" +feedIdParam + " area: '" + areaNameParam + "' node:
'" + nodeNameParam + "'");
+
// Feed type
String pathInfo = request.getPathInfo();
log.debug("requested feed type: " + pathInfo);
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -3,6 +3,8 @@
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
import org.jboss.seam.wiki.core.model.WikiUpload;
import org.jboss.seam.wiki.core.model.WikiUploadImage;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.servlet.ContextualHttpServletRequest;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
@@ -42,14 +44,27 @@
}
- // TODO: All data access in this method runs with auto-commit mode, see
http://jira.jboss.com/jira/browse/JBSEAM-957
@Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ protected void doGet(final HttpServletRequest request, final HttpServletResponse
response)
throws ServletException, IOException {
+ new ContextualHttpServletRequest(request) {
+ @Override
+ public void process() throws Exception {
+ doWork(request, response);
+ }
+ }.run();
+ }
+ // TODO: All data access in this method runs with auto-commit mode, see
http://jira.jboss.com/jira/browse/JBSEAM-957
+ protected void doWork(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
if (DOWNLOAD_PATH.equals(request.getPathInfo())) {
String id = request.getParameter("fileId");
+
+ Contexts.getSessionContext().set("LAST_ACCESS_ACTION", "File:
" + id);
+
WikiUpload file = null;
if (!"".equals(id)) {
Deleted:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/MacroComponentHandler.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/MacroComponentHandler.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/MacroComponentHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -1,26 +0,0 @@
-package org.jboss.seam.wiki.core.ui;
-
-import com.sun.facelets.FaceletContext;
-import com.sun.facelets.tag.jsf.ComponentConfig;
-import com.sun.facelets.tag.jsf.ComponentHandler;
-
-import javax.faces.component.UIComponent;
-
-/**
- * Chaining up the macros. Still a bit of a riddle, what Pete did here.
- *
- * @author Pete Muir
- */
-public class MacroComponentHandler extends ComponentHandler {
-
- public MacroComponentHandler(ComponentConfig config) {
- super(config);
- }
-
- @Override
- protected void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent
parent) {
- super.onComponentCreated(ctx, c, parent);
- parent.getAttributes().put(UIMacro.NEXT_MACRO,
c.getClientId(ctx.getFacesContext()));
- }
-
-}
Deleted: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIMacro.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIMacro.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIMacro.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -1,35 +0,0 @@
-package org.jboss.seam.wiki.core.ui;
-
-import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
-
-import javax.faces.component.UINamingContainer;
-
-/**
- * A wrapper component that applies to macro includes.
- * <p>
- * A macro XHTML template must have a <tt><wiki:macro></tt>
root element.
- * </p>
- *
- * @author Pete Muir
- */
-public class UIMacro extends UINamingContainer {
-
- public static final String COMPONENT_FAMILY =
"org.jboss.seam.wiki.core.ui.UIMacro";
-
- public static final String NEXT_MACRO =
"org.jboss.seam.wiki.core.ui.UIMacro.nextMacro";
-
- @Override
- public String getFamily() {
- return COMPONENT_FAMILY;
- }
-
- private WikiPluginMacro wikiPluginMacro;
-
- public WikiPluginMacro getWikiMacro() {
- return wikiPluginMacro;
- }
-
- public void setWikiMacro(WikiPluginMacro wikiPluginMacro) {
- this.wikiPluginMacro = wikiPluginMacro;
- }
-}
Deleted:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -1,289 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at
gnu.org.
- */
-package org.jboss.seam.wiki.core.ui;
-
-import antlr.ANTLRException;
-import antlr.RecognitionException;
-import org.jboss.seam.Component;
-import org.jboss.seam.core.Events;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.log.Log;
-import org.jboss.seam.log.Logging;
-import org.jboss.seam.ui.util.JSF;
-import org.jboss.seam.wiki.core.engine.*;
-import org.jboss.seam.wiki.core.model.WikiFile;
-import org.jboss.seam.wiki.core.model.WikiUploadImage;
-import org.jboss.seam.wiki.core.model.WikiTextMacro;
-import org.jboss.seam.wiki.core.renderer.DefaultWikiTextRenderer;
-import org.jboss.seam.wiki.util.WikiUtil;
-import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
-
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIOutput;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Uses WikiTextParser and WikiLinkResolver to render Seam Text markup with wiki links.
- *
- * Any lexer/parser error results in WARN level log message, you can disable this in your
logging
- * configuration by raising the log level for this class to ERROR.
- *
- * @author Christian Bauer
- */
-public class UIWikiFormattedText extends UIOutput {
-
- Log log = Logging.getLog(UIWikiFormattedText.class);
-
- public static final String ATTR_LINK_STYLE_CLASS =
"linkStyleClass";
- public static final String ATTR_BROKEN_LINK_STYLE_CLASS =
"brokenLinkStyleClass";
- public static final String ATTR_ATTACHMENT_LINK_STYLE_CLASS =
"attachmentLinkStyleClass";
- public static final String ATTR_THUMBNAIL_LINK_STYLE_CLASS =
"thumbnailLinkStyleClass";
- public static final String ATTR_INTERNAL_TARGET_FRAME =
"internalTargetFrame";
- public static final String ATTR_EXTERNAL_TARGET_FRAME =
"externalTargetFrame";
- public static final String ATTR_LINK_BASE_FILE =
"linkBaseFile";
- public static final String ATTR_CURRENT_AREA_NUMBER =
"currentAreaNumber";
- public static final String ATTR_ENABLE_MACRO_RENDERING =
"enableMacroRendering";
- public static final String ATTR_ENABLE_TRANSIENT_MACROS =
"enableTransientMacros";
-
- private Map<Integer, WikiPluginMacro> macrosWithTemplateByPosition;
-
- public static final String COMPONENT_FAMILY =
"org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
-
- public static final String COMPONENT_TYPE =
"org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
-
- public UIWikiFormattedText() {
- super();
- macrosWithTemplateByPosition = new HashMap<Integer, WikiPluginMacro>();
- }
-
- @Override
- public String getFamily() {
- return COMPONENT_FAMILY;
- }
-
- @Override
- public boolean getRendersChildren() {
- return true;
- }
-
- @Override
- public String getRendererType() {
- return null;
- }
-
- @Override
- public void encodeBegin(FacesContext facesContext) throws IOException {
- if (!isRendered() || getValue() == null) return;
- log.debug(">>> ENCODE BEGIN of WikiFormattedText component");
-
- // Use the WikiTextParser to resolve macros
- WikiTextParser parser = new WikiTextParser((String) getValue(), true, true);
-
- // Resolve the base document and directory we are resolving against
- final WikiFile baseFile = (WikiFile)getAttributes().get(ATTR_LINK_BASE_FILE);
- final Long currentAreaNumber =
(Long)getAttributes().get(ATTR_CURRENT_AREA_NUMBER);
- parser.setCurrentAreaNumber(currentAreaNumber);
-
-
parser.setResolver((WikiLinkResolver)Component.getInstance("wikiLinkResolver"));
-
- // Set a customized renderer for parser macro callbacks
- class WikiFormattedTextRenderer extends DefaultWikiTextRenderer {
-
- @Override
- public String renderInternalLink(WikiLink internalLink) {
- return "<a href=\""
- + (
- internalLink.isBroken()
- ? internalLink.getUrl()
- : wikiURLRenderer.renderURL(internalLink.getFile())
- )
- + (
- internalLink.getFragment() != null
- ? "#"+internalLink.getEncodedFragment()
- : ""
- )
- + "\" target=\""
- + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
- + "\" class=\""
- + (internalLink.isBroken() ?
getAttributes().get(ATTR_BROKEN_LINK_STYLE_CLASS)
- : getAttributes().get(ATTR_LINK_STYLE_CLASS)) +
"\">"
- + internalLink.getDescription() + "</a>";
- }
-
- @Override
- public String renderExternalLink(WikiLink externalLink) {
- return "<a href=\""
- + WikiUtil.escapeEmailURL(externalLink.getUrl())
- + "\" target=\""
- + (getAttributes().get(ATTR_EXTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_EXTERNAL_TARGET_FRAME) : "")
- + "\" class=\""
- + (externalLink.isBroken() ?
getAttributes().get(ATTR_BROKEN_LINK_STYLE_CLASS)
- : getAttributes().get(ATTR_LINK_STYLE_CLASS)) +
"\">"
- + WikiUtil.escapeEmailURL(externalLink.getDescription()) +
"</a>";
- }
-
- @Override
- public String renderFileAttachmentLink(int attachmentNumber, WikiLink
attachmentLink) {
- return "<a href=\""
- + wikiURLRenderer.renderURL(baseFile)
- + "#attachment" + attachmentNumber
- + "\" target=\""
- + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
- + "\" class=\""
- + getAttributes().get(ATTR_ATTACHMENT_LINK_STYLE_CLASS) +
"\">"
- + attachmentLink.getDescription() + "[" +
attachmentNumber + "]" + "</a>";
- }
-
- @Override
- public String renderThumbnailImageLink(WikiLink link) {
-
- // TODO: This is not typesafe and clean, need different rendering
strategy for WikiUpload subclasses
- WikiUploadImage image = (WikiUploadImage)link.getFile();
- if (image.getThumbnail() == 'F') {
- // Full size display, no thumbnail
- //TODO: Make sure we really don't need this - but it messes up
the comment form conversation:
- //String imageUrl = WikiUtil.renderURL(image) +
"&cid=" + Conversation.instance().getId();
- String imageUrl = wikiURLRenderer.renderURL(image);
- return "<img src='"+ imageUrl + "'" +
- " width='"+ image.getSizeX()+"'"
+
- " height='"+ image.getSizeY()
+"'/>";
- } else {
- // Thumbnail with link display
-
- //TODO: Make sure we really don't need this - but it messes up
the comment form conversation:
- // String thumbnailUrl = WikiUtil.renderURL(image) +
"&thumbnail=true&cid=" + Conversation.instance().getId();
- String thumbnailUrl = wikiURLRenderer.renderURL(image) +
"?thumbnail=true";
-
- return "<a href=\""
- + (link.isBroken() ? link.getUrl() :
wikiURLRenderer.renderURL(image))
- + "\" target=\""
- + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
- + "\" class=\""
- + getAttributes().get(ATTR_THUMBNAIL_LINK_STYLE_CLASS) +
"\"><img src=\""
- + thumbnailUrl + "\"/></a>";
- }
- }
-
- @Override
- public String renderMacro(WikiTextMacro macro) {
-
- WikiPluginMacro pluginMacroWithTemplate =
macrosWithTemplateByPosition.get(macro.getPosition());
- if (pluginMacroWithTemplate == null) {
- log.debug("macro does not have an XHTML template/include,
skipping: " + macro);
- return "";
- }
-
- log.debug("firing BEFORE_VIEW_RENDER macro event");
- Events.instance().raiseEvent(
-
pluginMacroWithTemplate.getCallbackEventName(WikiPluginMacro.CallbackEvent.BEFORE_VIEW_RENDER),
- pluginMacroWithTemplate
- );
-
- log.debug("preparing include rendering for macro: " +
pluginMacroWithTemplate);
- UIComponent child = findComponent( pluginMacroWithTemplate.getClientId()
);
- log.debug("JSF child client identifier: " +
child.getClientId(getFacesContext()));
- ResponseWriter originalResponseWriter =
getFacesContext().getResponseWriter();
- StringWriter stringWriter = new StringWriter();
- ResponseWriter tempResponseWriter = originalResponseWriter
- .cloneWithWriter(stringWriter);
- getFacesContext().setResponseWriter(tempResponseWriter);
-
- try {
- log.debug("rendering template of macro: " +
pluginMacroWithTemplate);
- JSF.renderChild(getFacesContext(), child);
-
- log.debug("firing AFTER_VIEW_RENDER macro event");
- Events.instance().raiseEvent(
-
pluginMacroWithTemplate.getCallbackEventName(WikiPluginMacro.CallbackEvent.AFTER_VIEW_RENDER),
- pluginMacroWithTemplate
- );
- }
- catch (Exception ex) {
- throw new RuntimeException(ex);
- } finally {
- getFacesContext().setResponseWriter(originalResponseWriter);
- }
- return stringWriter.getBuffer().toString();
- }
-
- @Override
- public void setAttachmentLinks(List<WikiLink> attachmentLinks) {
- // Put attachments (wiki links...) into the event context for later
rendering
- setLinks("wikiTextAttachments", attachmentLinks);
- }
-
- @Override
- public void setExternalLinks(List<WikiLink> externalLinks) {
- // Put external links (to targets not on this wiki) into the event
context for later rendering
- setLinks("wikiTextExternalLinks", externalLinks);
- }
-
- private void setLinks(String contextVariable, List<WikiLink> links) {
- // TODO: Need some tricks here with link identifiers and attachment
numbers, right now we just skip this if it's already set
- /// ... hoping that the first caller was the document renderer and not
the comment renderer - that means comment attachments are broken
- List<WikiLink> contextLinks =
(List<WikiLink>)Contexts.getEventContext().get(contextVariable);
- if (contextLinks == null || contextLinks.size()==0) {
- Contexts.getEventContext().set(contextVariable, links);
- }
- /*
- Map<Integer, WikiLink> contextLinks =
-
(Map<Integer,WikiLink>)Contexts.getEventContext().get(contextVariable);
- if (contextLinks == null) {
- contextLinks = new HashMap<Integer, WikiLink>();
- }
- for (WikiLink link : links) {
- contextLinks.put(link.getIdentifier(), link);
- }
- Contexts.getEventContext().set(contextVariable, contextLinks);
- */
- }
-
- @Override
- protected String getHeadlineId(Headline h, String headline) {
- // HTML id attribute has restrictions on valid values... so the easiest
way is to make this a WikiLink
- return HEADLINE_ID_PREFIX+WikiUtil.convertToWikiName(headline);
- // We also need to access it correctly, see WikiLink.java and
getHeadLineLink()
- }
-
- @Override
- protected String getHeadlineLink(Headline h, String headline) {
- return "<a href=\""+
wikiURLRenderer.renderURL(baseFile)+"#"+WikiTextRenderer.HEADLINE_ID_PREFIX+WikiUtil.convertToWikiName(headline)+"\">"
- + headline
- +"</a>";
- }
- }
-
- parser.setRenderer(new WikiFormattedTextRenderer());
-
- try {
- log.debug("parsing wiki text for HTML encoding");
- parser.parse();
-
- } catch (RecognitionException rex) {
- // Log a nice message for any lexer/parser errors, users can disable this if
they want to
- log.warn( WikiFormattedTextValidator.getErrorMessage((String) getValue(),
rex) );
- } catch (ANTLRException ex) {
- // All other errors are fatal;
- throw new RuntimeException(ex);
- }
-
- facesContext.getResponseWriter().write(parser.toString());
-
- log.debug("<<< ENCODE END of WikiFormattedText component");
- }
-
- protected void addMacroWithTemplate(WikiPluginMacro pluginMacro) {
- macrosWithTemplateByPosition.put(pluginMacro.getPosition(), pluginMacro);
- }
-
-}
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFaceletsResourceResolver.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFaceletsResourceResolver.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFaceletsResourceResolver.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -11,7 +11,7 @@
import java.net.URL;
/**
- * Utitility to load Facelets XHTML files as a resource from the classapth.
+ * Utitility to load Facelets XHTML files as a resource from the classpath.
*
* @author Christian Bauer
*/
Deleted:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -1,378 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at
gnu.org.
- */
-package org.jboss.seam.wiki.core.ui;
-
-import antlr.ANTLRException;
-import antlr.RecognitionException;
-import com.sun.facelets.FaceletContext;
-import com.sun.facelets.el.VariableMapperWrapper;
-import com.sun.facelets.tag.MetaRuleset;
-import com.sun.facelets.tag.MetaTagHandler;
-import com.sun.facelets.tag.TagAttribute;
-import com.sun.facelets.tag.TagConfig;
-import com.sun.facelets.tag.jsf.ComponentSupport;
-import org.jboss.seam.Component;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.core.Events;
-import org.jboss.seam.core.Expressions;
-import org.jboss.seam.faces.ResourceLoader;
-import org.jboss.seam.log.Log;
-import org.jboss.seam.log.Logging;
-import org.jboss.seam.wiki.core.engine.WikiTextParser;
-import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
-import org.jboss.seam.wiki.core.plugin.PluginRegistry;
-import org.jboss.seam.wiki.core.plugin.metamodel.MacroPluginModule;
-import org.jboss.seam.wiki.core.renderer.NullWikiTextRenderer;
-import org.jboss.seam.wiki.core.model.WikiTextMacro;
-import org.ajax4jsf.component.html.HtmlLoadStyle;
-
-import javax.el.ELException;
-import javax.el.VariableMapper;
-import javax.faces.FacesException;
-import javax.faces.component.UIComponent;
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * Creates a <tt>UIWikiFormattedText</tt> JSF component and substitutes macro
names in wiki
- * text with real macro components in the tree. These <tt>UIMacro</tt>
components are
- * build from XHTML fragments/includes. Interacts closely with the state of the
- * <tt>UIWikiFormattedText</tt> component to split component tree creation
and rendering duties.
- *
- * @author Peter Muir
- * @author Christian Bauer
- */
-public class WikiFormattedTextHandler extends MetaTagHandler {
-
- public static final String MACRO_STACK_PAGE_VARIABLE = "macroStack";
-
- private Log log = Logging.getLog(WikiFormattedTextHandler.class);
-
- private static final String MARK =
"org.jboss.seam.wiki.core.ui.WikiFormattedTextHandler";
- private TagAttribute valueAttribute;
-
- public WikiFormattedTextHandler(TagConfig config) {
- super(config);
- this.valueAttribute = this.getRequiredAttribute("value");
- }
-
- /*
- * Main apply method called by facelets to create this component.
- */
- public void apply(FaceletContext ctx, UIComponent parent) throws IOException,
FacesException, ELException {
- log.debug(">>> building wiki text components for child of: " +
parent.getClientId(ctx.getFacesContext()));
- String id = ctx.generateUniqueId(this.tagId);
- UIComponent cmp = findChildByTagId(parent, id);
- if (cmp == null) {
- cmp = createComponent(ctx);
- cmp.getAttributes().put(MARK, id);
- }
- this.nextHandler.apply(ctx, cmp);
- parent.getChildren().add(cmp);
- createMacroComponents(ctx, cmp);
- log.debug("<<< completed building wiki text components for child
of: " + parent.getClientId(ctx.getFacesContext()));
- }
-
- private UIComponent createComponent(FaceletContext ctx) {
- UIWikiFormattedText wikiFormattedText = new UIWikiFormattedText();
- setAttributes(ctx, wikiFormattedText);
- return wikiFormattedText;
- }
-
- /*
- * Have to manually wire the component as the Facelets magic wirer
- * is a package scoped class.
- */
- @Override
- protected void setAttributes(FaceletContext ctx, Object instance) {
- UIComponent cmp = (UIComponent) instance;
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_LINK_STYLE_CLASS);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_BROKEN_LINK_STYLE_CLASS);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ATTACHMENT_LINK_STYLE_CLASS);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_THUMBNAIL_LINK_STYLE_CLASS);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_INTERNAL_TARGET_FRAME);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_EXTERNAL_TARGET_FRAME);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_LINK_BASE_FILE);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_CURRENT_AREA_NUMBER);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING, false);
- setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS, false);
- }
-
- @Override
- protected MetaRuleset createMetaRuleset(Class type) {
- return super.createMetaRuleset(type).ignoreAll();
- }
-
- /**
- * We create the included macro template components as first-class components here.
- * <p/>
- * This routine parses the wiki text and for each encountered wiki macro, it tries
to
- * include an XHTML template. If no template is found, we do nothing. If a template
is
- * found, we also include its CSS into the document header, then add it to the
parent
- * component, the <tt>UIWikiFormattedText</tt> we are handling. This
parent component
- * keeps a map of <tt>WikiMacro</tt> instances, keyed by position in the
rendered
- * wiki text.
- * </p>
- * <p>
- * Macros are never reentrant, that means a macro can not render itself. To avoid
this,
- * we push a macro onto a stack before including it in the component tree, after
checking if
- * it is already present on the stack. If it is already present, we log a warning and
don't do
- * anything. After rendering, we pop the stack. The stack is held in the PAGE
context.
- * </p>
- * @param ctx FaceletContext
- * @param parent Parent component
- */
- private void createMacroComponents(final FaceletContext ctx, final UIComponent
parent) {
- if (!(parent instanceof UIWikiFormattedText)) return;
- final UIWikiFormattedText wikiFormattedTextComponent = (UIWikiFormattedText)
parent;
-
- String unparsed = valueAttribute.getValue(ctx);
-
- // Don't forget this, transporting the value to the handled component, we
need to render it (again) later
- wikiFormattedTextComponent.setValue(unparsed);
-
- if (getAttribute(UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING) == null ||
-
!getAttribute(UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING).getBoolean(ctx)) {
- log.debug("macro rendering disabled");
- return;
- }
-
- // We need to parse the wiki text once (later again for rendering) to find all
macros in the text
- log.debug("creating macro components from wiki text macros");
- WikiTextParser parser = new WikiTextParser(unparsed, true, false);
- parser.setRenderer(
- new NullWikiTextRenderer() {
-
- // A collection of all macros (whether they have templates or not) that
we found in this piece of wiki text
- final Set<String> macrosFoundInWikiText = new
HashSet<String>();
-
- @Override
- public String renderMacro(WikiTextMacro wikiTextMacro) {
- log.debug("=== found macro in wiki text: " +
wikiTextMacro);
-
- // Check reentrancy
- if (!isMacroOnPageStack(wikiTextMacro)) {
- log.debug("adding macro to page macro stack");
- getPageMacroStack().push(wikiTextMacro);
- } else {
- log.warn("macros are not reentrant, duplicate macro on page
stack: " + wikiTextMacro);
- return null;
- }
-
- // Check if the wikiTextMacro actually is registered, we don't
build unknown macros
- WikiPluginMacro pluginMacro =
PluginRegistry.instance().createWikiPluginMacro(wikiTextMacro);
- if (pluginMacro == null) {
- log.info("macro is not bound in plugin registry: " +
wikiTextMacro);
- getPageMacroStack().pop();
- return null;
- }
-
- // Check if we can find the template to include for this
wikiTextMacro
- String macroIncludePath = getMacroIncludePath(pluginMacro);
- if (macroIncludePath == null) {
- getPageMacroStack().pop();
- return null;
- }
-
- // Before we build the nested components, set the WikiMacro instance
in the PAGE context under a
- // unique name, so we can use a VariableMapper later and alias this
as 'currentMacro'
- String macroPageVariableName = pluginMacro.getPageVariableName();
- log.debug("setting WikiMacro instance in PAGE context as
variable named: " + macroPageVariableName);
- Contexts.getPageContext().set(macroPageVariableName, pluginMacro);
-
- // Whoever wants to do something before we finally build the XHTML
template
- log.debug("firing VIEW_BUILD macro event");
-
Events.instance().raiseEvent(pluginMacro.getCallbackEventName(WikiPluginMacro.CallbackEvent.VIEW_BUILD),
pluginMacro);
-
- // This is where the magic happens... the UIWikiFormattedText
component should have one child after that, a UIMacro
- includeMacroFacelet(pluginMacro, macroIncludePath, ctx,
wikiFormattedTextComponent);
-
- // Now get the identifier of the newly created UIMacro instance and
set it for future use
- Object macroId =
wikiFormattedTextComponent.getAttributes().get(UIMacro.NEXT_MACRO);
- if (macroId != null) {
- pluginMacro.setClientId(macroId.toString());
-
wikiFormattedTextComponent.getAttributes().remove(UIMacro.NEXT_MACRO);
- } else {
- // Best guess based wikiTextMacro renderer, needed during
reRendering when we don't build the child
- // - only then is NEXT_MACRO set by the MacroComponentHandler
- macroId =
- wikiFormattedTextComponent.getChildren().get(
- wikiFormattedTextComponent.getChildCount()-1
- ).getClientId( ctx.getFacesContext() );
- pluginMacro.setClientId(macroId.toString());
- }
-
- // Put an optional CSS include in the header of the wiki document we
are rendering in.
- // (This needs to happen after the clientId is set, as CSS resource
path rendering needs to
- // know if it occurs in a JSF request (clientId present) or not.
- includeMacroCSS(pluginMacro, wikiFormattedTextComponent);
-
- // We need to make the UIMacro child transient if we run in the wiki
text editor preview. The reason
- // is complicated: If we don't make it transient, all value
expressions inside the wikiTextMacro templates that
- // use 'currentMacro' will refer to the "old" saved
ValueExpression and then of course to the "old"
- // VariableMapper. In other words: We need to make sure that the
subtree is completely fresh every
- // time the wiki text preview is reRendered, otherwise we never get a
'currentMacro' binding updated.
- // This also means that VariableMapper is a completely useless
construct, because it is basically an
- // alias that is evaluated just once.
- // Note: This means we can't click on form elements of any
plugin/wikiTextMacro template in the preview. This
- // should be solved by not showing/ghosting any form elements during
preview.
- if (getAttribute(UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS) !=
null &&
-
getAttribute(UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS).getBoolean(ctx)) {
- log.debug("setting macro to transient rendering, not storing
its state between renderings: " + pluginMacro);
- UIMacro uiMacro =
(UIMacro)ComponentSupport.findChild(wikiFormattedTextComponent, macroId.toString());
- uiMacro.setTransient(true);
- }
-
- // Finally, pop the wikiTextMacro stack of the page, then transport
the finished WikiMacro instance into
- // the UIWikiFormattedText component for rendering - we are done
building the component tree at this
- // point.
- getPageMacroStack().pop();
- wikiFormattedTextComponent.addMacroWithTemplate(pluginMacro);
-
- // Well, we don't render anything here...
- return null;
- }
-
- private String getMacroIncludePath(WikiPluginMacro pluginMacro) {
-
- // Check singleton configuration
- if
(pluginMacro.getMetadata().isRenderOptionSet(MacroPluginModule.RenderOption.SINGLETON)
&&
- macrosFoundInWikiText.contains(pluginMacro.getName())) {
- log.warn("macro is a SINGLETON, can not be used twice in the
same document area: " + pluginMacro);
- return null;
- } else {
- macrosFoundInWikiText.add(pluginMacro.getName());
- }
-
- // Check skin configuration
- String currentSkin =
(String)Component.getInstance("skin");
- if (!pluginMacro.getMetadata().isAvailableForSkin(currentSkin)) {
- log.warn("macro is not available for skin
'"+currentSkin+"': " + pluginMacro);
- return null;
- }
-
- // Try to get an XHTML template, our source for building nested
components
- // Fun with slashes: For some reason, Facelets really needs a slash
at the start, otherwise
- // it doesn't use my custom ResourceResolver...
- String includePath = "/"+
pluginMacro.getMetadata().getPlugin().getPackageDefaultTemplatePath(pluginMacro.getName());
- URL faceletURL = ResourceLoader.instance().getResource(includePath);
- if (faceletURL == null) {
- log.debug("macro has no default include file, not building
any components: " + pluginMacro);
- return null;
- } else {
- log.debug("using default template include as a resource from
package: " + includePath);
- }
-
- return includePath;
- }
-
- private void includeMacroFacelet(WikiPluginMacro pluginMacro, String
includePath, FaceletContext ctx, UIComponent parent) {
- VariableMapper orig = ctx.getVariableMapper();
- try {
- log.debug("setting 'currentMacro' as an EL variable,
resolves dynamically to WikiMacro instance in PAGE context");
- ctx.setVariableMapper(new VariableMapperWrapper(orig));
- ctx.getVariableMapper().setVariable(
- WikiPluginMacro.CURRENT_MACRO_EL_VARIABLE,
- Expressions.instance().createValueExpression("#{"+
pluginMacro.getPageVariableName()+"}").toUnifiedValueExpression()
- );
-
- log.debug("including macro facelets file from path: " +
includePath);
- ctx.includeFacelet(parent, includePath);
-
- } catch (IOException e) {
- throw new RuntimeException(e);
- } finally {
- ctx.setVariableMapper(orig);
- }
- }
-
-
- private void includeMacroCSS(WikiPluginMacro pluginMacro, UIComponent
cmp) {
-
- String cssPath = "/"+
pluginMacro.getMetadata().getPlugin().getPackageCSSPath()+"/"+
pluginMacro.getName()+".css";
- log.debug("trying to load CSS resource from classpath: " +
cssPath);
- if (ResourceLoader.instance().getResource(cssPath) != null) {
- String cssRequestURIPath =
pluginMacro.getRequestCSSPath()+"/"+ pluginMacro.getName()+".css";
- log.debug("including macro CSS file, rendering URI for
document head: " + cssRequestURIPath);
-
- // Use Ajax4JSF loader, it can do what we want - add a CSS to the
HTML <head>
- HtmlLoadStyle style = new HtmlLoadStyle();
- style.setSrc(cssRequestURIPath);
-
- cmp.getChildren().add(style);
- // Clear these out in the next build phase
- ComponentSupport.markForDeletion(style);
- } else {
- log.debug("no CSS resource found for macro");
- }
- }
- }
- );
-
- try {
- parser.parse();
- } catch (RecognitionException rex) {
- // Swallow parsing errors, we don't really care here...
- } catch (ANTLRException ex) {
- // All other errors are fatal;
- throw new RuntimeException(ex);
- }
- }
-
- // Some utilities...
-
- private static UIComponent findChildByTagId(UIComponent parent, String id) {
- Iterator itr = parent.getFacetsAndChildren();
- while (itr.hasNext()) {
- UIComponent c = (UIComponent) itr.next();
- String cid = (String) c.getAttributes().get(MARK);
- if (id.equals(cid)) {
- return c;
- }
- }
- return null;
- }
-
- private void setAttribute(FaceletContext ctx, UIComponent cmp, String name) {
- setAttribute(ctx, cmp, name, null);
- }
-
- private void setAttribute(FaceletContext ctx, UIComponent cmp, String name, Object
defaultValue) {
- TagAttribute attribute = this.getAttribute(name);
- if (attribute != null) {
- Object o = attribute.getObject(ctx);
- if (o == null && defaultValue == null) {
- throw new IllegalArgumentException("Attribute '" + name +
"' resolved to null and no default value specified");
- } else if (o == null) {
- cmp.getAttributes().put(name, defaultValue);
- } else {
- cmp.getAttributes().put(name, o);
- }
- }
- }
-
- private Stack<WikiTextMacro> getPageMacroStack() {
- if (Contexts.getPageContext().get(MACRO_STACK_PAGE_VARIABLE) == null) {
- log.debug("macro page stack is null, creating new stack for this
page");
- Contexts.getPageContext().set(MACRO_STACK_PAGE_VARIABLE, new
Stack<WikiTextMacro>());
- }
- return
(Stack<WikiTextMacro>)Contexts.getPageContext().get(MACRO_STACK_PAGE_VARIABLE);
- }
-
- private boolean isMacroOnPageStack(WikiTextMacro macro) {
- Stack<WikiTextMacro> macroStack = getPageMacroStack();
- for (WikiTextMacro macroOnPageStack : macroStack) {
- if (macroOnPageStack.getName().equals(macro.getName())) return true;
- }
- return false;
- }
-
-}
\ No newline at end of file
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiRedirect.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiRedirect.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiRedirect.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -14,7 +14,6 @@
import org.jboss.seam.log.Log;
import org.jboss.seam.faces.RedirectException;
import org.jboss.seam.wiki.core.model.WikiDocument;
-import org.jboss.seam.wiki.core.renderer.WikiURLRenderer;
import javax.faces.context.FacesContext;
import javax.faces.context.ExternalContext;
Deleted: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextEditor.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextEditor.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextEditor.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -1,47 +0,0 @@
-package org.jboss.seam.wiki.core.ui;
-
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Logger;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.wiki.core.engine.WikiFormattedTextValidator;
-import org.jboss.seam.international.StatusMessages;
-import org.jboss.seam.log.Log;
-
-import static org.jboss.seam.international.StatusMessage.Severity.WARN;
-
-import java.io.Serializable;
-
-import javax.faces.validator.ValidatorException;
-
-/**
- * Utility class bound to Wiki text editor UI.
- * <p>
- *
- * @author Christian Bauer
- */
-@Name("wikiTextEditor")
-(a)Scope(ScopeType.CONVERSATION)
-public class WikiTextEditor implements Serializable {
-
- @Logger
- Log log;
-
- public void validate(String textEditorId, String value) {
- if (value == null) return;
- log.debug("validating value of text editor: " + textEditorId);
- WikiFormattedTextValidator validator = new WikiFormattedTextValidator();
- try {
- validator.validate(null, null, value);
- } catch (ValidatorException e) {
- log.debug("exception during validation: " +
e.getFacesMessage().getSummary());
- StatusMessages.instance().addToControl(
- textEditorId + "TextArea",
- WARN,
- e.getFacesMessage().getSummary()
- );
- }
- log.debug("completed validation of text editor value");
-
- }
-}
Copied: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiURLRenderer.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/renderer/WikiURLRenderer.java)
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiURLRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiURLRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.ui;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.wiki.util.WikiUtil;
+import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
+import org.jboss.seam.wiki.core.model.WikiNode;
+import org.jboss.seam.wiki.core.model.User;
+import org.jboss.seam.wiki.core.model.Feed;
+import org.jboss.seam.wiki.core.ui.FeedServlet;
+
+import java.io.Serializable;
+
+/**
+ * Renders outgoing URLs in a unified fashion, see urlrewrite.xml for incoming URL GET
request rewriting.
+ * <p>
+ * Note that some of the rendering is delegated into the domain model for subclasses of
<tt>WikiNode</tt>.
+ * </p>
+ *
+ * @author Christian Bauer
+ */
+
+@Name("wikiURLRenderer")
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class WikiURLRenderer implements Serializable {
+
+ @In
+ String contextPath;
+
+ @In("#{preferences.get('Wiki')}")
+ WikiPreferences prefs;
+
+ public String renderSearchURL(String search) {
+ return renderSearchURL(search, false);
+ }
+
+ public String renderSearchURL(String search, boolean usePrefsPath) {
+ if (search == null || search.length() == 0) return "";
+ StringBuilder url = new StringBuilder();
+ String skin = Component.getInstance("skin") != null ?
(String)Component.getInstance("skin") : "d";
+ url.append(usePrefsPath ? prefs.getBaseUrl() : contextPath);
+
url.append("/search_").append(skin).append(".seam?query=").append(encodeURL(search));
+ return url.toString();
+ }
+
+ public String renderTagURL(String tag) {
+ return renderTagURL(tag, false);
+ }
+
+ public String renderTagURL(String tag, boolean usePrefsPath) {
+ if (tag == null || tag.length() == 0) return "";
+ StringBuilder url = new StringBuilder();
+ url.append(usePrefsPath ? prefs.getBaseUrl() : contextPath);
+ url.append("/tag/").append(encodeURL(tag));
+ return url.toString();
+ }
+
+ public String renderUserInfoURL(User user) {
+ return renderUserInfoURL(user, false);
+ }
+
+ public String renderUserInfoURL(User user, boolean usePrefsPath) {
+ if (user == null || user.getUsername() == null) return "";
+ StringBuilder url = new StringBuilder();
+ url.append(usePrefsPath ? prefs.getBaseUrl() : contextPath);
+ url.append("/user/").append(user.getUsername());
+ return url.toString();
+ }
+
+ public String renderAggregateFeedURL(String aggregateId) {
+ return renderAggregateFeedURL(aggregateId, false);
+ }
+
+ public String renderAggregateFeedURL(String aggregateId, boolean usePrefsPath) {
+ if (aggregateId == null) return "";
+ StringBuilder url = new StringBuilder();
+ url.append(usePrefsPath ? prefs.getBaseUrl() : contextPath);
+ url.append("/service/Feed/atom/Aggregate/").append(aggregateId);
+ return url.toString();
+ }
+
+ public String renderFeedURL(Feed feed) {
+ return renderFeedURL(feed, null, null, false);
+ }
+
+ public String renderFeedURL(Feed feed, String tag, String comments) {
+ return renderFeedURL(feed, tag, comments, false);
+ }
+
+ public String renderFeedURL(Feed feed, String tag, String comments, boolean
usePrefsPath) {
+ if (feed == null || feed.getId() == null) return "";
+ StringBuilder url = new StringBuilder();
+ url.append(usePrefsPath ? prefs.getBaseUrl() : contextPath);
+ url.append("/service/Feed/atom").append(feed.getURL());
+ if (comments != null && comments.length() >0) {
+
url.append("/Comments/").append(FeedServlet.Comments.valueOf(comments));
+ }
+ if (tag != null && tag.length() >0) {
+ url.append("/Tag/").append(encodeURL(tag));
+ }
+ return url.toString();
+ }
+
+ public String renderURL(WikiNode node) {
+ return renderURL(node, false);
+ }
+
+ public String renderURL(WikiNode node, boolean usePrefsPath) {
+ if (node == null || node.getId() == null) return "";
+ return prefs.isRenderPermlinks() ? renderPermURL(node, usePrefsPath) :
renderWikiURL(node, usePrefsPath);
+ }
+
+ public String renderPermURL(WikiNode node) {
+ return renderPermURL(node, false);
+ }
+
+ public String renderPermURL(WikiNode node, boolean usePrefsPath) {
+ if (node == null || node.getId() == null) return "";
+ return (usePrefsPath ? prefs.getBaseUrl() : contextPath) + "/" +
node.getPermURL(prefs.getPermlinkSuffix());
+ }
+
+ public String renderWikiURL(WikiNode node) {
+ return renderWikiURL(node, false);
+ }
+
+ public String renderWikiURL(WikiNode node, boolean usePrefsPath) {
+ if (node == null || node.getId() == null) return "";
+ return (usePrefsPath ? prefs.getBaseUrl() : contextPath) + "/" +
node.getWikiURL();
+ }
+
+ // TODO: We need more methods here, rendering year/month/day/tag/etc. on WikiURL (not
perm url)
+
+ private String encodeURL(String s) {
+ return WikiUtil.encodeURL(s);
+ }
+
+ public static WikiURLRenderer instance() {
+ return (WikiURLRenderer) Component.getInstance(WikiURLRenderer.class);
+ }
+
+}
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/UploadHandler.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/UploadHandler.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/UploadHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -3,7 +3,6 @@
import org.jboss.seam.wiki.core.model.WikiUpload;
import org.jboss.seam.wiki.core.upload.editor.UploadEditor;
import org.jboss.seam.wiki.core.upload.Uploader;
-import org.jboss.seam.wiki.core.engine.WikiLink;
public abstract class UploadHandler<WU extends WikiUpload> {
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/WikiUploadImageHandler.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/WikiUploadImageHandler.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/handler/WikiUploadImageHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -4,9 +4,6 @@
import org.jboss.seam.wiki.core.upload.Uploader;
import org.jboss.seam.wiki.core.upload.editor.UploadEditor;
import org.jboss.seam.wiki.core.upload.editor.WikiUploadImageEditor;
-import org.jboss.seam.wiki.core.engine.WikiLink;
-import org.jboss.seam.wiki.util.WikiUtil;
-import org.jboss.seam.core.Conversation;
import javax.swing.*;
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiFormattedTextValidator.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/WikiFormattedTextValidator.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiFormattedTextValidator.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiFormattedTextValidator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.editor;
+
+import org.jboss.seam.ui.validator.FormattedTextValidator;
+import org.jboss.seam.text.SeamTextParser;
+import antlr.SemanticException;
+
+/**
+ * Disables the Seam Text validation for link tags, so wiki links are OK.
+ * <p>
+ * Also provides some conversation to i18n error messages.
+ * </p>
+ *
+ * TODO: Finish the i18n and well, maybe we should just duplicate the
+ * Seam validator here to drop that dependency on the UI package...
+ *
+ * @author Christian Bauer
+ */
+public class WikiFormattedTextValidator extends FormattedTextValidator {
+
+ public SeamTextParser getSeamTextParser(String s) {
+ SeamTextParser parser = super.getSeamTextParser(s);
+ parser.setSanitizer(
+ new SeamTextParser.DefaultSanitizer() {
+
+ // Disable this part of the validation
+ @Override
+ public void validateLinkTagURI(String s) throws SemanticException {}
+
+ @Override
+ public String getInvalidURIMessage(String s) {
+ return super.getInvalidURIMessage(s);
+ }
+
+ @Override
+ public String getInvalidElementMessage(String s) {
+ return super.getInvalidElementMessage(s);
+ }
+
+ @Override
+ public String getInvalidAttributeMessage(String s, String s1) {
+ return super.getInvalidAttributeMessage(s, s1);
+ }
+
+ @Override
+ public String getInvalidAttributeValueMessage(String s, String s1, String
s2) {
+ return super.getInvalidAttributeValueMessage(s, s1, s2);
+ }
+ }
+ );
+ return parser;
+ }
+
+ @Override
+ public String getNoViableAltErrorMessage(String s, String s1) {
+ return super.getNoViableAltErrorMessage(s, s1);
+ }
+
+ @Override
+ public String getMismatchedTokenErrorMessage(String s, String s1) {
+ return super.getMismatchedTokenErrorMessage(s, s1);
+ }
+
+ @Override
+ public String getSemanticErrorMessage(String s) {
+ return super.getSemanticErrorMessage(s);
+ }
+
+ @Override
+ public int getNumberOfCharsBeforeErrorLocation() {
+ return 20;
+ }
+
+ @Override
+ public int getNumberOfCharsAfterErrorLocation() {
+ return 20;
+ }
+
+}
Added:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextPreview.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextPreview.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextPreview.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.editor;
+
+import org.jboss.seam.annotations.*;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.log.Log;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+
+/**
+ * Holds conversation-scoped state of wiki text preview feature.
+ *
+ * @author Christian Bauer
+ */
+@Name("wikiTextPreview")
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class WikiTextPreview implements Serializable {
+
+ @Logger
+ Log log;
+
+ @In
+ WikiTextValidator wikiTextValidator;
+
+ private Map<String, Boolean> previewEnabled = new HashMap<String,
Boolean>();
+
+ public void enablePreview(String key) {
+ previewEnabled.put(key, true);
+ }
+
+ public void enablePreview(String key, String value, boolean valueRequired) {
+ // Only enable preview if text passes validation
+ wikiTextValidator.validate(key, value, valueRequired);
+ if (wikiTextValidator.isValid(key)) previewEnabled.put(key, true);
+ }
+
+ public void disablePreview(String key) {
+ previewEnabled.remove(key);
+ }
+
+ public Boolean isPreviewEnabled(String key) {
+ return previewEnabled.get(key);
+ }
+
+}
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextValidator.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiTextEditor.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextValidator.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextValidator.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,123 @@
+package org.jboss.seam.wiki.core.wikitext.editor;
+
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Logger;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.log.Log;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.faces.validator.ValidatorException;
+import javax.faces.application.FacesMessage;
+
+/**
+ * Wraps the <tt>WikiFormattedTextValidator</tt> into a conversation-scoped
action
+ * that queues the right messages and holds the status of various text editors
+ * for easy error checking by the user interface.
+ *
+ * @see WikiFormattedTextValidator
+ *
+ * @author Christian Bauer
+ */
+@Name("wikiTextValidator")
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class WikiTextValidator implements Serializable {
+
+ @Logger
+ Log log;
+
+ private Map<String, String> validationFailures = new HashMap<String,
String>();
+
+ /**
+ * Validates the wiki text value and stores the validation state in this component.
+ *
+ * @param key
+ * The key under which the validation status is stored and can be later
retrieved with <tt>isValid()</tt>
+ * @param value
+ * The wiki text
+ * @param valueRequired
+ * Checks before validation if a value is present and required.
+ */
+ public void validate(String key, String value, boolean valueRequired) {
+ log.debug("validating value of text editor: " + key);
+ if (valueRequired && (value == null || value.length() == 0)) {
+ log.debug("validation failed for required but null or empty wiki text
with key: " + key);
+ validationFailures.put(key,
"lacewiki.msg.wikiTextValidator.EmptyWikiText");
+ return;
+ }
+ WikiFormattedTextValidator validator = new WikiFormattedTextValidator();
+ try {
+ validationFailures.remove(key);
+ validator.validate(null, null, value);
+ } catch (ValidatorException e) {
+ log.debug("exception during validation: " +
e.getFacesMessage().getSummary());
+ validationFailures.put(key, convertFacesMessage(e.getFacesMessage()));
+ }
+ log.debug("completed validation of text editor value for key: " +
key);
+ }
+
+ /**
+ * Makes it easier to call the validation routine programmatically.
+ *
+ * @param validationCommand
+ * A command that bundles the validation values and options.
+ */
+ public void validate(ValidationCommand validationCommand) {
+ validate(
+ validationCommand.getKey(),
+ validationCommand.getWikiTextValue(),
+ validationCommand.getWikiTextRequired()
+ );
+ }
+
+ /**
+ * Validation status of wiki text with the given key.
+ * <p>
+ * <b>Attention: Returns <tt>true</tt> if the given key can not be
found!</b>
+ * </p>
+ *
+ * @param key
+ * The key under which the validation status has been stored, i.e. from an
earlier <tt>validate()</tt> call
+ * @return
+ * True if no status for <tt>key</tt> can be found or if previous
validation failed for <tt>key</tt>
+ */
+ public boolean isValid(String key) {
+ return !validationFailures.containsKey(key);
+ }
+
+ /**
+ * Return the last validation failure message key for the given wiki text key.
+ *
+ * @param key
+ * The key under which the validation status has been stored, i.e. from an
earlier <tt>validate()</tt> call
+ * @return
+ * The validation failure message bundle key or null if no error is known.
+ */
+ public String getValidationFailureMessageBundleKey(String key) {
+ return validationFailures.get(key);
+ }
+
+ // TODO: These are supposed to be message bundle keys, not the literal ANTLR parser
messages, see WikiFormattedTextValidator
+ protected String convertFacesMessage(FacesMessage fm) {
+ // Convert the FacesMessage to a StatusMessage (which of course is then converted
back to JSF...)
+ StringBuilder msg = new StringBuilder();
+ msg.append(fm.getSummary());
+
+ // Append the detail only if the summary doesn't end with it already
+ if (!fm.getSummary().endsWith(fm.getDetail())) {
+ msg.append(" (").append(fm.getDetail()).append(")");
+ }
+ return msg.toString();
+ }
+
+ public interface ValidationCommand {
+ public String getKey();
+ public String getWikiTextValue();
+ public boolean getWikiTextRequired();
+ }
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/editor/WikiTextValidator.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLink.java (from
rev 8330, trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/WikiLink.java)
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLink.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLink.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,59 @@
+package org.jboss.seam.wiki.core.wikitext.engine;
+
+import org.jboss.seam.wiki.core.model.WikiFile;
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
+import org.jboss.seam.wiki.util.WikiUtil;
+
+/**
+ * Simple value holder for link resolution and rendering.
+ *
+ * @author Christian Bauer
+ */
+public class WikiLink {
+
+ int identifier;
+ WikiFile file;
+ boolean requiresUpdating = false;
+ String url;
+ String fragment;
+ String description;
+ boolean broken = false;
+ boolean external = false;
+
+ public WikiLink(boolean broken, boolean external) {
+ this.broken = broken;
+ this.external = external;
+ }
+
+ public int getIdentifier() { return identifier; }
+ public void setIdentifier(int identifier) { this.identifier = identifier; }
+
+ public WikiFile getFile() { return file; }
+ public void setFile(WikiFile file) { this.file = file; }
+
+ public String getUrl() { return url; }
+ public void setUrl(String url) { this.url = url; }
+
+ public String getFragment() { return fragment; }
+ public void setFragment(String fragment) { this.fragment = fragment; }
+
+ public String getEncodedFragment() {
+ if (fragment != null) {
+ return
WikiTextRenderer.HEADLINE_ID_PREFIX+WikiUtil.convertToWikiName(fragment);
+ }
+ return "";
+ }
+
+ public String getDescription() { return description; }
+ public void setDescription(String description) { this.description = description; }
+
+ public boolean isBroken() { return broken; }
+ public boolean isExternal() { return external; }
+
+ public boolean isRequiresUpdating() { return requiresUpdating; }
+ public void setRequiresUpdating(boolean requiresUpdating) { this.requiresUpdating =
requiresUpdating; }
+
+ public String toString() {
+ return "File:" + file + " Description: " + description +
" URL: " + url;
+ }
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLink.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLinkResolver.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/WikiLinkResolver.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLinkResolver.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLinkResolver.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,175 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.engine;
+
+import org.jboss.seam.wiki.core.model.WikiFile;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * The heart of the wiki, converts and resolves human-readable link tags from and to
permanent
+ * links that can be stored (or read) persistently. Also resolves link texts (from
stored
+ * link tags) to <tt>WikiLink</tt> objects, for rendering.
+ * <p>
+ * Use the supplied regular expressions to implement the methods, or parse the wiki text
+ * completely by hand and convert/resolve links.
+ *
+ * TODO: With a new multi-stage SeamTextParser we could remove most of this regex stuff
+ *
+ * @author Christian Bauer
+ */
+public interface WikiLinkResolver {
+
+ /**
+ * Matches known protocols, e.g. [=>http://foo.bar], which can be ignored and
"resolved" as-is
+ */
+ public static final String REGEX_KNOWN_PROTOCOL =
"^(http://)|(https://)|(ftp://)|(mailto:).+$";
+
+ /**
+ * Matches customized protocols, e.g. [=>seamjira://123], which should be resolved
and rendered
+ */
+ public static final String REGEX_CUSTOM_PROTOCOL = "^([a-zA-Z]+)://(.+)$";
+
+ /**
+ * Matches WikiNode.getName() constraint.
+ */
+ public static final String REGEX_NODE_NAME =
"[a-zA-Z0-9]+[^/#\\|\\]\\[]*";
+
+ /**
+ * Matches URL fragments, punctuation is limited, so not all fragments are
reachable.
+ */
+ public static final String REGEX_FRAGMENT =
"#[\\w\\s\\.\\,\\;\\-\\?\\!\\(\\)\\&\\/]+";
+
+ /**
+ * Matches "Node Name#Fragment123" with two groups.
+ */
+ public static final String REGEX_NODE_NAME_FRAGMENT =
"("+REGEX_NODE_NAME+")(" + REGEX_FRAGMENT + ")?";
+
+ /**
+ * Prepended to primary identifiers when links are stored, e.g. [This is a stored
link=>wiki://5]
+ */
+ public static final String REGEX_WIKI_PROTOCOL =
"wiki://([0-9]+)("+REGEX_FRAGMENT+")?";
+
+ /**
+ * Match [GROUP1=>GROUP1], used to replace links from user input with wiki:// URLs
- used
+ * in <tt>convertToWikiProtocol()</tt>.
+ */
+ public static final String REGEX_WIKILINK_FORWARD =
+ Pattern.quote("[") + "([^" + Pattern.quote("]")
+ "|" + Pattern.quote("[") + "]*)" +
+ "=>([^" + Pattern.quote("]") +
Pattern.quote("[") + "]+)" + Pattern.quote("]");
+
+ /**
+ * Match [GROUP1=>wiki://GROUP2], used to replace wiki:// URLs with page names
+ */
+ public static final String REGEX_WIKILINK_REVERSE =
+ Pattern.quote("[") + "([^" + Pattern.quote("]")
+ "|" + Pattern.quote("[") + "]*)" +
+ "=>" + REGEX_WIKI_PROTOCOL + Pattern.quote("]");
+
+ /**
+ * Match "Foo Bar|Baz Brrr#Fragment" as three groups
+ */
+ public static final String REGEX_WIKILINK_CROSSAREA = "^(" +
REGEX_NODE_NAME +")"+ Pattern.quote("|") + REGEX_NODE_NAME_FRAGMENT +
"$";
+
+ /**
+ * Replaces clear text links such as <tt>[Link description=>Target
Name]</tt> in <tt>wikiText</tt> with
+ * <tt>[Link description=>wiki://id]</tt> strings, usually resolves
the target name as a unique wiki name
+ * in some data store.
+ * The <tt>currentAreaNumber</tt> of the current document is supplied and
can be used as the namespace for scoped resolving.
+ * <p>
+ * This method should be called whenever a wiki document is stored, we want to store
the permanent
+ * identifiers of a target node. That way, the target node can be renamed and the
document that links
+ * to that target node still contains the valid link.
+ * </p><p>
+ * Either parse the <tt>wikiText</tt> by hand to find and replace links,
or use the
+ * <tt>REGEX_WIKILINK_FORWARD</tt> pattern which matches
<tt>[GROUP1=>GROUP2]</tt>.
+ * Convert the target name (<tt>GROUP2</tt>) to a unique wiki name, and
then to some primary
+ * identifier which you can lookup again in the future in a reliable fashion.
<tt>GROUP1</tt> is
+ * the optional link description entered by the user, you need to keep this string
and only replace
+ * <tt>GROUP2</tt> with a permanent identifier (prefixed with the
<tt>wiki://</tt> protocol).
+ * </p><p>
+ * Note that cross-namespace linking should be supported, so in addition to
<tt>[=>Target Name]</tt>,
+ * links can be entered by the user as <tt>[=>Target Area|Target
Name]</tt>. To resolve these link
+ * texts, use <tt>REGEX_WIKILINK_CROSSAREA</tt> on the original
<tt>GROUP2</tt>, which produces
+ * two groups. Ignore the given <tt>currentAreaNumber</tt> parameter and
resolve in the target namespace entered by
+ * the user on the link tag.
+ * </p><p>
+ * Example pseudo code:
+ * </p><p>
+ * <pre>
+ * if (targetName = wikiText.match(REGEX_WIKI_LINK_FORWARD)) {
+ *
+ * if (targetNamespace, newTargetName =
targetName.match(REGEX_WIKILINK_CROSSAREA) {
+ *
+ * wikiText.replace( resolveNodeId(targetNamespace, newTargetName) );
+ *
+ * } else {
+ * wikiText.replace( resolveNodeId(givenNamespace, targetName) );
+ * }
+ * }
+ * </pre>
+ *
+ * @param linkTargets This collection will be filled with
<tt>WikiFile</tt> instances which are the link targets in the wiki text
+ * @param currentAreaNumber The currennt area useable as the namespace for scoped
resolving
+ * @param wikiText Text with wiki markup containing [=>Target Name] links
+ * @return The <tt>wikiText</tt> with all <tt>[=>Target
Name]<tt> links replaced with <tt>[=>wiki://id]</tt>
+ */
+ public String convertToWikiProtocol(Set<WikiFile> linkTargets, Long
currentAreaNumber, String wikiText);
+
+ /**
+ * Replace stored text links such as <tt>[Link
description=>wiki://id]</tt> with clear text target names, so
+ * users can edit the link again in clear text.
+ * </p><p>
+ * Either parse by hand or use the <tt>REGEX_WIKILINK_REVERSE</tt>
pattern, which matches
+ * <tt>[GROUP1=>(wiki://GROUP2)]. Replace with <tt>[GROUP1=>Target
Name]</tt> or, if the target is not in
+ * the same namespace as the given <tt>area</tt> parameter, append the
area:
+ * <tt>[GROUP1=>Target Area|Target Name]</tt>.
+ *
+ * @param currentAreaNumber The current area useable as the namespace for scoped
resolving
+ * @param wikiText Text with wiki markup containing [=>wiki://id] links
+ * @return The <tt>wikiText</tt> with all
<tt>[=>wiki://id]<tt> links replaced with <tt>[=>Target
Name]</tt>
+ */
+ public String convertFromWikiProtocol(Long currentAreaNumber, String wikiText);
+
+ /**
+ * Resolve the given <tt>linkText</tt> to an instance of
<tt>WikiLink</tt> and put it in the <tt>links</tt> map.
+ * <p>
+ * The <tt>WikiLink</tt> objects are used during rendering, the rules are
as follows:
+ * <ul>
+ * <li>If the <tt>linkText</tt> matches
<tt>REGEX_KNOWN_PROTOCOL</tt>, don't resolve but create
+ * a <tt>WikiLink</tt> instance that contains <tt>url</tt>,
<tt>description</tt> (same as <tt>url</tt>),
+ * <tt>broken=false</tt>, <tt>external=true</tt>. The
<tt>url</tt> is the actual <tt>linkText</tt>, as-is.
+ * </li>
+ * <li>If the <tt>linkText</tt> matches
<tt>REGEX_WIKI_PROTOCOL</tt>, resolve it and create
+ * a <tt>WikiLink</tt> instance that contains the resolved
<tt>Node</tt> instance, the node name
+ * as <tt>description</tt>, no <tt>url</tt>, and
<tt>external=false</tt>. If the <tt>linkText</tt>
+ * can't be resolved to a <tt>Node</tt>, set
<tt>broken=true</tt>, a null <tt>node</tt>, and whatever
+ * <tt>url</tt> and <tt>description</tt> you want to render
for a broken link.
+ * </li>
+ * <li>Otherwise, the <tt>linkText</tt> represents a clear text
link such as <tt>Target Name</tt> or
+ * <tt>Target Area|TargetName</tt>, which you can resolve if you want and
return a
+ * <tt>WikiLink</tt> instance as in the previous rule. If it can't be
resolved, return a broken link
+ * indicator as described in the previous rule. If it has been resolved, you may
indicate that the
+ * original document that contains this <tt>linkText</tt> should be
updated in the datastore (usually
+ * by passing its wiki text content through
<tt>convertToWikiProtocol</tt>) - set
<tt>requiresUpdating=true</tt>
+ * on the <tt>WikiLink</tt> instance. It's the job of the client of
this resolver to handle this flag
+ * (or to ignore it).
+ *</li>
+ * </ul>
+ *
+ * @param currentAreaNumber The current area useable as the namespace for scoped
resolving
+ * @param links A map of all resolved <tt>WikiLink</tt> objects, keyed by
<tt>linkText</tt>
+ * @param linkText A stored link text, such as "wiki://123" or
"http://foo.bar" or "Target Area|Target Name]"
+ */
+ public void resolveLinkText(Long currentAreaNumber, Map<String, WikiLink>
links, String linkText);
+
+ public Long resolveWikiDirectoryId(Long currentAreaNumber, String linkText);
+
+ public Long resolveWikiDocumentId(Long currentAreaNumber, String linktext);
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiLinkResolver.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiTextParser.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/WikiTextParser.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiTextParser.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiTextParser.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,231 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.engine;
+
+import antlr.ANTLRException;
+import antlr.SemanticException;
+import org.jboss.seam.text.SeamTextLexer;
+import org.jboss.seam.text.SeamTextParser;
+import org.jboss.seam.wiki.core.model.*;
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
+
+import java.io.StringReader;
+import java.util.*;
+
+/**
+ * Parses SeamText markup and also resolves link and macro tags as wiki links and wiki
plugins.
+ * <p>
+ * Don't forget to set the resolver and renderer base with
<tt>setCurrentAreaNumber()</tt>!
+ * </p><p>
+ * Picks the <tt>WikiLinkResolver</tt> present in the contextual variable
<tt>wikiLinkResolver</tt>. Calls
+ * out to a <tt>WikiTextRender</tt> for the actual in-document rendering of
wiki links and wiki plugins. Might update
+ * the <tt>currentDocument</tt>'s content, this change should be flushed
to the datastore after calling
+ * the parser.
+ * </p><p>
+ * After parsing, all links to attachments and all external links are pushed onto the
renderer, where they
+ * can be used to render an attachment list or appendixes to the text.
+ * </p>
+ *
+ * @see org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer
+ *
+ * @author Christian Bauer
+ */
+public class WikiTextParser extends SeamTextParser {
+
+ private int macroPosition = 0;
+ private int linkCounter = 0;
+
+ private WikiTextRenderer renderer;
+
+ private boolean resolveLinks;
+ private WikiLinkResolver resolver;
+ private Long currentAreaNumber;
+
+ private Map<String, WikiLink> resolvedLinks = new HashMap<String,
WikiLink>();
+ private List<WikiLink> attachments = new ArrayList<WikiLink>();
+ private List<WikiLink> externalLinks = new ArrayList<WikiLink>();
+ private Set<String> macroNames = new HashSet<String>();
+ private boolean renderDuplicateMacros;
+
+ public WikiTextParser(String wikiText, boolean renderDuplicateMacros, boolean
resolveLinks) {
+ super(new SeamTextLexer(new StringReader(wikiText)));
+ this.renderDuplicateMacros = renderDuplicateMacros;
+ this.resolveLinks = resolveLinks;
+
+ setSanitizer(
+ new DefaultSanitizer() {
+ @Override
+ public void validateLinkTagURI(String s) throws SemanticException {
+ // NOOP, we validate that later in linkTag()
+ }
+ }
+ );
+ }
+
+ /**
+ * Mandatory, you need to set a renderer before starting the parer.
+ *
+ * @param renderer an implementation of WikiTextRenderer
+ * @return the called instance
+ */
+ public WikiTextParser setRenderer(WikiTextRenderer renderer) {
+ this.renderer = renderer;
+ return this;
+ }
+
+ /**
+ * Mandatory, you need to set a resolver before starting the parer.
+ *
+ * @param resolver an implementation of WikiLinkresolver
+ * @return the called instance
+ */
+ public WikiTextParser setResolver(WikiLinkResolver resolver) {
+ this.resolver = resolver;
+ return this;
+ }
+
+ /*
+ * The render/link resolving base
+ * @return the called instance
+ */
+
+ public void setCurrentAreaNumber(Long currentAreaNumber) {
+ this.currentAreaNumber = currentAreaNumber;
+ }
+
+ /**
+ * Start parsing the wiki text and resolve wiki links and wiki plugins.
+ * <p>
+ * @throws ANTLRException if lexer or parser errors occur, see
+ */
+ public void parse() throws ANTLRException {
+ if (renderer == null) throw new IllegalStateException("WikiTextParser
requires not null setRenderer()");
+
+ if (resolveLinks) {
+ if (resolver == null) throw new IllegalStateException("WikiTextParser
requires not null setResolver()");
+ if (currentAreaNumber == null) throw new
IllegalStateException("WikiTextParser requires not null
setCurrentAreaNumber()");
+ }
+
+ startRule();
+
+ renderer.setAttachmentLinks(attachments);
+ renderer.setExternalLinks(externalLinks);
+ }
+
+ protected String linkTag(String descriptionText, String linkText) {
+ if (!resolveLinks) {
+ // Don't resolve links, just call back to renderer for simple inline
rendering of what we have
+ WikiLink unresolvedLink = new WikiLink(false, false);
+ unresolvedLink.setDescription(descriptionText);
+ unresolvedLink.setUrl(linkText);
+ return renderer.renderInternalLink(unresolvedLink);
+ }
+
+ resolver.resolveLinkText(currentAreaNumber, resolvedLinks, linkText);
+ WikiLink link = resolvedLinks.get((linkText));
+ if (link == null) return "";
+
+ // Set an internal identifier, used for attachments and external links we later
push into a hashmap into the contexts
+ link.setIdentifier(linkCounter++);
+
+ // Override the description of the WikiLink with description found in tag
+ String finalDescriptionText =
+ (descriptionText!=null && descriptionText.length() > 0 ?
descriptionText : link.getDescription());
+ link.setDescription(finalDescriptionText);
+
+ // Link to upload (inline or attached)
+ if (link.getFile() != null &&
link.getFile().isInstance(WikiUpload.class)) {
+ WikiUpload upload = (WikiUpload)link.getFile();
+ if (upload.isAttachedToDocuments()) {
+ if (!attachments.contains(link)) {
+ attachments.add(link);
+ }
+ return renderer.renderFileAttachmentLink((attachments.indexOf(link)+1),
link);
+ } else {
+ return renderer.renderThumbnailImageLink(link);
+ }
+ }
+
+ // External link
+ if (link.isExternal()) {
+ if (!externalLinks.contains(link)) externalLinks.add(link);
+ return renderer.renderExternalLink(link);
+ }
+
+ // Regular link
+ return renderer.renderInternalLink(link);
+ }
+
+ protected String paragraphOpenTag() {
+ return renderer.renderParagraphOpenTag();
+ }
+
+ protected String preformattedOpenTag() {
+ return renderer.renderPreformattedOpenTag();
+ }
+
+ protected String blockquoteOpenTag() {
+ return renderer.renderBlockquoteOpenTag();
+ }
+
+ protected String headline1(String headline) {
+ return renderer.renderHeadline1(headline);
+ }
+
+ protected String headline2(String headline) {
+ return renderer.renderHeadline2(headline);
+ }
+
+ protected String headline3(String headline) {
+ return renderer.renderHeadline3(headline);
+ }
+
+ protected String headline4(String headline) {
+ return renderer.renderHeadline4(headline);
+ }
+
+ protected String orderedListOpenTag() {
+ return renderer.renderOrderedListOpenTag();
+ }
+
+ protected String orderedListItemOpenTag() {
+ return renderer.renderOrderedListItemOpenTag();
+ }
+
+ protected String unorderedListOpenTag() {
+ return renderer.renderUnorderedListOpenTag();
+ }
+
+ protected String unorderedListItemOpenTag() {
+ return renderer.renderUnorderedListItemOpenTag();
+ }
+
+ protected String emphasisOpenTag() {
+ return renderer.renderEmphasisOpenTag();
+ }
+
+ protected String emphasisCloseTag() {
+ return renderer.renderEmphasisCloseTag();
+ }
+
+ protected String macroInclude(Macro macro) {
+ if (macro.name == null || macro.name.length() == 0) return "";
+
+ if ( (macroNames.contains(macro.name) && renderDuplicateMacros) ||
!macroNames.contains(macro.name)) {
+ macroNames.add(macro.name);
+
+ WikiTextMacro wikiTextMacro = new WikiTextMacro(macro.name,
macroPosition++);
+ wikiTextMacro.setParams(macro.params);
+
+ return renderer.renderMacro(wikiTextMacro);
+ } else {
+ macroPosition++;
+ return "[Can't use the same macro twice!]";
+ }
+ }
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/engine/WikiTextParser.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/DefaultWikiTextRenderer.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/renderer/DefaultWikiTextRenderer.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/DefaultWikiTextRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/DefaultWikiTextRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,124 @@
+package org.jboss.seam.wiki.core.wikitext.renderer;
+
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+import org.jboss.seam.wiki.core.ui.WikiURLRenderer;
+import org.jboss.seam.Component;
+
+import java.util.List;
+
+/**
+ * Convenience class that renders some sensible defaults that apply for the wiki.
+ *
+ * @author Christian Bauer
+ */
+public class DefaultWikiTextRenderer implements WikiTextRenderer {
+
+ protected WikiURLRenderer wikiURLRenderer = (WikiURLRenderer)
Component.getInstance(WikiURLRenderer.class);
+
+ public static enum Headline {
+ H1, H2, H3, H4
+ }
+
+ public String renderInternalLink(WikiLink internalLink) {
+ return !internalLink.isBroken() ?
+ "<a href=\""
+ + wikiURLRenderer.renderURL(internalLink.getFile())
+ + "\">"
+ + internalLink.getDescription()
+ + "</a>" : "[Broken Link]";
+ }
+
+ public String renderExternalLink(WikiLink externalLink) {
+ return "<a href=\""
+ + externalLink.getUrl()
+ + "\">"
+ + externalLink.getDescription()
+ + "</a>";
+ }
+
+ public String renderFileAttachmentLink(int attachmentNumber, WikiLink attachmentLink)
{
+ return "[Attachment]";
+ }
+
+ public String renderThumbnailImageLink(WikiLink link) {
+ return "[Embedded Image]";
+ }
+
+ public String renderMacro(WikiTextMacro macro) {
+ return "[Macro]";
+ }
+
+ public void setAttachmentLinks(List<WikiLink> attachmentLinks) {}
+ public void setExternalLinks(List<WikiLink> externalLinks) {}
+
+ public String renderParagraphOpenTag() {
+ return "<p class=\"wikiPara\">\n";
+ }
+
+ public String renderPreformattedOpenTag() {
+ return "<pre class=\"wikiPreformatted\">\n";
+ }
+
+ public String renderBlockquoteOpenTag() {
+ return "<blockquote class=\"wikiBlockquote\">\n";
+ }
+
+ public String renderHeadline1(String headline) {
+ return "<h1 class=\"wikiHeadline1\"
id=\""+getHeadlineId(Headline.H1, headline)+"\">"
+ + getHeadlineLink(Headline.H1, headline)
+ + "</h1>";
+ }
+
+ public String renderHeadline2(String headline) {
+ return "<h2 class=\"wikiHeadline2\"
id=\""+getHeadlineId(Headline.H2, headline)+"\">"
+ + getHeadlineLink(Headline.H2, headline)
+ + "</h2>";
+ }
+
+ public String renderHeadline3(String headline) {
+ return "<h3 class=\"wikiHeadline3\"
id=\""+getHeadlineId(Headline.H3, headline)+"\">"
+ + getHeadlineLink(Headline.H3, headline)
+ + "</h3>";
+ }
+
+ public String renderHeadline4(String headline) {
+ return "<h4 class=\"wikiHeadline4\"
id=\""+getHeadlineId(Headline.H4, headline)+"\">"
+ + getHeadlineLink(Headline.H4, headline)
+ + "</h4>";
+ }
+
+
+ public String renderOrderedListOpenTag() {
+ return "<ol class=\"wikiOrderedList\">\n";
+ }
+
+ public String renderOrderedListItemOpenTag() {
+ return "<li class=\"wikiOrderedListItem\">";
+ }
+
+ public String renderUnorderedListOpenTag() {
+ return "<ul class=\"wikiUnorderedList\">\n";
+ }
+
+ public String renderUnorderedListItemOpenTag() {
+ return "<li class=\"wikiUnorderedListItem\">";
+ }
+
+ public String renderEmphasisOpenTag() {
+ return "<i class=\"wikiEmphasis\">";
+ }
+
+ public String renderEmphasisCloseTag() {
+ return "</i>";
+ }
+
+ protected String getHeadlineId(Headline h, String headline) {
+ return "";
+ }
+
+ protected String getHeadlineLink(Headline h, String headline) {
+ return headline;
+ }
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/DefaultWikiTextRenderer.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/MacroWikiTextRenderer.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/renderer/MacroWikiTextRenderer.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/MacroWikiTextRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/MacroWikiTextRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,39 @@
+package org.jboss.seam.wiki.core.wikitext.renderer;
+
+import java.util.Set;
+import java.util.LinkedHashSet;
+
+import antlr.RecognitionException;
+import antlr.ANTLRException;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiTextParser;
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+
+public class MacroWikiTextRenderer extends NullWikiTextRenderer {
+
+ private Set<WikiTextMacro> macros = new LinkedHashSet<WikiTextMacro>();
+
+ @Override
+ public String renderMacro(WikiTextMacro macro) {
+ macros.add(macro);
+ return null;
+ }
+
+ public Set<WikiTextMacro> getMacros() {
+ return macros;
+ }
+
+ public static MacroWikiTextRenderer renderMacros(String wikiText) {
+ WikiTextParser parser = new WikiTextParser(wikiText, false, false);
+ MacroWikiTextRenderer renderer = new MacroWikiTextRenderer();
+ try {
+ parser.setRenderer(renderer).parse();
+ } catch (RecognitionException rex) {
+ // Swallowing, we don't really care if there was a parse error
+ } catch (ANTLRException ex) {
+ // All other errors are fatal;
+ throw new RuntimeException(ex);
+ }
+ return renderer;
+ }
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/MacroWikiTextRenderer.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/NullWikiTextRenderer.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/renderer/NullWikiTextRenderer.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/NullWikiTextRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/NullWikiTextRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,37 @@
+package org.jboss.seam.wiki.core.wikitext.renderer;
+
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+
+import java.util.List;
+
+/**
+ * Renders nothing for links and macros and unstyled HTML for anything else.
+ *
+ * @author Christian Bauer
+ */
+public class NullWikiTextRenderer implements WikiTextRenderer {
+
+ public String renderInternalLink(WikiLink internalLink) { return null; }
+ public String renderExternalLink(WikiLink externalLink) { return null; }
+ public String renderFileAttachmentLink(int attachmentNumber, WikiLink attachmentLink)
{ return null; }
+ public String renderThumbnailImageLink(WikiLink link) { return null; }
+ public void setAttachmentLinks(List<WikiLink> attachmentLinks) {}
+ public void setExternalLinks(List<WikiLink> externalLinks) {}
+ public String renderMacro(WikiTextMacro macro) { return null; }
+ public String renderParagraphOpenTag() { return "<p>\n"; }
+ public String renderPreformattedOpenTag() { return "<pre>\n"; }
+ public String renderBlockquoteOpenTag() { return "<blockquote>\n"; }
+ public String renderHeadline1(String headline) { return
"<h1>"+headline+"</h1>"; }
+ public String renderHeadline2(String headline) { return
"<h2>"+headline+"</h2>"; }
+ public String renderHeadline3(String headline) { return
"<h3>"+headline+"</h3>"; }
+ public String renderHeadline4(String headline) { return
"<h4>"+headline+"</h4>"; }
+ public String renderOrderedListOpenTag() { return "<ol>\n"; }
+ public String renderOrderedListItemOpenTag() { return "<li>"; }
+ public String renderUnorderedListOpenTag() { return "<ul>\n"; }
+ public String renderUnorderedListItemOpenTag() { return "<li>"; }
+ public String renderEmphasisOpenTag() { return "<i>"; }
+ public String renderEmphasisCloseTag() { return "</i>"; }
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/NullWikiTextRenderer.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/WikiTextRenderer.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/engine/WikiTextRenderer.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/WikiTextRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/WikiTextRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,39 @@
+package org.jboss.seam.wiki.core.wikitext.renderer;
+
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+
+import java.util.List;
+
+/**
+ * Called by the WikiTextParser to render [A Link=>Target] and [<=MacroName].
+ *
+ * @author Christian Bauer
+ */
+public interface WikiTextRenderer {
+
+ public static final String HEADLINE_ID_PREFIX = "H-";
+
+ public String renderInternalLink(WikiLink internalLink);
+ public String renderExternalLink(WikiLink externalLink);
+ public String renderThumbnailImageLink(WikiLink link);
+ public String renderFileAttachmentLink(int attachmentNumber, WikiLink
attachmentLink);
+ public String renderMacro(WikiTextMacro macro);
+
+ public String renderParagraphOpenTag();
+ public String renderPreformattedOpenTag();
+ public String renderBlockquoteOpenTag();
+ public String renderHeadline1(String headline);
+ public String renderHeadline2(String headline);
+ public String renderHeadline3(String headline);
+ public String renderHeadline4(String headline);
+ public String renderOrderedListOpenTag();
+ public String renderOrderedListItemOpenTag();
+ public String renderUnorderedListOpenTag();
+ public String renderUnorderedListItemOpenTag();
+ public String renderEmphasisOpenTag();
+ public String renderEmphasisCloseTag();
+
+ public void setAttachmentLinks(List<WikiLink> attachmentLinks);
+ public void setExternalLinks(List<WikiLink> externalLinks);
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/WikiTextRenderer.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroComponentHandler.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/MacroComponentHandler.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroComponentHandler.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroComponentHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,26 @@
+package org.jboss.seam.wiki.core.wikitext.renderer.jsf;
+
+import com.sun.facelets.FaceletContext;
+import com.sun.facelets.tag.jsf.ComponentConfig;
+import com.sun.facelets.tag.jsf.ComponentHandler;
+
+import javax.faces.component.UIComponent;
+
+/**
+ * Chaining up the macros in the JSF component tree.
+ *
+ * @author Pete Muir
+ */
+public class MacroComponentHandler extends ComponentHandler {
+
+ public MacroComponentHandler(ComponentConfig config) {
+ super(config);
+ }
+
+ @Override
+ protected void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent
parent) {
+ super.onComponentCreated(ctx, c, parent);
+ parent.getAttributes().put(UIMacro.NEXT_MACRO,
c.getClientId(ctx.getFacesContext()));
+ }
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroComponentHandler.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Added:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroIncludeTextRenderer.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroIncludeTextRenderer.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/MacroIncludeTextRenderer.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,257 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.renderer.jsf;
+
+import org.jboss.seam.wiki.core.wikitext.renderer.NullWikiTextRenderer;
+import org.jboss.seam.wiki.core.plugin.PluginRegistry;
+import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
+import org.jboss.seam.wiki.core.plugin.metamodel.MacroPluginModule;
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+import org.jboss.seam.core.Events;
+import org.jboss.seam.core.ResourceLoader;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.Component;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+import org.ajax4jsf.component.html.HtmlLoadStyle;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+import java.io.IOException;
+import java.net.URL;
+
+import com.sun.facelets.FaceletContext;
+import com.sun.facelets.el.VariableMapperWrapper;
+import com.sun.facelets.tag.jsf.ComponentSupport;
+
+import javax.faces.component.UIComponent;
+import javax.el.VariableMapper;
+
+/**
+ * Creates the included macro template components as first-class components in the JSF
view
+ * as children of the <tt>UIWikiFormattedText</tt> component.
+ *
+ * <p>
+ * This routine parses the wiki text and for each encountered wiki macro, it tries to
+ * include an XHTML template. If no template is found, we do nothing. If a template is
+ * found, we also include its CSS into the document header, then add it to the parent
+ * component, the <tt>UIWikiFormattedText</tt> we are handling. This parent
component
+ * keeps a map of <tt>WikiMacro</tt> instances, keyed by position in the
rendered
+ * wiki text. This map of macros can be pulled out later, when we render the JSF view
+ * tree.
+ * </p>
+ * <p>
+ * Macros are never reentrant, that means a macro can not render itself. To avoid this,
+ * we push a macro onto a stack before including it in the component tree, after checking
if
+ * it is already present on the stack. If it is already present, we log a warning and
don't do
+ * anything. After rendering, we pop the stack. The stack is held in the PAGE context.
+ * </p>
+ * <p>
+ * This code is complicated, because Facelets is complicated. Do not touch it unless you
+ * are absolutely sure you know what you are doing.
+ * </p>
+ *
+ * @author Christian Bauer
+ */
+public class MacroIncludeTextRenderer extends NullWikiTextRenderer {
+
+ private Log log = Logging.getLog(WikiFormattedTextHandler.class);
+
+ public static final String MACRO_STACK_PAGE_VARIABLE = "macroStack";
+
+ // A collection of all macros (whether they have templates or not) that we found in
this piece of wiki text
+ private Set<String> macrosFoundInWikiText = new HashSet<String>();
+
+ UIWikiFormattedText parent;
+ FaceletContext context;
+ boolean enableTransientMacros;
+
+ public MacroIncludeTextRenderer(UIWikiFormattedText parent, FaceletContext context,
boolean enableTransientMacros) {
+ this.parent = parent;
+ this.context = context;
+ this.enableTransientMacros = enableTransientMacros;
+ }
+
+ @Override
+ public String renderMacro(WikiTextMacro wikiTextMacro) {
+ log.debug("=== found macro in wiki text: " + wikiTextMacro);
+
+ // Check reentrancy
+ if (!isMacroOnPageStack(wikiTextMacro)) {
+ log.debug("adding macro to page macro stack");
+ getPageMacroStack().push(wikiTextMacro);
+ } else {
+ log.warn("macros are not reentrant, duplicate macro on page stack:
" + wikiTextMacro);
+ return null;
+ }
+
+ // Check if the wikiTextMacro actually is registered, we don't build unknown
macros
+ WikiPluginMacro pluginMacro =
PluginRegistry.instance().createWikiPluginMacro(wikiTextMacro);
+ if (pluginMacro == null) {
+ log.info("macro is not bound in plugin registry: " +
wikiTextMacro);
+ getPageMacroStack().pop();
+ return null;
+ }
+
+ // Check if we can find the template to include for this wikiTextMacro
+ String macroIncludePath = getMacroIncludePath(pluginMacro);
+ if (macroIncludePath == null) {
+ getPageMacroStack().pop();
+ return null;
+ }
+
+ // Before we build the nested components, set the WikiMacro instance in the PAGE
context under a
+ // unique name, so we can use a VariableMapper later and alias this as
'currentMacro'
+ String macroPageVariableName = pluginMacro.getPageVariableName();
+ log.debug("setting WikiMacro instance in PAGE context as variable named:
" + macroPageVariableName);
+ Contexts.getPageContext().set(macroPageVariableName, pluginMacro);
+
+ // Whoever wants to do something before we finally build the XHTML template
+ log.debug("firing VIEW_BUILD macro event");
+
Events.instance().raiseEvent(pluginMacro.getCallbackEventName(WikiPluginMacro.CallbackEvent.VIEW_BUILD),
pluginMacro);
+
+ // This is where the magic happens... the UIWikiFormattedText component should
have one child after that, a UIMacro
+ includeMacroFacelet(pluginMacro, macroIncludePath, context, parent);
+
+ // Now get the identifier of the newly created UIMacro instance and set it for
future use
+ Object macroId = parent.getAttributes().get(UIMacro.NEXT_MACRO);
+ if (macroId != null) {
+ pluginMacro.setClientId(macroId.toString());
+ parent.getAttributes().remove(UIMacro.NEXT_MACRO);
+ } else {
+ // Best guess based wikiTextMacro renderer, needed during reRendering when we
don't build the child
+ // - only then is NEXT_MACRO set by the MacroComponentHandler
+ macroId =
+ parent.getChildren().get(
+ parent.getChildCount() - 1
+ ).getClientId(context.getFacesContext());
+ pluginMacro.setClientId(macroId.toString());
+ }
+
+ // Put an optional CSS include in the header of the wiki document we are
rendering in.
+ // (This needs to happen after the clientId is set, as CSS resource path
rendering needs to
+ // know if it occurs in a JSF request (clientId present) or not.
+ includeMacroCSS(pluginMacro, parent);
+
+ // We need to make the UIMacro child transient if we run in the wiki text editor
preview. The reason
+ // is complicated: If we don't make it transient, all value expressions
inside the wikiTextMacro templates that
+ // use 'currentMacro' will refer to the "old" saved
ValueExpression and then of course to the "old"
+ // VariableMapper. In other words: We need to make sure that the subtree is
completely fresh every
+ // time the wiki text preview is reRendered, otherwise we never get a
'currentMacro' binding updated.
+ // This also means that VariableMapper is a completely useless construct, because
it is basically an
+ // alias that is evaluated just once.
+ // Note: This means we can't click on form elements of any
plugin/wikiTextMacro template in the preview. This
+ // should be solved by not showing/ghosting any form elements during preview.
+ if (enableTransientMacros) {
+ log.debug("setting macro to transient rendering, not storing its state
between renderings: " + pluginMacro);
+ UIMacro uiMacro = (UIMacro) ComponentSupport.findChild(parent,
macroId.toString());
+ uiMacro.setTransient(true);
+ }
+
+ // Finally, pop the wikiTextMacro stack of the page, then transport the finished
WikiMacro instance into
+ // the UIWikiFormattedText component for rendering - we are done building the
component tree at this
+ // point.
+ getPageMacroStack().pop();
+ parent.addMacroWithTemplate(pluginMacro);
+
+ // Well, we don't render anything here...
+ return null;
+ }
+
+ private String getMacroIncludePath(WikiPluginMacro pluginMacro) {
+
+ // Check singleton configuration
+ if
(pluginMacro.getMetadata().isRenderOptionSet(MacroPluginModule.RenderOption.SINGLETON)
&&
+ macrosFoundInWikiText.contains(pluginMacro.getName())) {
+ log.warn("macro is a SINGLETON, can not be used twice in the same
document area: " + pluginMacro);
+ return null;
+ } else {
+ macrosFoundInWikiText.add(pluginMacro.getName());
+ }
+
+ // Check skin configuration
+ String currentSkin = (String) Component.getInstance("skin");
+ if (!pluginMacro.getMetadata().isAvailableForSkin(currentSkin)) {
+ log.warn("macro is not available for skin '" + currentSkin +
"': " + pluginMacro);
+ return null;
+ }
+
+ // Try to get an XHTML template, our source for building nested components
+ // Fun with slashes: For some reason, Facelets really needs a slash at the start,
otherwise
+ // it doesn't use my custom ResourceResolver...
+ String includePath = "/" +
pluginMacro.getMetadata().getPlugin().getPackageDefaultTemplatePath(pluginMacro.getName());
+ URL faceletURL = ResourceLoader.instance().getResource(includePath);
+ if (faceletURL == null) {
+ log.debug("macro has no default include file, not building any
components: " + pluginMacro);
+ return null;
+ } else {
+ log.debug("using default template include as a resource from package:
" + includePath);
+ }
+
+ return includePath;
+ }
+
+ private void includeMacroFacelet(WikiPluginMacro pluginMacro, String includePath,
FaceletContext ctx, UIComponent parent) {
+ VariableMapper orig = ctx.getVariableMapper();
+ try {
+ log.debug("setting 'currentMacro' as an EL variable, resolves
dynamically to WikiMacro instance in PAGE context");
+ ctx.setVariableMapper(new VariableMapperWrapper(orig));
+ ctx.getVariableMapper().setVariable(
+ WikiPluginMacro.CURRENT_MACRO_EL_VARIABLE,
+ Expressions.instance().createValueExpression("#{" +
pluginMacro.getPageVariableName() + "}").toUnifiedValueExpression()
+ );
+
+ log.debug("including macro facelets file from path: " +
includePath);
+ ctx.includeFacelet(parent, includePath);
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ ctx.setVariableMapper(orig);
+ }
+ }
+
+ private void includeMacroCSS(WikiPluginMacro pluginMacro, UIComponent cmp) {
+
+ String cssPath = "/" +
pluginMacro.getMetadata().getPlugin().getPackageCSSPath() + "/" +
pluginMacro.getName() + ".css";
+ log.debug("trying to load CSS resource from classpath: " + cssPath);
+ if (ResourceLoader.instance().getResource(cssPath) != null) {
+ String cssRequestURIPath = pluginMacro.getRequestCSSPath() + "/" +
pluginMacro.getName() + ".css";
+ log.debug("including macro CSS file, rendering URI for document head:
" + cssRequestURIPath);
+
+ // Use Ajax4JSF loader, it can do what we want - add a CSS <link> to
the HTML <head>
+ HtmlLoadStyle style = new HtmlLoadStyle();
+ style.setSrc(cssRequestURIPath);
+
+ cmp.getChildren().add(style);
+ // Clear these out in the next build phase
+ ComponentSupport.markForDeletion(style);
+ } else {
+ log.debug("no CSS resource found for macro");
+ }
+ }
+
+ private Stack<WikiTextMacro> getPageMacroStack() {
+ if (Contexts.getPageContext().get(MACRO_STACK_PAGE_VARIABLE) == null) {
+ log.debug("macro page stack is null, creating new stack for this
page");
+ Contexts.getPageContext().set(MACRO_STACK_PAGE_VARIABLE, new
Stack<WikiTextMacro>());
+ }
+ return
(Stack<WikiTextMacro>)Contexts.getPageContext().get(MACRO_STACK_PAGE_VARIABLE);
+ }
+
+ private boolean isMacroOnPageStack(WikiTextMacro macro) {
+ Stack<WikiTextMacro> macroStack = getPageMacroStack();
+ for (WikiTextMacro macroOnPageStack : macroStack) {
+ if (macroOnPageStack.getName().equals(macro.getName())) return true;
+ }
+ return false;
+ }
+
+}
+
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIMacro.java
(from rev 8330, trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIMacro.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIMacro.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIMacro.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,35 @@
+package org.jboss.seam.wiki.core.wikitext.renderer.jsf;
+
+import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
+
+import javax.faces.component.UINamingContainer;
+
+/**
+ * A wrapper component that applies to macro includes.
+ * <p>
+ * A macro XHTML template must have a <tt><wiki:macro></tt>
root element.
+ * </p>
+ *
+ * @author Pete Muir
+ */
+public class UIMacro extends UINamingContainer {
+
+ public static final String COMPONENT_FAMILY =
"org.jboss.seam.wiki.core.ui.UIMacro";
+
+ public static final String NEXT_MACRO =
"org.jboss.seam.wiki.core.ui.UIMacro.nextMacro";
+
+ @Override
+ public String getFamily() {
+ return COMPONENT_FAMILY;
+ }
+
+ private WikiPluginMacro wikiPluginMacro;
+
+ public WikiPluginMacro getWikiMacro() {
+ return wikiPluginMacro;
+ }
+
+ public void setWikiMacro(WikiPluginMacro wikiPluginMacro) {
+ this.wikiPluginMacro = wikiPluginMacro;
+ }
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIMacro.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIWikiFormattedText.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIWikiFormattedText.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIWikiFormattedText.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,296 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.renderer.jsf;
+
+import antlr.ANTLRException;
+import antlr.RecognitionException;
+import org.jboss.seam.Component;
+import org.jboss.seam.core.Events;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.ui.util.JSF;
+import org.jboss.seam.wiki.core.model.WikiFile;
+import org.jboss.seam.wiki.core.model.WikiUploadImage;
+import org.jboss.seam.wiki.core.model.WikiTextMacro;
+import org.jboss.seam.wiki.core.wikitext.renderer.DefaultWikiTextRenderer;
+import org.jboss.seam.wiki.util.WikiUtil;
+import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiFormattedTextValidator;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiTextParser;
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Uses WikiTextParser and WikiLinkResolver to render Seam Text markup with wiki links.
+ *
+ * <p>
+ * Any lexer/parser error results in WARN level log message, you can disable this in your
logging
+ * configuration by raising the log level for this class to ERROR.
+ * </p>
+ *
+ * @author Christian Bauer
+ */
+public class UIWikiFormattedText extends UIOutput {
+
+ Log log = Logging.getLog(UIWikiFormattedText.class);
+
+ public static final String ATTR_LINK_STYLE_CLASS =
"linkStyleClass";
+ public static final String ATTR_BROKEN_LINK_STYLE_CLASS =
"brokenLinkStyleClass";
+ public static final String ATTR_ATTACHMENT_LINK_STYLE_CLASS =
"attachmentLinkStyleClass";
+ public static final String ATTR_THUMBNAIL_LINK_STYLE_CLASS =
"thumbnailLinkStyleClass";
+ public static final String ATTR_INTERNAL_TARGET_FRAME =
"internalTargetFrame";
+ public static final String ATTR_EXTERNAL_TARGET_FRAME =
"externalTargetFrame";
+ public static final String ATTR_LINK_BASE_FILE =
"linkBaseFile";
+ public static final String ATTR_CURRENT_AREA_NUMBER =
"currentAreaNumber";
+ public static final String ATTR_ENABLE_MACRO_RENDERING =
"enableMacroRendering";
+ public static final String ATTR_ENABLE_TRANSIENT_MACROS =
"enableTransientMacros";
+
+ private Map<Integer, WikiPluginMacro> macrosWithTemplateByPosition;
+
+ public static final String COMPONENT_FAMILY =
"org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
+
+ public static final String COMPONENT_TYPE =
"org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
+
+ public UIWikiFormattedText() {
+ super();
+ macrosWithTemplateByPosition = new HashMap<Integer, WikiPluginMacro>();
+ }
+
+ @Override
+ public String getFamily() {
+ return COMPONENT_FAMILY;
+ }
+
+ @Override
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ @Override
+ public String getRendererType() {
+ return null;
+ }
+
+ @Override
+ public void encodeBegin(FacesContext facesContext) throws IOException {
+ if (!isRendered() || getValue() == null) return;
+ log.debug(">>> ENCODE BEGIN of WikiFormattedText component");
+
+ // Use the WikiTextParser to resolve macros
+ WikiTextParser parser = new WikiTextParser((String) getValue(), true, true);
+
+ // Resolve the base document and directory we are resolving against
+ final WikiFile baseFile = (WikiFile)getAttributes().get(ATTR_LINK_BASE_FILE);
+ final Long currentAreaNumber =
(Long)getAttributes().get(ATTR_CURRENT_AREA_NUMBER);
+ parser.setCurrentAreaNumber(currentAreaNumber);
+
+
parser.setResolver((WikiLinkResolver)Component.getInstance("wikiLinkResolver"));
+
+ // TODO: Externalize this to separate class, extensible
+ // Set a customized renderer for parser macro callbacks
+ class WikiFormattedTextRenderer extends DefaultWikiTextRenderer {
+
+ @Override
+ public String renderInternalLink(WikiLink internalLink) {
+ return "<a href=\""
+ + (
+ internalLink.isBroken()
+ ? internalLink.getUrl()
+ : wikiURLRenderer.renderURL(internalLink.getFile())
+ )
+ + (
+ internalLink.getFragment() != null
+ ? "#"+internalLink.getEncodedFragment()
+ : ""
+ )
+ + "\" target=\""
+ + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
+ + "\" class=\""
+ + (internalLink.isBroken() ?
getAttributes().get(ATTR_BROKEN_LINK_STYLE_CLASS)
+ : getAttributes().get(ATTR_LINK_STYLE_CLASS)) +
"\">"
+ + internalLink.getDescription() + "</a>";
+ }
+
+ @Override
+ public String renderExternalLink(WikiLink externalLink) {
+ return "<a href=\""
+ + WikiUtil.escapeEmailURL(externalLink.getUrl())
+ + "\" target=\""
+ + (getAttributes().get(ATTR_EXTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_EXTERNAL_TARGET_FRAME) : "")
+ + "\" class=\""
+ + (externalLink.isBroken() ?
getAttributes().get(ATTR_BROKEN_LINK_STYLE_CLASS)
+ : getAttributes().get(ATTR_LINK_STYLE_CLASS)) +
"\">"
+ + WikiUtil.escapeEmailURL(externalLink.getDescription()) +
"</a>";
+ }
+
+ @Override
+ public String renderFileAttachmentLink(int attachmentNumber, WikiLink
attachmentLink) {
+ return "<a href=\""
+ + wikiURLRenderer.renderURL(baseFile)
+ + "#attachment" + attachmentNumber
+ + "\" target=\""
+ + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
+ + "\" class=\""
+ + getAttributes().get(ATTR_ATTACHMENT_LINK_STYLE_CLASS) +
"\">"
+ + attachmentLink.getDescription() + "[" +
attachmentNumber + "]" + "</a>";
+ }
+
+ @Override
+ public String renderThumbnailImageLink(WikiLink link) {
+
+ // TODO: This is not typesafe and clean, need different rendering
strategy for WikiUpload subclasses
+ WikiUploadImage image = (WikiUploadImage)link.getFile();
+ if (image.getThumbnail() == 'F') {
+ // Full size display, no thumbnail
+ //TODO: Make sure we really don't need this - but it messes up
the comment form conversation:
+ //String imageUrl = WikiUtil.renderURL(image) +
"&cid=" + Conversation.instance().getId();
+ String imageUrl = wikiURLRenderer.renderURL(image);
+ return "<img src='"+ imageUrl + "'" +
+ " width='"+ image.getSizeX()+"'"
+
+ " height='"+ image.getSizeY()
+"'/>";
+ } else {
+ // Thumbnail with link display
+
+ //TODO: Make sure we really don't need this - but it messes up
the comment form conversation:
+ // String thumbnailUrl = WikiUtil.renderURL(image) +
"&thumbnail=true&cid=" + Conversation.instance().getId();
+ String thumbnailUrl = wikiURLRenderer.renderURL(image) +
"?thumbnail=true";
+
+ return "<a href=\""
+ + (link.isBroken() ? link.getUrl() :
wikiURLRenderer.renderURL(image))
+ + "\" target=\""
+ + (getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) != null ?
getAttributes().get(ATTR_INTERNAL_TARGET_FRAME) : "")
+ + "\" class=\""
+ + getAttributes().get(ATTR_THUMBNAIL_LINK_STYLE_CLASS) +
"\"><img src=\""
+ + thumbnailUrl + "\"/></a>";
+ }
+ }
+
+ @Override
+ public String renderMacro(WikiTextMacro macro) {
+
+ WikiPluginMacro pluginMacroWithTemplate =
macrosWithTemplateByPosition.get(macro.getPosition());
+ if (pluginMacroWithTemplate == null) {
+ log.debug("macro does not have an XHTML template/include,
skipping: " + macro);
+ return "";
+ }
+
+ log.debug("firing BEFORE_VIEW_RENDER macro event");
+ Events.instance().raiseEvent(
+
pluginMacroWithTemplate.getCallbackEventName(WikiPluginMacro.CallbackEvent.BEFORE_VIEW_RENDER),
+ pluginMacroWithTemplate
+ );
+
+ log.debug("preparing include rendering for macro: " +
pluginMacroWithTemplate);
+ UIComponent child = findComponent( pluginMacroWithTemplate.getClientId()
);
+ log.debug("JSF child client identifier: " +
child.getClientId(getFacesContext()));
+ ResponseWriter originalResponseWriter =
getFacesContext().getResponseWriter();
+ StringWriter stringWriter = new StringWriter();
+ ResponseWriter tempResponseWriter = originalResponseWriter
+ .cloneWithWriter(stringWriter);
+ getFacesContext().setResponseWriter(tempResponseWriter);
+
+ try {
+ log.debug("rendering template of macro: " +
pluginMacroWithTemplate);
+ JSF.renderChild(getFacesContext(), child);
+
+ log.debug("firing AFTER_VIEW_RENDER macro event");
+ Events.instance().raiseEvent(
+
pluginMacroWithTemplate.getCallbackEventName(WikiPluginMacro.CallbackEvent.AFTER_VIEW_RENDER),
+ pluginMacroWithTemplate
+ );
+ }
+ catch (Exception ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ getFacesContext().setResponseWriter(originalResponseWriter);
+ }
+ return stringWriter.getBuffer().toString();
+ }
+
+ @Override
+ public void setAttachmentLinks(List<WikiLink> attachmentLinks) {
+ // Put attachments (wiki links...) into the event context for later
rendering
+ setLinks("wikiTextAttachments", attachmentLinks);
+ }
+
+ @Override
+ public void setExternalLinks(List<WikiLink> externalLinks) {
+ // Put external links (to targets not on this wiki) into the event
context for later rendering
+ setLinks("wikiTextExternalLinks", externalLinks);
+ }
+
+ private void setLinks(String contextVariable, List<WikiLink> links) {
+ // TODO: Need some tricks here with link identifiers and attachment
numbers, right now we just skip this if it's already set
+ /// ... hoping that the first caller was the document renderer and not
the comment renderer - that means comment attachments are broken
+ List<WikiLink> contextLinks =
(List<WikiLink>)Contexts.getEventContext().get(contextVariable);
+ if (contextLinks == null || contextLinks.size()==0) {
+ Contexts.getEventContext().set(contextVariable, links);
+ }
+ /*
+ Map<Integer, WikiLink> contextLinks =
+
(Map<Integer,WikiLink>)Contexts.getEventContext().get(contextVariable);
+ if (contextLinks == null) {
+ contextLinks = new HashMap<Integer, WikiLink>();
+ }
+ for (WikiLink link : links) {
+ contextLinks.put(link.getIdentifier(), link);
+ }
+ Contexts.getEventContext().set(contextVariable, contextLinks);
+ */
+ }
+
+ @Override
+ protected String getHeadlineId(Headline h, String headline) {
+ // HTML id attribute has restrictions on valid values... so the easiest
way is to make this a WikiLink
+ return HEADLINE_ID_PREFIX+WikiUtil.convertToWikiName(headline);
+ // We also need to access it correctly, see WikiLink.java and
getHeadLineLink()
+ }
+
+ @Override
+ protected String getHeadlineLink(Headline h, String headline) {
+ return "<a href=\""+
wikiURLRenderer.renderURL(baseFile)+"#"+
WikiTextRenderer.HEADLINE_ID_PREFIX+WikiUtil.convertToWikiName(headline)+"\">"
+ + headline
+ +"</a>";
+ }
+ }
+
+ parser.setRenderer(new WikiFormattedTextRenderer());
+
+ try {
+ log.debug("parsing wiki text for HTML encoding");
+ parser.parse();
+
+ } catch (RecognitionException rex) {
+ // Log a nice message for any lexer/parser errors, users can disable this if
they want to
+ log.warn( WikiFormattedTextValidator.getErrorMessage((String) getValue(),
rex) );
+ } catch (ANTLRException ex) {
+ // All other errors are fatal;
+ throw new RuntimeException(ex);
+ }
+
+ facesContext.getResponseWriter().write(parser.toString());
+
+ log.debug("<<< ENCODE END of WikiFormattedText component");
+ }
+
+ protected void addMacroWithTemplate(WikiPluginMacro pluginMacro) {
+ macrosWithTemplateByPosition.put(pluginMacro.getPosition(), pluginMacro);
+ }
+
+}
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/UIWikiFormattedText.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Copied:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/WikiFormattedTextHandler.java
(from rev 8330,
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java)
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/WikiFormattedTextHandler.java
(rev 0)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/WikiFormattedTextHandler.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.seam.wiki.core.wikitext.renderer.jsf;
+
+import antlr.ANTLRException;
+import antlr.RecognitionException;
+import com.sun.facelets.FaceletContext;
+import com.sun.facelets.tag.MetaRuleset;
+import com.sun.facelets.tag.MetaTagHandler;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagConfig;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiTextParser;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * Creates a <tt>UIWikiFormattedText</tt> JSF component and substitutes macro
names in wiki
+ * text with real macro components in the tree. These <tt>UIMacro</tt>
components are
+ * build from XHTML fragments/includes. Interacts closely with the state of the
+ * <tt>UIWikiFormattedText</tt> component to split component tree creation
and rendering duties.
+ *
+ * @author Peter Muir
+ * @author Christian Bauer
+ */
+public class WikiFormattedTextHandler extends MetaTagHandler {
+
+ private Log log = Logging.getLog(WikiFormattedTextHandler.class);
+
+ private static final String MARK =
"org.jboss.seam.wiki.core.ui.WikiFormattedTextHandler";
+ private TagAttribute valueAttribute;
+
+ public WikiFormattedTextHandler(TagConfig config) {
+ super(config);
+ this.valueAttribute = this.getRequiredAttribute("value");
+ }
+
+ /*
+ * Main apply method called by facelets to create this component.
+ */
+ public void apply(FaceletContext ctx, UIComponent parent) throws IOException,
FacesException, ELException {
+ log.debug(">>> building wiki text components for child of: " +
parent.getClientId(ctx.getFacesContext()));
+ String id = ctx.generateUniqueId(this.tagId);
+ UIComponent cmp = findChildByTagId(parent, id);
+ if (cmp == null) {
+ cmp = createComponent(ctx);
+ cmp.getAttributes().put(MARK, id);
+ }
+ this.nextHandler.apply(ctx, cmp);
+ parent.getChildren().add(cmp);
+ createMacroComponents(ctx, cmp);
+ log.debug("<<< completed building wiki text components for child
of: " + parent.getClientId(ctx.getFacesContext()));
+ }
+
+ private UIComponent createComponent(FaceletContext ctx) {
+ UIWikiFormattedText wikiFormattedText = new UIWikiFormattedText();
+ setAttributes(ctx, wikiFormattedText);
+ return wikiFormattedText;
+ }
+
+ /*
+ * Have to manually wire the component as the Facelets magic wirer
+ * is a package scoped class.
+ */
+ @Override
+ protected void setAttributes(FaceletContext ctx, Object instance) {
+ UIComponent cmp = (UIComponent) instance;
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_LINK_STYLE_CLASS);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_BROKEN_LINK_STYLE_CLASS);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ATTACHMENT_LINK_STYLE_CLASS);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_THUMBNAIL_LINK_STYLE_CLASS);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_INTERNAL_TARGET_FRAME);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_EXTERNAL_TARGET_FRAME);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_LINK_BASE_FILE);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_CURRENT_AREA_NUMBER);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING, false);
+ setAttribute(ctx, cmp, UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS, false);
+ }
+
+ @Override
+ protected MetaRuleset createMetaRuleset(Class type) {
+ return super.createMetaRuleset(type).ignoreAll();
+ }
+
+ private void createMacroComponents(final FaceletContext ctx, final UIComponent
parent) {
+ if (!(parent instanceof UIWikiFormattedText)) return;
+ final UIWikiFormattedText wikiFormattedTextComponent = (UIWikiFormattedText)
parent;
+
+ String unparsed = valueAttribute.getValue(ctx);
+
+ // Don't forget this, transporting the value to the handled component, we
need to render it (again) later
+ wikiFormattedTextComponent.setValue(unparsed);
+
+ if (getAttribute(UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING) == null ||
+
!getAttribute(UIWikiFormattedText.ATTR_ENABLE_MACRO_RENDERING).getBoolean(ctx)) {
+ log.debug("macro rendering disabled");
+ return;
+ }
+
+ // We need to parse the wiki text once (later again for rendering) to find all
macros in the text
+ log.debug("creating macro components from wiki text macros");
+ WikiTextParser parser = new WikiTextParser(unparsed, true, false);
+
+ // This is a special flag that disables/enables caching of ValueExpressions
inside macro templates,
+ // see the MacroIncludeTextRenderer for an explanation...
+ boolean enableTransientMacros =
+ (getAttribute(UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS) != null
&&
+
getAttribute(UIWikiFormattedText.ATTR_ENABLE_TRANSIENT_MACROS).getBoolean(ctx));
+
+ // We use a renderer to implement the callbacks from the parsing and to create
the components in the tree
+ parser.setRenderer(
+ new MacroIncludeTextRenderer(wikiFormattedTextComponent, ctx,
enableTransientMacros)
+ );
+
+ try {
+ parser.parse();
+ } catch (RecognitionException rex) {
+ // Swallow parsing errors, we don't really care here...
+ } catch (ANTLRException ex) {
+ // All other errors are fatal;
+ throw new RuntimeException(ex);
+ }
+ }
+
+ // Some utilities...
+
+ private static UIComponent findChildByTagId(UIComponent parent, String id) {
+ Iterator itr = parent.getFacetsAndChildren();
+ while (itr.hasNext()) {
+ UIComponent c = (UIComponent) itr.next();
+ String cid = (String) c.getAttributes().get(MARK);
+ if (id.equals(cid)) {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ private void setAttribute(FaceletContext ctx, UIComponent cmp, String name) {
+ setAttribute(ctx, cmp, name, null);
+ }
+
+ private void setAttribute(FaceletContext ctx, UIComponent cmp, String name, Object
defaultValue) {
+ TagAttribute attribute = this.getAttribute(name);
+ if (attribute != null) {
+ Object o = attribute.getObject(ctx);
+ if (o == null && defaultValue == null) {
+ throw new IllegalArgumentException("Attribute '" + name +
"' resolved to null and no default value specified");
+ } else if (o == null) {
+ cmp.getAttributes().put(name, defaultValue);
+ } else {
+ cmp.getAttributes().put(name, o);
+ }
+ }
+ }
+
+
+}
\ No newline at end of file
Property changes on:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/wikitext/renderer/jsf/WikiFormattedTextHandler.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Modified:
trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java
===================================================================
---
trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -195,7 +195,6 @@
*/
public class Property implements Comparable, Serializable {
- private Field field;
private String fieldName;
private Class fieldType;
private String description;
@@ -207,7 +206,6 @@
public Property(String fieldName, Class fieldType, String description,
PreferenceVisibility[] visibility,
String editorIncludeName, String templateComponentName, String
mappedTo) {
- this.field = Reflections.getField(getClazz(), fieldName);
this.fieldName = fieldName;
this.fieldType = fieldType;
this.description = description;
@@ -218,7 +216,7 @@
}
public Field getField() {
- return field;
+ return Reflections.getField(getClazz(), fieldName);
}
public String getOwningEntityName() {
@@ -266,12 +264,13 @@
}
public void write(Object preferenceEntityInstance, Object value) throws Exception
{
+ Field field = getField();
field.setAccessible(true);
Reflections.set(field, preferenceEntityInstance, value);
}
public boolean isNullable() {
- return !field.isAnnotationPresent(NotNull.class);
+ return !getField().isAnnotationPresent(NotNull.class);
}
public InvalidValue[] validate(Object value) {
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -295,12 +295,35 @@
return spaces.toString();
}
+ public static Date toDate(Long time) {
+ return new Date(time);
+ }
+
+ public static String getTimeDifferenceToCurrent(Date d) {
+ return getTimeDifference(new Date(), d);
+ }
+
+ public static String getTimeDifference(Date a, Date b) {
+ long time = a.getTime() > b.getTime() ? a.getTime() - b.getTime() :
b.getTime() - a.getTime();
+ int seconds = (int)((time/1000) % 60);
+ int minutes = (int)((time/60000) % 60);
+ int hours = (int)((time/3600000) % 24);
+ String secondsStr = (seconds<10 ? "0" : "")+seconds;
+ String minutesStr = (minutes<10 ? "0" : "")+minutes;
+ String hoursStr = (hours<10 ? "0" : "")+hours;
+ return hoursStr + ":" + minutesStr + ":" + secondsStr;
+ }
+
public static String formatDate(Date date) {
// TODO: Exceptional date formatting here...
SimpleDateFormat fmt = new SimpleDateFormat("MMM dd, yyyy HH:mm");
return fmt.format(date);
}
+ public static Date currentDate() {
+ return new Date();
+ }
+
public static String attachSignature(String wikiText, String sig) {
StringBuilder builder = new StringBuilder();
builder.append(wikiText).append("\n\n-- ").append(sig);
@@ -312,12 +335,8 @@
!(user.getUsername().equals(User.ADMIN_USERNAME) ||
user.getUsername().equals(User.GUEST_USERNAME));
}
- /**
- * Used for conditional rendering of JSF messages, again, inflexible EL can't
take value bindings with arguments
- * or support simple String concat...
- */
- public static boolean hasMessage(String namingContainer, String componentId) {
- return
FacesContext.getCurrentInstance().getMessages(namingContainer.replaceAll("\\\\",
"") + ":" + componentId).hasNext();
+ public static boolean isGuestOrAdminUsername(String username) {
+ return User.ADMIN_USERNAME.equals(username) ||
User.GUEST_USERNAME.equals(username);
}
/**
Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirMenu.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirMenu.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirMenu.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -32,18 +32,15 @@
@In
WikiDirectory currentDirectory;
- @In
- WikiNodeDAO wikiNodeDAO;
-
public NestedSetNodeWrapper<WikiDirectory> getRoot(WikiPluginMacro macro) {
// We cache the result in the macro, so that when the getter is called over and
over during rendering, we have it
if (macro.getAttributes().get(MACRO_ATTR_ROOT) == null) {
NestedSetNodeWrapper<WikiDirectory> root;
DirMenuPreferences prefs =
Preferences.instance().get(DirMenuPreferences.class, macro);
if (prefs.getOnlyMenuItems() != null && prefs.getOnlyMenuItems()) {
- root = wikiNodeDAO.findMenuItemTree(currentDirectory, 3l, 3l, false);
+ root = WikiNodeDAO.instance().findMenuItemTree(currentDirectory, 3l, 3l,
false);
} else {
- root = wikiNodeDAO.findWikiDirectoryTree(currentDirectory, 3l, 3l,
false);
+ root = WikiNodeDAO.instance().findWikiDirectoryTree(currentDirectory, 3l,
3l, false);
}
macro.getAttributes().put(MACRO_ATTR_ROOT, root);
}
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirTocQuery.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirTocQuery.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DirTocQuery.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -14,7 +14,7 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.model.WikiDocument;
import org.jboss.seam.wiki.core.nestedset.query.NestedSetNodeWrapper;
@@ -44,10 +44,6 @@
@In
WikiDirectory currentDirectory;
- @In
- WikiNodeDAO wikiNodeDAO;
-
-
public NestedSetNodeWrapper<WikiDirectory> getTocRoot(WikiPluginMacro macro) {
NestedSetNodeWrapper<WikiDirectory> tocRoot =
@@ -58,13 +54,13 @@
if (prefs.getRootDocumentLink() != null) {
Long id =
((WikiLinkResolver)Component.getInstance("wikiLinkResolver"))
.resolveWikiDirectoryId(currentDirectory.getAreaNumber(),
prefs.getRootDocumentLink());
- WikiDirectory foundDir = wikiNodeDAO.findWikiDirectory(id);
+ WikiDirectory foundDir = WikiNodeDAO.instance().findWikiDirectory(id);
if (foundDir != null)
currentDirectory = foundDir;
}
// Query the directory tree
- tocRoot = wikiNodeDAO.findWikiDirectoryTree(currentDirectory);
+ tocRoot = WikiNodeDAO.instance().findWikiDirectoryTree(currentDirectory);
Set<Long> directoryIds = new
HashSet<Long>(tocRoot.getFlatTree().keySet());
if (prefs.getShowRootDocuments() != null &&
prefs.getShowRootDocuments()) {
Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DocPager.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DocPager.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/DocPager.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -27,15 +27,12 @@
public static final String MACRO_ATTR_PAGER_NEXT = "docPagerNext";
@In
- WikiNodeDAO wikiNodeDAO;
-
- @In
WikiDocument currentDocument;
public WikiDocument getPrevious(WikiPluginMacro macro) {
WikiDocument previous = (WikiDocument)
macro.getAttributes().get(MACRO_ATTR_PAGER_PREVIOUS);
if (previous == null) {
- previous = wikiNodeDAO.findSiblingWikiDocumentInDirectory(currentDocument,
getSortingProperty(macro), true);
+ previous =
WikiNodeDAO.instance().findSiblingWikiDocumentInDirectory(currentDocument,
getSortingProperty(macro), true);
macro.getAttributes().put(MACRO_ATTR_PAGER_PREVIOUS, previous);
}
return previous;
@@ -44,7 +41,7 @@
public WikiDocument getNext(WikiPluginMacro macro) {
WikiDocument next = (WikiDocument)
macro.getAttributes().get(MACRO_ATTR_PAGER_NEXT);
if (next == null) {
- next = wikiNodeDAO.findSiblingWikiDocumentInDirectory(currentDocument,
getSortingProperty(macro), false);
+ next =
WikiNodeDAO.instance().findSiblingWikiDocumentInDirectory(currentDocument,
getSortingProperty(macro), false);
macro.getAttributes().put(MACRO_ATTR_PAGER_NEXT, next);
}
return next;
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/LastModifiedDocuments.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/LastModifiedDocuments.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/basic/LastModifiedDocuments.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -21,12 +21,9 @@
@Scope(ScopeType.PAGE)
public class LastModifiedDocuments implements Serializable {
- @In
- WikiNodeDAO wikiNodeDAO;
-
public List<WikiDocument> getListOfDocuments(LastModifiedDocumentsPreferences
prefs) {
return
- wikiNodeDAO.findWikiDocuments(
+ WikiNodeDAO.instance().findWikiDocuments(
Long.valueOf(prefs.getNumberOfItems()).intValue(),
WikiNode.SortableProperty.lastModifiedOn,
false
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/faqBrowser/templates/faqQuestionForm.xhtml
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/faqBrowser/templates/faqQuestionForm.xhtml 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/faqBrowser/templates/faqQuestionForm.xhtml 2008-06-07
00:25:03 UTC (rev 8348)
@@ -29,7 +29,6 @@
<ui:include src="/includes/wikiTextEditor.xhtml">
<ui:param name="textEditorId"
value="faqQuestion"/>
- <ui:param name="textPreviewId"
value="faqQuestionPreview"/>
<ui:param name="namingContainer"
value="faqBrowserPlugin\\\\:faqQuestionForm"/>
<ui:param name="label"
value="#{messages['fb.faqBrowser.label.QuestionText']}"/>
<ui:param name="valueBinding"
value="#{faqQuestionHome.formContent}"/>
@@ -41,7 +40,7 @@
<s:div styleClass="marginLeft">
<ui:include src="/includes/wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="faqQuestionPreview"/>
+ <ui:param name="textEditorId"
value="faqQuestion"/>
<ui:param name="valueBinding"
value="#{faqQuestionHome.instance.content}"/>
<ui:param name="baseDocument"
value="#{faqQuestionHome.instance}"/>
<ui:param name="baseDirectory"
value="#{currentDirectory}"/>
Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQuery.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQuery.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQuery.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -8,8 +8,8 @@
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.action.Pager;
-import org.jboss.seam.wiki.core.engine.WikiLink;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
import org.jboss.seam.wiki.core.model.User;
import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ReplyHome.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ReplyHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ReplyHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -7,6 +7,7 @@
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.security.Identity;
import org.jboss.seam.wiki.core.action.CommentHome;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.core.model.WikiComment;
import org.jboss.seam.wiki.core.model.WikiNode;
import org.jboss.seam.wiki.core.ui.WikiRedirect;
@@ -100,8 +101,23 @@
return "forumReplyFeedEntryManager";
}
- protected String getTextAreaId() {
- return "replyTextArea";
+ @Override
+ protected WikiTextValidator.ValidationCommand[] getPersistValidationCommands() {
+ return new WikiTextValidator.ValidationCommand[] {
+ new WikiTextValidator.ValidationCommand() {
+ public String getKey() {
+ return "reply";
+ }
+
+ public String getWikiTextValue() {
+ return getInstance().getContent();
+ }
+
+ public boolean getWikiTextRequired() {
+ return true;
+ }
+ }
+ };
}
/* -------------------------- Messages ------------------------------ */
Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -8,19 +8,16 @@
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.international.StatusMessages;
import org.jboss.seam.wiki.core.action.DocumentHome;
+import org.jboss.seam.wiki.core.wikitext.editor.WikiTextValidator;
import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.model.WikiDocument;
import org.jboss.seam.wiki.core.model.WikiTextMacro;
import org.jboss.seam.wiki.core.ui.WikiRedirect;
import org.jboss.seam.wiki.core.plugin.PluginRegistry;
-import org.jboss.seam.wiki.core.engine.WikiFormattedTextValidator;
import org.jboss.seam.wiki.preferences.Preferences;
-import static org.jboss.seam.international.StatusMessage.Severity.WARN;
import static org.jboss.seam.international.StatusMessage.Severity.INFO;
-import javax.faces.validator.ValidatorException;
-
@Name("topicHome")
@Scope(ScopeType.CONVERSATION)
public class TopicHome extends DocumentHome {
@@ -68,23 +65,6 @@
}
@Override
- protected boolean preparePersist() {
- // TODO: Why here again?
- WikiFormattedTextValidator validator = new WikiFormattedTextValidator();
- try {
- validator.validate(null, null, getInstance().getContent());
- } catch (ValidatorException e) {
- StatusMessages.instance().addToControl(
- "topicTextArea",
- WARN,
- e.getFacesMessage().getSummary()
- );
- return false;
- }
- return super.preparePersist();
- }
-
- @Override
protected boolean beforePersist() {
// TODO: Use macro parameters for "sticky" and "notify"
options instead of additional macros
if (isSticky()) {
@@ -136,6 +116,33 @@
return null; // Prevent navigation
}
+ @Override
+ protected WikiTextValidator.ValidationCommand[] getPersistValidationCommands() {
+ return getValidationCommands();
+ }
+
+ protected WikiTextValidator.ValidationCommand[] getUpdateValidationCommands() {
+ return getValidationCommands();
+ }
+
+ private WikiTextValidator.ValidationCommand[] getValidationCommands() {
+ return new WikiTextValidator.ValidationCommand[] {
+ new WikiTextValidator.ValidationCommand() {
+ public String getKey() {
+ return "topic";
+ }
+
+ public String getWikiTextValue() {
+ return getInstance().getContent();
+ }
+
+ public boolean getWikiTextRequired() {
+ return true;
+ }
+ }
+ };
+ }
+
/* -------------------------- Messages ------------------------------ */
protected void createdMessage() {
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/lastTopicPost.xhtml
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/lastTopicPost.xhtml 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/lastTopicPost.xhtml 2008-06-07
00:25:03 UTC (rev 8348)
@@ -10,7 +10,7 @@
<s:div>
<h:outputLink value="#{link}" tabindex="1">
- <h:outputText value="#{wiki:truncateString(name, 15,
'...')}"/>
+ <h:outputText value="#{wiki:truncateString(name, 25,
'...')}"/>
<h:graphicImage styleClass="topicGotoIcon"
value="#{currentMacro.requestImagePath}/icon.posting_goto.gif"
width="18" height="9"/>
</h:outputLink>
</s:div>
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/replyForm.xhtml
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/replyForm.xhtml 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/replyForm.xhtml 2008-06-07
00:25:03 UTC (rev 8348)
@@ -76,7 +76,6 @@
<a:region>
<ui:include
src="/includes/wikiTextEditor.xhtml">
<ui:param name="textEditorId"
value="reply"/>
- <ui:param name="textPreviewId"
value="replyPreview"/>
<ui:param name="namingContainer"
value="forumRepliesPlugin\\\\:replyForm"/>
<ui:param name="label"
value="#{messages['forum.label.replyForm.Message']}"/>
<ui:param name="valueBinding"
value="#{replyHome.instance.content}"/>
@@ -87,7 +86,7 @@
</ui:include>
<ui:include
src="/includes/wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="replyPreview"/>
+ <ui:param name="textEditorId"
value="reply"/>
<ui:param name="valueBinding"
value="#{replyHome.instance.content}"/>
<ui:param name="baseDocument"
value="#{currentDocument}"/>
<ui:param name="baseDirectory"
value="#{currentDocument.parent}"/>
Modified:
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml
===================================================================
---
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml 2008-06-07
00:25:03 UTC (rev 8348)
@@ -30,7 +30,6 @@
<a:region>
<ui:include
src="/includes/wikiTextEditor.xhtml">
<ui:param name="textEditorId"
value="topic"/>
- <ui:param name="textPreviewId"
value="topicPreview"/>
<ui:param name="namingContainer"
value="forumTopicsPlugin\\\\:topicForm"/>
<ui:param name="label"
value="#{messages['forum.label.Message']}"/>
<ui:param name="valueBinding"
value="#{topicHome.formContent}"/>
@@ -42,7 +41,7 @@
<s:div styleClass="marginLeft">
<ui:include
src="/includes/wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="topicPreview"/>
+ <ui:param name="textEditorId"
value="topic"/>
<ui:param name="valueBinding"
value="#{topicHome.instance.content}"/>
<ui:param name="baseDocument"
value="#{topicHome.instance}"/>
<ui:param name="baseDirectory"
value="#{currentDirectory}"/>
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Linking.java
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Linking.java 2008-06-07
00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Linking.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -8,9 +8,9 @@
import org.dbunit.operation.DatabaseOperation;
import org.jboss.seam.wiki.core.action.DocumentHome;
-import org.jboss.seam.wiki.core.engine.WikiLink;
-import org.jboss.seam.wiki.core.engine.WikiLinkResolver;
-import org.jboss.seam.wiki.core.engine.WikiTextRenderer;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLink;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiLinkResolver;
+import org.jboss.seam.wiki.core.wikitext.renderer.WikiTextRenderer;
import org.jboss.seam.wiki.core.model.WikiDocument;
import org.jboss.seam.wiki.core.model.WikiUpload;
import org.jboss.seam.wiki.test.util.DBUnitSeamTest;
Modified:
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java
===================================================================
---
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java 2008-06-07
00:00:46 UTC (rev 8347)
+++
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java 2008-06-07
00:25:03 UTC (rev 8348)
@@ -9,11 +9,11 @@
import org.dbunit.operation.DatabaseOperation;
import org.jboss.seam.core.Conversation;
import org.jboss.seam.wiki.core.action.DocumentHome;
-import org.jboss.seam.wiki.core.engine.WikiTextParser;
+import org.jboss.seam.wiki.core.wikitext.engine.WikiTextParser;
import org.jboss.seam.wiki.core.model.WikiTextMacro;
import org.jboss.seam.wiki.core.plugin.WikiPluginMacro;
import org.jboss.seam.wiki.core.plugin.PluginRegistry;
-import org.jboss.seam.wiki.core.renderer.NullWikiTextRenderer;
+import org.jboss.seam.wiki.core.wikitext.renderer.NullWikiTextRenderer;
import org.jboss.seam.wiki.plugin.basic.LastModifiedDocumentsPreferences;
import org.jboss.seam.wiki.preferences.Preferences;
import org.jboss.seam.wiki.test.util.DBUnitSeamTest;
Modified: trunk/examples/wiki/view/adminHome_d.xhtml
===================================================================
--- trunk/examples/wiki/view/adminHome_d.xhtml 2008-06-07 00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/view/adminHome_d.xhtml 2008-06-07 00:25:03 UTC (rev 8348)
@@ -93,6 +93,7 @@
<div id="systemStats">
<div class="formFields" style="padding: 20px;">
+
<a:region>
<a:jsFunction name="reloadIndexStatistics"
@@ -152,6 +153,14 @@
</h:dataTable>
</a:region>
+
+ <br/>
+ <br/>
+
+ <a:region>
+ <ui:include
src="includes/admin/sessionManager.xhtml"/>
+ </a:region>
+
</div>
</div>
Modified: trunk/examples/wiki/view/docEdit_d.xhtml
===================================================================
--- trunk/examples/wiki/view/docEdit_d.xhtml 2008-06-07 00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/view/docEdit_d.xhtml 2008-06-07 00:25:03 UTC (rev 8348)
@@ -174,22 +174,23 @@
<ui:include
src="includes/wikiTextEditor.xhtml">
<ui:param name="textEditorId"
value="content"/>
- <ui:param name="textPreviewId"
value="#{documentHome.enabledPreview ? 'contentPreview' :
''}"/>
+ <ui:param name="valueBinding"
value="#{documentHome.formContent}"/>
+ <ui:param name="tabId"
value="docContentTab"/>
<ui:param name="namingContainer"
value="docEditForm"/>
<ui:param name="label"
value="#{messages['lacewiki.label.docEdit.Content']}"/>
<ui:param name="textEditorColumns"
value="#{preferences.get('DocEditor').regularEditAreaColumns}"/>
<ui:param name="textEditorRows"
value="#{preferences.get('DocEditor').regularEditAreaRows}"/>
- <ui:param name="valueBinding"
value="#{documentHome.formContent}"/>
<ui:param name="valueMaxLength"
value="32767"/>
<ui:param name="valueRequired"
value="true"/>
</ui:include>
-
+<!--
<s:div styleClass="entry"
id="previewSwitchDiv">
<h:message for="previewSwitch"/>
<div
class="label"> </div>
<div class="input">
- <h:selectBooleanCheckbox
styleClass="ajaxSupport" value="#{documentHome.enabledPreview}"
tabindex="1" id="previewSwitch">
- <a:support status="globalStatus"
+ <h:selectBooleanCheckbox
styleClass="ajaxSupport"
value="#{wikiTextPreview.isPreviewEnabled('content')}"
tabindex="1" id="previewSwitch">
+ <a:support
action="#{documentHome.wikiTextValidator.validate('content',
documentHome.formContent, true)}"
+ status="globalStatus"
event="onchange"
oncomplete="onAjaxRequestComplete()"
reRender="contentPreview,
docEditForm:contentTextEditor, pluginSwitch"/>
@@ -209,7 +210,7 @@
</div>
</s:div>
</s:div>
-
+-->
</div>
</a:region>
@@ -361,7 +362,7 @@
<br/>
<s:div id="contentPreview">
- <c:if test="#{documentHome.enabledPreview}">
+ <c:if test="#{wikiTextPreview.isPreviewEnabled('content') and
wikiTextValidator.isValid('content')}">
<s:div id="documentDisplayContainer"
styleClass="box">
<s:fragment
rendered="#{documentHome.instance.macroPresent('clearBackground')}">
@@ -391,10 +392,13 @@
</s:div>
</s:div>
- <s:div rendered="#{documentHome.enabledPreview}">
+ <s:div
rendered="#{wikiTextPreview.isPreviewEnabled('content')}">
<ui:include src="includes/attachmentDisplay.xhtml"/>
</s:div>
</c:if>
+ <c:if test="#{wikiTextPreview.isPreviewEnabled('content') and not
wikiTextValidator.isValid('content')}">
+ <h:outputText
value="#{messages['lacewiki.msg.wikiTextValidator.InvalidWikiText']}"/>
+ </c:if>
</s:div>
</ui:define>
Added: trunk/examples/wiki/view/includes/admin/sessionManager.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/admin/sessionManager.xhtml
(rev 0)
+++ trunk/examples/wiki/view/includes/admin/sessionManager.xhtml 2008-06-07 00:25:03 UTC
(rev 8348)
@@ -0,0 +1,175 @@
+<s:fragment
+
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
+
xmlns:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:wiki="http://jboss.com/products/seam/wiki"
+
xmlns:a="https://ajax4jsf.dev.java.net/ajax"
+
xmlns:c="http://java.sun.com/jstl/core"
+
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
+
xmlns:s="http://jboss.com/products/seam/taglib">
+
+<script type="text/javascript">
+
+ function switchSessionControl() {
+ var sessionControlsEnabled = false
+ jQuery(".wikiSessionSelect").each(
+ function checkSelected() {
+ if (jQuery(this).attr("checked")) {
+ sessionControlsEnabled = true;
+ }
+ }
+ );
+ if (sessionControlsEnabled) {
+ jQuery(".sessionControl").show();
+ } else {
+ jQuery(".sessionControl").hide();
+ }
+ }
+</script>
+
+<s:div id="sessionManager">
+
+ <h:panelGrid columns="3" style="width:100%;"
+ columnClasses="twentyPercentColumn alignLeft,
+ twentyPercentColumn alignLeft,
+ defaultColumn alignRight">
+
+ <h:panelGroup styleClass="undecoratedLink">
+ <h:outputText value="Select: "/>
+
+ <h:outputLink
value="javascript:selectCheckBoxes('wikiSessionSelect');
switchSessionControl();">
+ <h:outputText value="All"/>
+ </h:outputLink>
+ <h:outputText value=" | "/>
+ <h:outputLink
value="javascript:selectCheckBoxes('wikiSessionSelectGuest');
switchSessionControl();">
+ <h:outputText value="Guests"/>
+ </h:outputLink>
+ <h:outputText value=" | "/>
+ <h:outputLink
value="javascript:selectCheckBoxes('wikiSessionSelectRegularUser');
switchSessionControl();">
+ <h:outputText value="Regular Users"/>
+ </h:outputLink>
+ <h:outputText value=" | "/>
+ <h:outputLink
value="javascript:deselectCheckBoxes('wikiSessionSelect');
switchSessionControl();">
+ <h:outputText value="None"/>
+ </h:outputLink>
+
+ </h:panelGroup>
+
+ <h:panelGroup styleClass="sessionControl"
style="display:none;">
+
+ <a:commandLink
action="#{wikiHttpSessionManager.calculateSelectedSessionsSize}"
+ reRender="sessionManager, messageBoxContainer"
+ status="globalStatus"
+ oncomplete="onAjaxRequestComplete()"
+ eventsQueue="ajaxEventQueue"
+ styleClass="buttonNonpersistent">
+ <h:outputText styleClass="buttonLabel" value="Calculate
Size"/>
+ </a:commandLink>
+
+ <!--
+ <a:commandLink
action="#{wikiHttpSessionManager.invalidateSelectedSessions}"
+ reRender="sessionManager, messageBoxContainer"
+ status="globalStatus"
+ oncomplete="onAjaxRequestComplete()"
+ eventsQueue="ajaxEventQueue"
+ styleClass="button">
+ <h:outputText styleClass="buttonLabel"
value="Invalidate"/>
+ </a:commandLink>
+ -->
+
+ </h:panelGroup>
+
+ <h:panelGroup>
+ <h:outputText value="Active sessions:
#{wikiHttpSessionManager.sessions.size()}"/>
+
+ <a:commandLink action="#{wikiHttpSessionManager.refresh()}"
+ reRender="sessionManager, messageBoxContainer"
+ status="globalStatus"
+ oncomplete="onAjaxRequestComplete()"
+ eventsQueue="ajaxEventQueue"
+ styleClass="buttonNonpersistent">
+ <h:outputText styleClass="buttonLabel"
value="Refresh"/>
+ </a:commandLink>
+ </h:panelGroup>
+
+ </h:panelGrid>
+
+ <h:dataTable value="#{wikiHttpSessionManager.sessions}"
var="s"
+ styleClass="datatable topLeftBottomBorder"
+ headerClass="regularHeader rightBorder smallFont"
+ columnClasses="onePercentColumn rightBorder alignLeft,
+ defaultColumn rightBorder alignCenter,
+ twentyPercentColumn rightBorder alignCenter,
+ twentyPercentColumn rightBorder alignCenter,
+ tenPercentColumn rightBorder alignCenter
+ tenPercentColumn rightBorder alignCenter
+ tenPercentColumn rightBorder alignCenter"
+ rowClasses="rowOdd,rowEven"
+ cellpadding="0" cellspacing="0"
border="0">
+
+ <h:column>
+ <h:selectBooleanCheckbox
value="#{wikiHttpSessionManager.selectedSessions[s.id]}"
+ styleClass="wikiSessionSelect
+
#{wikiHttpSessionManager.getUsername(s.id) == 'Guest'
+ ? 'wikiSessionSelectGuest'
+ :
'wikiSessionSelectRegularUser'}"
+ onchange="switchSessionControl()"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="User"/>
+ </f:facet>
+ <h:outputText
value="#{wikiHttpSessionManager.getUsername(s.id)}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Created"/>
+ </f:facet>
+ <h:outputText value="#{wiki:toDate(s.creationTime)}">
+ <f:convertDateTime pattern="dd. MMM yyyy, HH:mm:ss"
timeZone="#{preferences.get('Wiki').timeZone}"/>
+ </h:outputText>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Last Access"/>
+ </f:facet>
+ <h:outputText value="#{wiki:toDate(s.lastAccessedTime)}">
+ <f:convertDateTime pattern="dd. MMM yyyy, HH:mm:ss"
timeZone="#{preferences.get('Wiki').timeZone}"/>
+ </h:outputText>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Idle"/>
+ </f:facet>
+ <h:outputText
value="#{wiki:getTimeDifferenceToCurrent(wiki:toDate(s.lastAccessedTime))}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Expires"/>
+ </f:facet>
+ <h:outputText
value="#{wiki:getTimeDifferenceToCurrent(wiki:toDate(s.lastAccessedTime +
s.maxInactiveInterval*1000))}"/>
+ <h:outputText value=" (EXPIRED!) "
+ rendered="#{wiki:toDate(s.lastAccessedTime +
s.maxInactiveInterval*1000).time < wiki:currentDate().time}"/>
+ </h:column>
+
+ <h:column>
+ <f:facet name="header">
+ <h:outputText value="Size"/>
+ </f:facet>
+ <h:outputText rendered="#{not empty
wikiHttpSessionManager.sessionsSize[s.id]}"
+
value="#{wiki:displayFilesize(wikiHttpSessionManager.sessionsSize[s.id])}"/>
+ <h:outputText rendered="#{empty
wikiHttpSessionManager.sessionsSize[s.id]}"
+ value="-"/>
+ </h:column>
+
+ </h:dataTable>
+
+</s:div>
+
+</s:fragment>
\ No newline at end of file
Modified: trunk/examples/wiki/view/includes/commentForm.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/commentForm.xhtml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/includes/commentForm.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -85,18 +85,17 @@
<a:region>
<ui:include src="wikiTextEditor.xhtml">
<ui:param name="textEditorId"
value="comment"/>
- <ui:param name="textPreviewId"
value="commentPreview"/>
+ <ui:param name="valueBinding"
value="#{commentHome.instance.content}"/>
<ui:param name="namingContainer"
value="commentForm"/>
<ui:param name="label"
value="#{messages['lacewiki.label.commentForm.Comment']}"/>
- <ui:param name="valueBinding"
value="#{commentHome.instance.content}"/>
- <ui:param name="valueMaxLength"
value="32767"/>
- <ui:param name="valueRequired"
value="true"/>
<ui:param name="textEditorColumns"
value="#{commentHome.instance.ownedByRegularUser ? '60' :
'48'}"/>
<ui:param name="textEditorRows"
value="10"/>
+ <ui:param name="valueMaxLength"
value="32767"/>
+ <ui:param name="valueRequired"
value="true"/>
</ui:include>
<ui:include src="wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="commentPreview"/>
+ <ui:param name="textEditorId"
value="comment"/>
<ui:param name="valueBinding"
value="#{commentHome.instance.content}"/>
<ui:param name="baseDocument"
value="#{currentDocument}"/>
<ui:param name="baseDirectory"
value="#{currentDocument.parent}"/>
Added: trunk/examples/wiki/view/includes/onlineUsers.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/onlineUsers.xhtml (rev 0)
+++ trunk/examples/wiki/view/includes/onlineUsers.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -0,0 +1,33 @@
+<s:fragment
+
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
+
xmlns:h="http://java.sun.com/jsf/html"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:s="http://jboss.com/products/seam/taglib">
+
+ <h:panelGrid styleClass="onlineUsersPanel" columns="4"
+ cellpadding="0" cellspacing="0"
border="0">
+
+ <h:outputText styleClass="onlineLabel"
value="Online: "/>
+
+ <s:fragment rendered="#{wikiHttpSessionManager.numberOfOnlineMembers >
0}">
+ <s:span styleClass="onlineValue">
+ <h:outputText
value="#{wikiHttpSessionManager.numberOfOnlineMembers}"/>
+ <h:outputText
value=" #{wikiHttpSessionManager.numberOfOnlineMembers > 1 ?
'Members' : 'Member'}"/>
+ </s:span>
+ </s:fragment>
+
+ <h:outputText styleClass="onlineSeparator"
value=" | "
+ rendered="#{wikiHttpSessionManager.numberOfOnlineMembers >
0 and
+ wikiHttpSessionManager.numberOfOnlineGuests >
0}"/>
+
+ <s:fragment rendered="#{wikiHttpSessionManager.numberOfOnlineGuests >
0}">
+ <s:span styleClass="onlineValue">
+ <h:outputText
value="#{wikiHttpSessionManager.numberOfOnlineGuests}"/>
+ <h:outputText
value=" #{wikiHttpSessionManager.numberOfOnlineGuests> 1 ?
'Guests' : 'Guest'}"/>
+ </s:span>
+ </s:fragment>
+
+ </h:panelGrid>
+
+</s:fragment>
\ No newline at end of file
Modified: trunk/examples/wiki/view/includes/wikiTextEditor.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/wikiTextEditor.xhtml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/includes/wikiTextEditor.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -31,33 +31,33 @@
</script>
<s:div id="#{textEditorId}MessageLabel"
- styleClass="#{wiki:hasMessage(namingContainer, wiki:concat(textEditorId,
'TextArea'))?'label errorEntry':'label'}">
+ styleClass="#{not wikiTextValidator.isValid(textEditorId) ? 'label
errorEntry' : 'label'}">
<s:div>
<h:outputText value="#{label}:"/>
- <s:fragment rendered="#{not empty textPreviewId}">
+ <s:fragment
rendered="#{wikiTextPreview.isPreviewEnabled(textEditorId)}">
<br/>
<h:outputText style="white-space:nowrap;"
value="(#{valueMaxLength - valueBinding.length()}
#{messages['lacewiki.label.wikiTextEditor.CharactersLeft']})"/>
</s:fragment>
</s:div>
- <s:div styleClass="errorMessage"
rendered="#{wiki:hasMessage(namingContainer, wiki:concat(textEditorId,
'TextArea'))}">
+ <s:div styleClass="errorMessage" rendered="#{not
wikiTextValidator.isValid(textEditorId)}">
<h:panelGrid columns="2" cellpadding="0"
cellspacing="0" border="0">
<h:graphicImage value="#{imagePath}/attention.gif"
width="18" height="18"
styleClass="attentionImage"/>
- <s:span styleClass="attentionMessage"> <span
id="#{textEditorId}MessageText"><h:message
for="#{textEditorId}TextArea"/></span></s:span>
+ <s:span styleClass="attentionMessage"><span
id="#{textEditorId}MessageText"><h:outputText
value="#{messages[wikiTextValidator.getValidationFailureMessageBundleKey(textEditorId)]}"/></span></s:span>
</h:panelGrid>
</s:div>
- <s:fragment rendered="#{!empty tabId}">
- <s:span rendered="#{wiki:hasMessage(namingContainer,
wiki:concat(textEditorId, 'TextArea'))}">
+ <s:fragment rendered="#{not empty tabId}">
+ <s:span rendered="#{not
wikiTextValidator.isValid(textEditorId)}">
<script type="text/javascript">jQuery(function() {
formTabRaiseError("#{tabId}",
"#{textEditorId}TextArea", '#{label}: ' +
jQuery("##{textEditorId}MessageText").html());
});</script>
</s:span>
- <s:span rendered="#{!wiki:hasMessage(namingContainer,
wiki:concat(textEditorId, 'TextArea'))}">
+ <s:span
rendered="#{wikiTextValidator.isValid(textEditorId)}">
<script type="text/javascript">jQuery(function() {
formTabClearError("#{tabId}",
"#{textEditorId}TextArea");
});</script>
@@ -68,100 +68,138 @@
<div class="input">
- <s:validateAll>
+ <h:panelGrid columns="1" cellpadding="0"
cellspacing="0" border="0">
- <h:panelGrid columns="1" cellpadding="0"
cellspacing="0" border="0">
+ <h:panelGrid id="#{textEditorId}Controls" columns="4"
cellpadding="0" cellspacing="0" border="0">
- <h:panelGrid columns="3" cellpadding="0"
cellspacing="0" border="0">
+ <s:fragment>
+ <select id="#{textEditorId}Formatter"
+ onchange="formatText(
+
jQuery('##{namingContainer}\\:#{textEditorId}TextArea')[0],
+
jQuery('##{textEditorId}Formatter')[0].options[jQuery('##{textEditorId}Formatter')[0].selectedIndex].value
+ );
+ #{textEditorId}RefreshPreview();
+
jQuery('##{textEditorId}Formatter')[0].options[0].selected = true;">
+ <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatSelection']}</option>
+ <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatInline']}</option>
+ <option
value="|{i}|">#{messages['lacewiki.msg.wikiTextEditor.FormatMonospace']}</option>
+ <option
value="*{i}*">#{messages['lacewiki.msg.wikiTextEditor.FormatEmphasis']}</option>
+ <option
value="_{i}_">#{messages['lacewiki.msg.wikiTextEditor.FormatUnderline']}</option>
+ <option
value="~{i}~">#{messages['lacewiki.msg.wikiTextEditor.FormatStrikeout']}</option>
+ <option
value="^{i}^">#{messages['lacewiki.msg.wikiTextEditor.FormatSuperscript']}</option>
+ <option
value=""{i}"">#{messages['lacewiki.msg.wikiTextEditor.FormatQuote']}</option>
+ <option value="[My
Link=>{i}]">#{messages['lacewiki.msg.wikiTextEditor.FormatLink']}</option>
+ <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatBlock']}</option>
+ <option
value="`{b}`">#{messages['lacewiki.msg.wikiTextEditor.FormatCodeBlock']}</option>
+ <option
value=""{b}"">#{messages['lacewiki.msg.wikiTextEditor.FormatQuoteBlock']}</option>
+ <option value="=
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatUnorderedList']}</option>
+ <option value="#
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatOrderedList']}</option>
+ <option value="+
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline1']}</option>
+ <option value="++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline2']}</option>
+ <option value="+++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline3']}</option>
+ <option value="++++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline4']}</option>
+ </select>
- <s:fragment>
- <select id="#{textEditorId}Formatter"
- onchange="formatText(
-
jQuery('##{namingContainer}\\:#{textEditorId}TextArea')[0],
-
jQuery('##{textEditorId}Formatter')[0].options[jQuery('##{textEditorId}Formatter')[0].selectedIndex].value
- );
- #{textEditorId}RefreshPreview();
-
jQuery('##{textEditorId}Formatter')[0].options[0].selected = true;">
- <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatSelection']}</option>
- <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatInline']}</option>
- <option
value="|{i}|">#{messages['lacewiki.msg.wikiTextEditor.FormatMonospace']}</option>
- <option
value="*{i}*">#{messages['lacewiki.msg.wikiTextEditor.FormatEmphasis']}</option>
- <option
value="_{i}_">#{messages['lacewiki.msg.wikiTextEditor.FormatUnderline']}</option>
- <option
value="~{i}~">#{messages['lacewiki.msg.wikiTextEditor.FormatStrikeout']}</option>
- <option
value="^{i}^">#{messages['lacewiki.msg.wikiTextEditor.FormatSuperscript']}</option>
- <option
value=""{i}"">#{messages['lacewiki.msg.wikiTextEditor.FormatQuote']}</option>
- <option value="[My
Link=>{i}]">#{messages['lacewiki.msg.wikiTextEditor.FormatLink']}</option>
- <option
value="">#{messages['lacewiki.msg.wikiTextEditor.FormatBlock']}</option>
- <option
value="`{b}`">#{messages['lacewiki.msg.wikiTextEditor.FormatCodeBlock']}</option>
- <option
value=""{b}"">#{messages['lacewiki.msg.wikiTextEditor.FormatQuoteBlock']}</option>
- <option value="=
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatUnorderedList']}</option>
- <option value="#
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatOrderedList']}</option>
- <option value="+
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline1']}</option>
- <option value="++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline2']}</option>
- <option value="+++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline3']}</option>
- <option value="++++
{b}">#{messages['lacewiki.msg.wikiTextEditor.FormatHeadline4']}</option>
- </select>
+ <a:jsFunction name="#{textEditorId}RefreshPreview"
status="globalStatus"
+ action="#{wikiTextValidator.validate(textEditorId,
valueBinding, valueRequired)}"
+ reRender="#{textEditorId}MessageLabel,
#{textEditorId}Preview"/>
+ </s:fragment>
- <a:jsFunction name="#{textEditorId}RefreshPreview"
status="globalStatus"
- reRender="#{textEditorId}MessageLabel,
#{textPreviewId}"/>
- </s:fragment>
+ <ui:decorate template="helpPopupButton.xhtml">
+ <ui:param name="label"
value="#{messages['lacewiki.button.help.Help']}"/>
+ <ui:param name="width"
value="450"/>
+ <ui:param name="height"
value="350"/>
+ <ui:param name="offsetId"
value="#{namingContainer}\\\\:#{textEditorId}TextAreaDiv"/>
+ <ui:param name="helpDocument" value="Wiki Text
Markup"/>
+ </ui:decorate>
- <ui:decorate template="helpPopupButton.xhtml">
- <ui:param name="label"
value="#{messages['lacewiki.button.help.Help']}"/>
- <ui:param name="width"
value="450"/>
- <ui:param name="height"
value="350"/>
- <ui:param name="offsetId"
value="#{namingContainer}\\\\:#{textEditorId}TextAreaDiv"/>
- <ui:param name="helpDocument" value="Wiki Text
Markup"/>
- </ui:decorate>
+ <s:fragment>
- <s:fragment>
- <s:fragment rendered="#{not empty
textPreviewId}">
- <h:outputLink value="javascript://no-op"
- tabindex="1"
styleClass="buttonNonpersistent noWrapWhitespace"
-
accesskey="#{messages['lacewiki.button.wikiTextEditor.UpdatePreview.accesskey']}"
-
onclick="rememberCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');
#{textEditorId}UpdatePreview(); return false;">
- <h:outputText styleClass="buttonLabel"
escape="false"
value="#{messages['lacewiki.button.wikiTextEditor.UpdatePreview']}"/>
- </h:outputLink>
+ <s:fragment rendered="#{not
wikiTextPreview.isPreviewEnabled(textEditorId)}">
+ <h:outputLink value="javascript://no-op"
+ tabindex="1"
styleClass="buttonNonpersistent noWrapWhitespace"
+
accesskey="#{messages['lacewiki.button.wikiTextEditor.Validate.accesskey']}"
+
onclick="rememberCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');
#{textEditorId}Validate(); return false;">
+ <h:outputText styleClass="buttonLabel"
escape="false"
value="#{messages['lacewiki.button.wikiTextEditor.Validate']}"/>
+ </h:outputLink>
- <a:jsFunction name="#{textEditorId}UpdatePreview"
-
action="#{wikiTextEditor.validate(textEditorId, valueBinding)}"
- status="globalStatus"
- reRender="#{textEditorId}MessageLabel,
#{textPreviewId}"
- eventsQueue="ajaxEventQueue"
-
oncomplete="onAjaxRequestComplete();setRememberedCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');"/>
- </s:fragment>
+ <a:jsFunction name="#{textEditorId}Validate"
+
action="#{wikiTextValidator.validate(textEditorId, valueBinding,
valueRequired)}"
+ reRender="#{textEditorId}MessageLabel,
#{textEditorId}Preview"
+ status="globalStatus"
+ ignoreDupResponses="true"
+ eventsQueue="ajaxEventQueue"
+ oncomplete="onAjaxRequestComplete();
+
setRememberedCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');"/>
+ </s:fragment>
+
+ </s:fragment>
+
+ <s:fragment>
+
+ <s:fragment rendered="#{not
wikiTextPreview.isPreviewEnabled(textEditorId)}">
+ <h:outputLink value="javascript://no-op"
+ tabindex="1"
styleClass="buttonNonpersistent noWrapWhitespace"
+
accesskey="#{messages['lacewiki.button.wikiTextEditor.EnablePreview.accesskey']}"
+
onclick="rememberCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');
#{textEditorId}EnablePreview(); return false;">
+ <h:outputText styleClass="buttonLabel"
escape="false"
value="#{messages['lacewiki.button.wikiTextEditor.EnablePreview']}"/>
+ </h:outputLink>
+
+ <a:jsFunction name="#{textEditorId}EnablePreview"
+
action="#{wikiTextPreview.enablePreview(textEditorId, valueBinding,
valueRequired)}"
+ status="globalStatus"
+ eventsQueue="ajaxEventQueue"
+ reRender="#{textEditorId}TextEditor,
#{textEditorId}Preview"
+
oncomplete="onAjaxRequestComplete();setRememberedCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');"/>
+
</s:fragment>
- </h:panelGrid>
+ <s:fragment
rendered="#{wikiTextPreview.isPreviewEnabled(textEditorId)}">
+ <h:outputLink value="javascript://no-op"
+ tabindex="1"
styleClass="buttonNonpersistent noWrapWhitespace"
+
accesskey="#{messages['lacewiki.button.wikiTextEditor.DisablePreview.accesskey']}"
+
onclick="rememberCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');
#{textEditorId}DisablePreview(); return false;">
+ <h:outputText styleClass="buttonLabel"
escape="false"
value="#{messages['lacewiki.button.wikiTextEditor.DisablePreview']}"/>
+ </h:outputLink>
- <s:div id="#{textEditorId}TextAreaDiv"
styleClass="textEditResizable">
+ <a:jsFunction name="#{textEditorId}DisablePreview"
+
action="#{wikiTextPreview.disablePreview(textEditorId)}"
+ status="globalStatus"
+ eventsQueue="ajaxEventQueue"
+ reRender="#{textEditorId}TextEditor,
#{textEditorId}Preview"
+
oncomplete="onAjaxRequestComplete();setRememberedCursorPosition('##{namingContainer}\\\\:#{textEditorId}TextArea');"/>
- <h:inputTextarea id="#{textEditorId}TextArea"
- styleClass="ajaxSupport"
- tabindex="1"
- cols="#{empty textEditorColumns ? '58'
: textEditorColumns}"
- rows="#{textEditorRows}"
- required="#{valueRequired}"
- value="#{valueBinding}">
- <a:support event="onkeyup"
- action="#{wikiTextEditor.validate(textEditorId,
valueBinding)}"
- reRender="#{textEditorId}MessageLabel,
#{textPreviewId}"
- status="globalStatus"
- ignoreDupResponses="true"
- requestDelay="3000"
- ajaxSingle="true"
- eventsQueue="ajaxEventQueue"
- oncomplete="onAjaxRequestComplete()"
- rendered="#{not empty textPreviewId}"/>
- </h:inputTextarea>
+ </s:fragment>
- <s:div id="#{textEditorId}TextEditResizeHandle"
styleClass="textEditResizeHandle"
style="display:none;float:right;"/>
- </s:div>
+ </s:fragment>
</h:panelGrid>
- </s:validateAll>
+ <s:div id="#{textEditorId}TextAreaDiv"
styleClass="textEditResizable">
+ <h:inputTextarea id="#{textEditorId}TextArea"
+ styleClass="ajaxSupport"
+ tabindex="1"
+ cols="#{empty textEditorColumns ? '58' :
textEditorColumns}"
+ rows="#{textEditorRows}"
+ value="#{valueBinding}">
+ <a:support event="onkeyup"
+ action="#{wikiTextValidator.validate(textEditorId,
valueBinding, valueRequired)}"
+ reRender="#{textEditorId}MessageLabel,
#{textEditorId}Preview"
+ status="globalStatus"
+ ignoreDupResponses="true"
+ requestDelay="3000"
+ ajaxSingle="true"
+ eventsQueue="ajaxEventQueue"
+ oncomplete="onAjaxRequestComplete()"
+
rendered="#{wikiTextPreview.isPreviewEnabled(textEditorId)}"/>
+ </h:inputTextarea>
+
+ <s:div id="#{textEditorId}TextEditResizeHandle"
styleClass="textEditResizeHandle"
style="display:none;float:right;"/>
+ </s:div>
+
+ </h:panelGrid>
+
</div>
</s:div>
Modified: trunk/examples/wiki/view/includes/wikiTextPreview.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/wikiTextPreview.xhtml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/includes/wikiTextPreview.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -6,17 +6,24 @@
xmlns:a="https://ajax4jsf.dev.java.net/ajax"
xmlns:wiki="http://jboss.com/products/seam/wiki">
-<s:div id="#{textPreviewId}">
- <s:div styleClass="textPreview" rendered="#{not empty
valueBinding}">
+<s:div id="#{textEditorId}Preview">
+ <s:div styleClass="textPreview"
+ rendered="#{not empty valueBinding
+ and wikiTextPreview.isPreviewEnabled(textEditorId)
+ and wikiTextValidator.isValid(textEditorId)}">
<wiki:formattedText value="#{valueBinding}"
linkStyleClass="regularLink"
brokenLinkStyleClass="brokenLink"
attachmentLinkStyleClass="regularLink"
thumbnailLinkStyleClass="regularLink"
- linkBaseFilet="#{baseDocument}"
+ linkBaseFile="#{baseDocument}"
currentAreaNumber="#{baseDirectory.areaNumber}"
enableMacroRendering="false"/>
</s:div>
+ <s:div styleClass="textPreview"
+ rendered="#{wikiTextPreview.isPreviewEnabled(textEditorId) and not
wikiTextValidator.isValid(textEditorId)}">
+ <h:outputText
value="#{messages['lacewiki.msg.wikiTextValidator.InvalidWikiText']}"/>
+ </s:div>
</s:div>
</s:fragment>
Modified: trunk/examples/wiki/view/themes/default/css/template.css
===================================================================
--- trunk/examples/wiki/view/themes/default/css/template.css 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/themes/default/css/template.css 2008-06-07 00:25:03 UTC (rev
8348)
@@ -698,6 +698,8 @@
margin-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
+ padding-top: 5px;
+ padding-bottom: 5px;
background-color: white;
margin-left: 80px;
margin-right: 80px;
@@ -1639,3 +1641,23 @@
font-size: 100%;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
+
+/* Online Users Panel
+----------------------------------------------- */
+
+.onlineUsersPanel {
+ margin: 5px;
+ font-size: 85%;
+}
+
+.onlineUsersPanel .onlineLabel {
+ font-weight: bold;
+}
+
+.onlineUsersPanel .onlineValue {
+}
+
+.onlineUsersPanel .onlineSeparator {
+ color: #ccc;
+}
+
Modified: trunk/examples/wiki/view/themes/default/template.xhtml
===================================================================
--- trunk/examples/wiki/view/themes/default/template.xhtml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/themes/default/template.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -273,6 +273,8 @@
</ui:define>
</ui:decorate>
+ <ui:include src="../../includes/onlineUsers.xhtml"/>
+
<ui:insert name="sidebar"/>
</s:div>
Modified: trunk/examples/wiki/view/themes/inrelationto/css/inrelationto.css
===================================================================
--- trunk/examples/wiki/view/themes/inrelationto/css/inrelationto.css 2008-06-07 00:00:46
UTC (rev 8347)
+++ trunk/examples/wiki/view/themes/inrelationto/css/inrelationto.css 2008-06-07 00:25:03
UTC (rev 8348)
@@ -712,6 +712,8 @@
margin-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
+ padding-top: 5px;
+ padding-bottom: 5px;
background-color: white;
margin-left: 80px;
margin-right: 80px;
Modified: trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css
===================================================================
--- trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css 2008-06-07 00:25:03 UTC (rev
8348)
@@ -993,6 +993,8 @@
margin-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
+ padding-top: 5px;
+ padding-bottom: 5px;
background-color: white;
margin-left: 50px;
margin-right: 50px;
@@ -1804,4 +1806,26 @@
#mainMenu .mainMenuFooter .feedText {
color:#ca884e;
-}
\ No newline at end of file
+}
+
+/* Online Users Panel
+----------------------------------------------- */
+
+.onlineUsersPanel {
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 85%;
+ color: #000;
+}
+
+.onlineUsersPanel .onlineLabel {
+ font-weight: bold;
+}
+
+.onlineUsersPanel .onlineValue {
+}
+
+.onlineUsersPanel .onlineSeparator {
+ color: #B6B6B6;
+}
+
Modified: trunk/examples/wiki/view/themes/sfwkorg/template.xhtml
===================================================================
--- trunk/examples/wiki/view/themes/sfwkorg/template.xhtml 2008-06-07 00:00:46 UTC (rev
8347)
+++ trunk/examples/wiki/view/themes/sfwkorg/template.xhtml 2008-06-07 00:25:03 UTC (rev
8348)
@@ -334,6 +334,12 @@
</div>
</div>
+ <s:div styleClass="membersAreaContainer"
style="margin-top:15px;">
+ <b class="rtop"><b class="r1"></b><b
class="r2"></b><b class="r3"></b><b
class="r4"></b></b>
+ <ui:include src="../../includes/onlineUsers.xhtml"/>
+ <b class="rbottom"><b
class="r4"></b><b class="r3"></b><b
class="r2"></b><b class="r1"></b></b>
+ </s:div>
+
</div>
<!-- Main Content area -->
Modified: trunk/examples/wiki/view/userHome_d.xhtml
===================================================================
--- trunk/examples/wiki/view/userHome_d.xhtml 2008-06-07 00:00:46 UTC (rev 8347)
+++ trunk/examples/wiki/view/userHome_d.xhtml 2008-06-07 00:25:03 UTC (rev 8348)
@@ -216,7 +216,6 @@
<ui:include src="includes/wikiTextEditor.xhtml">
<ui:param name="tabId"
value="userProfileTab"/>
<ui:param name="textEditorId"
value="bio"/>
- <ui:param name="textPreviewId"
value="bioPreview"/>
<ui:param name="namingContainer"
value="userHomeForm"/>
<ui:param name="label"
value="#{messages['lacewiki.label.userHome.Bio']}"/>
<ui:param name="valueBinding"
value="#{userHome.instance.profile.bio}"/>
@@ -226,7 +225,7 @@
</ui:include>
<ui:include src="includes/wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="bioPreview"/>
+ <ui:param name="textEditorId"
value="bio"/>
<ui:param name="valueBinding"
value="#{userHome.instance.profile.bio}"/>
<ui:param name="baseDocument"
value="#{wikiStart}"/>
<ui:param name="baseDirectory"
value="#{wikiStart.parent}"/>
@@ -262,7 +261,6 @@
<ui:include src="includes/wikiTextEditor.xhtml">
<ui:param name="tabId"
value="userProfileTab"/>
<ui:param name="textEditorId"
value="signature"/>
- <ui:param name="textPreviewId"
value="signaturePreview"/>
<ui:param name="namingContainer"
value="userHomeForm"/>
<ui:param name="label"
value="#{messages['lacewiki.label.userHome.Signature']}"/>
<ui:param name="valueBinding"
value="#{userHome.instance.profile.signature}"/>
@@ -272,7 +270,7 @@
</ui:include>
<ui:include src="includes/wikiTextPreview.xhtml">
- <ui:param name="textPreviewId"
value="signaturePreview"/>
+ <ui:param name="textEditorId"
value="signature"/>
<ui:param name="valueBinding"
value="#{userHome.instance.profile.signature}"/>
<ui:param name="baseDocument"
value="#{wikiStart}"/>
<ui:param name="baseDirectory"
value="#{wikiStart.parent}"/>