[jboss-svn-commits] JBL Code SVN: r5432 - in labs/shotoku/trunk: shotoku-base/src/java/org/jboss/shotoku/tools shotoku-feeds/src/java/org/jboss/shotoku/feeds shotoku-feeds/src/java/org/jboss/shotoku/feeds/data shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special shotoku-feeds/src/java/org/jboss/shotoku/feeds/portlet shotoku-feeds/src/java/org/jboss/shotoku/feeds/service shotoku-feeds/src/web/WEB-INF shotoku-tags/src/java/org/jboss/shotoku/tags/test shotoku-user/src/java/org/jboss/shotoku/user

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Aug 3 09:47:50 EDT 2006


Author: adamw
Date: 2006-08-03 09:47:45 -0400 (Thu, 03 Aug 2006)
New Revision: 5432

Added:
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/FeedParsing.java
   labs/shotoku/trunk/shotoku-tags/src/java/org/jboss/shotoku/tags/test/TagsServiceMultiThreadTest.java
Modified:
   labs/shotoku/trunk/shotoku-base/src/java/org/jboss/shotoku/tools/Tools.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/CommentsService.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/CommentableFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/InformaBasedFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/RomeBasedFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/ShotokuCommentableFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/DummyFeedEntries.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/FeedEntry.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/CommentFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/ConcreteCommentFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/Rss2CommentFeed.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/portlet/FeedsViewPortlet.java
   labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/service/CommentsServiceImpl.java
   labs/shotoku/trunk/shotoku-feeds/src/web/WEB-INF/web.xml
   labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/Group.java
   labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/User.java
Log:
http://jira.jboss.org/jira/browse/JBSHOTOKU-38

Modified: labs/shotoku/trunk/shotoku-base/src/java/org/jboss/shotoku/tools/Tools.java
===================================================================
--- labs/shotoku/trunk/shotoku-base/src/java/org/jboss/shotoku/tools/Tools.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-base/src/java/org/jboss/shotoku/tools/Tools.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -337,6 +337,10 @@
      * @return True iff the given link is an outside link.
      */
     public static boolean isOutsideLink(String link) {
+        if (link == null) {
+            return false;
+        }
+        
         link = link.trim();
         return link.startsWith("http:") || link.startsWith("ftp:")
                 || link.startsWith("https:") || link.startsWith("mailto:")

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/CommentsService.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/CommentsService.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/CommentsService.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -21,6 +21,8 @@
     public String getCommentFeedLink(String feedName,
                                      String feedElement, String feedType);
 
+    public String getCommentFeedName(String feedName, String feedElement);
+
     public Directory getCommentsDirectory(Node commentedNode)
             throws ResourceDoesNotExist;
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/CommentableFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/CommentableFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/CommentableFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -10,12 +10,72 @@
  * @author Adam Warski (adamw at aster.pl)
  */
 public interface CommentableFeed extends NormalFeed {
+    /**
+     * Checks if commenting is at all available for this feed.
+     * @return True iff commenting of feed entries is at all
+     * available for this feed.
+     */
     public boolean getCommentsEnabled();
+
+    /**
+     * Checks if a specified user can add comments to entries
+     * of this feed.
+     * @param username Name of the user to check.
+     * @return True iff the specified user can add comments to
+     * entries of this feed.
+     */
+    public boolean getUserCanAddComments(String username);
+
+    /**
+     * Checks if comments to entries of this feed are moderated, that is,
+     * need to be approved before being visible in the comments feed.
+     * @return True if comments to entries of this feed are moderated.
+     */
     public boolean getCommentsModerated();
-    public List<String> getGroupsAllowedToModerateComments();
-    public boolean getFeedElementExists(String feedElement);
-    public void addComment(String feedElement, String username, String title,
+
+    /**
+     * Checks if a specified user can moderate comments to entries
+     * of this feed.
+     * @param username Name of the user to check.
+     * @return True iff the specified user can moderate comments to
+     * entries of this feed.
+     */
+    public boolean getUserModerateComments(String username);
+
+    /**
+     * Checks if a specified feed entry exists.
+     * @param feedEntry Identifier of the entry to check.
+     * @return True if a feed entry identified by <code>feedEntry</code>
+     * exists.
+     */
+    public boolean getFeedEntryExists(String feedEntry);
+
+    /**
+     * Adds a comment to a specified feed entry.
+     * @param feedEntry Identifier of an entry to which the comment should
+     * be added. What <code>feedEntry</code> is depends on the comments
+     * implementation. Most typically it is the guid.
+     * @param username Name of the user which adds the comments.
+     * @param title
+     * @param content
+     * @param userIp
+     * @throws UnauthorizedToCommentException
+     * @throws CommentsNotAvialableException
+     * @throws FeedDoesNotExistException
+     */
+    public void addComment(String feedEntry, String username, String title,
                            String content, String userIp)
             throws UnauthorizedToCommentException,
             CommentsNotAvialableException, FeedDoesNotExistException;
+
+    /**
+     * Gets a feed of comments to a specific feed element.
+     * @param feedEntry Identifier of an entry for which the comments should
+     * be read. What <code>feedEntry</code> is depends on the comments
+     * implementation. Most typically it is the guid.
+     * @return A feed of comments to a specified element.
+     * @throws FeedDoesNotExistException
+     */
+    public Feed getCommentFeed(String feedEntry)
+            throws FeedDoesNotExistException;
 }

Added: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/FeedParsing.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/FeedParsing.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/FeedParsing.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -0,0 +1,89 @@
+package org.jboss.shotoku.feeds.data;
+
+import org.jboss.shotoku.feeds.data.model.FeedEntries;
+import org.jboss.shotoku.feeds.data.model.FeedEntry;
+import org.jboss.shotoku.feeds.rome.CommentRssModule;
+import org.jboss.shotoku.tools.Tools;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.SyndEntry;
+import de.nava.informa.impl.basic.ChannelBuilder;
+import de.nava.informa.core.ChannelIF;
+import de.nava.informa.core.ItemIF;
+import de.nava.informa.core.ParseException;
+import de.nava.informa.parsers.FeedParser;
+
+/**
+ * @author Adam Warski (adamw at aster.pl)
+ */
+public class FeedParsing {
+    public static FeedEntries parseWithRome(InputStream is)
+            throws IOException, FeedException {
+        // Parsing the generated feed.
+        SyndFeedInput input = new SyndFeedInput();
+        SyndFeed inFeed = input.build(new XmlReader(is));
+
+        List<FeedEntry> entries = new ArrayList<FeedEntry>();
+
+        String defaultAuthor = inFeed.getAuthor();
+        for (Object o : inFeed.getEntries()) {
+            SyndEntry entry = (SyndEntry) o;
+
+            CommentRssModule commRssModule = (CommentRssModule)
+                    entry.getModule(
+                            "http://wellformedweb.org/CommentAPI/");
+            String commentsRss = null;
+            if (commRssModule != null) {
+                commentsRss = commRssModule.getCommentRss();
+                if (commentsRss != null) {
+                    commentsRss = commentsRss.trim();
+                }
+            }
+
+            String author = entry.getAuthor();
+            entries.add(new FeedEntry(
+                    Tools.isEmpty(author) ? defaultAuthor : author,
+                    entry.getTitle(), entry.getDescription().getValue(),
+                    entry.getPublishedDate(), entry.getLink(),
+                    entry.getUri(), commentsRss));
+        }
+
+        return new FeedEntries(inFeed.getAuthor(), inFeed.getTitle(),
+                inFeed.getDescription(), inFeed.getPublishedDate(),
+                inFeed.getLink(), entries);
+    }
+
+    public static FeedEntries parseWithInforma(InputStream is)
+            throws IOException, ParseException {
+        // Parsing the generated feed.
+        ChannelBuilder builder = new ChannelBuilder();
+        ChannelIF childChannel =
+                FeedParser.parse(builder, is);
+
+        List<FeedEntry> entries = new ArrayList<FeedEntry>();
+
+        String defaultAuthor = childChannel.getCreator();
+        for (Object o : childChannel.getItems()) {
+            ItemIF nextItem = (ItemIF) o;
+            String author = nextItem.getCreator();
+            entries.add(new FeedEntry(
+                    Tools.isEmpty(author) ? defaultAuthor : author,
+                    nextItem.getTitle(), nextItem.getDescription(),
+                    nextItem.getDate(), nextItem.getLink().toString(),
+                    nextItem.getGuid().getLocation(), ""));
+        }
+
+        return new FeedEntries(childChannel.getCreator(),
+                childChannel.getTitle(), childChannel.getDescription(),
+                childChannel.getPubDate(),
+                "", entries);
+    }
+}

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/InformaBasedFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/InformaBasedFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/InformaBasedFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -14,6 +14,7 @@
 import de.nava.informa.utils.ItemComparator;
 import org.jboss.shotoku.feeds.data.model.FeedEntries;
 import org.jboss.shotoku.feeds.data.model.FeedEntry;
+import org.jboss.shotoku.feeds.data.model.DummyFeedEntries;
 
 public abstract class InformaBasedFeed extends FileBasedFeed {
     public InformaBasedFeed(String id, String name, String displayName,
@@ -73,29 +74,10 @@
 
     public FeedEntries getFeedEntries() {
         try {
-            // Parsing the generated feed.
-            ChannelBuilder builder = new ChannelBuilder();
-            ChannelIF childChannel =
-                    FeedParser.parse(builder, getInputStream());
-
-            List<FeedEntry> entries = new ArrayList<FeedEntry>();
-
-            for (Object o : childChannel.getItems()) {
-                ItemIF nextItem = (ItemIF) o;
-                entries.add(new FeedEntry(nextItem.getCreator(),
-                        nextItem.getTitle(), nextItem.getDescription(),
-                        nextItem.getDate(), nextItem.getLink().toString(),
-                        nextItem.getGuid().getLocation(), ""));
-            }
-
-            return new FeedEntries(childChannel.getCreator(),
-                    childChannel.getTitle(), childChannel.getDescription(),
-                    childChannel.getPubDate(),
-                    "", entries);
+            return FeedParsing.parseWithInforma(getInputStream());
         } catch (Exception e) {
-            return new FeedEntries("", "Error generating feed entries",
-                    e.getMessage(), new Date(), "",
-                    new ArrayList<FeedEntry>());
+            return new DummyFeedEntries("Error generating feed entries",
+                    e.getMessage());
         }
     }
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/RomeBasedFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/RomeBasedFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/RomeBasedFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -34,6 +34,7 @@
 import com.sun.syndication.io.XmlReader;
 import org.jboss.shotoku.feeds.data.model.FeedEntries;
 import org.jboss.shotoku.feeds.data.model.FeedEntry;
+import org.jboss.shotoku.feeds.data.model.DummyFeedEntries;
 import org.jboss.shotoku.feeds.rome.CommentRssModule;
 
 public abstract class RomeBasedFeed extends FileBasedFeed {
@@ -111,39 +112,10 @@
 
     public FeedEntries getFeedEntries() {
         try {
-            // Parsing the generated feed.
-            SyndFeedInput input = new SyndFeedInput();
-            SyndFeed inFeed = input.build(new XmlReader(getInputStream()));
-
-            List<FeedEntry> entries = new ArrayList<FeedEntry>();
-
-            for (Object o : inFeed.getEntries()) {
-                SyndEntry entry = (SyndEntry) o;
-
-                CommentRssModule commRssModule = (CommentRssModule)
-                        entry.getModule(
-                                "http://wellformedweb.org/CommentAPI/");
-                String commentsRss = null;
-                if (commRssModule != null) {
-                    commentsRss = commRssModule.getCommentRss();
-                    if (commentsRss != null) {
-                        commentsRss = commentsRss.trim();
-                    }
-                }
-
-                entries.add(new FeedEntry(entry.getAuthor(),
-                        entry.getTitle(), entry.getDescription().getValue(),
-                        entry.getPublishedDate(), entry.getLink(),
-                        entry.getUri(), commentsRss));
-            }
-
-            return new FeedEntries(inFeed.getAuthor(), inFeed.getTitle(),
-                    inFeed.getDescription(), inFeed.getPublishedDate(),
-                    inFeed.getLink(), entries);
+            return FeedParsing.parseWithRome(getInputStream());
         } catch (Exception e) {
-            return new FeedEntries("", "Error generating feed entries",
-                    e.getMessage(), new Date(), "",
-                    new ArrayList<FeedEntry>());
+            return new DummyFeedEntries("Error generating feed entries",
+                    e.getMessage());
         }
     }
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/ShotokuCommentableFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/ShotokuCommentableFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/ShotokuCommentableFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -2,6 +2,8 @@
 
 import org.jboss.shotoku.NodeList;
 import org.jboss.shotoku.Node;
+import org.jboss.shotoku.user.UserNotFoundException;
+import org.jboss.shotoku.tags.tools.UserTools;
 import org.jboss.shotoku.feeds.data.model.FeedEntries;
 import org.jboss.shotoku.feeds.tools.FeedsTools;
 import org.jboss.shotoku.feeds.tools.FeedDefAttributes;
@@ -31,6 +33,7 @@
     private List<String> groupsAllowedToModerate;
     private boolean commentsModerated;
     private NodeList feedElements;
+    private boolean requireLoggedInUsers;
 
     public ShotokuCommentableFeed(NormalFeed nf, NodeList feedElements) {
         this.nf = nf;
@@ -43,6 +46,8 @@
         groupsAllowedToModerate = Arrays.asList(
                 Tools.toStringNotNull(
                         getAttributes().get("moderators")).split("[,]"));
+        requireLoggedInUsers = Tools.isTrue(
+                Tools.toString(getAttributes().get("requireLoginToComment")));
     }
 
     /*
@@ -57,11 +62,21 @@
         return commentsModerated;
     }
 
-    public List<String> getGroupsAllowedToModerateComments() {
-        return groupsAllowedToModerate;
+    public boolean getUserModerateComments(String username) {
+        for (String group : groupsAllowedToModerate) {
+            try {
+                if (UserTools.getService().getUser(username).isInGroup(group)) {
+                    return true;
+                }
+            } catch (UserNotFoundException e) {
+                return false;
+            }
+        }
+
+        return false;
     }
 
-    public boolean getFeedElementExists(String feedElement) {
+    public boolean getFeedEntryExists(String feedElement) {
         return getNodeForFeedElement(feedElement) != null;
     }
 
@@ -76,10 +91,8 @@
         return null;
     }
 
-    public void addComment(String feedElement, String username, String title,
-                           String content, String userIp)
-            throws UnauthorizedToCommentException,
-            CommentsNotAvialableException, FeedDoesNotExistException {
+    private String prepareFeedElement(String feedElement)
+            throws FeedDoesNotExistException {
         // It may be possible that the feed element is a full URL,
         // so we have to cut off the unnecessary part.
         if (Tools.isOutsideLink(feedElement)) {
@@ -93,14 +106,34 @@
             }
         }
 
+        return feedElement;
+    }
+
+    public void addComment(String feedElement, String username, String title,
+                           String content, String userIp)
+            throws UnauthorizedToCommentException,
+            CommentsNotAvialableException, FeedDoesNotExistException {
         FeedsTools.getCommentsService().addComment(nf.getId(),
-                nf.getName(), feedElement, nf.getType(), username,
-                title, content, userIp);
+                nf.getName(), prepareFeedElement(feedElement), nf.getType(),
+                username, title, content, userIp);
     }
 
+    public Feed getCommentFeed(String feedElement)
+            throws FeedDoesNotExistException {
+        return FeedsTools.getService().getFeed(nf.getId(),
+                FeedsTools.getCommentsService().getCommentFeedName(
+                        nf.getName(), prepareFeedElement(feedElement)),
+                nf.getType());
+    }
+
+    public boolean getUserCanAddComments(String username) {
+        return commentsEnabled && ((!requireLoggedInUsers) ||
+                username != null);
+    }
+
     /*
-     * Delegating all non-comments methods.
-     */
+    * Delegating all non-comments methods.
+    */
 
     public Map<String, Object> getAttributes() {
         return nf.getAttributes();

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/DummyFeedEntries.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/DummyFeedEntries.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/DummyFeedEntries.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -11,4 +11,8 @@
     public DummyFeedEntries() {
         super("", "", "", null, "", new ArrayList<FeedEntry>());
     }
+
+    public DummyFeedEntries(String title, String description) {
+        super("", title, description, null, "", new ArrayList<FeedEntry>());
+    }
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/FeedEntry.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/FeedEntry.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/model/FeedEntry.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -1,6 +1,8 @@
 package org.jboss.shotoku.feeds.data.model;
 
 import java.util.Date;
+import java.util.Locale;
+import java.text.DateFormat;
 
 /**
  * @author Adam Warski (adamw at aster.pl)
@@ -42,6 +44,16 @@
         return created;
     }
 
+    public String getCreatedDate() {
+        return DateFormat.getDateInstance(DateFormat.FULL,
+                Locale.getDefault()).format(created);
+    }
+
+    public String getCreatedTime() {
+        return DateFormat.getTimeInstance(DateFormat.SHORT,
+                Locale.getDefault()).format(created);
+    }
+
     public String getLink() {
         return link;
     }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/CommentFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/CommentFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/CommentFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -62,8 +62,7 @@
         }
     }
 
-    public void write(OutputStream os, String fullName,
-                      HttpServletRequest request) throws IOException {
+    public void write(OutputStream os, String fullName) throws IOException {
         // Getting the feed for which elements feed should be generated
         // and checking if everything is ok.
         check(fullName.length() >= nameLength+1);
@@ -73,7 +72,7 @@
         int lastSlash = info.lastIndexOf('/');
         check(lastSlash != -1);
         String feedName = info.substring(0, lastSlash);
-        String feedElement = info.substring(lastSlash+1);
+        String feedElement = Tools.decodeURL(info.substring(lastSlash+1));
 
         CommentableFeed feed = FeedsTools.getService().getCommentableFeed(
                 getId(), feedName, getType());
@@ -86,7 +85,7 @@
         //noinspection ConstantConditions
         ShotokuCommentableFeed scf = (ShotokuCommentableFeed) feed;
         Node commentedNode = scf.getNodeForFeedElement(feedElement);
-
+        
         check(commentedNode != null);
 
         NodeList comments;
@@ -140,10 +139,10 @@
         }
     }
 
-    public void write(HttpServletResponse response, String fullName,
-                      HttpServletRequest request) throws IOException {
+    public void write(HttpServletResponse response, String fullName)
+            throws IOException {
         response.setContentType(getContentType());
-        write(response.getOutputStream(), fullName, request);
+        write(response.getOutputStream(), fullName);
     }
 
     public void write(OutputStream os, HttpServletRequest request) throws IOException {
@@ -161,4 +160,6 @@
     public FeedEntries getFeedEntries() {
         throw new RuntimeException("Can't get entries of a special feed");
     }
+
+    public abstract FeedEntries getFeedEntries(String fullName);
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/ConcreteCommentFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/ConcreteCommentFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/ConcreteCommentFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -24,14 +24,18 @@
 
     public void write(OutputStream os, HttpServletRequest request)
             throws IOException {
-        commentFeed.write(os, fullName, request);
+        commentFeed.write(os, fullName);
     }
 
     public void write(HttpServletResponse response, HttpServletRequest request)
             throws IOException {
-        commentFeed.write(response, fullName, request);
+        commentFeed.write(response, fullName);
     }
 
+    public FeedEntries getFeedEntries() {
+        return commentFeed.getFeedEntries(fullName);
+    }
+
     public String getName() {
         return commentFeed.getName();
     }
@@ -52,10 +56,6 @@
         return commentFeed.getAttributes();
     }
 
-    public FeedEntries getFeedEntries() {
-        return commentFeed.getFeedEntries();
-    }
-
     public String getId() {
         return commentFeed.getId();
     }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/Rss2CommentFeed.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/Rss2CommentFeed.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/data/special/Rss2CommentFeed.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -2,8 +2,13 @@
 
 import org.apache.velocity.VelocityContext;
 import org.jboss.shotoku.feeds.tools.FeedsConstants;
+import org.jboss.shotoku.feeds.data.model.FeedEntries;
+import org.jboss.shotoku.feeds.data.model.DummyFeedEntries;
+import org.jboss.shotoku.feeds.data.FeedParsing;
 
 import java.util.Map;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
 
 /**
  * @author Adam Warski (adamw at aster.pl)
@@ -17,4 +22,17 @@
     public String getContentType() {
         return FeedsConstants.RSS_CONTENT_TYPE;
     }
+
+    public FeedEntries getFeedEntries(String fullName) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            write(baos, fullName);
+
+            return FeedParsing.parseWithRome(new ByteArrayInputStream(
+                    baos.toByteArray()));
+        } catch (Exception e) {
+            return new DummyFeedEntries("Error generating and parsing " +
+                    "comment feed", e.getMessage());
+        }
+    }
 }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/portlet/FeedsViewPortlet.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/portlet/FeedsViewPortlet.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/portlet/FeedsViewPortlet.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -6,17 +6,24 @@
 import org.jboss.shotoku.feeds.tools.FeedsTools;
 import org.jboss.shotoku.feeds.tools.FeedsConstants;
 import org.jboss.shotoku.feeds.FeedsDescriptor;
+import org.jboss.shotoku.feeds.comments.UnauthorizedToCommentException;
+import org.jboss.shotoku.feeds.comments.CommentsNotAvialableException;
+import org.jboss.shotoku.feeds.comments.FeedDoesNotExistException;
 import org.jboss.shotoku.feeds.data.Feed;
+import org.jboss.shotoku.feeds.data.CommentableFeed;
 import org.jboss.shotoku.feeds.data.model.FeedEntry;
 import org.apache.log4j.Logger;
 
 import javax.portlet.*;
 import java.io.IOException;
 import java.util.List;
+import java.util.ArrayList;
 
 import static org.jboss.shotoku.feeds.tools.FeedDefAttributes.EntriesExpandMode;
 import org.jboss.shotoku.tools.Constants;
 import org.jboss.shotoku.tools.Tools;
+import org.jboss.shotoku.tags.tools.UserTools;
+import org.jboss.shotoku.user.UserNotFoundException;
 
 /**
  * @author Adam Warski (adamw at aster.pl)
@@ -40,6 +47,9 @@
     private static final String SHOW_GUID   = "showGuid";
     private static final String SHOW_ALL    = "showAll";
     private static final String SHOW_SINGLE = "showSingle";
+    private static final String COMMENTABLE = "commentable";
+    private static final String COMMENTABLE_BY_USER = "commentableByUser";
+    private static final String MESSAGES    = "messages";
 
     /**
      * Parameter where operation type is held when doing ActionRequests.
@@ -62,11 +72,17 @@
         // Previous page of entries.
         PREVIOUS,
         // Back from a single-entry view to the list view.
-        BACK
+        BACK,
+        // Add a comment.
+        ADD_COMMENT
     }
 
     private ViewFeedGetter vfg;
 
+    /**
+     * @return Id of feeds configuration (in the future, should be read from
+     * PortletConfig).
+     */
     private String getId() {
         return "default";
     }
@@ -130,9 +146,130 @@
             i++;
         }
 
-        return 0;
+        return -1;
     }
 
+    private void clearMessages(Feed feed, PortletRequest request) {
+        List<String> msgs = (List<String>) getSessionAttribute(request,
+                feed.getGuid(), MESSAGES);
+
+        if (msgs != null) {
+            msgs.clear();
+        }
+    }
+
+    private void addMessage(Feed feed, PortletRequest request,
+                            String message) {
+        List<String> msgs = (List<String>) getSessionAttribute(request,
+                feed.getGuid(), MESSAGES);
+
+        if (msgs == null) {
+            msgs = new ArrayList<String>();
+            setSessionAttribute(request, feed.getGuid(), MESSAGES, msgs);
+        }
+
+        msgs.add(message);
+    }
+
+    /*
+     * Action-processing functions.
+     */
+
+    private void processActionView(Feed feed, ActionRequest request) {
+        String guid = request.getParameter(GUID_PARAM);
+        setSessionAttribute(request, feed.getGuid(), SHOW_GUID, guid);
+
+        switch (feed.getEntriesExpandMode()) {
+            case TOP :
+                // We have to look up the entry and move the begin
+                // index.
+                int index = getFeedEntryIndex(feed.getFeedEntries().
+                        getEntries(), guid);
+                if (index == -1) {
+                    // Entry not found -> simply showing the first one.
+                    index = 0;
+                }
+                setEntriesBegin(feed.getGuid(), request, index);
+                break;
+
+            case SINGLE:
+                setSessionAttribute(request, feed.getGuid(),
+                        SHOW_SINGLE, true);
+                break;
+
+            case INPLACE:
+                // No actions needed.
+                break;
+        }
+    }
+
+    private void processActionBack(Feed feed, ActionRequest request) {
+        setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
+        setSessionAttribute(request, feed.getGuid(), SHOW_SINGLE, null);
+    }
+
+    private void processActionNext(Feed feed, ActionRequest request) {
+        setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
+        setEntriesBegin(feed.getGuid(), request, getEntriesBegin(
+                feed.getGuid(), request) +
+                feed.getEntriesVisible());
+    }
+
+    private void processActionPrevious(Feed feed, ActionRequest request) {
+        setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
+        setEntriesBegin(feed.getGuid(), request, getEntriesBegin(
+                feed.getGuid(), request) -
+                feed.getEntriesVisible());
+    }
+
+    private void processActionAddComment(CommentableFeed feed,
+                                         ActionRequest request) {
+        String title = request.getParameter("title");
+        String description = request.getParameter("description");
+        String author = request.getParameter("author");
+        String guid = Tools.toString(getSessionAttribute(request,
+                feed.getGuid(), SHOW_GUID));
+
+        if (author == null) {
+            author = request.getRemoteUser();
+        }
+
+        boolean ok = true;
+        if (Tools.isEmpty(author)) {
+            addMessage(feed, request, "Author can't be empty!");
+            ok = false;
+        }
+
+        if (Tools.isEmpty(title)) {
+            addMessage(feed, request, "Title can't be empty!");
+            ok = false;
+        }
+
+        if (Tools.isEmpty(description)) {
+            addMessage(feed, request, "Description can't be empty!");
+            ok = false;
+        }
+
+        if (!ok) {
+            return;
+        }
+
+        try {
+            feed.addComment(guid, author, title, description,
+                    request.getServerName());
+            addMessage(feed, request, "Comment added. It should appear " +
+                    "soon.");
+        } catch (UnauthorizedToCommentException e) {
+            addMessage(feed, request, "You are not authorized to add " +
+                    "comments.");
+        } catch (CommentsNotAvialableException e) {
+            addMessage(feed, request, "You cannot add comments to this feed.");
+        } catch (FeedDoesNotExistException e) {
+            addMessage(feed, request, "The feed or entry which you want to " +
+                    "comment does not exist");
+        }
+    }
+
     public void processAction(ActionRequest request,
                               ActionResponse response)
             throws PortletException, IOException {
@@ -148,50 +285,20 @@
         // If action name is correct, getting the currently displayed feed.
         Feed feed = vfg.getFeed(getId(), request);
 
+        // Clearing any previous messages.
+        clearMessages(feed, request);
+
+        // Exectuing the appropriate actions.
         switch (opType) {
-            case VIEW:
-                String guid = request.getParameter(GUID_PARAM);
-                setSessionAttribute(request, feed.getGuid(), SHOW_GUID, guid);
-
-                switch (feed.getEntriesExpandMode()) {
-                    case TOP :
-                        // We have to look up the entry and move the begin
-                        // index.
-                        setEntriesBegin(feed.getGuid(), request,
-                                getFeedEntryIndex( feed.getFeedEntries().
-                                        getEntries(), guid));
-                        break;
-
-                    case SINGLE:
-                        setSessionAttribute(request, feed.getGuid(),
-                                SHOW_SINGLE, true);
-                        break;
-
-                    case INPLACE:
-                        // No actions needed.
-                        break;
-                }
-
+            case VIEW: processActionView(feed, request); break;
+            case BACK: processActionBack(feed, request); break;
+            case NEXT: processActionNext(feed, request); break;
+            case PREVIOUS: processActionPrevious(feed, request); break;
+            case ADD_COMMENT:
+                CommentableFeed cFeed = vfg.getCommentableFeed(getId(),
+                        request);
+                if (cFeed != null) { processActionAddComment(cFeed, request); }
                 break;
-
-            case BACK:
-                setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
-                setSessionAttribute(request, feed.getGuid(), SHOW_SINGLE, null);
-                break;
-
-            case NEXT:
-                setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
-                setEntriesBegin(feed.getGuid(), request, getEntriesBegin(
-                        feed.getGuid(), request) +
-                        feed.getEntriesVisible());
-                break;
-
-            case PREVIOUS:
-                setSessionAttribute(request, feed.getGuid(), SHOW_GUID, null);
-                setEntriesBegin(feed.getGuid(), request, getEntriesBegin(
-                        feed.getGuid(), request) -
-                        feed.getEntriesVisible());
-                break;
         }
     }
 
@@ -201,6 +308,21 @@
         // Getting the feed to display.
         Feed feed = vfg.getFeed(getId(), request);
 
+        // Checking if the feed is commentable. If so, setting the
+        // necessary parameters.
+        CommentableFeed cFeed = vfg.getCommentableFeed(getId(), request);
+        if (cFeed != null && cFeed.getCommentsEnabled()) {
+            request.setAttribute(COMMENTABLE, true);
+
+            if (cFeed.getUserCanAddComments(request.getRemoteUser())) {
+                request.setAttribute(COMMENTABLE_BY_USER, true);
+            }
+        }
+
+        // Copying messages.
+        request.setAttribute(MESSAGES, getSessionAttribute(request,
+                feed.getGuid(), MESSAGES));
+
         Object showSingleObj = getSessionAttribute(request, feed.getGuid(),
                 SHOW_SINGLE);
         boolean showSingle = ((showSingleObj != null) &&
@@ -208,26 +330,58 @@
 
         response.setContentType("text/html");
         if (showSingle) {
+            // Showing a single entry.
             String guid = Tools.toStringNotNull(
                     getSessionAttribute(request, feed.getGuid(), SHOW_GUID));
 
+            // Looking up the entry to show.
             List<FeedEntry> entries = feed.getFeedEntries().getEntries();
-            request.setAttribute("entry",
-                    entries.get(getFeedEntryIndex(entries, guid)));
+            int index = getFeedEntryIndex(entries, guid);
+            if (index == -1) {
+                // If the entry is not found, simply showing the whole list.
+                showSingle = false;
+            } else {
+                FeedEntry entry = entries.get(index);
+                request.setAttribute("entry", entry);
 
-            getPortletContext().getRequestDispatcher(JSP_SINGLE).include(
-                    request, response);
-        } else {
+                if (entry.getCommentLink() != null) {
+                    // There are comments for this feed.
+
+                    if (cFeed != null) {
+                        // 1. This is a commentable feed and we can access the
+                        // comments directly.
+                        try {
+                            request.setAttribute("comments",
+                                    cFeed.getCommentFeed(guid).getFeedEntries());
+                        } catch (Exception e) {
+                            log.warn("Unable to get comments from a commentable " +
+                                    "feed.", e);
+                        }
+                    } else {
+                        // 2. Otherwise, we have to get them from the URL.
+
+                    }
+                }
+
+                getPortletContext().getRequestDispatcher(JSP_SINGLE).include(
+                        request, response);
+            }
+        }
+
+        if (!showSingle) {
+            // Showing a list of entries, possibly expanded.
             request.setAttribute("entries", feed.getFeedEntries());
 
-            // Setting posts boundaries.
+            // Setting entries boundaries.
             int begin = getEntriesBegin(feed.getGuid(), request);
             request.setAttribute(BEGIN_ATTR, begin);
             request.setAttribute(END_ATTR, begin + feed.getEntriesVisible() - 1);
 
             if (feed.getEntriesExpanded()) {
+                // Expanding all entries.
                 request.setAttribute(SHOW_ALL, true);
             } else {
+                // Expanding one entry.
                 request.setAttribute(SHOW_GUID,
                         getSessionAttribute(request, feed.getGuid(), SHOW_GUID));
             }

Modified: labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/service/CommentsServiceImpl.java
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/service/CommentsServiceImpl.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/java/org/jboss/shotoku/feeds/service/CommentsServiceImpl.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -57,8 +57,8 @@
     @PersistenceUnit
     private EntityManagerFactory emf;
 
-    public void addComment(String feedId, String feedName, String feedType,
-                           String feedElement, String username,
+    public void addComment(String feedId, String feedName, String feedElement,
+                           String feedType, String username,
                            String title, String content, String userIp)
             throws FeedDoesNotExistException, CommentsNotAvialableException,
             UnauthorizedToCommentException {
@@ -92,7 +92,7 @@
         }
 
         // Checking if the commented item exists in the content manager.
-        if (!feed.getFeedElementExists(feedElement)) {
+        if (!feed.getFeedEntryExists(feedElement)) {
             throw new FeedDoesNotExistException("Invalid feed element.");
         }
 
@@ -106,10 +106,14 @@
         }
     }
 
+    public String getCommentFeedName(String feedName, String feedElement) {
+        return "comments/" + feedName + "/" + Tools.encodeURL(feedElement);
+    }
+
     public String getCommentFeedLink(String feedName,
                                      String feedElement, String feedType) {
-        return "/feeds/comments/" + feedName + "/" +
-                Tools.encodeURL(feedElement) + "/" + feedType;
+        return "/feeds/" + getCommentFeedName(feedName, feedElement) +
+                "/" + feedType;
     }
 
     private String getCommentsDirectoryName(Node commentedNode) {

Modified: labs/shotoku/trunk/shotoku-feeds/src/web/WEB-INF/web.xml
===================================================================
--- labs/shotoku/trunk/shotoku-feeds/src/web/WEB-INF/web.xml	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-feeds/src/web/WEB-INF/web.xml	2006-08-03 13:47:45 UTC (rev 5432)
@@ -54,6 +54,6 @@
 
     <servlet-mapping>
         <servlet-name>commentsServlet</servlet-name>
-        <url-pattern>/comments/*</url-pattern>
+        <url-pattern>/commentsServlet/*</url-pattern>
     </servlet-mapping>
 </web-app>
\ No newline at end of file

Added: labs/shotoku/trunk/shotoku-tags/src/java/org/jboss/shotoku/tags/test/TagsServiceMultiThreadTest.java
===================================================================
--- labs/shotoku/trunk/shotoku-tags/src/java/org/jboss/shotoku/tags/test/TagsServiceMultiThreadTest.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-tags/src/java/org/jboss/shotoku/tags/test/TagsServiceMultiThreadTest.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -0,0 +1,8 @@
+package org.jboss.shotoku.tags.test;
+
+/**
+ * @author Adam Warski (adamw at aster.pl)
+ */
+public class TagsServiceMultiThreadTest {
+
+}

Modified: labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/Group.java
===================================================================
--- labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/Group.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/Group.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -35,4 +35,14 @@
             return new ArrayList<User>();
         }
     }
+
+    public boolean containsUser(String userName) {
+        for (User u : getUsers()) {
+            if (u.getUserName().equals(userName)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
 }

Modified: labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/User.java
===================================================================
--- labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/User.java	2006-08-03 13:38:20 UTC (rev 5431)
+++ labs/shotoku/trunk/shotoku-user/src/java/org/jboss/shotoku/user/User.java	2006-08-03 13:47:45 UTC (rev 5432)
@@ -47,4 +47,18 @@
             return new ArrayList<Group>();
         }
     }
+
+    public boolean isInGroup(String groupName) {
+        for (Group g : getGroups()) {
+            if (g.getGroupName().equals(groupName)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public String getFullName() {
+        return getGivenName() + " " + getFamilyName();
+    }
 }




More information about the jboss-svn-commits mailing list