[seam-commits] Seam SVN: r8430 - in trunk/examples/wiki: src/etc/i18n and 18 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Jul 1 06:02:54 EDT 2008


Author: christian.bauer at jboss.com
Date: 2008-07-01 06:02:54 -0400 (Tue, 01 Jul 2008)
New Revision: 8430

Added:
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumTopicsPreferences.java
   trunk/examples/wiki/view/includes/onlineMembers.xhtml
Removed:
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/blosxom/
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/AbstractImporter.java
Modified:
   trunk/examples/wiki/src/etc/META-INF/seam-deployment.properties
   trunk/examples/wiki/src/etc/i18n/messages_en.properties
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.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/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/dao/UserDAO.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiComment.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectory.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDocument.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiNode.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiUploadImage.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/Converters.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/UploadTypes.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/ZipImporter.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/Importer.java
   trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/ImporterRegistry.java
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/blog/BlogDAO.java
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQueries.hbm.xml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/i18n/messages_forum_en.properties
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyReplyToList.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyTopicToList.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyReplyToList.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyTopicToList.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyReplyToList.xhtml
   trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyTopicToList.xhtml
   trunk/examples/wiki/view/docDisplay_d.xhtml
   trunk/examples/wiki/view/includes/onlineUsers.xhtml
   trunk/examples/wiki/view/themes/default/css/template.css
   trunk/examples/wiki/view/uploadEdit_d.xhtml
   trunk/examples/wiki/view/userList_d.xhtml
Log:
New wiki features: Upload Importers, Online Members with portrait, Mailinglist per Forum

Modified: trunk/examples/wiki/src/etc/META-INF/seam-deployment.properties
===================================================================
--- trunk/examples/wiki/src/etc/META-INF/seam-deployment.properties	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/etc/META-INF/seam-deployment.properties	2008-07-01 10:02:54 UTC (rev 8430)
@@ -1,2 +1,2 @@
-org.jboss.seam.deployment.annotationTypes=org.jboss.seam.wiki.preferences.annotations.Preferences:org.jboss.seam.wiki.core.template.WikiDocumentTemplate
+org.jboss.seam.deployment.annotationTypes=org.jboss.seam.wiki.preferences.annotations.Preferences:org.jboss.seam.wiki.core.template.WikiDocumentTemplate:org.jboss.seam.wiki.core.upload.importers.annotations.UploadImporter
 org.jboss.seam.deployment.deploymentHandlers=org.jboss.seam.wiki.core.plugin.binding.lacewiki.PluginDeploymentHandler:org.jboss.seam.wiki.core.plugin.binding.lacewiki.PluginI18NDeploymentHandler
\ No newline at end of file

Modified: trunk/examples/wiki/src/etc/i18n/messages_en.properties
===================================================================
--- trunk/examples/wiki/src/etc/i18n/messages_en.properties	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/etc/i18n/messages_en.properties	2008-07-01 10:02:54 UTC (rev 8430)
@@ -465,7 +465,15 @@
 lacewiki.label.userList.View=View
 lacewiki.label.userList.Edit=Edit
 lacewiki.label.userList.NotAvailableForSkin=User search is not available with this skin.
+lacewiki.label.userList.OnlineMembers=Online Members
+lacewiki.label.userList.Online=Online
+lacewiki.label.userList.Of=of
+lacewiki.label.userList.Member=Member
+lacewiki.label.userList.Members=Members
+lacewiki.label.userList.Guest=Guest
+lacewiki.label.userList.Guests=Guests
 
+
 # User Profile
 
 lacewiki.label.userProfile.UserProfile=User Profile
@@ -506,7 +514,8 @@
 lacewiki.label.uploadEdit.CreatedOn=Created on
 lacewiki.label.uploadEdit.Name=Name
 lacewiki.label.uploadEdit.FileDetails=File Details
-lacewiki.label.uploadEdit.Converters=Converters
+lacewiki.label.uploadEdit.Importers=Importers
+lacewiki.label.uploadEdit.ImportNoSelection=Select an importer to convert the file
 lacewiki.label.uploadEdit.OriginalImageSize=Original Image Size
 lacewiki.label.uploadEdit.Pixel=px
 lacewiki.label.uploadEdit.ImagePreview=Image Preview
@@ -528,6 +537,7 @@
 lacewiki.button.uploadEdit.Delete=<u>D</u>elete
 lacewiki.button.uploadEdit.Delete.accesskey=D
 lacewiki.msg.uploadEdit.UpdateUpload=File {0} has been uploaded.
+lacewiki.button.uploadEdit.Import=Import
 
 # Document Edit
 
@@ -687,10 +697,6 @@
 lacewiki.msg.MemberHomedirectoryNotFound=Could not find member area with name {0}  - your configuration is broken, please change it.
 lacewiki.msg.TrashAreaNotFound=Could not find trash area with name {0}  - your configuration is broken, please change it.
 lacewiki.msg.HelpAreaNotFound=Could not find help area with name {0}  - your configuration is broken, please change it.
-lacewiki.msg.ImportSkippingDirectory=Skipping directory '{0}', importing not supported...
-lacewiki.msg.ImportDuplicateName=Skipping file '{0}', name is already used in this area...
-lacewiki.msg.ImportInvalidNode=Skipping entry '{0}', invalid: {1}
-lacewiki.msg.ImportOk=Created file '{0}' in current directory.
 lacewiki.msg.OptimisticLockError=Someone modified the same record while you were editing it. Your workspace has been closed.
 lacewiki.msg.AccessDenied=Access Denied
 lacewiki.msg.FatalError=Request failed, please check the application log or contact the administrator
@@ -748,3 +754,12 @@
 # Templates
 
 lacewiki.label.template.RegularWikiDocument=Regular Document
+
+
+# Importers
+
+lacewiki.msg.ImportSkippingDirectory=Skipping directory '{0}', importing not supported...
+lacewiki.msg.ImportDuplicateName=Skipping file '{0}', name is already used in this area...
+lacewiki.msg.ImportInvalidNode=Skipping entry '{0}', invalid: {1}
+lacewiki.msg.ImportOk=Created file '{0}' in current directory.
+lacewiki.label.ZipImporter=Extract archive as individual files

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/admin/WikiHttpSessionManager.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -9,15 +9,14 @@
 import org.jboss.seam.ScopeType;
 import org.jboss.seam.wiki.core.model.User;
 import org.jboss.seam.wiki.core.model.Role;
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Logger;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.wiki.core.dao.UserDAO;
+import org.jboss.seam.annotations.*;
 import org.jboss.seam.annotations.security.Restrict;
 import org.jboss.seam.log.Log;
 import org.jboss.seam.security.Identity;
 
 import javax.servlet.http.HttpSession;
+import javax.persistence.EntityManager;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
@@ -31,12 +30,16 @@
 @AutoCreate
 public class WikiHttpSessionManager implements Serializable {
 
-    protected static final String SESSION_ATTR_IDENTITY = "org.jboss.seam.security.identity";
-    protected static final String SESSION_ATTR_ACCESSLVL = "currentAccessLevel";
+    protected static final String SESSION_ATTR_IDENTITY     = "org.jboss.seam.security.identity";
+    protected static final String SESSION_ATTR_ACCESSLVL    = "currentAccessLevel";
+    protected static final String SESSION_ATTR_USER         = "currentUser";
 
     @Logger
     private Log log;
 
+    @In
+    UserDAO userDAO;
+
     transient private Map<String, Boolean> selectedSessions = new HashMap<String,Boolean>();
     transient private Map<String, Long> sessionsSize = new HashMap<String,Long>();
 
@@ -145,6 +148,24 @@
     }
     */
 
+    public List<User> getOnlineMembers() {
+        Set<String> onlineUsernames = new HashSet<String>();
+        Collection<HttpSession> sessions = WikiServletListener.getSessions().values();
+        for (HttpSession session : sessions) {
+            Integer userLevel = (Integer)session.getAttribute(SESSION_ATTR_ACCESSLVL);
+            if (userLevel != null && userLevel > Role.GUESTROLE_ACCESSLEVEL) {
+                onlineUsernames.add( ((User)session.getAttribute(SESSION_ATTR_USER)).getUsername() );
+            }
+        }
+
+        // Need to load these guys, the are not in this persistence context
+        return userDAO.findUsersWithUsername(onlineUsernames);
+    }
+
+    public long getTotalMembers() {
+        return userDAO.findTotalNoOfUsers();
+    }
+
     public long getNumberOfOnlineMembers() {
         Collection<HttpSession> sessions = WikiServletListener.getSessions().values();
 

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -197,8 +197,12 @@
 
     @Observer("org.jboss.seam.security.loggedOut")
     public void resetSessionTime() {
-        int regularSessionTimeout = (Integer) Contexts.getSessionContext().get(REGULAR_SESSION_MAX_INACTIVE_SECONDS);
-        log.debug("resetting timeout of user session after logout to minutes: " + regularSessionTimeout/60);
-        ServletContexts.getInstance().getRequest().getSession().setMaxInactiveInterval(regularSessionTimeout);
+        // Don't rely on that, do a null check
+        Object o = Contexts.getSessionContext().get(REGULAR_SESSION_MAX_INACTIVE_SECONDS);
+        if (o != null) {
+            int regularSessionTimeout = (Integer) o;
+            log.debug("resetting timeout of user session after logout to minutes: " + regularSessionTimeout/60);
+            ServletContexts.getInstance().getRequest().getSession().setMaxInactiveInterval(regularSessionTimeout);
+        }
     }
 }

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-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -85,6 +85,11 @@
         return dir;
     }
 
+    @Override
+    protected boolean requiresMessageId() {
+        return false;
+    }
+
     /* -------------------------- Custom CUD ------------------------------ */
 
     @Override

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -245,6 +245,19 @@
             Events.instance().raiseEvent("PreferenceEditor.flushAll");
             Events.instance().raiseEvent("Node.persisted", getInstance());
         }
+
+        // Now set the message identifier, if nobody else did
+        if (getInstance().getMessageId() == null && requiresMessageId()) {
+            getInstance().setMessageId(
+                // Use the identifier and the creation time, both quite unique and immutable
+                WikiUtil.calculateMessageId(
+                    getInstance().getId(),
+                    String.valueOf(getInstance().getCreatedOn().getTime()))
+            );
+            // Need to flush again, to execute UPDATE
+            getEntityManager().flush();
+        }
+
         return outcome;
     }
 
@@ -432,6 +445,10 @@
         return null;
     }
 
+    protected boolean requiresMessageId() {
+        return true;
+    }
+
     /* -------------------------- Optional Subclass Callbacks ------------------------------ */
 
     protected boolean isPageRootController() { return true; }

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-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UploadHome.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -12,12 +12,16 @@
 import org.jboss.seam.wiki.core.upload.UploadType;
 import org.jboss.seam.wiki.core.upload.UploadTypes;
 import org.jboss.seam.wiki.core.upload.Uploader;
+import org.jboss.seam.wiki.core.upload.importers.metamodel.ImporterRegistry;
+import org.jboss.seam.wiki.core.upload.importers.metamodel.Importer;
 import org.jboss.seam.wiki.core.upload.editor.UploadEditor;
 
 import static org.jboss.seam.international.StatusMessage.Severity.INFO;
 
 import java.util.Date;
 import java.util.Map;
+import java.util.List;
+import java.util.Collections;
 
 @Name("uploadHome")
 @Scope(ScopeType.CONVERSATION)
@@ -36,9 +40,13 @@
     @In
     private TagEditor tagEditor;
 
+    @In
+    ImporterRegistry importerRegistry;
+
     /* -------------------------- Internal State ------------------------------ */
 
     protected UploadEditor uploadEditor;
+    protected String importer;
 
     /* -------------------------- Basic Overrides ------------------------------ */
 
@@ -197,4 +205,27 @@
     public TagEditor getTagEditor() {
         return tagEditor;
     }
+
+    public List<String> getAvailableImporters() {
+        if (getInstance().getContentType() == null) return Collections.EMPTY_LIST;
+        return importerRegistry.getAvailableImporters(getInstance().getContentType(), getInstance().getExtension());
+    }
+
+    public String getImporter() {
+        return importer;
+    }
+
+    public void setImporter(String importer) {
+        this.importer = importer;
+    }
+
+    public void importInstance() {
+        if (importer == null) return;
+
+        getLog().debug("importing with importer: " + importer);
+        Importer imp = (Importer)Component.getInstance(importer);
+        imp.handleImport(getEntityManager(), getInstance());
+        getEntityManager().flush();
+
+    }
 }

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/dao/UserDAO.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -3,6 +3,7 @@
 import javax.persistence.EntityManager;
 import javax.persistence.EntityNotFoundException;
 import javax.persistence.NoResultException;
+import javax.persistence.Query;
 
 import org.jboss.seam.annotations.In;
 import org.jboss.seam.annotations.Name;
@@ -18,6 +19,8 @@
 import org.hibernate.transform.DistinctRootEntityResultTransformer;
 
 import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
 
 @Name("userDAO")
 @AutoCreate
@@ -49,6 +52,38 @@
         return null;
     }
 
+    public long findTotalNoOfUsers() {
+        Query q =
+            entityManager.createQuery(
+                "select count(u) from User u where not u.username = :guestUsername and not u.username = :adminUsername"
+            );
+        q.setParameter("guestUsername", User.GUEST_USERNAME);
+        q.setParameter("adminUsername", User.ADMIN_USERNAME);
+        q.setHint("org.hibernate.comment", "Find number of members");
+        q.setHint("org.hibernate.cacheable", true);
+        return (Long)q.getSingleResult();
+    }
+
+    public List<User> findUsersWithUsername(Collection<String> usernames) {
+        // We need to batch this because we use an in() expression
+        int batchsize = 50;
+        int i = 0;
+        List<String> usernamesToQuery = new ArrayList<String>(batchsize);
+        List<User> users = new ArrayList<User>();
+        for (String username : usernames) {
+            usernamesToQuery.add(username);
+            i++;
+            if (i % batchsize == 0 || usernames.size() < batchsize) {
+                // Query and clear
+                Query q = entityManager.createQuery("select u from User u left join fetch u.profile where u.username in(:usernames)");
+                q.setParameter("usernames", usernamesToQuery);
+                users.addAll(q.getResultList());
+                usernamesToQuery.clear();
+            }
+        }
+        return users;
+    }
+
     public User findUserWithActivationCode(String activationCode) {
         StringBuilder query = new StringBuilder("select u from User u where u.activationCode = :activationCode");
         try {

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiComment.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiComment.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiComment.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -116,7 +116,7 @@
     public String[] getPropertiesForGroupingInQueries() {
         return new String[]{
             "version", "parent", "rating",
-            "areaNumber", "name", "wikiname", "createdBy", "createdOn",
+            "areaNumber", "name", "wikiname", "createdBy", "createdOn", "messageId",
             "lastModifiedBy", "lastModifiedOn", "readAccessLevel", "writeAccessLevel", "writeProtected",
             "subject", "fromUserName", "fromUserEmail", "fromUserHomepage", "useWikiText",
         };

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectory.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectory.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDirectory.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -86,7 +86,7 @@
     public String[] getPropertiesForGroupingInQueries() {
         return new String[]{
             "version", "parent", "rating",
-            "areaNumber", "name", "wikiname", "createdBy", "createdOn",
+            "areaNumber", "name", "wikiname", "createdBy", "createdOn", "messageId",
             "lastModifiedBy", "lastModifiedOn", "readAccessLevel", "writeAccessLevel", "writeProtected",
             "defaultFile", "description"
         };

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDocument.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDocument.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiDocument.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -322,7 +322,7 @@
     public static String[] getPropertiesForGroupingInQueries() {
         return new String[]{
             "id", "version", "parent", "rating",
-            "areaNumber", "name", "wikiname", "createdBy", "createdOn",
+            "areaNumber", "name", "wikiname", "createdBy", "createdOn", "messageId",
             "lastModifiedBy", "lastModifiedOn", "readAccessLevel", "writeAccessLevel", "writeProtected",
             "nameAsTitle", "enableComments", "enableCommentForm", "enableCommentsOnFeeds",
             "header", "headerMacrosString", "contentMacrosString", "footer", "footerMacrosString"

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiNode.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiNode.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiNode.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -58,6 +58,9 @@
     )
     protected String wikiname;
 
+    @Column(name = "MESSAGE_ID", length = 1023, nullable = true)
+    protected String messageId;
+
     @Column(name = "CREATED_ON", nullable = false, updatable = false)
     @org.hibernate.search.annotations.Field(
         index = org.hibernate.search.annotations.Index.UN_TOKENIZED,
@@ -133,6 +136,9 @@
     public String getWikiname() { return wikiname; }
     public void setWikiname(String wikiname) { this.wikiname = wikiname; }
 
+    public String getMessageId() { return messageId; }
+    public void setMessageId(String messageId) { this.messageId = messageId; }
+
     public Date getCreatedOn() { return createdOn; }
     public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; }
 

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiUploadImage.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiUploadImage.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/model/WikiUploadImage.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -15,9 +15,10 @@
     private int sizeY;
 
     @Column(name = "THUMBNAIL")
-    private char thumbnail = 'A'; // Disable embedding by default, attach
+    private char thumbnail = 'M'; // Medium size thumbnail by default, not attached
 
-    // SchemaExport needs length.. MySQL has "tinyblob", "mediumblob" and other such nonsense types
+    // TODO: SchemaExport needs length.. MySQL has "tinyblob", "mediumblob" and other such nonsense types, this
+    // is a best-guess value
     @Lob
     @Column(name = "THUMBNAIL_DATA", length = 1000000, nullable = true)
     @Basic(fetch = FetchType.LAZY) // Lazy loaded through bytecode instrumentation

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/Converters.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/Converters.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/Converters.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -13,8 +13,6 @@
 import org.jboss.seam.wiki.core.model.Role;
 import org.jboss.seam.wiki.core.search.metamodel.SearchRegistry;
 import org.jboss.seam.wiki.core.search.metamodel.SearchableEntity;
-import org.jboss.seam.wiki.core.upload.importers.metamodel.Importer;
-import org.jboss.seam.wiki.core.upload.importers.metamodel.ImporterRegistry;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
@@ -32,27 +30,6 @@
         return new String[]{"NULL","January","February","March","April","May","June","July","August","September","October","November","December"};
     }
 
-    @Name("importerConverter")
-    @org.jboss.seam.annotations.faces.Converter(forClass = Importer.class)
-    public static class ImporterConverter implements Converter, Serializable {
-
-        public Object getAsObject(FacesContext arg0,
-                                  UIComponent arg1,
-                                  String arg2) throws ConverterException {
-            if (arg2 == null) return null;
-            ImporterRegistry importerRegistry = (ImporterRegistry)Component.getInstance("importerRegistry");
-            return importerRegistry.getImportersByName().get(arg2);
-        }
-
-        public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) throws ConverterException {
-            if (arg2 instanceof Importer) {
-                return ((Importer)arg2).getComponentName();
-            } else {
-                return null;
-            }
-        }
-    }
-
     @Name("searchableEntityConverter")
     @org.jboss.seam.annotations.faces.Converter(forClass = SearchableEntity.class)
     public static class SearchableEntityConverter implements Converter, Serializable {

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/UploadTypes.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/UploadTypes.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/UploadTypes.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -24,6 +24,7 @@
 public class UploadTypes {
 
     public static final String GENERIC_UPLOAD_TYPE = "generic";
+    public static final String DEFAULT_UPLOAD_TYPE = "application/octet-stream";
 
     private Map<String, UploadType> uploadTypes = new HashMap<String, UploadType>() {
         {
@@ -33,7 +34,7 @@
             put("image/gif",                    new UploadType("icon.fileimg.gif", new WikiUploadHandler() ));
             put("text/plain",                   new UploadType("icon.filetxt.gif", new WikiUploadHandler() ));
             put("application/pdf",              new UploadType("icon.filepdf.gif", new WikiUploadHandler() ));
-            put("application/octet-stream",     new UploadType("icon.filegeneric.gif", new WikiUploadHandler() ));
+            put(DEFAULT_UPLOAD_TYPE,            new UploadType("icon.filegeneric.gif", new WikiUploadHandler() ));
             put(GENERIC_UPLOAD_TYPE,            new UploadType("icon.filegeneric.gif", new WikiUploadHandler() ));
         }
     };

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/ZipImporter.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/ZipImporter.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/ZipImporter.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -1,40 +1,43 @@
 package org.jboss.seam.wiki.core.upload.importers;
 
+import net.sf.jmimemagic.Magic;
+import org.hibernate.validator.ClassValidator;
+import org.hibernate.validator.InvalidValue;
 import org.jboss.seam.annotations.In;
 import org.jboss.seam.annotations.Logger;
 import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.core.Validators;
+import static org.jboss.seam.international.StatusMessage.Severity.ERROR;
+import static org.jboss.seam.international.StatusMessage.Severity.INFO;
+import org.jboss.seam.international.StatusMessages;
 import org.jboss.seam.log.Log;
 import org.jboss.seam.wiki.core.dao.WikiNodeDAO;
-import org.jboss.seam.wiki.core.upload.importers.annotations.UploadImporter;
-import org.jboss.seam.wiki.core.upload.importers.metamodel.AbstractImporter;
-import org.jboss.seam.wiki.core.upload.UploadType;
-import org.jboss.seam.wiki.core.model.WikiUpload;
 import org.jboss.seam.wiki.core.model.WikiNode;
+import org.jboss.seam.wiki.core.model.WikiUpload;
+import org.jboss.seam.wiki.core.upload.UploadType;
+import org.jboss.seam.wiki.core.upload.UploadTypes;
+import org.jboss.seam.wiki.core.upload.Uploader;
+import org.jboss.seam.wiki.core.upload.importers.annotations.UploadImporter;
+import org.jboss.seam.wiki.core.upload.importers.metamodel.Importer;
 import org.jboss.seam.wiki.util.WikiUtil;
-import org.jboss.seam.core.Validators;
-import org.hibernate.validator.InvalidValue;
-import org.hibernate.validator.ClassValidator;
 
-import static org.jboss.seam.international.StatusMessage.Severity.ERROR;
-import static org.jboss.seam.international.StatusMessage.Severity.INFO;
-
 import javax.persistence.EntityManager;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.util.*;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.BufferedInputStream;
 
-import net.sf.jmimemagic.Magic;
-
 @Name("zipImporter")
 @UploadImporter(
         handledMimeTypes = {"application/zip", "application/java-archive"},
         handledExtensions = {"zip", "jar"},
-        description = "Extract archive as individual files"
+        description = "lacewiki.label.ZipImporter"
 )
-public class ZipImporter extends AbstractImporter {
+ at AutoCreate
+public class ZipImporter implements Importer {
 
     @Logger
     Log log;
@@ -45,6 +48,9 @@
     @In
     protected Map<String, UploadType> uploadTypes;
 
+    @In
+    protected StatusMessages statusMessages;
+
     public boolean handleImport(EntityManager em, WikiUpload zipFile) {
 
         if (zipFile.getData().length == 0) return true;
@@ -67,10 +73,8 @@
             while ((ze = zipInputStream.getNextEntry()) != null) {
                 log.debug("extracting zip entry: " + ze.getName());
 
-                if (ze.getName().contains("/") && !handleDirectory(em, zipFile, ze)) continue;
+                if (!beforeUncompress(em, zipFile, ze)) continue;
 
-                if (!continueUncompressing(em, zipFile, ze)) continue;
-
                 baos = new ByteArrayOutputStream();
                 while ((bytesRead = zipInputStream.read(buffer, 0, bufferSize)) > 0) {
                     baos.write(buffer, 0, bytesRead);
@@ -97,35 +101,29 @@
             }
         }
 
-        // By default append them to the
-        persistNewNodesSorted(
-            em,
-            zipFile,
-            newObjects,
-            new Comparator() {
-                public int compare(Object o, Object o1) {
-                    if ( !(o instanceof WikiNode) &&  !(o1 instanceof WikiNode) ) return 0;
-                    return ((WikiNode)o).getWikiname().compareTo( ((WikiNode)o1).getWikiname() );
-                }
-            }
-        );
+        handleNewObjects(em, zipFile, newObjects);
 
         return true;
     }
 
-    protected boolean handleDirectory(EntityManager em, WikiUpload zipFile, ZipEntry zipEntry) {
-        log.debug("skipping directory: " + zipEntry.getName());
-        getStatusMessages().addFromResourceBundleOrDefault(
-            ERROR,
-            "lacewiki.msg.ImportSkippingDirectory",
-            "Skipping directory '{0}', importing not supported...",
-            zipEntry.getName()
-        );
-        return false; // Not supported
-    }
+    protected boolean beforeUncompress(EntityManager em, WikiUpload zipFile, ZipEntry zipEntry) {
 
-    protected boolean continueUncompressing(EntityManager em, WikiUpload zipFile, ZipEntry zipEntry) {
-        return validateNewWikiname(zipFile, WikiUtil.convertToWikiName(zipEntry.getName()));
+        if (zipEntry.getName().contains("/")) {
+            log.debug("skipping directory: " + zipEntry.getName());
+            statusMessages.addFromResourceBundleOrDefault(
+                ERROR,
+                "lacewiki.msg.ImportSkippingDirectory",
+                "Skipping directory '{0}', importing not supported...",
+                zipEntry.getName()
+            );
+            return false; // Not supported
+        }
+
+        // This assumes that the wiki name is the zip entry filename without extension - maybe we should
+        // support with extension as option, that's unique inside a zip archive so we fail too often
+        WikiUpload tmp = new WikiUpload();
+        tmp.setFilename(zipEntry.getName());
+        return validateNewWikiname(zipFile, WikiUtil.convertToWikiName(tmp.getFilenameWithoutExtension()));
     }
 
     protected boolean validateNewWikiname(WikiUpload zipFile, String newWikiname) {
@@ -136,7 +134,7 @@
             return true;
         } else {
             log.debug("new name is not unique and invalid");
-            getStatusMessages().addFromResourceBundleOrDefault(
+            statusMessages.addFromResourceBundleOrDefault(
                 ERROR,
                 "lacewiki.msg.ImportDuplicateName",
                 "Skipping file '{0}', name is already used in this area...",
@@ -149,51 +147,56 @@
     protected Object createNewObject(EntityManager em, WikiUpload zipFile, ZipEntry zipEntry, byte[] uncompressedBytes) {
         log.debug("creating new file from zip entry: " + zipEntry.getName());
 
-        WikiUpload wikiUpload = new WikiUpload();
-        wikiUpload.setFilename(zipEntry.getName());
-        wikiUpload.setName(zipEntry.getName());
-        wikiUpload.setWikiname(WikiUtil.convertToWikiName(wikiUpload.getName()));
+        // First figure out what it is
+        String mimeType = null;
+        try {
+            mimeType = Magic.getMagicMatch(uncompressedBytes).getMimeType();
+        } catch (Exception ex) {}
+        String contentType = mimeType != null ? mimeType : UploadTypes.DEFAULT_UPLOAD_TYPE;
 
+        // Just a temporary value holder this time
+        Uploader uploader = new Uploader();
+        uploader.setData(uncompressedBytes);
+        uploader.setFilename(zipEntry.getName());
+        uploader.setContentType(contentType);
+
+        // Get the right handler for that type and produce a WikiUpload instance
+        UploadType uploadType = uploadTypes.get(contentType);
+        if (uploadType == null) uploadType = uploadTypes.get(UploadTypes.GENERIC_UPLOAD_TYPE);
+        WikiUpload wikiUpload = uploadType.getUploadHandler().handleUpload(uploader);
+
+        // Now set the other properties so we can persist it directly
+        wikiUpload.setName(wikiUpload.getFilenameWithoutExtension());
+        wikiUpload.setWikiname(WikiUtil.convertToWikiName(wikiUpload.getName()));
         wikiUpload.setAreaNumber(zipFile.getAreaNumber());
         wikiUpload.setCreatedBy(zipFile.getCreatedBy());
         wikiUpload.setLastModifiedBy(wikiUpload.getCreatedBy());
         wikiUpload.setCreatedOn(new Date(zipEntry.getTime()));
-        wikiUpload.setLastModifiedOn(new Date());
+        wikiUpload.setLastModifiedOn(wikiUpload.getCreatedOn());
         wikiUpload.setReadAccessLevel(zipFile.getReadAccessLevel());
         wikiUpload.setWriteAccessLevel(zipFile.getWriteAccessLevel());
 
-        log.debug("detecting mime type of zip entry: " + zipEntry.getName());
-        String mimeType;
-        try {
-            mimeType = Magic.getMagicMatch(uncompressedBytes).getMimeType();
-            log.debug("mime type of zip entry is: " + mimeType);
-        } catch (Exception ex) {
-            log.debug("could not detect mime type, defaulting to binary");
-            mimeType = "application/octet-stream";
-        }
-        wikiUpload.setContentType(mimeType);
-        wikiUpload.setData(uncompressedBytes);
-        wikiUpload.setFilesize(uncompressedBytes.length);
+        log.debug("created new file from zip entry: " + wikiUpload);
 
-        // TODO: Make this generic, duplicated here and in uploadHome
-        /* TODO: fixme
-        if (fileMetaMap.get(wikiUpload.getContentType()) != null &&
-            fileMetaMap.get(wikiUpload.getContentType()).image) {
-            throw new RuntimeException("TODO: Images not supported");
-            wikiUpload.setImageMetaInfo(new ImageMetaInfo());
-            ImageIcon icon = new ImageIcon(wikiUpload.getData());
-            int imageSizeX = icon.getImage().getWidth(null);
-            int imageSizeY = icon.getImage().getHeight(null);
-            wikiUpload.getImageMetaInfo().setSizeX(imageSizeX);
-            wikiUpload.getImageMetaInfo().setSizeY(imageSizeY);
-        }
-        */
-
         return wikiUpload;
     }
 
-    protected void persistNewNodesSorted(EntityManager em, WikiUpload zipFile, Map<String, Object> newObjects, Comparator comparator) {
+    public void handleNewObjects(EntityManager em, WikiUpload zipFile, Map<String, Object> newObjects) {
+        persistWikiUploadsSorted(
+            em,
+            zipFile,
+            newObjects,
+            new Comparator() {
+                public int compare(Object o, Object o1) {
+                    if ( !(o instanceof WikiNode) &&  !(o1 instanceof WikiNode) ) return 0;
+                    return ((WikiNode)o).getWikiname().compareTo( ((WikiNode)o1).getWikiname() );
+                }
+            }
+        );
+    }
 
+    private void persistWikiUploadsSorted(EntityManager em, WikiUpload zipFile, Map<String, Object> newObjects, Comparator comparator) {
+
         List<WikiNode> newNodes = new ArrayList<WikiNode>();
         for (Object newObject : newObjects.values()) {
             if (newObject instanceof WikiNode) {
@@ -202,7 +205,6 @@
         }
         Collections.sort(newNodes, comparator);
 
-        int i = 0;
         for (WikiNode newNode : newNodes) {
             log.debug("validating new node");
 
@@ -211,7 +213,7 @@
             if (invalidValues != null && invalidValues.length > 0) {
                 log.debug("new node is invalid: " + newNode);
                 for (InvalidValue invalidValue : invalidValues) {
-                    getStatusMessages().addFromResourceBundleOrDefault(
+                    statusMessages.addFromResourceBundleOrDefault(
                         ERROR,
                         "lacewiki.msg.ImportInvalidNode",
                         "Skipping entry '{0}', invalid: {1}",
@@ -226,19 +228,12 @@
             log.debug("persisting newly imported node: " + newNode);
             newNode.setParent(zipFile.getParent());
             em.persist(newNode);
-            getStatusMessages().addFromResourceBundleOrDefault(
+            statusMessages.addFromResourceBundleOrDefault(
                 INFO,
                 "lacewiki.msg.ImportOk",
                 "Created file '{0}' in current directory.",
                 newNode.getName()
             );
-
-            // Batch the work (we can't clear because of nested set updates, unfortunately)
-            i++;
-            if (i==100) {
-                em.flush();
-                i = 0;
-            }
         }
     }
 

Deleted: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/AbstractImporter.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/AbstractImporter.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/AbstractImporter.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -1,26 +0,0 @@
-package org.jboss.seam.wiki.core.upload.importers.metamodel;
-
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.international.StatusMessages;
-import org.jboss.seam.wiki.core.model.WikiUpload;
-
-import javax.persistence.EntityManager;
-import java.util.Set;
-
- at Scope(ScopeType.APPLICATION)
-public abstract class AbstractImporter {
-
-    @Observer("Importers.addImporter")
-    public void add(Set<AbstractImporter> importerComponents) {
-        importerComponents.add(this);
-    }
-
-    protected StatusMessages getStatusMessages() {
-        return StatusMessages.instance();
-    }
-
-    public abstract boolean handleImport(EntityManager em, WikiUpload file);
-
-}

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/Importer.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/Importer.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/Importer.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -1,51 +1,11 @@
 package org.jboss.seam.wiki.core.upload.importers.metamodel;
 
-import org.jboss.seam.wiki.core.upload.importers.annotations.UploadImporter;
-import org.jboss.seam.annotations.Name;
+import org.jboss.seam.wiki.core.model.WikiUpload;
 
-public class Importer implements Comparable {
+import javax.persistence.EntityManager;
 
-    private Class clazz;
-    private String componentName;
-    private String[] handledMimeTypes;
-    private String[] handledExtensions;
-    private String description;
+public interface Importer {
 
-    public Importer(Class<?> clazz) {
-        this.clazz = clazz;
+    public boolean handleImport(EntityManager entityManager, WikiUpload file);
 
-        this.componentName = clazz.getAnnotation(Name.class).value();
-        this.handledMimeTypes = clazz.getAnnotation(UploadImporter.class).handledMimeTypes();
-        this.handledExtensions = clazz.getAnnotation(UploadImporter.class).handledExtensions();
-        this.description = clazz.getAnnotation(UploadImporter.class).description();
-    }
-
-    public Class getClazz() {
-        return clazz;
-    }
-
-    public String getComponentName() {
-        return componentName;
-    }
-
-    public String[] getHandledMimeTypes() {
-        return handledMimeTypes;
-    }
-
-    public String[] getHandledExtensions() {
-        return handledExtensions;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public String toString() {
-        return "importer class: " + getClazz().getName();
-    }
-
-    public int compareTo(Object o) {
-        Importer other = (Importer)o;
-        return this.getDescription().compareTo(other.getDescription());
-    }
 }

Modified: trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/ImporterRegistry.java
===================================================================
--- trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/ImporterRegistry.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/main/org/jboss/seam/wiki/core/upload/importers/metamodel/ImporterRegistry.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -1,74 +1,62 @@
 package org.jboss.seam.wiki.core.upload.importers.metamodel;
 
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Logger;
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
 import org.jboss.seam.wiki.core.upload.importers.annotations.UploadImporter;
-import org.jboss.seam.core.Events;
-import org.jboss.seam.log.Log;
+import org.jboss.seam.wiki.util.AnnotationDeploymentHelper;
 
 import java.util.*;
 
 @Name("importerRegistry")
 @Scope(ScopeType.APPLICATION)
+ at Startup
+ at BypassInterceptors
+
 public class ImporterRegistry {
 
-    @Logger
-    static Log log;
+    private static final LogProvider log = Logging.getLogProvider(ImporterRegistry.class);
 
-    Map<String, Importer> importersByName = new HashMap<String, Importer>();
-    List<Importer> importers = new ArrayList<Importer>();
+    SortedMap<String, UploadImporter> importerComponents = new TreeMap<String, UploadImporter>();
 
-    // TODO: Fix importers
-    //@Observer("Wiki.startup")
-    public void scanForFileImporters() {
+    @Create
+    public void startup() {
 
-        log.debug("initializing file importer registry");
-        importers.clear();
-        importersByName.clear();
+        log.debug("initializing upload importer registry");
 
-        // Fire an event and let all listeners add themself into the given collection
-        Set<AbstractImporter> importerComponents = new HashSet<AbstractImporter>();
-        Events.instance().raiseEvent("Importers.addImporter", importerComponents);
+        Set<Class<Object>> importerClasses = AnnotationDeploymentHelper.getAnnotatedClasses(UploadImporter.class);
+        if (importerClasses == null) return;
 
-        log.debug("found file importer components: " + importerComponents.size());
+        for (Class<?> importerClass : importerClasses) {
 
-        for (AbstractImporter importerComponent : importerComponents) {
-            if (importerComponent.getClass().isAnnotationPresent(UploadImporter.class)) {
-                Importer importer = new Importer(importerComponent.getClass());
-                importers.add(importer);
-                importersByName.put(importer.getComponentName(), importer);
-            }
+            importerComponents.put(
+                importerClass.getAnnotation(Name.class).value(),
+                importerClass.getAnnotation(UploadImporter.class)
+            );
+            log.debug("added upload importer to registry: " + importerClass.getAnnotation(Name.class).value());
         }
-        log.debug("added file importers to registry: " + importers.size());
-
-        // Sort entities
-        Collections.sort(importers);
-
-        if (log.isTraceEnabled()) {
-            for (Importer importer : importers) {
-                log.trace(importer);
-            }
-        }
     }
 
-    public Map<String, Importer> getImportersByName() {
-        return importersByName;
+    public SortedMap<String, UploadImporter> getImporterComponents() {
+        return importerComponents;
     }
 
-    public List<Importer> getImporters() {
-        return importers;
+    public List<String> getImporterComponentNames() {
+        return new ArrayList(importerComponents.keySet());
     }
 
-    public List<Importer> getAvailableImporters(String mimeType, String extension) {
-        List<Importer> availableImporters = new ArrayList<Importer>();
-        for (Importer importer : importers) {
-            List<String> supportedMimeTypes = Arrays.asList(importer.getHandledMimeTypes());
-            List<String> supportedExtensions = Arrays.asList(importer.getHandledExtensions());
+    public List<String> getAvailableImporters(String mimeType, String extension) {
+        List<String> availableImporters = new ArrayList<String>();
+        for (Map.Entry<String, UploadImporter> importerEntry : importerComponents.entrySet()) {
+            List<String> supportedMimeTypes = Arrays.asList(importerEntry.getValue().handledMimeTypes());
+            List<String> supportedExtensions = Arrays.asList(importerEntry.getValue().handledExtensions());
             if (supportedMimeTypes.contains(mimeType) && supportedExtensions.contains(extension) ) {
-                availableImporters.add(importer);
+                availableImporters.add(importerEntry.getKey());
             }
         }
         return availableImporters;

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/blog/BlogDAO.java
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/blog/BlogDAO.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/blog/BlogDAO.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -50,7 +50,7 @@
     private String[] getWikiDocumentSQLColumnNames() {
         return new String[]{
             "doc2.NODE_ID",
-            "doc2.OBJ_VERSION", "doc2.PARENT_NODE_ID", "doc2.RATING",
+            "doc2.OBJ_VERSION", "doc2.PARENT_NODE_ID", "doc2.RATING", "doc2.MESSAGE_ID",
             "doc2.AREA_NR", "doc2.NAME", "doc2.WIKINAME", "doc2.CREATED_BY_USER_ID", "doc2.CREATED_ON", "doc2.WRITE_PROTECTED",
             "doc2.LAST_MODIFIED_BY_USER_ID", "doc2.LAST_MODIFIED_ON", "doc2.READ_ACCESS_LEVEL", "doc2.WRITE_ACCESS_LEVEL",
             "doc1.FILE_REVISION",

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQueries.hbm.xml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQueries.hbm.xml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumQueries.hbm.xml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -93,6 +93,7 @@
             c1.AREA_NR as AREA_NR,
             c1.NAME as NAME,
             c1.WIKINAME as WIKINAME,
+            c1.MESSAGE_ID as MESSAGE_ID,
             c1.CREATED_ON as CREATED_ON,
             c1.CREATED_BY_USER_ID as CREATED_BY_USER_ID,
             c1.LAST_MODIFIED_ON as LAST_MODIFIED_ON,
@@ -231,6 +232,7 @@
             doc2.AREA_NR as AREA_NR,
             doc2.NAME as NAME,
             doc2.WIKINAME as WIKINAME,
+            doc2.MESSAGE_ID as MESSAGE_ID,
             doc2.CREATED_ON as CREATED_ON,
             doc2.CREATED_BY_USER_ID as CREATED_BY_USER_ID,
             doc2.LAST_MODIFIED_ON as LAST_MODIFIED_ON,
@@ -288,6 +290,7 @@
             cl1.AREA_NR as AREA_NR,
             cl1.NAME as NAME,
             cl1.WIKINAME as WIKINAME,
+            cl1.MESSAGE_ID as MESSAGE_ID,
             cl1.CREATED_ON as CREATED_ON,
             cl1.CREATED_BY_USER_ID as CREATED_BY_USER_ID,
             cl1.LAST_MODIFIED_ON as LAST_MODIFIED_ON,
@@ -337,7 +340,7 @@
                 limit 1
           )
         group by
-            cl1.OBJ_VERSION, cl1.RATING, cl1.AREA_NR, cl1.NAME, cl1.WIKINAME, cl1.CREATED_ON, cl1.CREATED_BY_USER_ID, cl1.LAST_MODIFIED_ON,
+            cl1.OBJ_VERSION, cl1.RATING, cl1.AREA_NR, cl1.NAME, cl1.WIKINAME, cl1.MESSAGE_ID, cl1.CREATED_ON, cl1.CREATED_BY_USER_ID, cl1.LAST_MODIFIED_ON,
             cl1.LAST_MODIFIED_BY_USER_ID, cl1.WRITE_ACCESS_LEVEL, cl1.READ_ACCESS_LEVEL, cl1.WRITE_PROTECTED, cl1.PARENT_NODE_ID,
             cl0.SUBJECT, cl0.FROM_USER_NAME, cl0.FROM_USER_EMAIL, cl0.FROM_USER_HOMEPAGE, cl0.USE_WIKI_TEXT, cl0.NS_LEFT, cl0.NS_RIGHT, cl0.NS_THREAD,
 

Added: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumTopicsPreferences.java
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumTopicsPreferences.java	                        (rev 0)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/ForumTopicsPreferences.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.wiki.plugin.forum;
+
+import org.jboss.seam.wiki.preferences.annotations.Preferences;
+import org.jboss.seam.wiki.preferences.annotations.PreferenceProperty;
+import org.jboss.seam.wiki.preferences.PreferenceVisibility;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.Email;
+
+/**
+ * @author Christian Bauer
+ */
+ at Preferences(
+    name = "ForumTopics",
+    description = "#{messages['forum.topics.preferences.description']}",
+    mappedTo = "forum.topics"
+)
+public class ForumTopicsPreferences {
+
+    @PreferenceProperty(
+        description = "#{messages['forum.topics.preferences.property.mailingList']}",
+        visibility = {PreferenceVisibility.INSTANCE},
+        editorIncludeName = "AdaptiveTextInput"
+    )
+    @Length(min = 4, max = 255)
+    @Email
+    private String mailingList;
+
+    public String getMailingList() {
+        return mailingList;
+    }
+}

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/TopicHome.java	2008-07-01 10:02:54 UTC (rev 8430)
@@ -11,20 +11,18 @@
 import org.jboss.seam.wiki.core.model.WikiDirectory;
 import org.jboss.seam.wiki.core.model.WikiDocument;
 import org.jboss.seam.wiki.core.model.WikiTextMacro;
-import org.jboss.seam.wiki.core.model.WikiFile;
 import org.jboss.seam.wiki.core.ui.WikiRedirect;
 import org.jboss.seam.wiki.core.plugin.PluginRegistry;
-import org.jboss.seam.wiki.core.wikitext.editor.WikiTextEditor;
 import org.jboss.seam.wiki.preferences.Preferences;
 
 import static org.jboss.seam.international.StatusMessage.Severity.INFO;
-import org.hibernate.validator.InvalidStateException;
-import org.hibernate.validator.InvalidValue;
 
 @Name("topicHome")
 @Scope(ScopeType.CONVERSATION)
 public class TopicHome extends DocumentHome {
 
+    public static final String TOPIC_LIST_MACRO             = "forumTopics";
+    public static final String TOPIC_LIST_MACRO_ML_PARAM    = "mailingList";
     public static final String TOPIC_NOTIFY_ME_MACRO        = "forumNotifyReplies";
     public static final String TOPIC_NOTIFY_LIST_TEMPLATE   = "/mailtemplates/forumNotifyTopicToList.xhtml";
 
@@ -37,6 +35,7 @@
     private boolean showForm = false;
     private boolean sticky = false;
     private boolean notifyReplies = false;
+    private String mailingList;
 
     /* -------------------------- Basic Overrides ------------------------------ */
 
@@ -58,6 +57,8 @@
         Boolean preferencesNotifyReplies = Preferences.instance().get(ForumPreferences.class).getNotifyMeOfReplies();
         notifyReplies = preferencesNotifyReplies != null && preferencesNotifyReplies;
 
+        // TODO: mailingList = getMailingListFromTopicMacro();
+
         textEditor.setKey("topic");
         textEditor.setAllowPlaintext(true);// Topics can be plain text, regular documents can't
     }
@@ -92,10 +93,18 @@
         if (outcome != null) {
 
             // Notify forum mailing list
-            String notificationMailingList =
+            /* TODO
+            if (mailingList != null) {
+                getLog().debug("sending topic e-mail to list: " + mailingList);
+                Renderer.instance().render(
+                    PluginRegistry.instance().getPlugin("forum").getPackageThemePath()+TOPIC_NOTIFY_LIST_TEMPLATE
+                );
+            }
+            */
+            String mailingList =
                     Preferences.instance().get(ForumPreferences.class).getNotificationMailingList();
-            if (notificationMailingList != null) {
-                getLog().debug("sending topic notification e-mail to forum list: " + notificationMailingList);
+            if (mailingList != null) {
+                getLog().debug("sending topic notification e-mail to forum list: " + mailingList);
                 Renderer.instance().render(
                     PluginRegistry.instance().getPlugin("forum").getPackageThemePath()+TOPIC_NOTIFY_LIST_TEMPLATE
                 );
@@ -170,6 +179,14 @@
         return "forumTopicFeedEntryManager";
     }
 
+    public String getMailingListFromTopicMacro() {
+        for (WikiTextMacro macro : currentDocument.getContentMacros()) {
+            if (macro.getName().equals(TOPIC_LIST_MACRO))
+                return macro.getParamValue(TOPIC_LIST_MACRO_ML_PARAM);
+        }
+        return null;
+    }
+
     /* -------------------------- Public Features ------------------------------ */
 
     public boolean isShowForm() {
@@ -196,6 +213,14 @@
         this.notifyReplies = notifyReplies;
     }
 
+    public String getMailingList() {
+        return mailingList;
+    }
+
+    public String getMailingListName() {
+        return currentDocument.getName();
+    }
+
     @Begin(flushMode = FlushModeType.MANUAL, join = true)
     public void newTopic() {
         initEditor(false);

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/i18n/messages_forum_en.properties
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/i18n/messages_forum_en.properties	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/i18n/messages_forum_en.properties	2008-07-01 10:02:54 UTC (rev 8430)
@@ -11,6 +11,8 @@
 
 forum.topics.label=Forum Topics
 forum.topics.description=List of all topics in a forum directory
+forum.topics.preferences.description=Plugin: Forum Topics
+forum.topics.preferences.property.mailingList=Send and receive topics to and from this mailinglist
 
 forum.posting.label=Forum Posting
 forum.posting.description=Turns a WikiDocument into a regular forum posting

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/templates/topicForm.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -68,11 +68,11 @@
                         <ui:param name="baseDocument" value="#{topicHome.instance}"/>
                         <ui:param name="baseDirectory" value="#{currentDirectory}"/>
                     </ui:include>
-
+<!--
                     <s:decorate id="verifyCaptchaEntry" template="/includes/captchaEntry.xhtml">
                         <ui:param name="rendered" value="#{!identity.loggedIn}"/>
                     </s:decorate>
-
+-->
                 </s:div>
 
                 <div class="formControls">

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyReplyToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyReplyToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyReplyToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,16 +4,15 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(replyHome.instance.id, replyHome.instance.name)}">
+            messageId="#{replyHome.instance.messageId}">
 
-    <m:header name="In-Reply-To" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>
-    <m:header name="References" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>
+    <m:header name="In-Reply-To" value="#{currentDocument.messageId}"/>
+    <m:header name="References" value="#{currentDocument.messageId}"/>
 
     <m:header name="X-Sent-From" value="JBoss Seam" />
     <m:header name="Precedence" value="list"/>
 
     <m:header name="From" value="#{replyHome.instance.createdBy.fullname} &lt;do-not-reply at jboss.com>"/>
-
     <m:to name="LaceWiki Forums List">#{preferences.get('Forum').notificationMailingList}</m:to>
 
     <m:subject>[LaceWiki Forums] #{replyHome.instance.subject}</m:subject>

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyTopicToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyTopicToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/default/mailtemplates/forumNotifyTopicToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,13 +4,13 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(topicHome.instance.id, topicHome.instance.name)}">
+            messageId="#{topicHome.instance.messageId}">
 
     <m:header name="X-Sent-From" value="JBoss Seam" />
     <m:header name="Precedence" value="list"/>
 
     <m:header name="From" value="#{topicHome.instance.createdBy.fullname} &lt;do-not-reply at jboss.com>"/>
-    <m:to name="LaceWiki Forums List">#{preferences.get('Forum').notificationMailingList}</m:to>
+    <m:to name="LaceWiki Forums List">#{topicHome.mailingList}</m:to>
 
     <m:subject>[LaceWiki Forums] #{topicHome.instance.name}</m:subject>
 

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyReplyToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyReplyToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyReplyToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,10 +4,10 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(replyHome.instance.id, replyHome.instance.name)}">
+            messageId="#{replyHome.instance.messageId}">
 
-    <m:header name="In-Reply-To" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>
-    <m:header name="References" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>
+    <m:header name="In-Reply-To" value="#{currentDocument.messageId}"/>
+    <m:header name="References" value="#{currentDocument.messageId}"/>
 
     <m:header name="X-Sent-From" value="JBoss Seam" />
     <m:header name="Precedence" value="list"/>

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyTopicToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyTopicToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/inrelationto/mailtemplates/forumNotifyTopicToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,15 +4,15 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(topicHome.instance.id, topicHome.instance.name)}">
+            messageId="#{topicHome.instance.messageId}">
 
     <m:header name="X-Sent-From" value="JBoss Seam" />
     <m:header name="Precedence" value="list"/>
 
     <m:header name="From" value="#{topicHome.instance.createdBy.fullname} &lt;do-not-reply at jboss.com>"/>
-    <m:to name="LaceWiki Forums List">#{preferences.get('Forum').notificationMailingList}</m:to>
+    <m:to name="LaceWiki Forums List">#{topicHome.mailingList}</m:to>
 
-    <m:subject>[SeamFramework.org Forums] #{topicHome.instance.name}</m:subject>
+    <m:subject>[LaceWiki Forums] #{topicHome.instance.name}</m:subject>
 
     <m:body>
         <html>

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyReplyToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyReplyToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyReplyToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,7 +4,7 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(replyHome.instance.id, replyHome.instance.name)}">
+            messageId="#{replyHome.instance.messageId}">
 
     <m:header name="In-Reply-To" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>
     <m:header name="References" value="#{wiki:calculateMessageId(currentDocument.id, currentDocument.name)}"/>

Modified: trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyTopicToList.xhtml
===================================================================
--- trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyTopicToList.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/src/plugin/org/jboss/seam/wiki/plugin/forum/themes/sfwkorg/mailtemplates/forumNotifyTopicToList.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -4,13 +4,13 @@
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:wiki="http://jboss.com/products/seam/wiki"
             xmlns:c="http://java.sun.com/jstl/core"
-            messageId="#{wiki:calculateMessageId(topicHome.instance.id, topicHome.instance.name)}">
+            messageId="#{topicHome.instance.messageId}">
 
     <m:header name="X-Sent-From" value="SeamFramework.org" />
     <m:header name="Precedence" value="list"/>
 
     <m:header name="From" value="#{topicHome.instance.createdBy.fullname} &lt;do-not-reply at jboss.com>"/>
-    <m:to name="SeamFramework.org Forums List">#{preferences.get('Forum').notificationMailingList}</m:to>
+    <m:to name="SeamFramework.org Forums List">#{topicHome.mailingList}</m:to>
 
     <m:subject>#{topicHome.instance.name}</m:subject>
 

Modified: trunk/examples/wiki/view/docDisplay_d.xhtml
===================================================================
--- trunk/examples/wiki/view/docDisplay_d.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/view/docDisplay_d.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -147,6 +147,7 @@
 
         <s:div rendered="#{preferences.get('Wiki').showTags and not documentHome.instance.macroPresent('hideTags') and not empty documentHome.instance.tags}"
                styleClass="documentTags undecoratedLink smallFont">
+            <!-- TODO: This should use wikiUrlRenderer for user link -->
             <s:div>
                 #{messages['lacewiki.label.docDisplay.Tags']}:&#160;
                 <ui:repeat var="tag" value="#{documentHome.tagEditor.tagsAsList}">

Added: trunk/examples/wiki/view/includes/onlineMembers.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/onlineMembers.xhtml	                        (rev 0)
+++ trunk/examples/wiki/view/includes/onlineMembers.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -0,0 +1,44 @@
+<s:fragment
+        xmlns="http://www.w3.org/1999/xhtml"
+        xmlns:ui="http://java.sun.com/jsf/facelets"
+        xmlns:h="http://java.sun.com/jsf/html"
+        xmlns:f="http://java.sun.com/jsf/core"
+        xmlns:c="http://java.sun.com/jstl/core"
+        xmlns:s="http://jboss.com/products/seam/taglib">
+
+    <h:panelGrid columns="1" cellpadding="0" cellspacing="0" border="0"
+                 styleClass="datatable topLeftBottomBorder rightBorder smallFont"
+                 headerClass="regularHeader"
+                 columnClasses="alignCenter alignBottom minorPadding">
+
+        <f:facet name="header">
+            <h:outputText value="#{messages['lacewiki.label.userList.OnlineMembers']}"/>
+            <h:outputText value="#{init.authenticatedSessionTimeoutMinutes} minutes"/>
+        </f:facet>
+
+        <h:panelGrid columns="10">
+            <c:forEach var="u" items="#{wikiHttpSessionManager.onlineMembers}">
+                <h:panelGrid columns="1">
+                    <s:div styleClass="alignCenter">
+                        <h:outputLink value="#{wikiURLRenderer.renderUserProfileURL(u)}">
+                            <s:graphicImage styleClass="userInfoPortraitImage"
+                                            rendered="#{!empty u.profile.imageContentType}"
+                                            value="#{u.profile.image}">
+                                <s:transformImageSize width="40" maintainRatio="true"/>
+                            </s:graphicImage>
+                            <h:graphicImage rendered="#{empty u.profile.imageContentType}"
+                                            style="background: #ccc;" value="#{imagePath}/blank.gif" width="40" height="40"/>
+                        </h:outputLink>
+                    </s:div>
+                    <s:div styleClass="undecoratedLink">
+                        <h:outputLink value="#{wikiURLRenderer.renderUserProfileURL(u)}">
+                            <h:outputText value="#{u.fullname}"/>
+                        </h:outputLink>
+                    </s:div>
+                </h:panelGrid>
+            </c:forEach>
+        </h:panelGrid>
+
+    </h:panelGrid>
+    
+</s:fragment>
\ No newline at end of file

Modified: trunk/examples/wiki/view/includes/onlineUsers.xhtml
===================================================================
--- trunk/examples/wiki/view/includes/onlineUsers.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/view/includes/onlineUsers.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -8,13 +8,20 @@
     <h:panelGrid styleClass="onlineUsersPanel" columns="4"
                  cellpadding="0" cellspacing="0" border="0">
 
-        <h:outputText styleClass="onlineLabel" value="Online:&#160;"/>
+        <h:outputText styleClass="onlineLabel" value="#{messages['lacewiki.label.userList.Online']}:&#160;"/>
 
         <s:fragment rendered="#{wikiHttpSessionManager.numberOfOnlineMembers > 0}">
-            <s:span styleClass="onlineValue">
-                <h:outputText value="#{wikiHttpSessionManager.numberOfOnlineMembers}"/>
-                <h:outputText value="&#160;#{wikiHttpSessionManager.numberOfOnlineMembers > 1 ? 'Members' : 'Member'}"/>
-            </s:span>
+            <s:link styleClass="link"
+                    view="/userList_#{skin}.xhtml" propagation="none">
+                <s:span styleClass="onlineValue">
+                    <h:outputText value="#{wikiHttpSessionManager.numberOfOnlineMembers}"/>
+                    <h:outputText value="&#160;#{wikiHttpSessionManager.numberOfOnlineMembers > 1
+                                                ? messages['lacewiki.label.userList.Members']
+                                                : messages['lacewiki.label.userList.Member']}"/>
+                    <h:outputText value="&#160;#{messages['lacewiki.label.userList.Of']}&#160;"/>
+                    <h:outputText value="#{wikiHttpSessionManager.totalMembers}"/>
+                </s:span>
+            </s:link>
         </s:fragment>
 
         <h:outputText styleClass="onlineSeparator" value="&#160;|&#160;"
@@ -24,7 +31,9 @@
         <s:fragment rendered="#{wikiHttpSessionManager.numberOfOnlineGuests > 0}">
             <s:span styleClass="onlineValue">
                 <h:outputText value="#{wikiHttpSessionManager.numberOfOnlineGuests}"/>
-                <h:outputText value="&#160;#{wikiHttpSessionManager.numberOfOnlineGuests> 1 ? 'Guests' : 'Guest'}"/>
+                <h:outputText value="&#160;#{wikiHttpSessionManager.numberOfOnlineGuests> 1
+                                             ? messages['lacewiki.label.userList.Guests']
+                                             : messages['lacewiki.label.userList.Guest']}"/>
             </s:span>
         </s:fragment>
 

Modified: trunk/examples/wiki/view/themes/default/css/template.css
===================================================================
--- trunk/examples/wiki/view/themes/default/css/template.css	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/view/themes/default/css/template.css	2008-07-01 10:02:54 UTC (rev 8430)
@@ -289,6 +289,7 @@
     font-weight: normal;
     vertical-align: top;
     background-color: #362f2d;
+    background-image: none;
     font-family: Verdana, Arial, Helvetica, sans-serif;
 }
 

Modified: trunk/examples/wiki/view/uploadEdit_d.xhtml
===================================================================
--- trunk/examples/wiki/view/uploadEdit_d.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/view/uploadEdit_d.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -92,6 +92,19 @@
                         </div>
                     </div>
 
+                    <s:div styleClass="entry">
+                        <div class="label">#{messages['lacewiki.label.uploadEdit.Importers']}:</div>
+                        <div class="input">
+                            <h:selectOneMenu id="importerSelect" value="#{uploadHome.importer}" tabindex="1"
+                                             onchange="if (jQuery('#uploadEditForm\\:importerSelect')[0].selectedIndex > 0 ) { jQuery('#uploadEditForm\\:import').show(); } else { jQuery('#uploadEditForm\\:import').hide(); }">
+                                <s:selectItems value="#{uploadHome.availableImporters}"
+                                               var="importerName"
+                                               label="#{messages[importerRegistry.importerComponents[importerName].description()]}"
+                                               noSelectionLabel="#{messages['lacewiki.label.uploadEdit.ImportNoSelection']}"/>
+                            </h:selectOneMenu>
+                        </div>
+                    </s:div>
+
                     <s:div id="uploadControl" styleClass="sessionEventTrigger">
                         <s:decorate id="uploadDecorate" template="includes/formFieldDecorate.xhtml">
                             <ui:define name="label">
@@ -126,6 +139,13 @@
                     <div class="label">&#160;</div>
                     <div class="input">
 
+                        <h:commandLink id="import" action="#{uploadHome.importInstance}"
+                                       rendered="#{uploadHome.managed}"
+                                       tabindex="1"
+                                       style="display:none;" styleClass="button sessionEventTrigger">
+                            <h:outputText escape="false" styleClass="buttonLabel" value="#{messages['lacewiki.button.uploadEdit.Import']}"/>
+                        </h:commandLink>
+
                         <h:commandLink id="save" action="#{uploadHome.persist}"
                                        rendered="#{!uploadHome.managed}"
                                        tabindex="1" accesskey="#{messages['lacewiki.button.uploadEdit.Save.accesskey']}"

Modified: trunk/examples/wiki/view/userList_d.xhtml
===================================================================
--- trunk/examples/wiki/view/userList_d.xhtml	2008-06-30 13:15:47 UTC (rev 8429)
+++ trunk/examples/wiki/view/userList_d.xhtml	2008-07-01 10:02:54 UTC (rev 8430)
@@ -30,6 +30,10 @@
 
 <ui:define name="content">
 
+    <s:div styleClass="box" style="margin-top:10px;">
+        <ui:include src="includes/onlineMembers.xhtml"/>
+    </s:div>
+
     <script type="text/javascript">jQuery(function() {
         jQuery(".contextMenu").show().menu({offsetLeft: 20});
     })</script>




More information about the seam-commits mailing list