Seam SVN: r7284 - in trunk: src/main/org/jboss/seam/init and 1 other directory.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-01-29 08:14:16 -0500 (Tue, 29 Jan 2008)
New Revision: 7284
Modified:
trunk/build/root.pom.xml
trunk/src/main/org/jboss/seam/init/Initialization.java
Log:
Revert bad commit and update to JBoss Cache 1.4.1.SP8
Modified: trunk/build/root.pom.xml
===================================================================
--- trunk/build/root.pom.xml 2008-01-29 12:46:46 UTC (rev 7283)
+++ trunk/build/root.pom.xml 2008-01-29 13:14:16 UTC (rev 7284)
@@ -210,7 +210,7 @@
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-cache</artifactId>
- <version>1.4.1.GA</version>
+ <version>1.4.1.SP8</version>
</dependency>
<dependency>
Modified: trunk/src/main/org/jboss/seam/init/Initialization.java
===================================================================
--- trunk/src/main/org/jboss/seam/init/Initialization.java 2008-01-29 12:46:46 UTC (rev 7283)
+++ trunk/src/main/org/jboss/seam/init/Initialization.java 2008-01-29 13:14:16 UTC (rev 7284)
@@ -880,7 +880,7 @@
{
try
{
- Reflections.classForName("org.jboss.cache.pojo.PojoCache");
+ Reflections.classForName("org.jboss.cache.aop.PojoCache");
addComponentDescriptor( new ComponentDescriptor(PojoCache.class, true) );
}
catch (ClassNotFoundException e) {}
16 years, 11 months
Seam SVN: r7283 - trunk.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-01-29 07:46:46 -0500 (Tue, 29 Jan 2008)
New Revision: 7283
Added:
trunk/seam21migration.txt
Log:
Start Seam 2.1 migration guide
Added: trunk/seam21migration.txt
===================================================================
--- trunk/seam21migration.txt (rev 0)
+++ trunk/seam21migration.txt 2008-01-29 12:46:46 UTC (rev 7283)
@@ -0,0 +1,15 @@
+Seam 2.1 Migration Guide
+========================
+Before you get started with Seam 2.1, there are a few things you should be aware
+of. This process should not be too painful - if you get stuck, just refer back
+to the updated Seam examples.
+
+This migration guide assumes you are using Seam 2.0, if you are migrating from
+Seam 1.2, see the seam2migration guide as well.
+
+Testing
+-------
+
+SeamTest now boots Seam at the start of each suite, rather than the start of
+each class. This is much faster. See the reference manual for how to alter the
+default.
\ No newline at end of file
Property changes on: trunk/seam21migration.txt
___________________________________________________________________
Name: svn:mime-type
+ text/plain
16 years, 11 months
Seam SVN: r7282 - trunk/examples/blog.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-01-29 07:42:32 -0500 (Tue, 29 Jan 2008)
New Revision: 7282
Modified:
trunk/examples/blog/
Log:
ignores
Property changes on: trunk/examples/blog
___________________________________________________________________
Name: svn:ignore
- build
test-output
+ build
test-output
exploded-archives
dist
16 years, 11 months
Seam SVN: r7281 - in trunk/examples/wiki: src/etc/META-INF and 19 other directories.
by seam-commits@lists.jboss.org
Author: christian.bauer(a)jboss.com
Date: 2008-01-29 02:59:33 -0500 (Tue, 29 Jan 2008)
New Revision: 7281
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/pages.xml
trunk/examples/wiki/src/etc/WEB-INF/urlrewrite.xml
trunk/examples/wiki/src/etc/import-prod.sql
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.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/NodeHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UploadHome.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/UserPasswordReset.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.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/dao/WikiNodeFactory.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/Preferences.java
trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Uploading.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java
trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java
trunk/examples/wiki/view/dirDisplay_d.xhtml
trunk/examples/wiki/view/docDisplay_m.xhtml
trunk/examples/wiki/view/includes/commentsDisplay.xhtml
trunk/examples/wiki/view/includes/userInfoLink.xhtml
trunk/examples/wiki/view/plugins/faqBrowser/faqControls.xhtml
trunk/examples/wiki/view/plugins/forumPosting/forumPostingHeader.xhtml
trunk/examples/wiki/view/plugins/lastModifiedDocuments/plugin.xhtml
trunk/examples/wiki/view/tagDisplay_d.xhtml
trunk/examples/wiki/view/userList_d.xhtml
Log:
Better user info URLs, more detail on workspace switcher
Modified: trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml
===================================================================
--- trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/etc/META-INF/wiki.taglib.xml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -13,6 +13,12 @@
</function>
<function>
+ <function-name>renderUserInfoURL</function-name>
+ <function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
+ <function-signature>java.lang.String renderUserInfoURL(org.jboss.seam.wiki.core.model.User)</function-signature>
+ </function>
+
+ <function>
<function-name>renderAggregateFeedURL</function-name>
<function-class>org.jboss.seam.wiki.util.WikiUtil</function-class>
<function-signature>java.lang.String renderAggregateFeedURL(java.lang.String)</function-signature>
Modified: trunk/examples/wiki/src/etc/WEB-INF/components.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/components.xml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/etc/WEB-INF/components.xml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -36,7 +36,7 @@
<!-- Conversation timeout: 20 minutes -->
<core:manager concurrent-request-timeout="2000"
- conversation-timeout="120000"
+ conversation-timeout="1200000"
conversation-id-parameter="cid"/>
<persistence:filter name="accessLevelFilter">
Modified: trunk/examples/wiki/src/etc/WEB-INF/pages.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/pages.xml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/etc/WEB-INF/pages.xml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -62,7 +62,7 @@
<page view-id="/docEdit*" no-conversation-view-id="/wiki.xhtml">
<param name="documentId" value="#{documentHome.nodeId}"/>
<param name="parentDirectoryId" value="#{documentHome.parentNodeId}"/>
- <action execute="#{documentHome.setEdit(true)}"/>
+ <action execute="#{documentHome.initEditor}"/>
<begin-conversation flush-mode="MANUAL" join="true"/>
<navigation>
@@ -92,7 +92,7 @@
<page view-id="/dirEdit*" no-conversation-view-id="/wiki.xhtml">
<param name="directoryId" value="#{directoryHome.nodeId}"/>
<param name="parentDirectoryId" value="#{directoryHome.parentNodeId}"/>
- <action execute="#{directoryHome.setEdit(true)}"/>
+ <action execute="#{directoryHome.initEditor()}"/>
<begin-conversation flush-mode="MANUAL" join="true"/>
<navigation>
@@ -142,7 +142,7 @@
<page view-id="/uploadEdit*" no-conversation-view-id="/wiki.xhtml">
<param name="uploadId" value="#{uploadHome.nodeId}"/>
<param name="parentDirectoryId" value="#{uploadHome.parentNodeId}"/>
- <action execute="#{uploadHome.setEdit(true)}"/>
+ <action execute="#{uploadHome.initEditor()}"/>
<begin-conversation flush-mode="MANUAL" join="true"/>
<navigation>
@@ -214,6 +214,7 @@
<page view-id="/userInfo*">
<param name="userId" value="#{userHome.userId}"/>
+ <param name="username" value="#{userHome.requestedUsername}"/>
</page>
<page view-id="/userList*">
@@ -280,24 +281,9 @@
<page view-id="/docHistory_d.xhtml">
<description>#{messages['lacewiki.label.docHistory.DocumentHistory']}</description>
</page>
- <page view-id="/docEdit_d.xhtml">
- <description>#{documentHome.idDefined
- ? messages['lacewiki.label.docEdit.EditDocument']
- : messages['lacewiki.label.docEdit.CreateDocument']}</description>
- </page>
- <page view-id="/dirEdit_d.xhtml">
- <description>#{directoryHome.idDefined
- ? messages['lacewiki.label.dirEdit.EditDirectory']
- : messages['lacewiki.label.dirEdit.CreateDirectory']}</description>
- </page>
<page view-id="/uploadCreate_d.xhtml">
<description>#{messages['lacewiki.label.upload.UploadFile']}</description>
</page>
- <page view-id="/uploadEdit_d.xhtml">
- <description>#{uploadHome.idDefined
- ? messages['lacewiki.label.uploadEdit.EditFile']
- : messages['lacewiki.label.uploadEdit.UploadFile']}</description>
- </page>
<page view-id="/search_d.xhtml">
<description>#{messages['lacewiki.label.search.Search']} (#{messages['lacewiki.label.search.Results']}: #{wikiSearch.searchResult.size})</description>
</page>
@@ -320,24 +306,9 @@
<page view-id="/docHistory_m.xhtml">
<description>#{messages['lacewiki.label.docHistory.DocumentHistory']}</description>
</page>
- <page view-id="/docEdit_m.xhtml">
- <description>#{documentHome.idDefined
- ? messages['lacewiki.label.docEdit.EditDocument']
- : messages['lacewiki.label.docEdit.CreateDocument']}</description>
- </page>
- <page view-id="/dirEdit_m.xhtml">
- <description>#{directoryHome.idDefined
- ? messages['lacewiki.label.dirEdit.EditDirectory']
- : messages['lacewiki.label.dirEdit.CreateDirectory']}</description>
- </page>
<page view-id="/uploadCreate_m.xhtml">
<description>#{messages['lacewiki.label.upload.UploadFile']}</description>
</page>
- <page view-id="/uploadEdit_m.xhtml">
- <description>#{uploadHome.idDefined
- ? messages['lacewiki.label.uploadEdit.EditFile']
- : messages['lacewiki.label.uploadEdit.UploadFile']}</description>
- </page>
<page view-id="/search_m.xhtml">
<description>#{messages['lacewiki.label.search.Search']} (#{messages['lacewiki.label.search.Results']}: #{wikiSearch.searchResult.size})</description>
</page>
Modified: trunk/examples/wiki/src/etc/WEB-INF/urlrewrite.xml
===================================================================
--- trunk/examples/wiki/src/etc/WEB-INF/urlrewrite.xml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/etc/WEB-INF/urlrewrite.xml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -17,6 +17,12 @@
<to last="true" type="temporary-redirect">/robots.txt</to>
</rule>
+ <!-- Default browser -->
+ <rule>
+ <from>.*</from>
+ <set type="session" name="skin">d</set>
+ </rule>
+
<!-- Mobile browser -->
<rule>
<from>.*</from>
@@ -32,6 +38,12 @@
<to last="true">/wiki.seam?nodeId=$1</to>
</rule>
+ <!-- /user/foo -->
+ <rule>
+ <from casesensitive="true">^/user/([a-zA-Z]?[a-zA-Z0-9]+)$</from>
+ <to last="true">/userInfo_%{session-attribute:skin}.seam?username=$1</to>
+ </rule>
+
<!-- /service/Feed/atom (/Area/Foo) (/Node/Bar) (/Comments/exclude/) (/Tag/foobar) (/Aggregate/My Aggregate) -->
<rule>
<from casesensitive="true">^/service/Feed/atom(?:/Area/([A-Z0-9]+[A-Za-z0-9]*))?(?:/Node/([A-Z0-9]+[A-Za-z0-9]*))?(?:/Comments/([a-z]+))?(?:/Tag/(.+))?(?:/Aggregate/(.+))?$</from>
Modified: trunk/examples/wiki/src/etc/import-prod.sql
===================================================================
--- trunk/examples/wiki/src/etc/import-prod.sql 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/etc/import-prod.sql 2008-01-29 07:59:33 UTC (rev 7281)
@@ -20,21 +20,22 @@
INSERT INTO PREFERENCE VALUES(17,'Wiki','showEmailToLoggedInOnly',NULL,NULL,NULL,TRUE,NULL,0,NULL)
INSERT INTO PREFERENCE VALUES(18,'Wiki','trashArea',NULL,NULL,NULL,NULL,'Trash',0,NULL)
INSERT INTO PREFERENCE VALUES(19,'Wiki','showSiteFeedInMenu',NULL,NULL,NULL,TRUE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(20,'Wiki','workspaceSwitcherDescriptionLength',25,NULL,NULL,NULL,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(20,'DocEditor','minorRevisionEnabled',NULL,NULL,NULL,TRUE,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(21,'DocEditor','regularEditAreaRows',15,NULL,NULL,NULL,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(22,'DocEditor','regularEditAreaColumns',65,NULL,NULL,NULL,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(50,'DocEditor','minorRevisionEnabled',NULL,NULL,NULL,TRUE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(51,'DocEditor','regularEditAreaRows',15,NULL,NULL,NULL,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(52,'DocEditor','regularEditAreaColumns',65,NULL,NULL,NULL,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(30,'UserManagement','activationCodeSalt',NULL,NULL,NULL,NULL,'MySecretSalt123',0,NULL)
-INSERT INTO PREFERENCE VALUES(31,'UserManagement','passwordRegex',NULL,NULL,NULL,NULL,'^[0-9A-Za-z]{6,15}',0,NULL)
-INSERT INTO PREFERENCE VALUES(32,'UserManagement','newUserInRole',NULL,NULL,NULL,NULL,'member',0,NULL)
-INSERT INTO PREFERENCE VALUES(33,'UserManagement','enableRegistration',NULL,NULL,NULL,TRUE,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(34,'UserManagement','createHomeAfterUserActivation',NULL,NULL,NULL,FALSE,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(35,'UserManagement','homepageDefaultContent',NULL,NULL,NULL,NULL,'This is your homepage, login to edit it.',0,NULL)
+INSERT INTO PREFERENCE VALUES(60,'UserManagement','activationCodeSalt',NULL,NULL,NULL,NULL,'MySecretSalt123',0,NULL)
+INSERT INTO PREFERENCE VALUES(61,'UserManagement','passwordRegex',NULL,NULL,NULL,NULL,'^[0-9A-Za-z]{6,15}',0,NULL)
+INSERT INTO PREFERENCE VALUES(62,'UserManagement','newUserInRole',NULL,NULL,NULL,NULL,'member',0,NULL)
+INSERT INTO PREFERENCE VALUES(63,'UserManagement','enableRegistration',NULL,NULL,NULL,TRUE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(64,'UserManagement','createHomeAfterUserActivation',NULL,NULL,NULL,FALSE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(65,'UserManagement','homepageDefaultContent',NULL,NULL,NULL,NULL,'This is your homepage, login to edit it.',0,NULL)
-INSERT INTO PREFERENCE VALUES(40,'Comments','listAscending',NULL,NULL,NULL,FALSE,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(41,'Comments','enableByDefault',NULL,NULL,NULL,TRUE,NULL,0,NULL)
-INSERT INTO PREFERENCE VALUES(42,'Comments','threaded',NULL,NULL,NULL,TRUE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(70,'Comments','listAscending',NULL,NULL,NULL,FALSE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(71,'Comments','enableByDefault',NULL,NULL,NULL,TRUE,NULL,0,NULL)
+INSERT INTO PREFERENCE VALUES(72,'Comments','threaded',NULL,NULL,NULL,TRUE,NULL,0,NULL)
INSERT INTO PREFERENCE VALUES(110,'LastModifiedDocuments','numberOfItems',5,NULL,NULL,NULL,NULL,0,NULL)
INSERT INTO PREFERENCE VALUES(111,'LastModifiedDocuments','showUsernames',NULL,NULL,NULL,TRUE,NULL,0,NULL)
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -163,6 +163,10 @@
getInstance().getSubject()
);
}
+
+ protected String getEditorWorkspaceDescription(boolean create) {
+ return "Foo";
+ }
/* -------------------------- Internal Methods ------------------------------ */
@@ -219,7 +223,7 @@
@Begin(flushMode = FlushModeType.MANUAL, join = true)
public String newComment() {
- setEdit(true);
+ initEditor();
showForm = true;
return "redirectToDocument";
}
@@ -287,7 +291,7 @@
public void remove(Long commentId) {
setNodeId(commentId);
- setEdit(true);
+ initEditor();
if (isManaged()) {
// Additional permission required besides NodeHome.remove()
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -195,6 +195,14 @@
"Removed syndication feed of this directory");
}
+ protected String getEditorWorkspaceDescription(boolean create) {
+ if (create) {
+ return Messages.instance().get("lacewiki.label.dirEdit.CreateDirectory");
+ } else {
+ return Messages.instance().get("lacewiki.label.dirEdit.EditDirectory") + ":" + getInstance().getName();
+ }
+ }
+
/* -------------------------- Internal Methods ------------------------------ */
private void refreshChildNodes(WikiDirectory dir) {
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -8,6 +8,7 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.international.Messages;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@@ -79,7 +80,7 @@
public WikiDocument beforeNodeEditNew(WikiDocument doc) {
doc = super.beforeNodeEditNew(doc);
- doc.setEnableComments( ((CommentsPreferences)Preferences.getInstance("Comments")).getEnableByDefault() );
+ doc.setEnableComments( Preferences.getInstance(CommentsPreferences.class).getEnableByDefault() );
return doc;
}
@@ -181,9 +182,8 @@
// Feeds should not be removed by a maintenance thread: If there
// is no activity on the site, feeds shouldn't be empty but show the last updates.
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
Calendar oldestDate = GregorianCalendar.getInstance();
- oldestDate.add(Calendar.DAY_OF_YEAR, -wikiPrefs.getPurgeFeedEntriesAfterDays().intValue());
+ oldestDate.add(Calendar.DAY_OF_YEAR, -Preferences.getInstance(WikiPreferences.class).getPurgeFeedEntriesAfterDays().intValue());
feedDAO.purgeOldFeedEntries(oldestDate.getTime());
// Write history log and prepare a new copy for further modification
@@ -200,9 +200,7 @@
historicalCopy.flatCopy(getInstance(), true);
// Reset form
- setMinorRevision(
- ((DocumentEditorPreferences)Preferences.getInstance("DocEditor")).getMinorRevisionEnabled()
- );
+ setMinorRevision( Preferences.getInstance(DocumentEditorPreferences.class).getMinorRevisionEnabled() );
}
return true;
@@ -250,6 +248,14 @@
);
}
+ protected String getEditorWorkspaceDescription(boolean create) {
+ if (create) {
+ return Messages.instance().get("lacewiki.label.docEdit.CreateDocument");
+ } else {
+ return Messages.instance().get("lacewiki.label.docEdit.EditDocument") + ":" + getInstance().getName();
+ }
+ }
+
/* -------------------------- Internal Methods ------------------------------ */
protected void findHistoricalFiles(WikiDocument doc) {
@@ -342,7 +348,7 @@
public boolean isMinorRevision() {
// Lazily initalize preferences
if (minorRevision == null)
- minorRevision = ((DocumentEditorPreferences) Preferences.getInstance("DocEditor")).getMinorRevisionEnabled();
+ minorRevision = Preferences.getInstance(DocumentEditorPreferences.class).getMinorRevisionEnabled();
return minorRevision;
}
public void setMinorRevision(boolean minorRevision) { this.minorRevision = minorRevision; }
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -10,6 +10,7 @@
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
+import org.jboss.seam.core.Conversation;
import org.jboss.seam.framework.EntityHome;
import org.jboss.seam.security.AuthorizationException;
import org.jboss.seam.security.Identity;
@@ -17,9 +18,10 @@
import org.jboss.seam.wiki.core.dao.UserDAO;
import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
import org.jboss.seam.wiki.core.model.*;
+import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
import org.jboss.seam.wiki.util.WikiUtil;
+import org.jboss.seam.wiki.preferences.Preferences;
-import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
import static javax.faces.application.FacesMessage.SEVERITY_WARN;
import static javax.faces.application.FacesMessage.SEVERITY_INFO;
import java.util.Date;
@@ -82,11 +84,23 @@
/* -------------------------- Additional States ------------------------------ */
- private boolean edit = false;
+ private boolean editor = false;
- public boolean isEdit() { return edit; }
- public void setEdit(boolean edit) { this.edit = edit; }
+ public boolean isEditor() { return editor; }
+ public void initEditor() {
+ getLog().debug("initializing editor workspace");
+ this.editor = true;
+
+ // Set workspace description of the current conversation
+ String desc = getEditorWorkspaceDescription(getNodeId() == null);
+ WikiPreferences prefs = Preferences.getInstance(WikiPreferences.class);
+ if (desc.length() > prefs.getWorkspaceSwitcherDescriptionLength()) {
+ desc = desc.substring(0, prefs.getWorkspaceSwitcherDescriptionLength().intValue()) + "...";
+ }
+ Conversation.instance().setDescription(desc);
+ }
+
/* -------------------------- Basic Overrides ------------------------------ */
@Override
@@ -103,7 +117,7 @@
return null;
}
getLog().debug("found instance: " + foundNode);
- return isEdit() ? beforeNodeEditFound(afterNodeFound(foundNode)) : afterNodeFound(foundNode);
+ return isEditor() ? beforeNodeEditFound(afterNodeFound(foundNode)) : afterNodeFound(foundNode);
}
@Override
@@ -111,7 +125,7 @@
getLog().debug("creating a new instance");
N newNode = super.createInstance();
getLog().debug("created new instance: " + newNode);
- return isEdit() ? beforeNodeEditNew(afterNodeCreated(newNode)) : afterNodeCreated(newNode);
+ return isEditor() ? beforeNodeEditNew(afterNodeCreated(newNode)) : afterNodeCreated(newNode);
}
/* -------------------------- Basic Subclass Callbacks ------------------------------ */
@@ -398,6 +412,8 @@
*/
protected abstract NodeRemover getNodeRemover();
+ protected abstract String getEditorWorkspaceDescription(boolean create);
+
/* -------------------------- Public Features ------------------------------ */
@Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UploadHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UploadHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UploadHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -2,6 +2,7 @@
import org.jboss.seam.ScopeType;
import org.jboss.seam.Component;
+import org.jboss.seam.international.Messages;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@@ -163,6 +164,14 @@
);
}
+ protected String getEditorWorkspaceDescription(boolean create) {
+ if (create) {
+ return Messages.instance().get("lacewiki.label.uploadEdit.UploadFile");
+ } else {
+ return Messages.instance().get("lacewiki.label.uploadEdit.EditFile") + ":" + getInstance().getName();
+ }
+ }
+
/* -------------------------- Public Features ------------------------------ */
public UploadEditor getUploadEditor() {
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -45,14 +45,6 @@
@Scope(ScopeType.CONVERSATION)
public class UserHome extends EntityHome<User> {
- public Long getUserId() {
- return (Long)getId();
- }
-
- public void setUserId(Long userId) {
- setId(userId);
- }
-
@In
private FacesMessages facesMessages;
@@ -74,6 +66,7 @@
private List<Role> roles;
private org.jboss.seam.wiki.core.model.Role defaultRole;
private Uploader uploader;
+ private String requestedUsername;
public Uploader getUploader() {
return uploader;
@@ -83,6 +76,23 @@
this.uploader = uploader;
}
+ public Long getUserId() {
+ return (Long)getId();
+ }
+
+ public void setUserId(Long userId) {
+ setId(userId);
+ }
+
+ public String getRequestedUsername() {
+ return requestedUsername;
+ }
+
+ public void setRequestedUsername(String requestedUsername) {
+ getLog().debug("######################## REQUESTED: " + requestedUsername);
+ this.requestedUsername = requestedUsername;
+ }
+
public void init() {
if (isManaged()) {
if (!Identity.instance().hasPermission("User", "edit", getInstance()) ) {
@@ -103,6 +113,28 @@
}
}
+ @Override
+ protected void initInstance() {
+ if ( isIdDefined() || (getRequestedUsername() != null && getRequestedUsername().length() >0) ) {
+ if ( !isTransactionMarkedRollback() ) {
+ setInstance( find() );
+ }
+ } else {
+ setInstance( createInstance() );
+ }
+ }
+
+ @Override
+ protected User loadInstance() {
+ if (getRequestedUsername() != null && getRequestedUsername().length() >0) {
+ getLog().debug("################ FINDING USER: " + getRequestedUsername());
+ return userDAO.findUser(getRequestedUsername(), true, true);
+ } else {
+ return getEntityManager().find(getEntityClass(), getId());
+ }
+ }
+
+ @Override
public String persist() {
// Validate
@@ -141,7 +173,7 @@
// Send confirmation email
renderer.render("/themes/"
- + ((WikiPreferences) Preferences.getInstance("Wiki")).getThemeName()
+ + Preferences.getInstance(WikiPreferences.class).getThemeName()
+ "/mailtemplates/confirmationRegistration.xhtml");
/* For debugging
@@ -160,6 +192,7 @@
}
}
+ @Override
@Restrict("#{s:hasPermission('User', 'edit', userHome.instance)}")
public String update() {
@@ -256,6 +289,7 @@
return outcome;
}
+ @Override
@Restrict("#{s:hasPermission('User', 'delete', userHome.instance)}")
public String remove() {
@@ -285,6 +319,7 @@
/* -------------------------- Messages ------------------------------ */
+ @Override
protected void createdMessage() {
getFacesMessages().addFromResourceBundleOrDefault(
SEVERITY_INFO,
@@ -294,6 +329,7 @@
);
}
+ @Override
protected void updatedMessage() {
getFacesMessages().addFromResourceBundleOrDefault(
SEVERITY_INFO,
@@ -303,6 +339,7 @@
);
}
+ @Override
protected void deletedMessage() {
getFacesMessages().addFromResourceBundleOrDefault(
SEVERITY_INFO,
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserPasswordReset.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserPasswordReset.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserPasswordReset.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -106,7 +106,7 @@
// Send confirmation email
renderer.render("/themes/"
- + ((WikiPreferences) Preferences.getInstance("Wiki")).getThemeName()
+ + Preferences.getInstance(WikiPreferences.class).getThemeName()
+ "/mailtemplates/resetPassword.xhtml");
facesMessages.addFromResourceBundleOrDefault(
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -174,6 +174,15 @@
)
private Boolean showTags;
+ @PreferenceProperty(
+ description = "#{messages['lacewiki.preferences.wiki.WorkspaceSwitcherDescriptionLength']}",
+ visibility = PreferenceVisibility.SYSTEM,
+ editorIncludeName = "NumberRange"
+ )
+ @Range(min = 3l, max = 100l)
+ @NotNull
+ private Long workspaceSwitcherDescriptionLength;
+
public String getBaseUrl() {
return baseUrl;
}
@@ -250,4 +259,7 @@
return showTags;
}
+ public Long getWorkspaceSwitcherDescriptionLength() {
+ return workspaceSwitcherDescriptionLength;
+ }
}
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -86,7 +86,7 @@
@Factory(value = "newUserDefaultRole", scope = ScopeType.SESSION)
public Role getDefaultRole() {
- UserManagementPreferences userPrefs = (UserManagementPreferences) Preferences.getInstance("UserManagement");
+ UserManagementPreferences userPrefs = Preferences.getInstance(UserManagementPreferences.class);
try {
return (Role) entityManager
.createQuery("select r from Role r where r.name = '"+userPrefs.getNewUserInRole()+"'")
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -339,11 +339,11 @@
}
return null;
}
-
+
public List<WikiDocument> findWikiDocuments(int maxResults, WikiNode.SortableProperty orderBy, boolean orderAscending) {
StringBuilder query = new StringBuilder();
- query.append("select d from WikiDocument d where d.lastModifiedOn is not null");
+ query.append("select d from WikiDocument d where d.").append(orderBy.name()).append(" is not null");
query.append(" order by d.").append(orderBy.name()).append(" ").append(orderAscending ? "asc" : "desc");
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -52,11 +52,10 @@
@Factory(value = "wikiStart", scope = ScopeType.PAGE, autoCreate = true)
public WikiDocument loadWikiStart() {
- WikiPreferences wikiPreferences = (WikiPreferences) Preferences.getInstance("Wiki");
try {
return (WikiDocument) restrictedEntityManager
.createQuery("select d from WikiDocument d where d.id = :id")
- .setParameter("id", wikiPreferences.getDefaultDocumentId())
+ .setParameter("id", Preferences.getInstance(WikiPreferences.class).getDefaultDocumentId())
.setHint("org.hibernate.comment", "Loading wikiStart")
.setHint("org.hibernate.cacheable", true)
.getSingleResult();
@@ -65,7 +64,8 @@
}
// TODO: Message instead!
- throw new RuntimeException("Couldn't find wiki default start document with id '" + wikiPreferences.getDefaultDocumentId() +"'");
+ throw new RuntimeException("Couldn't find wiki default start document with id '"
+ + Preferences.getInstance(WikiPreferences.class).getDefaultDocumentId() +"'");
}
// Loads the same instance into a different persistence context
@@ -87,7 +87,7 @@
@Factory(value = "memberArea", scope = ScopeType.PAGE, autoCreate = true)
public WikiDirectory loadMemberArea() {
- String memberAreaName = ((WikiPreferences)Preferences.getInstance("Wiki")).getMemberArea();
+ String memberAreaName = Preferences.getInstance(WikiPreferences.class).getMemberArea();
try {
return (WikiDirectory) entityManager
.createQuery("select d from WikiDirectory d left join fetch d.feed where d.wikiname = :name and d.parent.parent is null")
@@ -108,7 +108,7 @@
@Factory(value = "trashArea", scope = ScopeType.PAGE, autoCreate = true)
public WikiDirectory loadTrashArea() {
- String trashAreaName = ((WikiPreferences)Preferences.getInstance("Wiki")).getTrashArea();
+ String trashAreaName = Preferences.getInstance(WikiPreferences.class).getTrashArea();
try {
return (WikiDirectory) entityManager
.createQuery("select d from WikiDirectory d left join fetch d.feed where d.wikiname = :name and d.parent.parent is null")
@@ -129,7 +129,7 @@
@Factory(value = "helpArea", scope = ScopeType.PAGE, autoCreate = true)
public WikiDirectory loadHelpArea() {
- String helpAreaName = ((WikiPreferences)Preferences.getInstance("Wiki")).getHelpArea();
+ String helpAreaName = Preferences.getInstance(WikiPreferences.class).getHelpArea();
try {
return (WikiDirectory) entityManager
.createQuery("select d from WikiDirectory d left join fetch d.feed where d.wikiname = :name and d.parent.parent is null")
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -1,17 +1,13 @@
package org.jboss.seam.wiki.core.search;
import org.apache.lucene.search.*;
-import org.apache.lucene.search.Filter;
import org.hibernate.Hibernate;
-import org.hibernate.search.FullTextSession;
import org.hibernate.search.FullTextQuery;
+import org.hibernate.search.FullTextSession;
import org.hibernate.search.bridge.StringBridge;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.core.Conversation;
import org.jboss.seam.annotations.*;
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.log.Log;
import org.jboss.seam.wiki.core.search.annotations.SearchableType;
import org.jboss.seam.wiki.core.search.metamodel.SearchRegistry;
Modified: 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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -233,7 +233,7 @@
*/
private void includePluginCSS(String macroName, UIComponent cmp) {
// Try to get the CSS for it
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
+ WikiPreferences wikiPrefs = Preferences.getInstance(WikiPreferences.class);
String css = "/themes/" + wikiPrefs.getThemeName() + "/css/" + macroName + ".css";
if (ResourceLoader.instance().getResource(css) != null) {
log.debug("including plugin CSS file from resource: " + css);
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -85,8 +85,8 @@
// Lazier than @In, would be too many injections because of c:forEach iteration on blog entry list
private void initializePreferences() {
// TODO: Uhm, we have several macros that use this backend bean... that doesn't work
- pageSize = ((BlogPreferences) Preferences.getInstance("Blog", "currentMacro")).getPageSize();
- recentBlogEntriesCount = ((BlogPreferences) Preferences.getInstance("Blog", "currentMacro")).getRecentEntriesItems();
+ pageSize = Preferences.getInstance(BlogPreferences.class, "currentMacro").getPageSize();
+ recentBlogEntriesCount = Preferences.getInstance(BlogPreferences.class, "currentMacro").getRecentEntriesItems();
}
private void queryNumOfBlogEntries() {
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -6,7 +6,6 @@
import org.jboss.seam.core.Events;
import org.jboss.seam.international.Messages;
import org.jboss.seam.wiki.core.action.DocumentHome;
-import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.model.WikiDocument;
import org.jboss.seam.wiki.core.model.WikiDocumentDefaults;
@@ -142,7 +141,7 @@
@Begin(flushMode = FlushModeType.MANUAL, join = true)
public void newQuestion() {
- setEdit(true);
+ initEditor();
showForm = true;
}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -197,14 +197,14 @@
@Begin(flushMode = FlushModeType.MANUAL, join = true)
public void newForum() {
- setEdit(true);
+ initEditor();
showForm = true;
}
@Begin(flushMode = FlushModeType.MANUAL, join = true)
public void edit(Long forumId) {
setId(forumId);
- setEdit(true);
+ initEditor();
showForm = true;
}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -2,7 +2,6 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.AuthorizationException;
@@ -35,7 +34,7 @@
)) {
getLog().debug("sending confirmation e-mail to original poster");
renderer.render("/themes/"
- + ((WikiPreferences) Preferences.getInstance("Wiki")).getThemeName()
+ + Preferences.getInstance(WikiPreferences.class).getThemeName()
+ "/mailtemplates/forumNotifyReply.xhtml");
}
}
@@ -45,7 +44,7 @@
getLog().debug("reply to document id: " + getParentNodeId());
newComment();
- setEdit(true);
+ initEditor();
getInstance().setSubject(REPLY_PREFIX + getParentNode().getName());
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -1,7 +1,6 @@
package org.jboss.seam.wiki.plugin.forum;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.faces.Redirect;
import org.jboss.seam.annotations.*;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.core.Conversation;
@@ -46,7 +45,7 @@
super.create();
setParentNodeId(currentDirectory.getId());
- Boolean preferencesNotifyReplies = ((ForumPreferences) Preferences.getInstance("Forum")).getNotifyMeOfReplies();
+ Boolean preferencesNotifyReplies = Preferences.getInstance(ForumPreferences.class).getNotifyMeOfReplies();
notifyReplies = preferencesNotifyReplies != null && preferencesNotifyReplies;
}
@@ -199,7 +198,7 @@
@Begin(flushMode = FlushModeType.MANUAL, join = true)
public void newTopic() {
- setEdit(true);
+ initEditor();
showForm = true;
}
Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/Preferences.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/Preferences.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/preferences/Preferences.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -100,6 +100,24 @@
return Expressions.instance().createValueExpression("#{preferences.get('" + preferenceEntityName + "')}").getValue();
}
+ public static <P> P getInstance(Class<P> clazz, String instanceName) {
+ return (P)getInstance(getPreferenceEntityName(clazz), instanceName);
+ }
+
+ public static <P> P getInstance(Class<P> clazz) {
+ return (P)getInstance(getPreferenceEntityName(clazz));
+ }
+
+ private static String getPreferenceEntityName(Class<?> clazz) {
+ org.jboss.seam.wiki.preferences.annotations.Preferences
+ p = clazz.getAnnotation(org.jboss.seam.wiki.preferences.annotations.Preferences.class);
+ if (p.name() != null) {
+ return p.name();
+ } else {
+ return clazz.getSimpleName();
+ }
+ }
+
private class CacheKey implements Serializable {
private String entityName;
private Object user;
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/util/WikiUtil.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -97,6 +97,13 @@
accessLevels.indexOf(new Role.AccessLevel(accessLevel, null))
);
}
+
+ public static String renderUserInfoURL(User user) {
+ if (user == null || user.getUsername() == null) return "";
+ StringBuilder url = new StringBuilder();
+ url.append(Component.getInstance("basePath")).append("/user/").append(user.getUsername());
+ return url.toString();
+ }
public static String renderAggregateFeedURL(String aggregateId) {
if (aggregateId == null) return "";
@@ -122,14 +129,12 @@
public static String renderURL(WikiNode node) {
if (node == null || node.getId() == null) return "";
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
- return wikiPrefs.isRenderPermlinks() ? renderPermURL(node) : renderWikiURL(node);
+ return Preferences.getInstance(WikiPreferences.class).isRenderPermlinks() ? renderPermURL(node) : renderWikiURL(node);
}
public static String renderPermURL(WikiNode node) {
if (node == null || node.getId() == null) return "";
- WikiPreferences prefs = (WikiPreferences)Preferences.getInstance("Wiki");
- return Component.getInstance("basePath") + "/" + node.getPermURL(prefs.getPermlinkSuffix());
+ return Component.getInstance("basePath") + "/" + node.getPermURL(Preferences.getInstance(WikiPreferences.class).getPermlinkSuffix());
}
public static String renderWikiURL(WikiNode node) {
@@ -138,10 +143,9 @@
}
public static boolean showEmailAddress() {
- WikiPreferences prefs = (WikiPreferences)Preferences.getInstance("Wiki");
- if (prefs.isShowEmailToLoggedInOnly() && Identity.instance().isLoggedIn()) {
+ if (Preferences.getInstance(WikiPreferences.class).isShowEmailToLoggedInOnly() && Identity.instance().isLoggedIn()) {
return true;
- } else if (!prefs.isShowEmailToLoggedInOnly()) {
+ } else if (!Preferences.getInstance(WikiPreferences.class).isShowEmailToLoggedInOnly()) {
return true;
}
return false;
@@ -177,15 +181,13 @@
}
public static String escapeEmailURL(String string) {
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
return string.length() >= 7 && string.substring(0, 7).equals("mailto:")
- ? string.replaceAll("@", wikiPrefs.getAtSymbolReplacement())
+ ? string.replaceAll("@", Preferences.getInstance(WikiPreferences.class).getAtSymbolReplacement())
: string;
}
public static String escapeAtSymbol(String string) {
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
- return string.replaceAll("@", wikiPrefs.getAtSymbolReplacement());
+ return string.replaceAll("@", Preferences.getInstance(WikiPreferences.class).getAtSymbolReplacement());
}
public static String escapeHtml(String string, boolean convertNewlines) {
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -4,7 +4,7 @@
<PREFERENCE PREF_ID = "1" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "baseUrl" STRING_VALUE = "http://localhost:8080/wiki" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "2" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "timeZone" STRING_VALUE = "CET" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
- <PREFERENCE PREF_ID = "3" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "themeName" STRING_VALUE = "sfwkorg" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
+ <PREFERENCE PREF_ID = "3" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "themeName" STRING_VALUE = "default" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "4" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "memberArea" STRING_VALUE = "Members" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "5" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "helpArea" STRING_VALUE = "Help" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "6" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "defaultDocumentId" STRING_VALUE = "[NULL]" LONG_VALUE = "6" BOOLEAN_VALUE = "[NULL]"/>
@@ -21,6 +21,7 @@
<PREFERENCE PREF_ID = "17" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "showEmailToLoggedInOnly" STRING_VALUE = "[NULL]" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "true"/>
<PREFERENCE PREF_ID = "18" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "trashArea" STRING_VALUE = "Trash" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "19" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "showSiteFeedInMenu" STRING_VALUE = "[NULL]" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "true"/>
+ <PREFERENCE PREF_ID = "20" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "Wiki" PROPERTY_NAME = "workspaceSwitcherDescriptionLength" STRING_VALUE = "[NULL]" LONG_VALUE = "25" BOOLEAN_VALUE = "[NULL]"/>
<PREFERENCE PREF_ID = "50" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "DocEditor" PROPERTY_NAME = "minorRevisionEnabled" STRING_VALUE = "[NULL]" LONG_VALUE = "[NULL]" BOOLEAN_VALUE = "true"/>
<PREFERENCE PREF_ID = "51" OBJ_VERSION = "0" USER_ID = "[NULL]" ENTITY_NAME = "DocEditor" PROPERTY_NAME = "regularEditAreaRows" STRING_VALUE = "[NULL]" LONG_VALUE = "15" BOOLEAN_VALUE = "[NULL]"/>
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -14,6 +14,7 @@
import org.jboss.seam.wiki.core.action.DocumentHome;
import org.jboss.seam.wiki.core.model.WikiDirectory;
import org.jboss.seam.wiki.core.model.WikiDocument;
+import org.jboss.seam.wiki.core.model.WikiNode;
import org.jboss.seam.wiki.test.util.DBUnitSeamTest;
import org.jboss.seam.faces.Redirect;
import org.testng.annotations.Test;
@@ -29,7 +30,38 @@
);
}
+
@Test
+ public void editDirectory() throws Exception {
+
+ final String conversationId = new NonFacesRequest("/dirEdit_d.xhtml") {
+ protected void beforeRequest() {
+ setParameter("directoryId", "2");
+ }
+ }.run();
+
+ new FacesRequest("/dirEdit_d.xhtml") {
+
+ protected void beforeRequest() {
+ setParameter("cid", conversationId);
+ }
+
+ protected void invokeApplication() throws Exception {
+ DirectoryHome dirHome = (DirectoryHome)getInstance(DirectoryHome.class);
+ dirHome.initEditor();
+
+ assert dirHome.getInstance().getId().equals(2l);
+ assert dirHome.isHasFeed();
+ assert dirHome.getChildDocuments().size() == 1;
+ assert dirHome.getMenuItems().size() == 0;
+ assert dirHome.getAvailableMenuItems().size() == 0;
+ assert dirHome.getChildNodes().size() == 1;
+ }
+
+ }.run();
+ }
+
+ @Test
public void deleteDirectory() throws Exception {
final String conversationId = new NonFacesRequest("/dirEdit_d.xhtml") {
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Uploading.java
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Uploading.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/editing/Uploading.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -71,7 +71,7 @@
protected void invokeApplication() throws Exception {
UploadHome uploadHome = (UploadHome)getInstance(UploadHome.class);
- uploadHome.setEdit(true);
+ uploadHome.initEditor();
assert uploadHome.getInstance().getFilename().equals("testupload2.zip");
assert uploadHome.getUploadEditor().getClass().equals(WikiUploadEditor.class);
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-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -59,7 +59,7 @@
if (macro.getName().equals("lastModifiedDocuments")) {
LastModifiedDocumentsPreferences lmdPrefs =
- (LastModifiedDocumentsPreferences)Preferences.getInstance("LastModifiedDocuments", "currentMacro");
+ Preferences.getInstance(LastModifiedDocumentsPreferences.class, "currentMacro");
assert lmdPrefs.getDocumentTitleLength().equals(60l);
}
@@ -119,7 +119,7 @@
if (macro.getName().equals("lastModifiedDocuments")) {
LastModifiedDocumentsPreferences lmdPrefs =
- (LastModifiedDocumentsPreferences)Preferences.getInstance("LastModifiedDocuments", "currentMacro");
+ Preferences.getInstance(LastModifiedDocumentsPreferences.class, "currentMacro");
assert lmdPrefs.getDocumentTitleLength().equals(66l);
}
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -38,7 +38,7 @@
}
protected void renderResponse() throws Exception {
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
+ WikiPreferences wikiPrefs = Preferences.getInstance(WikiPreferences.class);
assert wikiPrefs.getShowDocumentCreatorHistory();
assert wikiPrefs.getShowTags();
assert wikiPrefs.getDefaultDocumentId().equals(6l);
@@ -101,7 +101,7 @@
}
protected void renderResponse() throws Exception {
- WikiPreferences wikiPrefs = (WikiPreferences) Preferences.getInstance("Wiki");
+ WikiPreferences wikiPrefs = Preferences.getInstance(WikiPreferences.class);
assert wikiPrefs.getPermlinkSuffix().equals(".newsuffix");
}
Modified: trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java
===================================================================
--- trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java 2008-01-29 07:59:33 UTC (rev 7281)
@@ -88,7 +88,7 @@
}
protected void renderResponse() throws Exception {
- DocumentEditorPreferences docEditorPrefs = (DocumentEditorPreferences) Preferences.getInstance("DocEditor");
+ DocumentEditorPreferences docEditorPrefs = Preferences.getInstance(DocumentEditorPreferences.class);
assert !docEditorPrefs.getMinorRevisionEnabled();
}
@@ -105,7 +105,7 @@
}
protected void renderResponse() throws Exception {
- DocumentEditorPreferences docEditorPrefs = (DocumentEditorPreferences) Preferences.getInstance("DocEditor");
+ DocumentEditorPreferences docEditorPrefs = Preferences.getInstance(DocumentEditorPreferences.class);
assert docEditorPrefs.getMinorRevisionEnabled();
}
Modified: trunk/examples/wiki/view/dirDisplay_d.xhtml
===================================================================
--- trunk/examples/wiki/view/dirDisplay_d.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/dirDisplay_d.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -472,10 +472,9 @@
<h:outputText value="#{messages['lacewiki.label.dirDisplay.Owner']}"/>
</f:facet>
<s:span styleClass="undecoratedLink" rendered="#{node.ownedByRegularUser}">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{node.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(node.createdBy)}">
<h:outputText value="#{node.createdBy.fullname}"/>
- </s:link>
+ </h:outputLink>
</s:span>
<h:outputText rendered="#{not node.ownedByRegularUser}" value="#{node.createdBy.fullname}"/>
</h:column>
@@ -502,10 +501,9 @@
<f:convertDateTime pattern="dd. MMM yyyy, HH:mm" timeZone="#{preferences.get('Wiki').timeZone}"/>
</h:outputText>
(<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{node.lastModifiedBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(node.lastModifiedBy.createdBy)}">
<h:outputText value="#{node.lastModifiedBy.username}"/>
- </s:link>
+ </h:outputLink>
</s:span>)
</h:column>
Modified: trunk/examples/wiki/view/docDisplay_m.xhtml
===================================================================
--- trunk/examples/wiki/view/docDisplay_m.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/docDisplay_m.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -226,10 +226,9 @@
</h:outputText>
<s:div rendered="#{c.ownedByRegularUser}">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{c.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(c.createdBy)}">
<h:outputText value="#{c.createdBy.fullname}"/>
- </s:link>
+ </h:outputLink>
<s:fragment rendered="#{wiki:showEmailAddress()}">
<br/>
<h:outputLink value="#{wiki:escapeEmailURL(wiki:concat('mailto:', c.createdBy.email))}">
Modified: trunk/examples/wiki/view/includes/commentsDisplay.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/commentsDisplay.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/includes/commentsDisplay.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -59,10 +59,9 @@
</s:div>
<s:div rendered="#{c.ownedByRegularUser}">
<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{c.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(c.createdBy)}">
<h:outputText value="#{c.createdBy.fullname}"/>
- </s:link>
+ </h:outputLink>
</s:span>
<s:fragment rendered="#{wiki:showEmailAddress()}">
<h:outputText value=" | "/>
@@ -87,12 +86,11 @@
<s:fragment rendered="#{c.ownedByRegularUser and !empty c.createdBy.profile.imageContentType}">
<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{c.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(c.createdBy)}">
<s:graphicImage styleClass="commentAuthorPortraitImage" value="#{c.createdBy.profile.image}">
<s:transformImageSize width="30" maintainRatio="true"/>
</s:graphicImage>
- </s:link>
+ </h:outputLink>
</s:span>
</s:fragment>
Modified: trunk/examples/wiki/view/includes/userInfoLink.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/userInfoLink.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/includes/userInfoLink.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -9,10 +9,9 @@
xmlns:s="http://jboss.com/products/seam/taglib">
<s:div styleClass="undecoratedLink" rendered="#{wiki:isRegularUser(user)}">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{user.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(user)}">
<h:outputText value="#{user.fullname}"/>
- </s:link>
+ </h:outputLink>
</s:div>
<s:div rendered="#{not wiki:isRegularUser(user)}">
<h:outputText value="#{user.fullname}"/>
Modified: trunk/examples/wiki/view/plugins/faqBrowser/faqControls.xhtml
===================================================================
--- trunk/examples/wiki/view/plugins/faqBrowser/faqControls.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/plugins/faqBrowser/faqControls.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -107,10 +107,9 @@
<f:convertDateTime pattern="dd. MMM yyyy, HH:mm" timeZone="#{preferences.get('Wiki').timeZone}"/>
</h:outputText>
(<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{q.lastModifiedBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(q.lastModifiedBy)}">
<h:outputText value="#{q.lastModifiedBy.username}"/>
- </s:link>
+ </h:outputLink>
</s:span>)
</s:fragment>
</h:column>
Modified: trunk/examples/wiki/view/plugins/forumPosting/forumPostingHeader.xhtml
===================================================================
--- trunk/examples/wiki/view/plugins/forumPosting/forumPostingHeader.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/plugins/forumPosting/forumPostingHeader.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -97,10 +97,9 @@
</s:div>
<s:div rendered="#{currentDocument.ownedByRegularUser}">
<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{currentDocument.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(currentDocument.createdBy)}">
<h:outputText value="#{currentDocument.createdBy.fullname}"/>
- </s:link>
+ </h:outputLink>
</s:span>
<s:fragment rendered="#{wiki:showEmailAddress()}">
<h:outputText value=" | "/>
@@ -116,12 +115,11 @@
<s:fragment rendered="#{currentDocument.ownedByRegularUser and !empty currentDocument.createdBy.profile.imageContentType}">
<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{currentDocument.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(currentDocument.createdBy)}">
<s:graphicImage styleClass="commentAuthorPortraitImage" value="#{currentDocument.createdBy.profile.image}">
<s:transformImageSize width="30" maintainRatio="true"/>
</s:graphicImage>
- </s:link>
+ </h:outputLink>
</s:span>
</s:fragment>
Modified: trunk/examples/wiki/view/plugins/lastModifiedDocuments/plugin.xhtml
===================================================================
--- trunk/examples/wiki/view/plugins/lastModifiedDocuments/plugin.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/plugins/lastModifiedDocuments/plugin.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -23,14 +23,27 @@
<h:column>
<s:div styleClass="lastModifiedAuthorDate smallFont">
- <h:outputText value="(#{doc.lastModifiedBy.username}) "
- rendered="#{!empty doc.lastModifiedBy and preferences.get('LastModifiedDocuments', currentMacro).showUsernames}">
- </h:outputText>
+
+ <s:fragment rendered="#{preferences.get('LastModifiedDocuments', currentMacro).showUsernames}">
+
+ <s:span styleClass="undecoratedLink" rendered="#{wiki:isRegularUser(doc.lastModifiedBy)}">
+ <h:outputLink value="#{wiki:renderUserInfoURL(doc.lastModifiedBy)}">
+ <h:outputText value="#{doc.lastModifiedBy.username}"/>
+ </h:outputLink>
+ </s:span>
+ <s:span rendered="#{not wiki:isRegularUser(doc.lastModifiedBy)}">
+ <h:outputText value="#{doc.lastModifiedBy.username}"/>
+ </s:span>
+
+ <h:outputText value=" "/>
+ </s:fragment>
+
<h:outputText value="#{doc.lastModifiedOn}"
rendered="#{!empty doc.lastModifiedOn}">
<f:convertDateTime pattern="dd. MMM yyyy, HH:mm" timeZone="#{preferences.get('Wiki').timeZone}"/>
</h:outputText>
<h:outputText value=" #{preferences.get('Wiki').timeZone}"/>
+
</s:div>
<s:div styleClass="lastModifiedTitle wrapWhitespace">
Modified: trunk/examples/wiki/view/tagDisplay_d.xhtml
===================================================================
--- trunk/examples/wiki/view/tagDisplay_d.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/tagDisplay_d.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -84,10 +84,9 @@
<h:outputText value="#{messages['lacewiki.label.tagDisplay.Owner']}"/>
</f:facet>
<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{file.createdBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(file.createdBy)}">
<h:outputText value="#{file.createdBy.fullname}"/>
- </s:link>
+ </h:outputLink>
</s:span>
</h:column>
<h:column>
@@ -106,10 +105,9 @@
<f:convertDateTime pattern="dd. MMM yyyy, HH:mm" timeZone="#{preferences.get('Wiki').timeZone}"/>
</h:outputText>
(<s:span styleClass="undecoratedLink">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{file.lastModifiedBy.id}"/>
+ <h:outputLink value="#{wiki:renderUserInfoURL(file.lastModifiedBy)}">
<h:outputText value="#{file.lastModifiedBy.username}"/>
- </s:link>
+ </h:outputLink>
</s:span>)
</h:column>
<h:column rendered="#{empty file.lastModifiedOn or empty file.lastModifiedBy}">
Modified: trunk/examples/wiki/view/userList_d.xhtml
===================================================================
--- trunk/examples/wiki/view/userList_d.xhtml 2008-01-29 07:06:47 UTC (rev 7280)
+++ trunk/examples/wiki/view/userList_d.xhtml 2008-01-29 07:59:33 UTC (rev 7281)
@@ -155,10 +155,9 @@
<h:outputText value="#{u.username}"/>
</s:fragment>
<s:fragment rendered="#{not u.admin and not u.guest}">
- <s:link view="/userInfo_#{skin}.xhtml" propagation="none">
- <f:param name="userId" value="#{u.id}"/>
- <h:outputText rendered="#{empty u.memberHome}" value="#{u.username}"/>
- </s:link>
+ <h:outputLink value="#{wiki:renderUserInfoURL(u)}">
+ <h:outputText value="#{u.username}"/>
+ </h:outputLink>
<h:outputText rendered="#{!u.activated}" value=" (#{messages['lacewiki.label.userList.NotActivated']})"/>
</s:fragment>
</h:column>
16 years, 11 months
Seam SVN: r7280 - trunk/src/main/org/jboss/seam/contexts.
by seam-commits@lists.jboss.org
Author: christian.bauer(a)jboss.com
Date: 2008-01-29 02:06:47 -0500 (Tue, 29 Jan 2008)
New Revision: 7280
Modified:
trunk/src/main/org/jboss/seam/contexts/Lifecycle.java
Log:
Minor, improved exception message
Modified: trunk/src/main/org/jboss/seam/contexts/Lifecycle.java
===================================================================
--- trunk/src/main/org/jboss/seam/contexts/Lifecycle.java 2008-01-29 07:05:44 UTC (rev 7279)
+++ trunk/src/main/org/jboss/seam/contexts/Lifecycle.java 2008-01-29 07:06:47 UTC (rev 7280)
@@ -218,7 +218,7 @@
if ( Contexts.isEventContextActive() || Contexts.isApplicationContextActive() )
{
- throw new IllegalStateException("Please end the HttpSession via Seam.invalidateSession()");
+ throw new IllegalStateException("Please end the HttpSession via org.jboss.seam.web.Session.instance().invalidate()");
}
Context tempApplicationContext = new ApplicationContext( getApplication() );
16 years, 11 months
Seam SVN: r7279 - in trunk/examples/wiki: src/main/org/jboss/seam/wiki/core/ui and 4 other directories.
by seam-commits@lists.jboss.org
Author: christian.bauer(a)jboss.com
Date: 2008-01-29 02:05:44 -0500 (Tue, 29 Jan 2008)
New Revision: 7279
Added:
trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_black.gif
trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_grey.gif
trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_white.gif
Modified:
trunk/examples/wiki/Wiki.ipr
trunk/examples/wiki/Wiki.iws
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/view/docHistory_d.xhtml
trunk/examples/wiki/view/themes/default/css/template.css
trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css
Log:
JBSEAM-2545 - Destroy session after servlet request to save memory
Modified: trunk/examples/wiki/Wiki.ipr
===================================================================
--- trunk/examples/wiki/Wiki.ipr 2008-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/Wiki.ipr 2008-01-29 07:05:44 UTC (rev 7279)
@@ -1482,25 +1482,5 @@
</value>
</option>
</component>
- <component name="libraryTable">
- <library name="jsf">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/lib/myfaces-api-1.1.4.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/myfaces-impl-1.1.4.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-beanutils-1.7.0.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-codec-1.3.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-collections-3.1.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-digester-1.6.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-el-1.0.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-jci-core-1.0-406301.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-jci-janino-2.4.3.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-lang-2.1.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/commons-logging-api-1.0.4.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/jstl-1.1.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </component>
</project>
Modified: trunk/examples/wiki/Wiki.iws
===================================================================
--- trunk/examples/wiki/Wiki.iws 2008-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/Wiki.iws 2008-01-29 07:05:44 UTC (rev 7279)
@@ -8,14 +8,18 @@
<editor_bookmark url="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/feeds/FeedDAO.java" line="96" />
</component>
<component name="CCaseConfig">
- <option name="implementation" value="net.sourceforge.transparent.CommandLineClearCase" />
<option name="checkoutReserved" value="false" />
<option name="markExternalChangeAsUpToDate" value="true" />
<option name="checkInUseHijack" value="true" />
+ <option name="useUcmModel" value="true" />
<option name="isOffline" value="false" />
+ <option name="synchOutside" value="false" />
+ <option name="isHistoryResticted" value="true" />
+ <option name="useIdenticalSwitch" value="true" />
+ <option name="synchActivitiesOnRefresh" value="true" />
<option name="lastScr" value="" />
<option name="scrTextFileName" value="" />
- <option name="lastViewType" />
+ <option name="historyRevisionsNumber" value="4" />
</component>
<component name="ChangeBrowserSettings">
<option name="MAIN_SPLITTER_PROPORTION" value="0.3" />
@@ -33,45 +37,50 @@
</component>
<component name="ChangeListManager">
<list default="true" name="Default" comment="">
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedAggregatorDAO.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/etc/messages_feedAggregator_en.properties" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/preferences/WikiPreferenceValue.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/preferences/WikiPreferenceValue.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator/FeedAggregator.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/preferences/metamodel/PreferenceEntity.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedConnector.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/RomeFeedConnector.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/blogdirectory/BlogDirectory.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/prefs/WikiPreferences.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/WikiNodeFactory.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/TopicHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/InstancePreferencesTests.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/themes/sfwkorg/css/sfwk.css" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/css/sfwk.css" />
- <change type="MOVED" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/connector/JiraConnector.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/connector/JiraConnectorTest.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/Wiki.iml" afterPath="$PROJECT_DIR$/Wiki.iml" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/cache/ConnectorCacheKey.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/cache/ConnectorCacheKey.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedEntryDTO.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedConnectorPreferences.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/connector/FeedConnectorTest.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/NodeHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/NodeHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/CommentHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/CommentHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/SystemPreferencesTests.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/UserRoleAccessFactory.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedConnectorCache.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/etc/META-INF/wiki.taglib.xml" afterPath="$PROJECT_DIR$/src/etc/META-INF/wiki.taglib.xml" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/cache/ConnectorCacheAsyncUpdater.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/cache/ConnectorCacheAsyncUpdater.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/etc/WEB-INF/pages.xml" afterPath="$PROJECT_DIR$/src/etc/WEB-INF/pages.xml" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/etc/WEB-INF/web.xml" afterPath="$PROJECT_DIR$/src/etc/WEB-INF/web.xml" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/editing/BasicNodeOperations.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/util/WikiUtil.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/util/WikiUtil.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator/FeedAggregatorPreferencesSupport.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/themes/default/css/feedAggregator.css" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/docHistory_d.xhtml" afterPath="$PROJECT_DIR$/view/docHistory_d.xhtml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/Wiki.iws" afterPath="$PROJECT_DIR$/Wiki.iws" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/plugins/feedAggregator" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator/FeedAggregatorPreferences.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedConnectorPreferencesSupport.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/model/FeedEntry.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/model/FeedEntry.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/css/feedAggregator.css" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/plugins/feedAggregator/plugin.xhtml" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/themes/sfwkorg/css/faqBrowser.css" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/css/faqBrowser.css" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextHandler.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/img/runningon_seamlogo_grey.gif" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/ReplyHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/faqBrowser/FaqQuestionHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/Wiki.ipr" afterPath="$PROJECT_DIR$/Wiki.ipr" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UserPasswordReset.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UserPasswordReset.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/search/WikiSearch.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UploadHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UploadHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum/ForumHome.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UserHome.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/UserHome.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/img/runningon_seamlogo_white.gif" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/etc/WEB-INF/components.xml" afterPath="$PROJECT_DIR$/src/etc/WEB-INF/components.xml" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/themes/sfwkorg/css/blogArchive.css" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/css/blogArchive.css" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/etc/messages_feedConnector_en.properties" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/jiraIssueList/JiraIssueListPreferences.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/jiraIssueList/JiraIssueListPreferences.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/plugins/feedTeasers/plugin.xhtml" afterPath="$PROJECT_DIR$/view/plugins/feedTeasers/plugin.xhtml" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/preferences/UserPreferencesTests.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/preferences/Preferences.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/preferences/Preferences.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java" afterPath="$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/editing/Uploading.java" afterPath="$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/editing/Uploading.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/etc/import-prod.sql" afterPath="$PROJECT_DIR$/src/etc/import-prod.sql" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/view/themes/sfwkorg/img/runningon_seamlogo_black.gif" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/view/themes/default/css/template.css" afterPath="$PROJECT_DIR$/view/themes/default/css/template.css" />
</list>
<list name="Failed commit: Default" comment="Oops" />
<list name="Foo" comment="" />
+ <ignored path="dist/" />
</component>
<component name="ChangesViewManager" flattened_view="false" show_ignored="false" />
<component name="Commander">
@@ -191,15 +200,24 @@
</component>
<component name="FileEditorManager">
<leaf>
- <file leaf-file-name="log4j.xml" pinned="false" current="true" current-in-tab="true">
- <entry file="file://$PROJECT_DIR$/src/test/log4j.xml">
+ <file leaf-file-name="FeedServlet.java" pinned="false" current="true" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="15" column="29" selection-start="742" selection-end="742" vertical-scroll-proportion="0.28931752">
+ <state line="241" column="0" selection-start="10913" selection-end="10913" vertical-scroll-proportion="0.5566038">
<folding />
</state>
</provider>
</entry>
</file>
+ <file leaf-file-name="FileServlet.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="128" column="0" selection-start="4941" selection-end="4941" vertical-scroll-proportion="0.9716981">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
</leaf>
</component>
<component name="FindManager">
@@ -491,14 +509,6 @@
<option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/themes" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/themes/sfwkorg" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/themes/sfwkorg/css" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
@@ -514,80 +524,6 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/themes" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/themes/default" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- </PATH>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/plugins" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- </PATH>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/plugins" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/view/plugins/feedAggregator" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- </PATH>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
<option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
@@ -648,7 +584,7 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/dao" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/feeds" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
@@ -678,7 +614,7 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/connector" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/editing" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
@@ -790,7 +726,7 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedTeasers" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/forum" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
@@ -820,13 +756,9 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
@@ -854,11 +786,11 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/jira" />
+ <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/engine" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
@@ -879,79 +811,7 @@
<option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
</PATH>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/cache" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- </PATH>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="Wiki" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="PsiDirectory:$PROJECT_DIR$/src/etc" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
- </PATH_ELEMENT>
- </PATH>
</subPane>
</component>
<component name="ProjectReloadState">
@@ -978,7 +838,7 @@
<showLibraryContents />
<hideEmptyPackages ProjectPane="true" />
<abbreviatePackageNames />
- <showStructure ProjectPane="false" Scope="false" PackagesPane="false" Favorites="false" />
+ <showStructure PackagesPane="false" Scope="false" Favorites="false" ProjectPane="false" />
<autoscrollToSource />
<autoscrollFromSource ProjectPane="false" />
<sortByType />
@@ -992,8 +852,8 @@
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_treeOrder4" value="4" />
<property name="TEMP_MODULE_EXPLODED_DIR_FOR_Wiki/web/Web" value="/private/tmp/webExplodedDir27892tmp" />
<property name="cvs_file_history_flatOrder1" value="1" />
- <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatOrder5" value="5" />
<property name="cvs_file_history_flatWidth1" value="351" />
+ <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatOrder5" value="5" />
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatWidth6" value="531" />
<property name="cvs_file_history_flatOrder2" value="2" />
<property name="MemberChooser.showClasses" value="true" />
@@ -1044,12 +904,12 @@
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_treeOrder0" value="0" />
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_treeWidth6" value="531" />
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatOrder0" value="0" />
- <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatWidth5" value="319" />
<property name="cvs_file_history_flatWidth6" value="350" />
+ <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatWidth5" value="319" />
<property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_flatOrder3" value="3" />
<property name="cvs_file_history_flatOrder5" value="5" />
- <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_treeOrder5" value="5" />
<property name="cvs_file_history_flatWidth5" value="351" />
+ <property name="FileHistory.com.intellij.cvsSupport2.history.CvsHistoryProvider_treeOrder5" value="5" />
<property name="cvs_file_history_treeOrder2" value="2" />
<property name="cvs_file_history_treeWidth5" value="351" />
<property name="cvs_file_history_flatWidth0" value="351" />
@@ -1085,6 +945,29 @@
<option name="BASE_DIRECTORY_NAME" value="" />
<predefined_log_file id="TOMCAT_LOCALHOST_LOG_ID" enabled="true" />
</configuration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ </configuration>
+ <configuration default="true" type="Application" factoryName="Application" enabled="false" merge="false">
+ <option name="MAIN_CLASS_NAME" />
+ <option name="VM_PARAMETERS" />
+ <option name="PROGRAM_PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <module name="" />
+ <envs />
+ <method>
+ <option name="Make" value="true" />
+ </method>
+ </configuration>
<configuration default="true" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Remote">
<option name="WORKING_DIRECTORY" />
<option name="HOST" value="localhost" />
@@ -1097,6 +980,18 @@
<option name="BASE_DIRECTORY_NAME" value="" />
<predefined_log_file id="TOMCAT_LOCALHOST_LOG_ID" enabled="true" />
</configuration>
+ <configuration default="true" type="Applet" factoryName="Applet">
+ <module name="" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="HTML_FILE_NAME" />
+ <option name="HTML_USED" value="false" />
+ <option name="WIDTH" value="400" />
+ <option name="HEIGHT" value="300" />
+ <option name="POLICY_FILE" value="$PROJECT_DIR$/../../../../../../../Desktop/IntelliJ IDEA.app/bin/appletviewer.policy" />
+ <option name="VM_PARAMETERS" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ </configuration>
<configuration default="true" type="TestNG" factoryName="TestNG" enabled="false" merge="false">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -1131,41 +1026,6 @@
<option name="Run ant target" value="false" />
</method>
</configuration>
- <configuration default="true" type="Applet" factoryName="Applet">
- <module name="" />
- <option name="MAIN_CLASS_NAME" />
- <option name="HTML_FILE_NAME" />
- <option name="HTML_USED" value="false" />
- <option name="WIDTH" value="400" />
- <option name="HEIGHT" value="300" />
- <option name="POLICY_FILE" value="$PROJECT_DIR$/../../../../../../../Desktop/IntelliJ IDEA.app/bin/appletviewer.policy" />
- <option name="VM_PARAMETERS" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- </configuration>
- <configuration default="true" type="Application" factoryName="Application" enabled="false" merge="false">
- <option name="MAIN_CLASS_NAME" />
- <option name="VM_PARAMETERS" />
- <option name="PROGRAM_PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <option name="ENV_VARIABLES" />
- <option name="PASS_PARENT_ENVS" value="true" />
- <module name="" />
- <envs />
- <method>
- <option name="Make" value="true" />
- </method>
- </configuration>
- <configuration default="true" type="Remote" factoryName="Remote">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="false" />
- <option name="SHMEM_ADDRESS" value="javadebug" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5005" />
- </configuration>
<configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -1296,11 +1156,11 @@
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="SUITE_NAME" value="" />
- <option name="PACKAGE_NAME" value="org.jboss.seam.wiki.test.connector" />
- <option name="MAIN_CLASS_NAME" value="org.jboss.seam.wiki.test.connector.FeedConnectorTest" />
- <option name="METHOD_NAME" value="linkToDocumentFragments" />
+ <option name="PACKAGE_NAME" value="org.jboss.seam.wiki.test.editing" />
+ <option name="MAIN_CLASS_NAME" value="org.jboss.seam.wiki.test.editing.BasicNodeOperations" />
+ <option name="METHOD_NAME" value="editDirectory" />
<option name="GROUP_NAME" value="" />
- <option name="TEST_OBJECT" value="CLASS" />
+ <option name="TEST_OBJECT" value="METHOD" />
<option name="VM_PARAMETERS" value="" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
@@ -1341,11 +1201,11 @@
<item index="3" class="java.lang.String" itemvalue="TestNG.AllTests" />
<item index="4" class="java.lang.String" itemvalue="TestNG.Adhoc" />
</list>
- <configuration default="true" type="#com.intellij.j2ee.web.jsr45.JSR45ConfigurationFactory" factoryName="Local">
+ <configuration default="true" type="#com.intellij.j2ee.web.jsr45.JSR45ConfigurationFactory" factoryName="Remote">
<option name="WORKING_DIRECTORY" />
<option name="HOST" value="localhost" />
<option name="PORT" value="8080" />
- <option name="LOCAL" value="true" />
+ <option name="LOCAL" value="false" />
<option name="OPEN_IN_BROWSER" value="true" />
<option name="OPEN_IN_BROWSER_URL" value="/" />
<option name="COMMON_VM_ARGUMENTS" value="" />
@@ -1370,11 +1230,11 @@
<predefined_log_file id="WEBLOGIC_DOMAIN_LOG_FILE" enabled="true" />
<predefined_log_file id="WEBLOGIC_SERVER_LOG_FILE" enabled="true" />
</configuration>
- <configuration default="true" type="#com.intellij.j2ee.web.jsr45.JSR45ConfigurationFactory" factoryName="Remote">
+ <configuration default="true" type="#com.intellij.j2ee.web.jsr45.JSR45ConfigurationFactory" factoryName="Local">
<option name="WORKING_DIRECTORY" />
<option name="HOST" value="localhost" />
<option name="PORT" value="8080" />
- <option name="LOCAL" value="false" />
+ <option name="LOCAL" value="true" />
<option name="OPEN_IN_BROWSER" value="true" />
<option name="OPEN_IN_BROWSER_URL" value="/" />
<option name="COMMON_VM_ARGUMENTS" value="" />
@@ -1486,24 +1346,23 @@
</todo-panel>
</component>
<component name="ToolWindowManager">
- <frame x="0" y="22" width="1440" height="836" extended-state="6" />
+ <frame x="0" y="22" width="2560" height="1523" extended-state="6" />
<editor active="false" />
<layout>
- <window_info id="SQL" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.46458924" order="16" x="11" y="253" width="1391" height="477" />
+ <window_info id="SQL" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.42507002" order="16" x="897" y="216" width="436" height="865" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.64235127" order="7" />
- <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.23220704" order="0" />
- <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.6175637" order="1" />
+ <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.20421974" order="0" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.6162465" order="1" />
<window_info id="Structure" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.16103522" order="7" />
- <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.28475034" order="12" x="24" y="688" width="925" height="442" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.28431374" order="12" x="2269" y="1083" width="300" height="438" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="5" />
- <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32961783" order="6" />
<window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39486468" order="13" />
+ <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32961783" order="6" />
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="4" />
- <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.16462976" order="2" />
- <window_info id="Maven projects" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32902297" order="3" />
- <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32928476" order="14" />
- <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.46558705" order="2" x="-1442" y="805" width="1440" height="900" />
- <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24930307" order="1" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.10987261" order="2" />
+ <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32913166" order="14" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.464986" order="2" x="-1442" y="805" width="1440" height="900" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24874191" order="1" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.67881244" order="3" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2109646" order="11" />
<window_info id="Duplicates" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3296322" order="9" />
@@ -1511,6 +1370,7 @@
<window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="2" />
<window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3297414" order="3" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="4" />
+ <window_info id="Maven projects" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32902297" order="3" />
<window_info id="SQL Schema" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.29215822" order="0" />
<window_info id="CVS" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="10" />
<window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
@@ -1536,7 +1396,7 @@
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
<option name="FORCE_NON_EMPTY_COMMENT" value="false" />
- <option name="LAST_COMMIT_MESSAGE" value="JBSEAM-2451 - Feed aggregator connector and plugin" />
+ <option name="LAST_COMMIT_MESSAGE" value="Improved exception handling a bit (still buggy)" />
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
@@ -1547,15 +1407,6 @@
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
- <MESSAGE value="Avoid NPE" />
- <MESSAGE value="Configurable forum reply e-mail notification and Safari3 fixes" />
- <MESSAGE value="Use new SeamTest superclass" />
- <MESSAGE value="JBSEAM-2397 and JBSEAM-1883 - implemented trashcan feature and more reliable update of 2nd level cache and lucene index" />
- <MESSAGE value="If you write new code, actually call it at some point..." />
- <MESSAGE value="JBSEAM-2477 - Only/no comments displayed on feeds" />
- <MESSAGE value="Better getInstance() calls" />
- <MESSAGE value="Improved macro handling in documents and URL rendering" />
- <MESSAGE value="Oops" />
<MESSAGE value="JBSEAM-2136 - Anchor/linking support for document headlines" />
<MESSAGE value="Right-click action menu on dir display" />
<MESSAGE value="JBSEAM-2457 - Render "REST" feed/file download URLs, breaks all current feed/file bookmarks" />
@@ -1572,13 +1423,21 @@
<MESSAGE value="Various bugfixes" />
<MESSAGE value="JBSEAM-2502 - JIRA issue list plugin and JIRA connector (plus re-usable remote connector data cache)" />
<MESSAGE value="JBSEAM-2451 - Feed aggregator connector and plugin" />
+ <MESSAGE value="Fix possible non-threadsafe map access, async updater might write after purge" />
+ <MESSAGE value="Configuration switch for site feed in main menu" />
+ <MESSAGE value="Implemented subscription for aggregated feeds" />
+ <MESSAGE value="Minor UI improvements, IE fixes" />
+ <MESSAGE value="Fix tests" />
+ <MESSAGE value="Rating system for comments and top posters plugin" />
+ <MESSAGE value="Fix NPE" />
+ <MESSAGE value="Minor changes" />
+ <MESSAGE value="Improved exception handling a bit (still buggy)" />
</component>
<component name="VssConfiguration">
<option name="CLIENT_PATH" value="" />
<option name="SRCSAFEINI_PATH" value="" />
<option name="USER_NAME" value="" />
<option name="PWD" value="" />
- <option name="VSS_IS_INITIALIZED" value="true" />
<CheckoutOptions>
<option name="COMMENT" value="" />
<option name="DO_NOT_GET_LATEST_VERSION" value="false" />
@@ -1644,7 +1503,7 @@
</targetFilters>
<treeView value="true" />
<verbose value="true" />
- <viewClosedWhenNoErrors value="false" />
+ <viewClosedWhenNoErrors value="true" />
</buildFile>
</component>
<component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1">
@@ -1658,114 +1517,114 @@
<option name="myLastEditedConfigurable" value="Default" />
</component>
<component name="editorHistoryManager">
- <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/FeedEntryDTO.java">
+ <entry file="file://$PROJECT_DIR$/migration.sql">
<provider selected="true" editor-type-id="text-editor">
- <state line="33" column="0" selection-start="694" selection-end="694" vertical-scroll-proportion="0.90697676">
+ <state line="199" column="59" selection-start="12559" selection-end="12559" vertical-scroll-proportion="0.5471698">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/feedAggregator/FeedAggregatorPreferences.java">
+ <entry file="file://$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml">
<provider selected="true" editor-type-id="text-editor">
- <state line="103" column="0" selection-start="3178" selection-end="3178" vertical-scroll-proportion="0.77378434">
+ <state line="23" column="140" selection-start="3839" selection-end="3873" vertical-scroll-proportion="0.22213967">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/etc/messages_feedAggregator_en.properties">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="8" column="63" selection-start="582" selection-end="582" vertical-scroll-proportion="0.21987315">
+ <state line="203" column="0" selection-start="6312" selection-end="6563" vertical-scroll-proportion="0.9150943">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/themes/default/css/feedAggregator.css">
+ <entry file="file://$PROJECT_DIR$/view/includes/searchControl.xhtml">
<provider selected="true" editor-type-id="text-editor">
- <state line="9" column="1" selection-start="112" selection-end="112" vertical-scroll-proportion="0.2473573">
+ <state line="21" column="13" selection-start="1410" selection-end="1410" vertical-scroll-proportion="0.20058781">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/themes/sfwkorg/css/feedAggregator.css">
+ <entry file="file://$PROJECT_DIR$/view/includes/userControl.xhtml">
<provider selected="true" editor-type-id="text-editor">
- <state line="11" column="0" selection-start="149" selection-end="149" vertical-scroll-proportion="0.30232558">
+ <state line="109" column="0" selection-start="5913" selection-end="5913" vertical-scroll-proportion="0.36296842">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/WikiBaseData.dbunit.xml">
+ <entry file="file://$PROJECT_DIR$/view/themes/default/css/template.css">
<provider selected="true" editor-type-id="text-editor">
- <state line="263" column="70" selection-start="23108" selection-end="23108" vertical-scroll-proportion="0.629742">
+ <state line="985" column="0" selection-start="16132" selection-end="16132" vertical-scroll-proportion="0.3490566">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/view/themes/sfwkorg/css/sfwk.css">
<provider selected="true" editor-type-id="text-editor">
- <state line="998" column="28" selection-start="15950" selection-end="15950" vertical-scroll-proportion="0.6637555">
+ <state line="734" column="0" selection-start="11189" selection-end="11237" vertical-scroll-proportion="0.009433962">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/themes/sfwkorg/css/faqBrowser.css">
+ <entry file="file://$PROJECT_DIR$/view/docDisplay_d.xhtml">
<provider selected="true" editor-type-id="text-editor">
- <state line="6" column="55" selection-start="157" selection-end="157" vertical-scroll-proportion="0.15856236">
+ <state line="205" column="33" selection-start="11321" selection-end="11321" vertical-scroll-proportion="0.51212347">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/themes/sfwkorg/css/blogArchive.css">
+ <entry file="file://$PROJECT_DIR$/view/includes/commentsDisplay.xhtml">
<provider selected="true" editor-type-id="text-editor">
- <state line="10" column="23" selection-start="173" selection-end="173" vertical-scroll-proportion="0.27484143">
+ <state line="104" column="0" selection-start="6141" selection-end="6141" vertical-scroll-proportion="0.55033064">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/plugins/feedAggregator/plugin.xhtml">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/dao/WikiNodeDAO.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="66" column="27" selection-start="3900" selection-end="3900" vertical-scroll-proportion="0.81632656">
+ <state line="345" column="94" selection-start="15370" selection-end="15370" vertical-scroll-proportion="0.3896952">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/migration.sql">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/lastmodified/LastModifiedDocuments.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="193" column="0" selection-start="12248" selection-end="12248" vertical-scroll-proportion="0.709607">
+ <state line="40" column="37" selection-start="1211" selection-end="1211" vertical-scroll-proportion="0.3773585">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/view/themes/sfwkorg/css/mainMenu.css">
+ <entry file="file://$PROJECT_DIR$/src/test/org/jboss/seam/wiki/test/dao/WikiNodeDAOTests.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="22" column="1" selection-start="395" selection-end="395" vertical-scroll-proportion="0.60465115">
+ <state line="82" column="48" selection-start="2791" selection-end="2791" vertical-scroll-proportion="0.11828737">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/plugin/lastmodified/LastModifiedDocumentsPreferences.java">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/model/WikiDocument.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="20" column="13" selection-start="846" selection-end="846" vertical-scroll-proportion="0.47145876">
+ <state line="12" column="13" selection-start="324" selection-end="324" vertical-scroll-proportion="0.11320755">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/etc/messages_en.properties">
+ <entry file="file://$PROJECT_DIR$/src/etc/WEB-INF/web.xml">
<provider selected="true" editor-type-id="text-editor">
- <state line="23" column="29" selection-start="831" selection-end="831" vertical-scroll-proportion="0.1612426">
+ <state line="113" column="26" selection-start="3388" selection-end="3388" vertical-scroll-proportion="0.904482">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/connectors/feed/RomeFeedConnector.java">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="27" column="22" selection-start="882" selection-end="882" vertical-scroll-proportion="0.5079595">
+ <state line="128" column="0" selection-start="4941" selection-end="4941" vertical-scroll-proportion="0.9716981">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/test/log4j.xml">
+ <entry file="file://$PROJECT_DIR$/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="15" column="29" selection-start="742" selection-end="742" vertical-scroll-proportion="0.28931752">
+ <state line="241" column="0" selection-start="10913" selection-end="10913" vertical-scroll-proportion="0.5566038">
<folding />
</state>
</provider>
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-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FeedServlet.java 2008-01-29 07:05:44 UTC (rev 7279)
@@ -9,6 +9,9 @@
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.io.SyndFeedOutput;
import org.jboss.seam.Component;
+import org.jboss.seam.Seam;
+import org.jboss.seam.web.Session;
+import org.jboss.seam.security.Identity;
import org.jboss.seam.international.Messages;
import org.jboss.seam.wiki.core.feeds.FeedDAO;
import org.jboss.seam.wiki.core.model.*;
@@ -137,7 +140,7 @@
feed.setAuthor(Messages.instance().get("lacewiki.msg.AutomaticallyGeneratedFeed"));
feed.setTitle(Messages.instance().get("lacewiki.msg.AutomaticallyGeneratedFeed") + ": " + aggregateParam);
feed.setPublishedDate(new Date());
- feed.setLink( ((WikiPreferences) Preferences.getInstance("Wiki")).getBaseUrl() );
+ feed.setLink( Preferences.getInstance(WikiPreferences.class).getBaseUrl() );
for (FeedEntryDTO feedEntryDTO : result) {
feed.getFeedEntries().add(feedEntryDTO.getFeedEntry());
}
@@ -235,6 +238,11 @@
}
throw new RuntimeException(ex);
}
+
+ // If the user is not logged in, we might as well destroy the session immediately, saving some memory
+ if (!Identity.instance().isLoggedIn()) {
+ Session.instance().invalidate();
+ }
}
public SyndFeed createSyndFeed(String baseURI, SyndFeedType syndFeedType, Feed feed, Integer currentAccessLevel) {
@@ -249,7 +257,7 @@
Comments comments,
String aggregateParam) {
- WikiPreferences prefs = (WikiPreferences) Preferences.getInstance("Wiki");
+ WikiPreferences prefs = Preferences.getInstance(WikiPreferences.class);
// Create feed
SyndFeed syndFeed = new SyndFeedImpl();
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-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/FileServlet.java 2008-01-29 07:05:44 UTC (rev 7279)
@@ -1,11 +1,11 @@
package org.jboss.seam.wiki.core.ui;
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.web.Session;
+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.wiki.core.dao.WikiNodeDAO;
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
@@ -122,5 +122,11 @@
response.getOutputStream().flush();
}
+
+ // If the user is not logged in, we might as well destroy the session immediately, saving some memory
+ if (!Identity.instance().isLoggedIn()) {
+ Session.instance().invalidate();
+ }
+
}
}
Modified: trunk/examples/wiki/view/docHistory_d.xhtml
===================================================================
--- trunk/examples/wiki/view/docHistory_d.xhtml 2008-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/view/docHistory_d.xhtml 2008-01-29 07:05:44 UTC (rev 7279)
@@ -79,7 +79,7 @@
value="#{historicalFileList}"
styleClass="datatable topLeftBottomBorder"
columnClasses="onePercentColumn rightBorder alignCenter,
- twentyPercentColumn rightBorder alignLeft,
+ twentyPercentColumn rightBorder alignLeft minorPadding,
twentyPercentColumn rightBorder alignCenter"
rowClasses="rowEven, rowOdd"
cellpadding="0" cellspacing="0" border="0">
Modified: trunk/examples/wiki/view/themes/default/css/template.css
===================================================================
--- trunk/examples/wiki/view/themes/default/css/template.css 2008-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/view/themes/default/css/template.css 2008-01-29 07:05:44 UTC (rev 7279)
@@ -943,6 +943,10 @@
margin-bottom: 5px;
}
+.commentControls form {
+ text-align:right;
+}
+
.commentRating, .commentRatingChooser {
font-weight: bold;
}
Modified: trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css
===================================================================
--- trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css 2008-01-29 06:20:52 UTC (rev 7278)
+++ trunk/examples/wiki/view/themes/sfwkorg/css/sfwk.css 2008-01-29 07:05:44 UTC (rev 7279)
@@ -729,6 +729,10 @@
margin-bottom: 5px;
}
+.commentControls form {
+ text-align:right;
+}
+
.commentRating, .commentRatingChooser {
font-weight: bold;
}
Added: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_black.gif
===================================================================
(Binary files differ)
Property changes on: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_black.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_grey.gif
===================================================================
(Binary files differ)
Property changes on: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_grey.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_white.gif
===================================================================
(Binary files differ)
Property changes on: trunk/examples/wiki/view/themes/sfwkorg/img/runningon_seamlogo_white.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
16 years, 11 months
Seam SVN: r7278 - trunk/src/main/org/jboss/seam/util.
by seam-commits@lists.jboss.org
Author: norman.richards(a)jboss.com
Date: 2008-01-29 01:20:52 -0500 (Tue, 29 Jan 2008)
New Revision: 7278
Modified:
trunk/src/main/org/jboss/seam/util/XML.java
Log:
JBSEAM-2194
Modified: trunk/src/main/org/jboss/seam/util/XML.java
===================================================================
--- trunk/src/main/org/jboss/seam/util/XML.java 2008-01-29 04:04:35 UTC (rev 7277)
+++ trunk/src/main/org/jboss/seam/util/XML.java 2008-01-29 06:20:52 UTC (rev 7278)
@@ -1,8 +1,10 @@
package org.jboss.seam.util;
import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.UnknownHostException;
import org.dom4j.DocumentException;
import org.dom4j.Element;
@@ -13,13 +15,28 @@
public class XML
{
- public static Element getRootElement(InputStream stream) throws DocumentException
- {
- SAXReader saxReader = new SAXReader();
- saxReader.setEntityResolver(new DTDEntityResolver());
- saxReader.setMergeAdjacentText(true);
- return saxReader.read(stream).getRootElement();
- }
+ public static Element getRootElement(InputStream stream) throws DocumentException
+ {
+ try {
+ SAXReader saxReader = new SAXReader();
+ saxReader.setEntityResolver(new DTDEntityResolver());
+ saxReader.setMergeAdjacentText(true);
+ return saxReader.read(stream).getRootElement();
+ } catch (DocumentException e) {
+ Throwable nested = e.getNestedException();
+ if (nested!= null) {
+ if (nested instanceof FileNotFoundException) {
+ throw new RuntimeException("Can't find schema/DTD reference: " +
+ nested.getMessage(), e);
+ } else if (nested instanceof UnknownHostException) {
+ throw new RuntimeException("Cannot connect to host from schema/DTD reference: " +
+ nested.getMessage() +
+ " - check that your schema/DTD reference is current", e);
+ }
+ }
+ throw e;
+ }
+ }
/**
16 years, 11 months
Seam SVN: r7277 - trunk/doc/reference/en/modules.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-01-28 23:04:35 -0500 (Mon, 28 Jan 2008)
New Revision: 7277
Modified:
trunk/doc/reference/en/modules/security.xml
Log:
describe security permissions for IdentityManager
Modified: trunk/doc/reference/en/modules/security.xml
===================================================================
--- trunk/doc/reference/en/modules/security.xml 2008-01-29 03:15:19 UTC (rev 7276)
+++ trunk/doc/reference/en/modules/security.xml 2008-01-29 04:04:35 UTC (rev 7277)
@@ -3,16 +3,16 @@
<para>
The Seam Security API is an optional Seam feature that provides authentication and authorization features
- for securing both domain and page resources within your Seam project.
+ for securing both domain and page resources within your Seam project.
</para>
-
+
<sect1>
<title>Overview</title>
-
+
<para>
Seam Security provides two different modes of operation:
</para>
-
+
<itemizedlist>
<listitem>
<para>
@@ -22,38 +22,38 @@
</listitem>
<listitem>
<para>
- <emphasis>advanced mode</emphasis> - this mode supports all the same features as the simplified mode,
- plus it offers rule-based security checks using JBoss Rules.
+ <emphasis>advanced mode</emphasis> - this mode supports all the same features as the simplified mode,
+ plus it offers rule-based security checks using JBoss Rules.
</para>
</listitem>
</itemizedlist>
-
+
<sect2>
<title>Which mode is right for my application?</title>
-
+
<para>
That all depends on the requirements of your application. If you have minimal security requirements, for example
if you only wish to restrict certain pages and actions to users who are logged in, or who belong to a certain role,
- then the simplified mode will probably be sufficient. The advantages of this is a more simplified configuration,
+ then the simplified mode will probably be sufficient. The advantages of this is a more simplified configuration,
significantly less libraries to include, and a smaller memory footprint.
</para>
-
+
<para>
- If on the other hand, your application requires security checks based on contextual state or complex business rules,
+ If on the other hand, your application requires security checks based on contextual state or complex business rules,
then you will require the features provided by the advanced mode.
</para>
</sect2>
</sect1>
-
+
<sect1>
<title>Requirements</title>
-
+
<para>
- If using the advanced mode features of Seam Security, the following jar files are required to be configured as modules in
+ If using the advanced mode features of Seam Security, the following jar files are required to be configured as modules in
<literal>application.xml</literal>. If you are using Seam Security in simplified mode, these are <emphasis>not</emphasis>
required:
</para>
-
+
<itemizedlist>
<listitem>
<para>drools-compiler.jar</para>
@@ -69,25 +69,25 @@
</listitem>
<listitem>
<para>mvel14.jar</para>
- </listitem>
- </itemizedlist>
-
+ </listitem>
+ </itemizedlist>
+
<para>
For web-based security, <literal>jboss-seam-ui.jar</literal> must also be included in the application's war file.
</para>
-
-
+
+
</sect1>
-
+
<sect1>
<title>Disabling Security</title>
-
+
<para>
In some situations it may be necessary to disable Seam Security, for example during unit tests. This can be done by
calling the static method <literal>Identity.setSecurityEnabled(false)</literal> to disable security checks. Doing this
prevents any security checks being performed for the following:
</para>
-
+
<itemizedlist>
<listitem>
<para>Entity Security</para>
@@ -100,7 +100,7 @@
</listitem>
<listitem>
<para>Page restrictions</para>
- </listitem>
+ </listitem>
</itemizedlist>
</sect1>
@@ -131,10 +131,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
- http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
-
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
<security:identity authenticate-method="#{authenticator.authenticate}"/>
-
+
</components>]]></programlisting>
<para>
@@ -157,18 +157,18 @@
<para>
The <literal>authenticate-method</literal> property specified for <literal>identity</literal> in
<literal>components.xml</literal> specifies which method will be used by <literal>SeamLoginModule</literal>
- to authenticate users. This method takes no parameters, and is expected to return a boolean indicating
+ to authenticate users. This method takes no parameters, and is expected to return a boolean indicating
whether authentication is successful or not. The user's username and password can be obtained from
<literal>Identity.instance().getUsername()</literal> and <literal>Identity.instance().getPassword()</literal>,
respectively. Any roles that the user is a member of should be assigned using
- <literal>Identity.instance().addRole()</literal>. Here's a complete example of an authentication method
+ <literal>Identity.instance().addRole()</literal>. Here's a complete example of an authentication method
inside a JavaBean component:
</para>
<programlisting><![CDATA[@Name("authenticator")
public class Authenticator {
@In EntityManager entityManager;
-
+
public boolean authenticate() {
try
{
@@ -190,9 +190,9 @@
{
return false;
}
-
+
}
-
+
}]]></programlisting>
<para>
@@ -202,21 +202,21 @@
In this case, if the user record is not found and a <literal>NoResultException</literal> thrown, the
authentication method returns <literal>false</literal> to indicate the authentication failed.
</para>
-
+
<sect3>
<title>Identity.addRole()</title>
-
+
<para>
The <literal>Identity.addRole()</literal> method behaves differently depending on whether the current
- session is authenticated or not. If the session is not authenticated, then <literal>addRole()</literal>
+ session is authenticated or not. If the session is not authenticated, then <literal>addRole()</literal>
should <emphasis>only</emphasis> be called during the authentication process. When called here, the
role name is placed into a temporary list of pre-authenticated roles. Once authentication is successful,
the pre-authenticated roles then become "real" roles, and calling <literal>Identity.hasRole()</literal>
for those roles will then return true. The following sequence diagram represents the list of pre-authenticated
roles as a first class object to show more clearly how it fits in to the authentication process.
-
+
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-addrole.png" align="center"/>
@@ -224,37 +224,37 @@
<imageobject role="html">
<imagedata fileref="../shared/images/security-addrole.png" align="center"/>
</imageobject>
- </mediaobject>
-
+ </mediaobject>
+
</sect3>
-
+
<sect3>
<title>Special Considerations</title>
-
+
<para>
- When writing an authenticator method, it is important that it is kept minimal and free from
- any side-effects. This is because there is no guarantee as to how many times the authenticator
+ When writing an authenticator method, it is important that it is kept minimal and free from
+ any side-effects. This is because there is no guarantee as to how many times the authenticator
method will be called by the security API, and as such it may be invoked multiple times during
a single request. Because of this, any special code that should execute upon a successful or
failed authentication should be written by implementing an event observer. See the section on
Security Events further down in this chapter for more information about which events are
raised by Seam Security.
</para>
-
+
<para>
To give an example, let's say that upon a successful login that some user statistics must be
- updated. We would do this by writing an event observer for the
+ updated. We would do this by writing an event observer for the
<literal>org.jboss.seam.security.loginSuccessful</literal> event, like this:
</para>
-
+
<programlisting><![CDATA[ @In UserStats userStats;
-
+
@Observer("org.jboss.seam.security.loginSuccessful")
public void updateUserStats()
{
userStats.setLastLoginDate(new Date());
- userStats.incrementLoginCount();
- }]]></programlisting>
+ userStats.incrementLoginCount();
+ }]]></programlisting>
</sect3>
</sect2>
@@ -265,8 +265,8 @@
<para>
The <literal>Identity</literal> component provides both <literal>username</literal> and <literal>password</literal>
properties, catering for the most common authentication scenario. These properties can be bound directly to the
- username and password fields on a login form. Once these properties are set, calling the
- <literal>identity.login()</literal> method will authenticate the user using the provided credentials.
+ username and password fields on a login form. Once these properties are set, calling the
+ <literal>identity.login()</literal> method will authenticate the user using the provided credentials.
Here's an example of a simple login form:
</para>
@@ -283,12 +283,12 @@
<div>
<h:commandButton value="Login" action="#{identity.login}"/>
</div>]]></programlisting>
-
+
<para>
Similarly, logging out the user is done by calling <literal>#{identity.logout}</literal>. Calling this
action will clear the security state of the currently authenticated user.
</para>
-
+
</sect2>
<sect2>
@@ -316,123 +316,123 @@
</itemizedlist>
</sect2>
-
+
<sect2>
<title>Handling Security Exceptions</title>
-
+
<para>
- To prevent users from receiving the default error page in response to a security error, it's recommended that
+ To prevent users from receiving the default error page in response to a security error, it's recommended that
<literal>pages.xml</literal> is configured to redirect security errors to a more "pretty" page. The two
main types of exceptions thrown by the security API are:
</para>
-
+
<itemizedlist>
<listitem>
<para>
- <literal>NotLoggedInException</literal> - This exception is thrown if the user attempts to access a
+ <literal>NotLoggedInException</literal> - This exception is thrown if the user attempts to access a
restricted action or page when they are not logged in.
</para>
- </listitem>
+ </listitem>
<listitem>
<para>
<literal>AuthorizationException</literal> - This exception is only thrown if the user is already logged in,
and they have attempted to access a restricted action or page for which they do not have the necessary
privileges.
</para>
- </listitem>
+ </listitem>
</itemizedlist>
-
+
<para>
In the case of a <literal>NotLoggedInException</literal>, it is recommended that the user is redirected to
either a login or registration page so that they can log in. For an <literal>AuthorizationException</literal>,
- it may be useful to redirect the user to an error page. Here's an example of a <literal>pages.xml</literal>
- file that redirects both of these security exceptions:
+ it may be useful to redirect the user to an error page. Here's an example of a <literal>pages.xml</literal>
+ file that redirects both of these security exceptions:
</para>
-
+
<programlisting><![CDATA[<pages>
...
-
+
<exception class="org.jboss.seam.security.NotLoggedInException">
<redirect view-id="/login.xhtml">
<message>You must be logged in to perform this action</message>
</redirect>
</exception>
-
+
<exception class="org.jboss.seam.security.AuthorizationException">
<end-conversation/>
<redirect view-id="/security_error.xhtml">
<message>You do not have the necessary security privileges to perform this action.</message>
</redirect>
</exception>
-
+
</pages>]]></programlisting>
-
+
<para>
Most web applications require even more sophisticated handling of login redirection, so
Seam includes some special functionality for handling this problem.
</para>
-
+
</sect2>
-
+
<sect2>
<title>Login Redirection</title>
-
+
<para>
- You can ask Seam to redirect the user to a login screen when an unauthenticated user tries
+ You can ask Seam to redirect the user to a login screen when an unauthenticated user tries
to access a particular view (or wildcarded view id) as follows:
</para>
-
+
<programlisting><![CDATA[<pages login-view-id="/login.xhtml">
<page view-id="/members/*" login-required="true"/>
-
+
...
-
+
</pages>]]></programlisting>
<para>
- (This is less of a blunt instrument than the exception handler shown above, but should
+ (This is less of a blunt instrument than the exception handler shown above, but should
probably be used in conjunction with it.)
</para>
-
+
<para>
After the user logs in, we want to automatically send them back where they came from, so
- they can retry the action that required logging in. If you add the following event listeners
- to <literal>components.xml</literal>, attempts to access a restricted view while not logged
- in will be remembered, so that upon the user successfully logging in they will be redirected
+ they can retry the action that required logging in. If you add the following event listeners
+ to <literal>components.xml</literal>, attempts to access a restricted view while not logged
+ in will be remembered, so that upon the user successfully logging in they will be redirected
to the originally requested view, with any page parameters that existed in the original
request.
</para>
-
+
<programlisting><![CDATA[<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}"/>
</event>
-
+
<event type="org.jboss.seam.security.postAuthenticate">
<action execute="#{redirect.returnToCapturedView}"/>
</event>]]></programlisting>
-
+
<para>
- Note that login redirection is implemented as a conversation-scoped mechanism, so don't end
+ Note that login redirection is implemented as a conversation-scoped mechanism, so don't end
the conversation in your <literal>authenticate()</literal> method.
</para>
-
+
</sect2>
-
+
<sect2>
<title>HTTP Authentication</title>
-
+
<para>
- Although not recommended for use unless absolutely necessary, Seam provides means for authenticating
- using either HTTP Basic or HTTP Digest (RFC 2617) methods. To use either form of authentication,
+ Although not recommended for use unless absolutely necessary, Seam provides means for authenticating
+ using either HTTP Basic or HTTP Digest (RFC 2617) methods. To use either form of authentication,
the <literal>authentication-filter</literal> component must be enabled in components.xml:
</para>
-
+
<programlisting><![CDATA[
<web:authentication-filter url-pattern="*.seam" auth-type="basic"/>
]]></programlisting>
-
+
<para>
To enable the filter for basic authentication, set <literal>auth-type</literal> to <literal>basic</literal>,
or for digest authentication, set it to <literal>digest</literal>. If using digest authentication, the
@@ -442,55 +442,55 @@
<programlisting><![CDATA[
<web:authentication-filter url-pattern="*.seam" auth-type="digest" key="AA3JK34aSDlkj" realm="My App"/>
]]></programlisting>
-
+
<para>
- The <literal>key</literal> can be any String value. The <literal>realm</literal> is the name of the
+ The <literal>key</literal> can be any String value. The <literal>realm</literal> is the name of the
authentication realm that is presented to the user when they authenticate.
</para>
-
+
<sect3>
<title>Writing a Digest Authenticator</title>
-
+
<para>
If using digest authentication, your authenticator class should extend the abstract class
<literal>org.jboss.seam.security.digest.DigestAuthenticator</literal>, and use the
<literal>validatePassword()</literal> method to validate the user's plain text password
against the digest request. Here is an example:
</para>
-
+
<programlisting><![CDATA[
- public boolean authenticate()
+ public boolean authenticate()
{
try
- {
+ {
User user = (User) entityManager.createQuery(
"from User where username = :username")
.setParameter("username", identity.getUsername())
.getSingleResult();
-
+
return validatePassword(user.getPassword());
}
catch (NoResultException ex)
{
return false;
- }
- }
+ }
+ }
]]></programlisting>
</sect3>
-
+
</sect2>
-
+
<sect2>
<title>Advanced Authentication Features</title>
-
+
<para>
This section explores some of the advanced features provided by the security API for addressing more complex
security requirements.
</para>
-
+
<sect3>
<title>Using your container's JAAS configuration</title>
-
+
<para>
If you would rather not use the simplified JAAS configuration provided by the Seam Security API, you may
instead delegate to the default system JAAS configuration by providing a <literal>jaasConfigName</literal>
@@ -498,33 +498,33 @@
the <literal>other</literal> policy (which uses the <literal>UsersRolesLoginModule</literal> login module
provided by JBoss AS), then the entry in <literal>components.xml</literal> would look like this:
</para>
-
- <programlisting><![CDATA[<security:identity authenticate-method="#{authenticator.authenticate}"
+
+ <programlisting><![CDATA[<security:identity authenticate-method="#{authenticator.authenticate}"
jaas-config-name="other"/>]]></programlisting>
-
+
</sect3>
-
+
</sect2>
</sect1>
-
+
<sect1>
<title>Error Messages</title>
-
+
<para>
- The security API produces a number of default faces messages for various security-related events.
- The following table lists the message keys that can be used to override these messages by specifying
+ The security API produces a number of default faces messages for various security-related events.
+ The following table lists the message keys that can be used to override these messages by specifying
them in a <literal>message.properties</literal> resource file. To suppress the message, just put the
key with an empty value in the resource file.
</para>
-
+
<table>
<title>Security Message Keys</title>
-
+
<tgroup cols="2">
<colspec colnum="1" colwidth="1*" />
<colspec colnum="2" colwidth="3*" />
-
+
<thead>
<row>
<entry align="center">
@@ -534,16 +534,16 @@
<para>Description</para>
</entry>
</row>
- </thead>
-
+ </thead>
+
<tbody>
-
+
<row>
<entry>
<para>
<literal>org.jboss.seam.loginSuccessful</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
This message is produced when a user successfully logs in via the security API.
@@ -555,7 +555,7 @@
<para>
<literal>org.jboss.seam.loginFailed</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
This message is produced when the login process fails, either because the user provided an
@@ -568,14 +568,14 @@
<para>
<literal>org.jboss.seam.NotLoggedIn</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
This message is produced when a user attempts to perform an action or access a page that requires
a security check, and the user is not currently authenticated.
</para>
</entry>
- </row>
+ </row>
</tbody>
</tgroup>
</table>
@@ -586,15 +586,15 @@
<para>
There are a number of authorization features provided by the Seam Security API for securing access to
- components, component methods, and pages. This section describes each of these. An important thing to
- note is that if you wish to use any of the advanced features (such as rule-based permissions) then
+ components, component methods, and pages. This section describes each of these. An important thing to
+ note is that if you wish to use any of the advanced features (such as rule-based permissions) then
your <literal>components.xml</literal> must be configured to support this - see the Configuration section
above.
</para>
<sect2>
<title>Core concepts</title>
-
+
<para>
Each of the authorization mechanisms provided by the Seam Security API are built upon the concept of a user
being granted roles and/or permissions. A role is a <emphasis>group</emphasis>, or <emphasis>type</emphasis>,
@@ -614,7 +614,7 @@
<sect2>
<title>Securing components</title>
-
+
<para>
Let's start by examining the simplest form of authorization, component security, starting with the
<literal>@Restrict</literal> annotation.
@@ -632,7 +632,7 @@
on just the component class itself is equivalent to adding <literal>@Restrict</literal> to each of its
methods.
</para>
-
+
<para>
An empty <literal>@Restrict</literal> implies a permission check of <literal>componentName:methodName</literal>.
Take for example the following component method:
@@ -657,7 +657,7 @@
public void insert() {
...
}
- @Restrict("#{s:hasRole('admin')}")
+ @Restrict("#{s:hasRole('admin')}")
public void delete() {
...
}
@@ -717,79 +717,79 @@
<para>
If the expression specified doesn't evaluate to <literal>true</literal>, either
</para>
-
+
<itemizedlist>
<listitem>
<para>
- if the user is not logged in, a <literal>NotLoggedInException</literal>
+ if the user is not logged in, a <literal>NotLoggedInException</literal>
exception is thrown or
</para>
</listitem>
<listitem>
<para>
- if the user is logged in, an <literal>AuthorizationException</literal>
+ if the user is logged in, an <literal>AuthorizationException</literal>
exception is thrown.
</para>
</listitem>
</itemizedlist>
-
+
<para>
- It is also possible to call the <literal>hasRole()</literal> and <literal>hasPermission()</literal>
+ It is also possible to call the <literal>hasRole()</literal> and <literal>hasPermission()</literal>
methods directly from Java code:
- </para>
+ </para>
<programlisting><![CDATA[if (!Identity.instance().hasRole("admin"))
throw new AuthorizationException("Must be admin to perform this action");
if (!Identity.instance().hasPermission("customer", "create", null))
throw new AuthorizationException("You may not create new customers");]]></programlisting>
-
+
</sect3>
</sect2>
-
+
<sect2>
<title>Security in the user interface</title>
-
+
<para>
- One indication of a well designed user interface is that the user is not presented with options for
- which they don't have the necessary privileges to use. Seam Security allows conditional rendering of
+ One indication of a well designed user interface is that the user is not presented with options for
+ which they don't have the necessary privileges to use. Seam Security allows conditional rendering of
either 1) sections of a page or 2) individual controls, based upon the privileges of the user, using
the very same EL expressions that are used for component security.
</para>
-
+
<para>
- Let's take a look at some examples of interface security. First of all, let's pretend that we have a
- login form that should only be rendered if the user is not already logged in. Using the
+ Let's take a look at some examples of interface security. First of all, let's pretend that we have a
+ login form that should only be rendered if the user is not already logged in. Using the
<literal>identity.isLoggedIn()</literal> property, we can write this:
</para>
-
+
<programlisting><![CDATA[<h:form class="loginForm" rendered="#{not identity.loggedIn}">]]></programlisting>
-
+
<para>
- If the user isn't logged in, then the login form will be rendered - very straight forward so far.
+ If the user isn't logged in, then the login form will be rendered - very straight forward so far.
Now let's pretend there is a menu on the page that contains some actions which should only be accessible
to users in the <literal>manager</literal> role. Here's one way that these could be written:
</para>
-
+
<programlisting><![CDATA[<h:outputLink action="#{reports.listManagerReports}" rendered="#{s:hasRole('manager')}">
Manager Reports
</h:outputLink>]]></programlisting>
-
+
<para>
This is also quite straight forward. If the user is not a member of the <literal>manager</literal>
role, then the outputLink will not be rendered. The <literal>rendered</literal> attribute can
- generally be used on the control itself, or on a surrounding <literal><s:div></literal> or
+ generally be used on the control itself, or on a surrounding <literal><s:div></literal> or
<literal><s:span></literal> control.
</para>
-
+
<para>
- Now for something more complex. Let's say you have a <literal>h:dataTable</literal> control on a
+ Now for something more complex. Let's say you have a <literal>h:dataTable</literal> control on a
page listing records for which you may or may not wish to render action links depending on the
user's privileges. The <literal>s:hasPermission</literal> EL function allows us to pass in an
- object parameter which can be used to determine whether the user has the requested permission
+ object parameter which can be used to determine whether the user has the requested permission
for that object or not. Here's how a dataTable with secured links might look:
</para>
-
+
<programlisting><![CDATA[<h:dataTable value="#{clients}" var="cl">
<h:column>
<f:facet name="header">Name</f:facet>
@@ -798,7 +798,7 @@
<h:column>
<f:facet name="header">City</f:facet>
#{cl.city}
- </h:column>
+ </h:column>
<h:column>
<f:facet name="header">Action</f:facet>
<s:link value="Modify Client" action="#{clientAction.modify}"
@@ -809,53 +809,53 @@
</h:dataTable>]]></programlisting>
</sect2>
-
+
<sect2>
- <title>Securing pages</title>
+ <title>Securing pages</title>
<para>
Page security requires that the application is using a <literal>pages.xml</literal> file, however is
extremely simple to configure. Simply include a <literal><restrict/></literal> element within
- the <literal>page</literal> elements that you wish to secure. If no explicit restriction is specified
- by the <literal>restrict</literal> element, an implied permission of <literal>/viewId.xhtml:render</literal>
- will be checked when the page is accessed via a non-faces (GET) request, and a permission of
+ the <literal>page</literal> elements that you wish to secure. If no explicit restriction is specified
+ by the <literal>restrict</literal> element, an implied permission of <literal>/viewId.xhtml:render</literal>
+ will be checked when the page is accessed via a non-faces (GET) request, and a permission of
<literal>/viewId.xhtml:restore</literal> will be required when any JSF postback (form submission) originates
- from the page. Otherwise, the specified restriction will be evaluated as a standard security expression.
+ from the page. Otherwise, the specified restriction will be evaluated as a standard security expression.
Here's a couple of examples:
</para>
-
+
<programlisting><![CDATA[<page view-id="/settings.xhtml">
<restrict/>
</page>]]></programlisting>
-
+
<para>
- This page has an implied permission of <literal>/settings.xhtml:render</literal> required for non-faces
+ This page has an implied permission of <literal>/settings.xhtml:render</literal> required for non-faces
requests and an implied permission of <literal>/settings.xhtml:restore</literal> for faces requests.
</para>
-
- <programlisting><![CDATA[<page view-id="/reports.xhtml">
+
+ <programlisting><![CDATA[<page view-id="/reports.xhtml">
<restrict>#{s:hasRole('admin')}</restrict>
</page>]]></programlisting>
-
+
<para>
- Both faces and non-faces requests to this page require that the user is a member of the
+ Both faces and non-faces requests to this page require that the user is a member of the
<literal>admin</literal> role.
</para>
-
+
</sect2>
-
+
<sect2>
<title>Securing Entities</title>
-
- <para>
- Seam security also makes it possible to apply security restrictions to read, insert, update and
+
+ <para>
+ Seam security also makes it possible to apply security restrictions to read, insert, update and
delete actions for entities.
</para>
-
+
<para>
To secure all actions for an entity class, add a <literal>@Restrict</literal> annotation on the class
itself:
</para>
-
+
<programlisting><![CDATA[@Entity
@Name("customer")
@Restrict
@@ -864,65 +864,65 @@
}]]></programlisting>
<para>
- If no expression is specified in the <literal>@Restrict</literal> annotation, the default security check
+ If no expression is specified in the <literal>@Restrict</literal> annotation, the default security check
that is performed is a permission check of <literal>entityName:action</literal>,
- where <literal>entityName</literal> is the Seam component name of the entity (or the fully-qualified class name if no @Name is
- specified), and the <literal>action</literal> is either <literal>read</literal>,
- <literal>insert</literal>, <literal>update</literal> or <literal>delete</literal>.
+ where <literal>entityName</literal> is the Seam component name of the entity (or the fully-qualified class name if no @Name is
+ specified), and the <literal>action</literal> is either <literal>read</literal>,
+ <literal>insert</literal>, <literal>update</literal> or <literal>delete</literal>.
</para>
-
+
<para>
- It is also possible to only restrict certain actions, by placing a <literal>@Restrict</literal> annotation
+ It is also possible to only restrict certain actions, by placing a <literal>@Restrict</literal> annotation
on the relevent entity lifecycle method (annotated as follows):
</para>
-
+
<itemizedlist>
<listitem>
<para>
<literal>@PostLoad</literal> - Called after an entity instance is loaded from the database. Use this
method to configure a <literal>read</literal> permission.
</para>
- </listitem>
+ </listitem>
<listitem>
<para>
<literal>@PrePersist</literal> - Called before a new instance of the entity is inserted. Use this method
to configure an <literal>insert</literal> permission.
</para>
- </listitem>
+ </listitem>
<listitem>
<para>
<literal>@PreUpdate</literal> - Called before an entity is updated. Use this method
to configure an <literal>update</literal> permission.
</para>
- </listitem>
+ </listitem>
<listitem>
<para>
<literal>@PreRemove</literal> - Called before an entity is deleted. Use this method
to configure a <literal>delete</literal> permission.
</para>
- </listitem>
- </itemizedlist>
-
+ </listitem>
+ </itemizedlist>
+
<para>
Here's an example of how an entity would be configured to perform a security check for any <literal>insert</literal>
- operations. Please note that the method is not required to do anything, the only important thing in regard to
+ operations. Please note that the method is not required to do anything, the only important thing in regard to
security is how it is annotated:
</para>
-
+
<programlisting><![CDATA[
@PrePersist @Restrict
- public void prePersist() {}
+ public void prePersist() {}
]]></programlisting>
-
+
<para>
And here's an example of an entity permission rule that checks if the authenticated user is allowed to insert
a new <literal>MemberBlog</literal> record (from the seamspace example). The entity for which the security
check is being made is automatically inserted into the working memory (in this case <literal>MemberBlog</literal>):
</para>
-
+
<programlisting><![CDATA[rule InsertMemberBlog
no-loop
- activation-group "permissions"
+ activation-group "permissions"
when
check: PermissionCheck(name == "memberBlog", action == "insert", granted == false)
Principal(principalName : name)
@@ -938,28 +938,28 @@
<literal>Principal</literal> fact (and other places) is a variable binding - it binds the <literal>name</literal>
property of the <literal>Principal</literal> to a variable called <literal>principalName</literal>. Variable bindings
allow the value to be referred to in other places, such as the following line which compares the member's username
- to the <literal>Principal</literal> name. For more details, please refer to the JBoss Rules documentation.
+ to the <literal>Principal</literal> name. For more details, please refer to the JBoss Rules documentation.
</para>
<para>
Finally, we need to install a listener class that integrates Seam security with
your JPA provider.
</para>
-
+
<sect3>
<title>Entity security with JPA</title>
-
+
<para>
Security checks for EJB3 entity beans are performed with an <literal>EntityListener</literal>.
You can install this listener by using the following <literal>META-INF/orm.xml</literal> file:
</para>
-
+
<programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
-
+
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
@@ -967,93 +967,93 @@
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
-
+
</entity-mappings>]]></programlisting>
</sect3>
-
+
<sect3>
<title>Entity security with Hibernate</title>
-
+
<para>
- If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam, you don't
+ If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam, you don't
need to do anything special to use entity security.
</para>
-
+
</sect3>
-
+
</sect2>
</sect1>
-
+
<sect1>
<title>Writing Security Rules</title>
-
+
<para>
Up to this point there has been a lot of mention of permissions, but no information about how permissions
- are actually defined or granted. This section completes the picture, by explaining how permission
+ are actually defined or granted. This section completes the picture, by explaining how permission
checks are processed, and how to implement permission checks for a Seam application.
</para>
-
+
<sect2>
<title>Permissions Overview</title>
-
+
<para>
- So how does the security API know whether a user has the <literal>customer:modify</literal> permission
+ So how does the security API know whether a user has the <literal>customer:modify</literal> permission
for a specific customer? Seam Security provides quite a novel method for determining user permissions,
- based on JBoss Rules. A couple of the advantages of using a rule engine are 1) a centralized location
- for the business logic that is behind each user permission, and 2) speed - JBoss Rules uses very efficient
+ based on JBoss Rules. A couple of the advantages of using a rule engine are 1) a centralized location
+ for the business logic that is behind each user permission, and 2) speed - JBoss Rules uses very efficient
algorithms for evaluating large numbers of complex rules involving multiple conditions.
- </para>
-
+ </para>
+
</sect2>
-
+
<sect2>
<title>Configuring a rules file</title>
-
+
<para>
Seam Security expects to find a <literal>RuleBase</literal> component called <literal>securityRules</literal>
which it uses to evaluate permission checks. This is configured in <literal>components.xml</literal> as follows:
</para>
-
+
<programlisting><![CDATA[<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:drools="http://jboss.com/products/seam/drools"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
- "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
+ "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.0.xsd"
- http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
-
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
<drools:rule-base name="securityRules">
<drools:rule-files>
<value>/META-INF/security.drl</value>
</drools:rule-files>
- </drools:rule-base>
-
+ </drools:rule-base>
+
</components>]]></programlisting>
-
+
<para>
Once the <literal>RuleBase</literal> component is configured, it's time to write the security rules.
</para>
</sect2>
-
+
<sect2>
<title>Creating a security rules file</title>
<para>
- For this step you need to create a file called <literal>security.drl</literal> in the
+ For this step you need to create a file called <literal>security.drl</literal> in the
<literal>/META-INF</literal> directory of your application's jar file. In actual fact this file can be called
anything you want, and exist in any location as long as it is configured appropriately in
<literal>components.xml</literal>.
</para>
-
+
<para>
- So what should the security rules file contain? At this stage it might be a good idea to at least skim
+ So what should the security rules file contain? At this stage it might be a good idea to at least skim
through the JBoss Rules documentation, however to get started here's an extremely simple example:
</para>
-
+
<programlisting><![CDATA[package MyApplicationPermissions;
import org.jboss.seam.security.PermissionCheck;
@@ -1066,278 +1066,278 @@
then
c.grant();
end;]]></programlisting>
-
+
<para>
Let's break this down. The first thing we see is the package declaration. A package in JBoss Rules
is essentially a collection of rules. The package name can be anything you want - it doesn't relate
to anything else outside the scope of the rule base.
</para>
-
+
<para>
The next thing we can notice is a couple of import statements for the <literal>PermissionCheck</literal>
- and <literal>Role</literal> classes. These imports inform the rules engine that we'll be referencing
+ and <literal>Role</literal> classes. These imports inform the rules engine that we'll be referencing
these classes within our rules.
</para>
-
+
<para>
- Finally we have the code for the rule. Each rule within a package should be given a unique name (usually
- describing the purpose of the rule). In this case our rule is called <literal>CanUserDeleteCustomers</literal>
+ Finally we have the code for the rule. Each rule within a package should be given a unique name (usually
+ describing the purpose of the rule). In this case our rule is called <literal>CanUserDeleteCustomers</literal>
and will be used to check whether a user is allowed to delete a customer record.
</para>
-
+
<para>
Looking at the body of the rule definition we can notice two distinct sections. Rules have what is known
- as a left hand side (LHS) and a right hand side (RHS). The LHS consists of the conditional part of the
- rule, i.e. a list of conditions which must be satisfied for the rule to fire. The LHS is represented by
+ as a left hand side (LHS) and a right hand side (RHS). The LHS consists of the conditional part of the
+ rule, i.e. a list of conditions which must be satisfied for the rule to fire. The LHS is represented by
the <literal>when</literal> section. The RHS is the consequence, or action section of the rule that will
only be fired if all of the conditions in the LHS are met. The RHS is represented by the
<literal>then</literal> section. The end of the rule is denoted by the <literal>end;</literal> line.
</para>
-
+
<para>
If we look at the LHS of the rule, we see two conditions listed there. Let's examine the first condition:
</para>
-
+
<programlisting><![CDATA[c: PermissionCheck(name == "customer", action == "delete")]]></programlisting>
-
+
<para>
- In plain english, this condition is stating that there must exist a <literal>PermissionCheck</literal> object
+ In plain english, this condition is stating that there must exist a <literal>PermissionCheck</literal> object
with a <literal>name</literal> property equal to "customer", and an <literal>action</literal> property equal
- to "delete" within the working memory. What is the working memory? It is a session-scoped object that contains
+ to "delete" within the working memory. What is the working memory? It is a session-scoped object that contains
the contextual information that is required by the rules engine to make a decision about a permission check.
Each time the <literal>hasPermission()</literal> method is called, a temporary <literal>PermissionCheck</literal>
object, or <emphasis>Fact</emphasis>, is inserted into the working memory. This <literal>PermissionCheck</literal>
- corresponds exactly to the permission that is being checked, so for example if you call
+ corresponds exactly to the permission that is being checked, so for example if you call
<literal>hasPermission("account", "create", null)</literal> then a <literal>PermissionCheck</literal>
object with a <literal>name</literal> equal to "account" and <literal>action</literal> equal to "create" will be
inserted into the working memory for the duration of the permission check.
</para>
-
+
<para>
So what else is in the working memory? Besides the short-lived temporary facts inserted during a permission
check, there are some longer-lived objects in the working memory that stay there for the entire duration of
a user being authenticated. These include any <literal>java.security.Principal</literal> objects that
are created as part of the authentication process, plus a <literal>org.jboss.seam.security.Role</literal>
- object for each of the roles that the user is a member of. It is also possible to insert additional
+ object for each of the roles that the user is a member of. It is also possible to insert additional
long-lived facts into the working memory by calling <literal>((RuleBasedIdentity) RuleBasedIdentity.instance()).getSecurityContext().insert()</literal>,
passing the object as a parameter.
</para>
-
+
<para>
Getting back to our simple example, we can also notice that the first line of our LHS is prefixed with
<literal>c:</literal>. This is a variable binding, and is used to refer back to the object that is
matched by the condition. Moving onto the second line of our LHS, we see this:
</para>
-
+
<programlisting><![CDATA[Role(name == "admin")]]></programlisting>
-
+
<para>
This condition simply states that there must be a <literal>Role</literal> object with
- a <literal>name</literal> of "admin" within the working memory. As mentioned, user roles are inserted
- into the working memory as long-lived facts. So, putting both conditions together, this rule is essentially
+ a <literal>name</literal> of "admin" within the working memory. As mentioned, user roles are inserted
+ into the working memory as long-lived facts. So, putting both conditions together, this rule is essentially
saying "I will fire if you are checking for the <literal>customer:delete</literal> permission and the user
is a member of the <literal>admin</literal> role".
</para>
-
+
<para>
So what is the consequence of the rule firing? Let's take a look at the RHS of the rule:
</para>
-
+
<programlisting><![CDATA[c.grant()]]></programlisting>
-
+
<para>
- The RHS consists of Java code, and in this case is invoking the <literal>grant()</literal>
- method of the <literal>c</literal> object, which as already mentioned is a variable binding
+ The RHS consists of Java code, and in this case is invoking the <literal>grant()</literal>
+ method of the <literal>c</literal> object, which as already mentioned is a variable binding
for the <literal>PermissionCheck</literal> object. Besides the <literal>name</literal> and
<literal>action</literal> properties of the <literal>PermissionCheck</literal> object, there
is also a <literal>granted</literal> property which is initially set to <literal>false</literal>.
- Calling <literal>grant()</literal> on a <literal>PermissionCheck</literal> sets the
+ Calling <literal>grant()</literal> on a <literal>PermissionCheck</literal> sets the
<literal>granted</literal> property to <literal>true</literal>, which means that the permission
check was successful, allowing the user to carry out whatever action the permission check was
intended for.
</para>
-
+
<sect3>
<title>Wildcard permission checks</title>
-
+
<para>
- It is possible to implement a wildcard permission check (which allows all actions for a given permission
+ It is possible to implement a wildcard permission check (which allows all actions for a given permission
name), by omitting the <literal>action</literal> constraint for the <literal>PermissionCheck</literal> in
your rule, like this:
</para>
-
+
<programlisting><![CDATA[rule CanDoAnythingToCustomersIfYouAreAnAdmin
when
c: PermissionCheck(name == "customer")
Role(name == "admin")
then
c.grant();
-end;
+end;
]]></programlisting>
-
+
<para>
This rule allows users with the <literal>admin</literal> role to perform <emphasis>any</emphasis> action for
any <literal>customer</literal> permission check.
</para>
</sect3>
-
+
</sect2>
-
+
</sect1>
-
+
<sect1>
<title>SSL Security</title>
-
+
<para>
Seam includes basic support for serving sensitive pages via the HTTPS protocol. This is easily
configured by specifying a <literal>scheme</literal> for the page in <literal>pages.xml</literal>.
The following example shows how the view <literal>/login.xhtml</literal> is configured to use
HTTPS:
</para>
-
+
<programlisting><![CDATA[<page view-id="/login.xhtml" scheme="https"/>]]></programlisting>
-
+
<para>
- This configuration is automatically extended to both <literal>s:link</literal> and
+ This configuration is automatically extended to both <literal>s:link</literal> and
<literal>s:button</literal> JSF controls, which (when specifying the <literal>view</literal>)
- will also render the link using the correct protocol. Based on the previous example, the following
+ will also render the link using the correct protocol. Based on the previous example, the following
link will use the HTTPS protocol because <literal>/login.xhtml</literal> is configured to use it:
</para>
-
+
<programlisting><![CDATA[<s:link view="/login.xhtml" value="Login"/>]]></programlisting>
-
+
<para>
- Browsing directly to a view when using the <emphasis>incorrect</emphasis> protocol will cause a
+ Browsing directly to a view when using the <emphasis>incorrect</emphasis> protocol will cause a
redirect to the same view using the <emphasis>correct</emphasis> protocol. For example, browsing
to a page that has <literal>scheme="https"</literal> using HTTP will cause a redirect to the same
page using HTTPS.
</para>
-
+
<para>
It is also possible to configure a <emphasis>default scheme</emphasis> for all pages. This is useful
- if you wish to use HTTPS for a only few pages. If no default scheme is specified then the normal
- behavior is to continue use the current scheme. So once the user accessed a page that required
+ if you wish to use HTTPS for a only few pages. If no default scheme is specified then the normal
+ behavior is to continue use the current scheme. So once the user accessed a page that required
HTTPS, then HTTPS would continue to be used after the user navigated away to other non-HTTPS pages.
- (While this is good for security, it is not so great for performance!). To define HTTP as the
+ (While this is good for security, it is not so great for performance!). To define HTTP as the
default <literal>scheme</literal>, add this line to <literal>pages.xml</literal>:
</para>
-
+
<programlisting><![CDATA[<page view-id="*" scheme="http" />]]></programlisting>
-
+
<para>
- Of course, if <emphasis>none</emphasis> of the pages in your application use HTTPS then it is not
+ Of course, if <emphasis>none</emphasis> of the pages in your application use HTTPS then it is not
required to specify a default scheme.
</para>
-
+
<para>
You may configure Seam to automatically invalidate the current HTTP session each time the scheme
changes. Just add this line to <literal>components.xml</literal>:
</para>
-
+
<programlisting><![CDATA[<core:servlet-session invalidate-on-scheme-change="true"/>]]></programlisting>
-
+
<para>
- This option helps make your system less vulnerable to sniffing of the session id or leakage of
+ This option helps make your system less vulnerable to sniffing of the session id or leakage of
sensitive data from pages using HTTPS to other pages using HTTP.
</para>
-
+
</sect1>
-
+
<sect1>
<title>CAPTCHA</title>
-
+
<para>
- Though strictly not part of the security API, Seam provides a built-in CAPTCHA (<emphasis>C</emphasis>ompletely
- <emphasis>A</emphasis>utomated <emphasis>P</emphasis>ublic <emphasis>T</emphasis>uring test to tell
- <emphasis>C</emphasis>omputers and <emphasis>H</emphasis>umans <emphasis>A</emphasis>part) algorithm to
+ Though strictly not part of the security API, Seam provides a built-in CAPTCHA (<emphasis>C</emphasis>ompletely
+ <emphasis>A</emphasis>utomated <emphasis>P</emphasis>ublic <emphasis>T</emphasis>uring test to tell
+ <emphasis>C</emphasis>omputers and <emphasis>H</emphasis>umans <emphasis>A</emphasis>part) algorithm to
prevent automated processes from interacting with your application.
</para>
-
+
<sect2>
<title>Configuring the CAPTCHA Servlet</title>
<para>
- To get up and running, it is necessary to configure the Seam Resource Servlet, which will provide the Captcha
+ To get up and running, it is necessary to configure the Seam Resource Servlet, which will provide the Captcha
challenge images to your pages. This requires the following entry in <literal>web.xml</literal>:
</para>
-
+
<programlisting><![CDATA[<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
-
+
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>]]></programlisting>
-
+
</sect2>
-
+
<sect2>
<title>Adding a CAPTCHA to a form</title>
-
+
<para>
Adding a CAPTCHA challenge to a form is extremely easy. Here's an example:
</para>
-
+
<programlisting><![CDATA[<h:graphicImage value="/seam/resource/captcha"/>
<h:inputText id="verifyCaptcha" value="#{captcha.response}" required="true">
<s:validate />
</h:inputText>
<h:message for="verifyCaptcha"/>]]></programlisting>
-
+
<para>
That's all there is to it. The <literal>graphicImage</literal> control displays the CAPTCHA challenge,
- and the <literal>inputText</literal> receives the user's response. The response is automatically
+ and the <literal>inputText</literal> receives the user's response. The response is automatically
validated against the CAPTCHA when the form is submitted.
</para>
-
+
</sect2>
-
+
<sect2>
<title>Customising the CAPTCHA algorithm</title>
-
+
<para>
You may customize the CAPTCHA algorithm by overriding the built-in component:
</para>
-
+
<programlisting><![CDATA[@Name("org.jboss.seam.captcha")
@Scope(SESSION)
public class HitchhikersCaptcha extends Captcha
{
@Override @Create
- public void init()
+ public void init()
{
setChallenge("What is the answer to life, the universe and everything?");
setCorrectResponse("42");
}
-
+
@Override
public BufferedImage renderChallenge()
{
- BufferedImage img = super.renderChallenge();
+ BufferedImage img = super.renderChallenge();
img.getGraphics().drawOval(5, 3, 60, 14); //add an obscuring decoration
return img;
}
}]]></programlisting>
</sect2>
-
+
</sect1>
-
+
<sect1>
<title>Security Events</title>
-
+
<para>
The following table describes a number of events (see <xref linkend="events"/>) raised by Seam Security.
</para>
-
+
<table>
<title>Security Events</title>
-
+
<tgroup cols="2">
<colspec colnum="1" colwidth="1*" />
<colspec colnum="2" colwidth="3*" />
-
+
<thead>
<row>
<entry align="center">
@@ -1347,16 +1347,16 @@
<para>Description</para>
</entry>
</row>
- </thead>
-
+ </thead>
+
<tbody>
-
+
<row>
<entry>
<para>
<literal>org.jboss.seam.security.loginSuccessful</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when a login attempt is successful.
@@ -1368,7 +1368,7 @@
<para>
<literal>org.jboss.seam.security.loginFailed</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when a login attempt fails.
@@ -1380,109 +1380,109 @@
<para>
<literal>org.jboss.seam.security.notLoggedIn</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when a security check fails when the user is not logged in.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.notAuthorized</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when a security check fails when the user is logged in however doesn't have sufficient privileges.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.preAuthenticate</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised just prior to user authentication.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.postAuthenticate</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised just after user authentication.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.loggedOut</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised after the user has logged out.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.credentialsUpdated</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when the user's credentials have been changed.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>org.jboss.seam.security.rememberMe</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Raised when the Identity's rememberMe property is changed.
</para>
</entry>
- </row>
-
+ </row>
+
</tbody>
</tgroup>
- </table>
-
+ </table>
+
</sect1>
-
+
<sect1>
<title>Extending the Identity component</title>
-
+
<para>
Sometimes it might be necessary to extend the Identity component if your application has
special security requirements. For example, users might be required to authenticate using
a Company or Department ID, along with their usual username and password. If permission-based
security is required then RuleBasedIdentity should be extended, otherwise Identity should be
extended.
- </para>
-
+ </para>
+
<para>
- The following example shows an extended Identity component with an additional
+ The following example shows an extended Identity component with an additional
<literal>companyCode</literal> field. The install precendence of <literal>APPLICATION</literal>
ensures that this extended Identity gets installed in preference to the built-in Identity.
</para>
-
+
<programlisting><![CDATA[@Name("org.jboss.seam.security.identity")
@Scope(SESSION)
@Install(precedence = APPLICATION)
@@ -1493,34 +1493,34 @@
private static final LogProvider log = Logging.getLogProvider(CustomIdentity.class);
private String companyCode;
-
+
public String getCompanyCode()
{
return companyCode;
}
-
+
public void setCompanyCode(String companyCode)
{
this.companyCode = companyCode;
}
-
+
@Override
public String login()
{
log.info("###### CUSTOM LOGIN CALLED ######");
return super.login();
}
-}]]></programlisting>
+}]]></programlisting>
</sect1>
-
+
<sect1>
<title>Identity Management</title>
-
+
<para>
Seam Security provides an optional identity management API, which offers the following features:
</para>
-
+
<itemizedlist>
<listitem>
<para>
@@ -1536,7 +1536,7 @@
<para>
A hierarchical role/group membership structure, allowing roles to be members of other roles.
</para>
- </listitem>
+ </listitem>
<listitem>
<para>
Pluggable identity store, allowing the developer to choose their security provider, whether it be
@@ -1544,14 +1544,14 @@
</para>
</listitem>
</itemizedlist>
-
+
<para>
The core of the identity management API is the <literal>IdentityManager</literal> component. Before it can be
- used however, it must be configured with an <literal>IdentityStore</literal> implementation. The
- <literal>IdentityStore</literal> does the actual work of interacting with the underlying security provider,
+ used however, it must be configured with an <literal>IdentityStore</literal> implementation. The
+ <literal>IdentityStore</literal> does the actual work of interacting with the underlying security provider,
whatever it may be.
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-identitymanager.png" align="center"/>
@@ -1559,35 +1559,35 @@
<imageobject role="html">
<imagedata fileref="../shared/images/security-identitymanager.png" align="center"/>
</imageobject>
- </mediaobject>
-
+ </mediaobject>
+
<sect2>
<title>Configuration</title>
-
+
<para>
- Configuration of the <literal>IdentityManager</literal> is extremely simple, requiring only an
+ Configuration of the <literal>IdentityManager</literal> is extremely simple, requiring only an
<literal>IdentityStore</literal> to be configured in <literal>components.xml</literal>.
The identity management namespace is <literal>http://jboss.com/products/seam/security/management</literal>
and its schema location is <literal>http://jboss.com/products/seam/identity-management-2.0.xsd</literal>.
Here's a simple example showing the configuration of a <literal>JPAIdentityStore</literal> - for the
<literal>IdentityManager</literal> to use it, it must be named <literal>identityStore</literal>:
</para>
-
+
<programlisting><![CDATA[
- <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>
+ <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>
]]></programlisting>
</sect2>
-
+
<sect2>
<title>JPAIdentityStore</title>
-
+
<para>
<literal>JPAIdentityStore</literal> is an <literal>IdentityStore</literal> implementation that uses
JPA as its underlying security provider. User accounts and their role memberships are stored in a
- self-referencing database table, for which the corresponding entity bean must extend
+ self-referencing database table, for which the corresponding entity bean must extend
<literal>org.jboss.seam.security.management.UserAccount</literal> to provide the following properties:
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-useraccount.png" align="center"/>
@@ -1596,11 +1596,11 @@
<imagedata fileref="../shared/images/security-useraccount.png" align="center"/>
</imageobject>
</mediaobject>
-
+
<para>
To provide a complete example, here's what the actual database tables may look like:
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-useraccountschema.png" align="center"/>
@@ -1608,42 +1608,42 @@
<imageobject role="html">
<imagedata fileref="../shared/images/security-useraccountschema.png" align="center"/>
</imageobject>
- </mediaobject>
-
+ </mediaobject>
+
<para>
And an example of the corresponding entity bean:
</para>
-
+
<programlisting><![CDATA[@Entity @Table(name = "USER_ACCOUNT")
-public class UserAccount extends org.jboss.seam.security.management.UserAccount
+public class UserAccount extends org.jboss.seam.security.management.UserAccount
implements Serializable
{
private Integer accountId;
private String username;
private String passwordHash;
- private boolean enabled;
+ private boolean enabled;
private AccountType accountType;
private Set<UserAccount> memberships;
-
- @Id @GeneratedValue public Integer getAccountId() { return accountId; }
+
+ @Id @GeneratedValue public Integer getAccountId() { return accountId; }
public void setAccountId(Integer accountId) { this.accountId = accountId; }
-
- @NotNull @Override public String getUsername() { return username; }
+
+ @NotNull @Override public String getUsername() { return username; }
@Override public void setUsername(String username) { this.username = username; }
-
- @Override public String getPasswordHash() { return passwordHash; }
- @Override public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
-
- @Override public AccountType getAccountType() { return accountType; }
+
+ @Override public String getPasswordHash() { return passwordHash; }
+ @Override public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
+
+ @Override public AccountType getAccountType() { return accountType; }
@Override public void setAccountType(AccountType accountType) { this.accountType = accountType; }
-
+
@Override public boolean isEnabled() { return enabled; }
- @Override public void setEnabled(boolean enabled) { this.enabled = enabled; }
+ @Override public void setEnabled(boolean enabled) { this.enabled = enabled; }
- @ManyToMany(targetEntity = MemberAccount.class) @JoinTable(name = "ACCOUNT_MEMBERSHIP",
+ @ManyToMany(targetEntity = MemberAccount.class) @JoinTable(name = "ACCOUNT_MEMBERSHIP",
joinColumns = @JoinColumn(name = "ACCOUNT_ID"),
inverseJoinColumns = @JoinColumn(name = "MEMBER_OF"))
- @Override public Set<UserAccount> getMemberships() { return memberships; }
+ @Override public Set<UserAccount> getMemberships() { return memberships; }
@Override public void setMemberships(Set<UserAccount> memberships) { this.memberships = memberships; }}]]></programlisting>
<para>
@@ -1654,64 +1654,64 @@
discriminator between the two. With this model, roles can be members of other roles, making it
possible to define complex role membership hierarchies.
</para>
-
+
<para>
Once the <literal>UserAccount</literal> implementation has been created, the <literal>JPAIdentityStore</literal>
- must be configured to use that implementation any time it performs an identity management operation.
+ must be configured to use that implementation any time it performs an identity management operation.
This is done by specifying the <literal>account-class</literal> property in <literal>components.xml</literal>.
In the following example, it is configured as <literal>com.acme.UserAccount</literal>:
</para>
-
+
<programlisting><![CDATA[
- <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>]]></programlisting>
-
+ <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>]]></programlisting>
+
<para>
Please note that this is a required parameter, and must always be specified when using the
<literal>JPAIdentityStore</literal>.
</para>
-
+
</sect2>
-
+
<sect2>
<title>Authentication with the Identity Management API</title>
-
+
<para>
To authenticate using the Identity Management API, it is as simple as not specifying the
<literal>authenticate-method</literal> property for the <literal>Identity</literal> component.
If no <literal>authenticate-method</literal> is specified, then by default the authentication
process (controlled by <literal>SeamLoginModule</literal>) will attempt to authenticate using
<literal>IdentityManager</literal>'s <literal>authenticate()</literal> method, and no
- Authenticator component is necessary.
+ Authenticator component is necessary.
</para>
</sect2>
-
+
<sect2>
<title>Using the IdentityManager API</title>
-
+
<para>
The <literal>IdentityManager</literal> can be accessed either by injecting it into your Seam
component as follows:
</para>
-
- <programlisting><![CDATA[ @In IdentityManager identityManager;]]></programlisting>
-
+
+ <programlisting><![CDATA[ @In IdentityManager identityManager;]]></programlisting>
+
<para>
or by accessing it through its static <literal>instance()</literal> method:
</para>
<programlisting><![CDATA[ IdentityManager identityManager = IdentityManager.instance();]]></programlisting>
-
+
<para>
- The following table describes each of the methods that the <literal>IdentityManager</literal> provides:
+ The following table describes each of the methods that <literal>IdentityManager</literal> provides:
</para>
-
+
<table>
<title>Identity Management API</title>
-
+
<tgroup cols="2">
<colspec colnum="1" colwidth="1*" />
<colspec colnum="2" colwidth="3*" />
-
+
<thead>
<row>
<entry align="center">
@@ -1719,106 +1719,106 @@
</entry>
<entry align="center">
<para>Returns</para>
- </entry>
+ </entry>
<entry align="center">
<para>Description</para>
</entry>
</row>
- </thead>
-
+ </thead>
+
<tbody>
-
+
<row>
<entry>
<para>
<literal>createAccount(String name, String password)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Creates a new user account, with the specified name and password. Returns <literal>true</literal>
if successful, or <literal>false</literal> if not.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>deleteAccount(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Deletes the user account with the specified name. Returns <literal>true</literal>
if successful, or <literal>false</literal> if not.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>enableAccount(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Enables the user account with the specified name. Accounts that are not enabled are
- not able to authenticate. Returns <literal>true</literal> if successful, or
+ not able to authenticate. Returns <literal>true</literal> if successful, or
<literal>false</literal> if not.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>disableAccount(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
- Disables the user account with the specified name. Returns <literal>true</literal> if
+ Disables the user account with the specified name. Returns <literal>true</literal> if
successful, or <literal>false</literal> if not.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>changePassword(String name, String password)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
- Changes the password for the user account with the specified name. Returns
+ Changes the password for the user account with the specified name. Returns
<literal>true</literal> if successful, or <literal>false</literal> if not.
</para>
</entry>
@@ -1829,35 +1829,35 @@
<para>
<literal>isEnabled(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
- Returns <literal>true</literal> if the specified user account is enabled, or
+ Returns <literal>true</literal> if the specified user account is enabled, or
<literal>false</literal> if it isn't.
</para>
</entry>
- </row>
+ </row>
<row>
<entry>
<para>
<literal>grantRole(String name, String role)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Grants the specified role to the specified user account. The role must already exist for it to
- be granted. Returns <literal>true</literal> if the role is successfully granted, or
+ be granted. Returns <literal>true</literal> if the role is successfully granted, or
<literal>false</literal> if it is already granted to the user.
</para>
</entry>
@@ -1868,105 +1868,105 @@
<para>
<literal>revokeRole(String name, String role)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
- Revokes the specified role from the specified user account. Returns <literal>true</literal>
- if the specified user is a member of the role and it is successfully revoked, or
+ Revokes the specified role from the specified user account. Returns <literal>true</literal>
+ if the specified user is a member of the role and it is successfully revoked, or
<literal>false</literal> if the user is not a member of the role.
</para>
</entry>
</row>
-
+
<row>
<entry>
<para>
<literal>accountExists(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns <literal>true</literal> if the specified user exists, or <literal>false</literal>
if it doesn't.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>listUsers()</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>List</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns a list of all user names, sorted in alpha-numeric order.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>listUsers(String filter)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>List</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns a list of all user names filtered by the specified filter parameter, sorted in alpha-numeric order.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>listRoles()</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>List</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns a list of all role names.
</para>
</entry>
- </row>
-
+ </row>
+
<row>
<entry>
<para>
<literal>getGrantedRoles(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>List</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns a list of the names of all the roles explicitly granted to the specified user name.
@@ -1979,12 +1979,12 @@
<para>
<literal>getImpliedRoles(String name)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>List</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Returns a list of the names of all the roles implicitly granted to the specified user name.
@@ -2002,12 +2002,12 @@
<para>
<literal>authenticate(String name, String password)</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
<literal>boolean</literal>
</para>
- </entry>
+ </entry>
<entry>
<para>
Authenticates the specified username and password using the configured Identity Store. Returns
@@ -2017,25 +2017,282 @@
<literal>Identity.login()</literal> must be used instead.
</para>
</entry>
- </row>
-
+ </row>
+
</tbody>
</tgroup>
</table>
-
+
+ <para>
+ Using the Identity Management API requires that the calling user has the appropriate authorization to invoke
+ its methods. The following table describes the permission requirements for each of the methods in
+ <literal>IdentityManager</literal>.
+ </para>
+
+ <table>
+ <title>Identity Management Security Permissions</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colwidth="1*" />
+ <colspec colnum="2" colwidth="3*" />
+
+ <thead>
+ <row>
+ <entry align="center">
+ <para>Method</para>
+ </entry>
+ <entry align="center">
+ <para>Permission Name</para>
+ </entry>
+ <entry align="center">
+ <para>Permission Action</para>
+ </entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>createAccount()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>create</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>deleteAccount()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>delete</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>enableAccount()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>update</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>disableAccount()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>update</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>changePassword()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>update</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>isEnabled()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>read</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>grantRole()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>update</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>revokeRole()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>update</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>accountExists()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>read</literal>
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <para>
+ <literal>listUsers()</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>seam.account</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <literal>read</literal>
+ </para>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The following code listing provides an example set of security rules that grants access to all
+ Identity Management-related methods to members of the <literal>admin</literal> role:
+ </para>
+
+ <programlisting><![CDATA[rule CreateAccount
+ no-loop
+ activation-group "permissions"
+when
+ check: PermissionCheck(name == "seam.account", action == "create", granted == false)
+ Role(name == "admin")
+then
+ check.grant();
+end
+
+rule ReadAccount
+ no-loop
+ activation-group "permissions"
+when
+ check: PermissionCheck(name == "seam.account", action == "read", granted == false)
+ Role(name == "admin")
+then
+ check.grant();
+end
+
+rule UpdateAccount
+ no-loop
+ activation-group "permissions"
+when
+ check: PermissionCheck(name == "seam.account", action == "update", granted == false)
+ Role(name == "admin")
+then
+ check.grant();
+end
+
+rule DeleteAccount
+ no-loop
+ activation-group "permissions"
+when
+ check: PermissionCheck(name == "seam.account", action == "delete", granted == false)
+ Role(name == "admin")
+then
+ check.grant();
+end]]></programlisting>
+
</sect2>
-
+
<sect2>
<title>Seam-gen and Identity Management</title>
-
+
<para>
- When creating a new project using seam-gen (see <xref linkend="gettingstarted"/>), by default the
+ When creating a new project using seam-gen (see <xref linkend="gettingstarted"/>), by default the
<literal>IdentityManager</literal> will be configured with a <literal>JPAIdentityStore</literal>
and a <literal>UserAccount</literal> implementation will be generated as part of the new project.
In addition to this, the project will include the following user management screens, allowing
new users to be created, roles assigned, etc:
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-usermanager1.png" align="center"/>
@@ -2044,11 +2301,11 @@
<imagedata fileref="../shared/images/security-usermanager1.png" align="center"/>
</imageobject>
</mediaobject>
-
+
<para>
The user detail screen:
</para>
-
+
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/security-usermanager2.png" align="center"/>
@@ -2056,9 +2313,9 @@
<imageobject role="html">
<imagedata fileref="../shared/images/security-usermanager2.png" align="center"/>
</imageobject>
- </mediaobject>
-
-
+ </mediaobject>
+
+
</sect2>
</sect1>
16 years, 11 months
Seam SVN: r7276 - in branches/Seam_2_0/doc/reference/en: modules and 1 other directory.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-01-28 22:15:19 -0500 (Mon, 28 Jan 2008)
New Revision: 7276
Removed:
branches/Seam_2_0/doc/reference/en/images/security-identitymanager.png
branches/Seam_2_0/doc/reference/en/images/security-useraccount.png
branches/Seam_2_0/doc/reference/en/images/security-useraccountschema.png
branches/Seam_2_0/doc/reference/en/images/security-usermanager1.png
branches/Seam_2_0/doc/reference/en/images/security-usermanager2.png
Modified:
branches/Seam_2_0/doc/reference/en/modules/security.xml
Log:
removed identity management from 2.0.x documentation
Deleted: branches/Seam_2_0/doc/reference/en/images/security-identitymanager.png
===================================================================
(Binary files differ)
Deleted: branches/Seam_2_0/doc/reference/en/images/security-useraccount.png
===================================================================
(Binary files differ)
Deleted: branches/Seam_2_0/doc/reference/en/images/security-useraccountschema.png
===================================================================
(Binary files differ)
Deleted: branches/Seam_2_0/doc/reference/en/images/security-usermanager1.png
===================================================================
(Binary files differ)
Deleted: branches/Seam_2_0/doc/reference/en/images/security-usermanager2.png
===================================================================
(Binary files differ)
Modified: branches/Seam_2_0/doc/reference/en/modules/security.xml
===================================================================
--- branches/Seam_2_0/doc/reference/en/modules/security.xml 2008-01-29 03:11:47 UTC (rev 7275)
+++ branches/Seam_2_0/doc/reference/en/modules/security.xml 2008-01-29 03:15:19 UTC (rev 7276)
@@ -1514,553 +1514,5 @@
</sect1>
- <sect1>
- <title>Identity Management</title>
-
- <para>
- Seam Security provides an optional identity management API, which offers the following features:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- User management - the ability to create, delete and modify user accounts and their role memberships.
- </para>
- </listitem>
- <listitem>
- <para>
- Authentication of users without the need for writing an Authenticator component.
- </para>
- </listitem>
- <listitem>
- <para>
- A hierarchical role/group membership structure, allowing roles to be members of other roles.
- </para>
- </listitem>
- <listitem>
- <para>
- Pluggable identity store, allowing the developer to choose their security provider, whether it be
- JPA, LDAP, Kerberos, etc.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- The core of the identity management API is the <literal>IdentityManager</literal> component. Before it can be
- used however, it must be configured with an <literal>IdentityStore</literal> implementation. The
- <literal>IdentityStore</literal> does the actual work of interacting with the underlying security provider,
- whatever it may be.
- </para>
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/security-identitymanager.png" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/security-identitymanager.png" align="center"/>
- </imageobject>
- </mediaobject>
-
- <sect2>
- <title>Configuration</title>
-
- <para>
- Configuration of the <literal>IdentityManager</literal> is extremely simple, requiring only an
- <literal>IdentityStore</literal> to be configured in <literal>components.xml</literal>.
- The identity management namespace is <literal>http://jboss.com/products/seam/security/management</literal>
- and its schema location is <literal>http://jboss.com/products/seam/identity-management-2.0.xsd</literal>.
- Here's a simple example showing the configuration of a <literal>JPAIdentityStore</literal> - for the
- <literal>IdentityManager</literal> to use it, it must be named <literal>identityStore</literal>:
- </para>
-
- <programlisting><![CDATA[
- <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>
- ]]></programlisting>
- </sect2>
-
- <sect2>
- <title>JPAIdentityStore</title>
-
- <para>
- <literal>JPAIdentityStore</literal> is an <literal>IdentityStore</literal> implementation that uses
- JPA as its underlying security provider. User accounts and their role memberships are stored in a
- self-referencing database table, for which the corresponding entity bean must extend
- <literal>org.jboss.seam.security.management.UserAccount</literal> to provide the following properties:
- </para>
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/security-useraccount.png" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/security-useraccount.png" align="center"/>
- </imageobject>
- </mediaobject>
-
- <para>
- To provide a complete example, here's what the actual database tables may look like:
- </para>
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/security-useraccountschema.png" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/security-useraccountschema.png" align="center"/>
- </imageobject>
- </mediaobject>
-
- <para>
- And an example of the corresponding entity bean:
- </para>
-
- <programlisting><![CDATA[@Entity @Table(name = "USER_ACCOUNT")
-public class UserAccount extends org.jboss.seam.security.management.UserAccount
- implements Serializable
-{
- private Integer accountId;
- private String username;
- private String passwordHash;
- private boolean enabled;
- private AccountType accountType;
- private Set<UserAccount> memberships;
-
- @Id @GeneratedValue public Integer getAccountId() { return accountId; }
- public void setAccountId(Integer accountId) { this.accountId = accountId; }
-
- @NotNull @Override public String getUsername() { return username; }
- @Override public void setUsername(String username) { this.username = username; }
-
- @Override public String getPasswordHash() { return passwordHash; }
- @Override public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
-
- @Override public AccountType getAccountType() { return accountType; }
- @Override public void setAccountType(AccountType accountType) { this.accountType = accountType; }
-
- @Override public boolean isEnabled() { return enabled; }
- @Override public void setEnabled(boolean enabled) { this.enabled = enabled; }
- @ManyToMany(targetEntity = MemberAccount.class) @JoinTable(name = "ACCOUNT_MEMBERSHIP",
- joinColumns = @JoinColumn(name = "ACCOUNT_ID"),
- inverseJoinColumns = @JoinColumn(name = "MEMBER_OF"))
- @Override public Set<UserAccount> getMemberships() { return memberships; }
- @Override public void setMemberships(Set<UserAccount> memberships) { this.memberships = memberships; }}]]></programlisting>
-
- <para>
- In the above example, the implementation of <literal>UserAccount</literal> is self-referencing
- in that it has a many-to-many relationship with itself via its <literal>memberships</literal>
- property. To keep the model simple, both user accounts and roles are persisted as
- <literal>UserAccount</literal>s, with the <literal>accountType</literal> property acting as the
- discriminator between the two. With this model, roles can be members of other roles, making it
- possible to define complex role membership hierarchies.
- </para>
-
- <para>
- Once the <literal>UserAccount</literal> implementation has been created, the <literal>JPAIdentityStore</literal>
- must be configured to use that implementation any time it performs an identity management operation.
- This is done by specifying the <literal>account-class</literal> property in <literal>components.xml</literal>.
- In the following example, it is configured as <literal>com.acme.UserAccount</literal>:
- </para>
-
- <programlisting><![CDATA[
- <identity-management:jpa-identity-store name="identityStore" account-class="com.acme.UserAccount"/>]]></programlisting>
-
- <para>
- Please note that this is a required parameter, and must always be specified when using the
- <literal>JPAIdentityStore</literal>.
- </para>
-
- </sect2>
-
- <sect2>
- <title>Authentication with the Identity Management API</title>
-
- <para>
- To authenticate using the Identity Management API, it is as simple as not specifying the
- <literal>authenticate-method</literal> property for the <literal>Identity</literal> component.
- If no <literal>authenticate-method</literal> is specified, then by default the authentication
- process (controlled by <literal>SeamLoginModule</literal>) will attempt to authenticate using
- <literal>IdentityManager</literal>'s <literal>authenticate()</literal> method, and no
- Authenticator component is necessary.
- </para>
- </sect2>
-
- <sect2>
- <title>Using the IdentityManager API</title>
-
- <para>
- The <literal>IdentityManager</literal> can be accessed either by injecting it into your Seam
- component as follows:
- </para>
-
- <programlisting><![CDATA[ @In IdentityManager identityManager;]]></programlisting>
-
- <para>
- or by accessing it through its static <literal>instance()</literal> method:
- </para>
-
- <programlisting><![CDATA[ IdentityManager identityManager = IdentityManager.instance();]]></programlisting>
-
- <para>
- The following table describes each of the methods that the <literal>IdentityManager</literal> provides:
- </para>
-
- <table>
- <title>Identity Management API</title>
-
- <tgroup cols="2">
- <colspec colnum="1" colwidth="1*" />
- <colspec colnum="2" colwidth="3*" />
-
- <thead>
- <row>
- <entry align="center">
- <para>Method</para>
- </entry>
- <entry align="center">
- <para>Returns</para>
- </entry>
- <entry align="center">
- <para>Description</para>
- </entry>
- </row>
- </thead>
-
- <tbody>
-
- <row>
- <entry>
- <para>
- <literal>createAccount(String name, String password)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Creates a new user account, with the specified name and password. Returns <literal>true</literal>
- if successful, or <literal>false</literal> if not.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>deleteAccount(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Deletes the user account with the specified name. Returns <literal>true</literal>
- if successful, or <literal>false</literal> if not.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>enableAccount(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Enables the user account with the specified name. Accounts that are not enabled are
- not able to authenticate. Returns <literal>true</literal> if successful, or
- <literal>false</literal> if not.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>disableAccount(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Disables the user account with the specified name. Returns <literal>true</literal> if
- successful, or <literal>false</literal> if not.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>changePassword(String name, String password)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Changes the password for the user account with the specified name. Returns
- <literal>true</literal> if successful, or <literal>false</literal> if not.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>isEnabled(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns <literal>true</literal> if the specified user account is enabled, or
- <literal>false</literal> if it isn't.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>grantRole(String name, String role)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Grants the specified role to the specified user account. The role must already exist for it to
- be granted. Returns <literal>true</literal> if the role is successfully granted, or
- <literal>false</literal> if it is already granted to the user.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>revokeRole(String name, String role)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Revokes the specified role from the specified user account. Returns <literal>true</literal>
- if the specified user is a member of the role and it is successfully revoked, or
- <literal>false</literal> if the user is not a member of the role.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>accountExists(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns <literal>true</literal> if the specified user exists, or <literal>false</literal>
- if it doesn't.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>listUsers()</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>List</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns a list of all user names, sorted in alpha-numeric order.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>listUsers(String filter)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>List</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns a list of all user names filtered by the specified filter parameter, sorted in alpha-numeric order.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>listRoles()</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>List</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns a list of all role names.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>getGrantedRoles(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>List</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns a list of the names of all the roles explicitly granted to the specified user name.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>getImpliedRoles(String name)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>List</literal>
- </para>
- </entry>
- <entry>
- <para>
- Returns a list of the names of all the roles implicitly granted to the specified user name.
- Implicitly granted roles include those that are not directly granted to a user, rather they are
- granted to the roles that the user is a member of. For example, is the <literal>admin</literal>
- role is a member of the <literal>user</literal> role, and a user is a member of the <literal>admin</literal>
- role, then the implied roles for the user are both the <literal>admin</literal>, and <literal>user</literal>
- roles.
- </para>
- </entry>
- </row>
-
- <row>
- <entry>
- <para>
- <literal>authenticate(String name, String password)</literal>
- </para>
- </entry>
- <entry>
- <para>
- <literal>boolean</literal>
- </para>
- </entry>
- <entry>
- <para>
- Authenticates the specified username and password using the configured Identity Store. Returns
- <literal>true</literal> if successful or <literal>false</literal> if authentication failed.
- Successful authentication implies nothing beyond the return value of the method. It does not
- change the state of the <literal>Identity</literal> component - to perform a proper Seam login the
- <literal>Identity.login()</literal> must be used instead.
- </para>
- </entry>
- </row>
-
- </tbody>
- </tgroup>
- </table>
-
- </sect2>
-
- <sect2>
- <title>Seam-gen and Identity Management</title>
-
- <para>
- When creating a new project using seam-gen (see <xref linkend="gettingstarted"/>), by default the
- <literal>IdentityManager</literal> will be configured with a <literal>JPAIdentityStore</literal>
- and a <literal>UserAccount</literal> implementation will be generated as part of the new project.
- In addition to this, the project will include the following user management screens, allowing
- new users to be created, roles assigned, etc:
- </para>
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/security-usermanager1.png" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/security-usermanager1.png" align="center"/>
- </imageobject>
- </mediaobject>
-
- <para>
- The user detail screen:
- </para>
-
- <mediaobject>
- <imageobject role="fo">
- <imagedata fileref="images/security-usermanager2.png" align="center"/>
- </imageobject>
- <imageobject role="html">
- <imagedata fileref="../shared/images/security-usermanager2.png" align="center"/>
- </imageobject>
- </mediaobject>
-
-
- </sect2>
-
- </sect1>
-
</chapter>
16 years, 11 months
Seam SVN: r7275 - branches/Seam_2_0/seam-gen/resources/WEB-INF.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-01-28 22:11:47 -0500 (Mon, 28 Jan 2008)
New Revision: 7275
Modified:
branches/Seam_2_0/seam-gen/resources/WEB-INF/components.xml
Log:
re-add authenticate-method
Modified: branches/Seam_2_0/seam-gen/resources/WEB-INF/components.xml
===================================================================
--- branches/Seam_2_0/seam-gen/resources/WEB-INF/components.xml 2008-01-28 23:40:13 UTC (rev 7274)
+++ branches/Seam_2_0/seam-gen/resources/WEB-INF/components.xml 2008-01-29 03:11:47 UTC (rev 7275)
@@ -32,7 +32,7 @@
</drools:rule-files>
</drools:rule-base>
- <security:identity security-rules="#{securityRules}" remember-me="true"/>
+ <security:identity security-rules="#{securityRules}" authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}"/>
16 years, 11 months