[jboss-cvs] JBossBlog SVN: r271 - in trunk: resources/WEB-INF and 15 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Mar 25 09:24:53 EDT 2008
Author: adamw
Date: 2008-03-25 09:24:53 -0400 (Tue, 25 Mar 2008)
New Revision: 271
Added:
trunk/src/action/org/jboss/blog/tools/
trunk/src/action/org/jboss/blog/tools/PostFilterTools.java
trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuException.java
Modified:
trunk/docs/tutorial.html
trunk/resources/WEB-INF/pages.xml
trunk/src/action/org/jboss/blog/session/feed/mod/PropositionsListener.java
trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java
trunk/src/action/org/jboss/blog/session/feed/posts/AggregatedFeedPosts.java
trunk/src/action/org/jboss/blog/session/feed/update/RemoteFeedUpdate.java
trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java
trunk/src/model/org/jboss/blog/model/feed/RemoteFeed.java
trunk/src/model/org/jboss/blog/model/post/filter/AbstractRegexpFilter.java
trunk/src/model/org/jboss/blog/model/post/filter/CategoryRegexpFilter.java
trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java
trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java
trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java
trunk/src/shotoku/org/jboss/shotoku/web/ShotokuFilesystemResourceResolver.java
trunk/view/manage/aggregated/filter_add.xhtml
trunk/view/manage/feed_mod.xhtml
trunk/view/manage/remote/remote_add.xhtml
trunk/view/manage/remote/remote_mod.xhtml
trunk/view/manage/remote/remote_propose.xhtml
Log:
Modified: trunk/docs/tutorial.html
===================================================================
--- trunk/docs/tutorial.html 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/docs/tutorial.html 2008-03-25 13:24:53 UTC (rev 271)
@@ -130,10 +130,32 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">4. Viewing</h2>
+ <h2 class="title">4. Archiving</h2>
</div>
</div>
</div>
+ <p>All feeds are updated in regular intervals of time (by default, every 15 minutes). In case of a remote feed
+ it means that if there are new posts, they will get merged with the posts that are currently held in the database.
+ No posts are deleted during merging, so if a post disappears from a remote feed (because, for example, the
+ remote feed has only 10 newest posts), it won't disappear from the feeds system.</p>
+
+ <p>This has one drawback, though: if you are not entirely concious when you get home in the evening, and decide to
+ write a very sincere post, with a degree of sincerity which isn't normally viewed as good manners, and in the
+ morning realize that you should delete the post, you'll have to delete it from the feeds sytem manually.</p>
+
+ <p>If you change your post, for example alter the content, the change will be picked up and the post in the
+ database will also be updated. With one exception: when you change the published date. That will be seen as a new
+ post.</p>
+</div>
+
+<div class="sect1">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title">5. Viewing</h2>
+ </div>
+ </div>
+ </div>
<p>Users can view the feeds and posts using the webpage, or using an ATOM feed. When viewing a post (either
as part of a feed page, or as part of a post page), there is always a link back to the original post, so that
users can, for example, add comments. The URL schemes are:</p>
@@ -180,7 +202,7 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">5. Community involvement</h2>
+ <h2 class="title">6. Community involvement</h2>
</div>
</div>
</div>
@@ -200,7 +222,7 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">6. Permissions</h2>
+ <h2 class="title">7. Permissions</h2>
</div>
</div>
</div>
@@ -221,7 +243,7 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">7. Administration</h2>
+ <h2 class="title">8. Administration</h2>
</div>
</div>
</div>
@@ -260,7 +282,7 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">8. Feeds portlet</h2>
+ <h2 class="title">9. Feeds portlet</h2>
</div>
</div>
</div>
@@ -293,7 +315,7 @@
<div class="titlepage">
<div>
<div>
- <h2 class="title">9. Future improvements</h2>
+ <h2 class="title">10. Future improvements</h2>
</div>
</div>
</div>
Modified: trunk/resources/WEB-INF/pages.xml
===================================================================
--- trunk/resources/WEB-INF/pages.xml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/resources/WEB-INF/pages.xml 2008-03-25 13:24:53 UTC (rev 271)
@@ -117,7 +117,7 @@
<end-conversation />
<redirect view-id="/manage/index.xhtml" />
</navigation>
- <navigation from-action="#{remoteFeedMod.saveOnlyPostAuthorType}">
+ <navigation from-action="#{remoteFeedMod.savePartial}">
<end-conversation />
<redirect view-id="/manage/index.xhtml" />
</navigation>
Modified: trunk/src/action/org/jboss/blog/session/feed/mod/PropositionsListener.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/mod/PropositionsListener.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/action/org/jboss/blog/session/feed/mod/PropositionsListener.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -12,6 +12,7 @@
import org.jboss.blog.session.security.FeedsIdentity;
import org.jboss.blog.session.security.external.ExternalSecurityService;
import org.jboss.blog.session.configuration.ConfigurationManager;
+import org.jboss.blog.tools.StringTools;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
@@ -50,7 +51,7 @@
}
private void sendEmail(String email, String view) {
- if (email != null) {
+ if (!StringTools.isEmpty(email)) {
try {
currentEmail = email;
renderer.render(view);
Modified: trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -3,10 +3,14 @@
import org.jboss.blog.model.feed.Feed;
import org.jboss.blog.model.feed.RemoteFeed;
import org.jboss.blog.model.feed.PostAuthorType;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.model.Category;
import org.jboss.blog.session.feed.InvalidFeedTypeException;
import org.jboss.blog.session.parser.ParserException;
import org.jboss.blog.session.parser.ParserService;
import org.jboss.blog.tools.StringTools;
+import org.jboss.blog.tools.PostFilterTools;
+import org.jboss.blog.tools.validator.Regexp;
import org.jboss.seam.ScopeType;
import org.jboss.seam.core.Events;
import org.jboss.seam.annotations.In;
@@ -16,8 +20,14 @@
import org.jboss.seam.faces.FacesMessages;
import javax.faces.application.FacesMessage;
+import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import java.io.Serializable;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.regex.Pattern;
/**
* @author <a href="mailto:adam at warski.org">Adam Warski</a>
@@ -40,6 +50,15 @@
@In
private PostsValidator postsValidator;
+ private List<SelectItem> includeCategories;
+
+ private String includeCategory;
+
+ @Regexp
+ private String includeOtherCategoryRegexp;
+
+ private List<Post> visiblePosts;
+
private RemoteFeed remoteFeed;
private Feed parsedFeed;
@@ -47,6 +66,9 @@
private boolean parseOk;
private Exception parseException;
+ private final static String ALL_CATEGORIES = "ALL";
+ private final static String OTHER_CATEGORY = "OTHER";
+
public RemoteFeed getRemoteFeed() throws InvalidFeedTypeException {
if (remoteFeed == null) {
if (feedMod.getFeed() == null) {
@@ -59,6 +81,15 @@
} else {
if (feedMod.getFeed() instanceof RemoteFeed) {
remoteFeed = (RemoteFeed) feedMod.getFeed();
+ if (StringTools.isEmpty(remoteFeed.getIncludeCategoryRegexp())) {
+ includeCategory = ALL_CATEGORIES;
+ } else {
+ includeCategory = OTHER_CATEGORY;
+ includeOtherCategoryRegexp = remoteFeed.getIncludeCategoryRegexp();
+ }
+
+ initIncludeCategories();
+ finishIncludeCategories();
} else {
throw new InvalidFeedTypeException();
}
@@ -84,10 +115,79 @@
this.parseException = parseException;
}
+ public List<SelectItem> getIncludeCategories() {
+ return includeCategories;
+ }
+
+ public String getIncludeCategory() {
+ return includeCategory;
+ }
+
+ public void setIncludeCategory(String includeCategory) throws InvalidFeedTypeException {
+ this.includeCategory = includeCategory;
+ }
+
+ public String getIncludeOtherCategoryRegexp() {
+ return includeOtherCategoryRegexp;
+ }
+
+ public void setIncludeOtherCategoryRegexp(String includeOtherCategoryRegexp) throws InvalidFeedTypeException {
+ this.includeOtherCategoryRegexp = includeOtherCategoryRegexp;
+ }
+
+ public List<Post> getVisiblePosts() {
+ return visiblePosts;
+ }
+
+ private void generateIncludedCategory() throws InvalidFeedTypeException {
+ if (ALL_CATEGORIES.equals(includeCategory)) {
+ getRemoteFeed().setIncludeCategoryRegexp(null);
+ } else if (OTHER_CATEGORY.equals(includeCategory)) {
+ getRemoteFeed().setIncludeCategoryRegexp(includeOtherCategoryRegexp);
+ } else {
+ getRemoteFeed().setIncludeCategoryRegexp(
+ includeCategory == null ? null : Pattern.quote(includeCategory));
+ }
+ }
+
+ public void generateVisiblePosts() throws InvalidFeedTypeException {
+ generateIncludedCategory();
+
+ RemoteFeed remoteFeed = getRemoteFeed();
+ visiblePosts = new ArrayList<Post>();
+
+ if (parsedFeed != null) {
+ for (Post post : parsedFeed.getPosts()) {
+ if (remoteFeed.getIncludeCategoryFilter().filter(post)) {
+ visiblePosts.add(post);
+ }
+ }
+ }
+ }
+
public void unsetAccepted() throws InvalidFeedTypeException {
getRemoteFeed().setAccepted(false);
}
+ private void initIncludeCategories() {
+ includeCategories = new ArrayList<SelectItem>();
+ includeCategories.add(new SelectItem(ALL_CATEGORIES, "All categories"));
+ }
+
+ private void finishIncludeCategories() {
+ includeCategories.add(new SelectItem(OTHER_CATEGORY, "Other (regular expression) ..."));
+ }
+
+ private Set<Category> getCategoriesOfPosts(Feed feed) {
+ Set<Category> categories = new HashSet<Category>();
+
+ for (Post post : feed.getPosts()) {
+ categories.addAll(post.getCategories());
+ }
+
+ return categories;
+ }
+
public void parseFeed() throws InvalidFeedTypeException {
try {
parsedFeed = parserService.parse(getRemoteFeed().getRemoteLink());
@@ -95,7 +195,15 @@
if (!postsValidator.validatePosts(parsedFeed.getPosts(), true, "link")) {
throw new ParserException("Posts are missing some information.");
}
-
+
+ initIncludeCategories();
+ for (Category cat : getCategoriesOfPosts(parsedFeed)) {
+ includeCategories.add(new SelectItem(cat.getName(), cat.getName()));
+ }
+ finishIncludeCategories();
+
+ generateVisiblePosts();
+
setParseOk(true);
} catch (ParserException e) {
setParseException(e);
@@ -104,13 +212,17 @@
}
public void saveNew() throws InvalidFeedTypeException {
- getRemoteFeed().setAuthor(parsedFeed.getAuthor());
- getRemoteFeed().setDescription(parsedFeed.getDescription());
- getRemoteFeed().setLink(parsedFeed.getLink());
- getRemoteFeed().setTitle(parsedFeed.getTitle());
+ RemoteFeed remoteFeed = getRemoteFeed();
+ remoteFeed.setAuthor(parsedFeed.getAuthor());
+ remoteFeed.setDescription(parsedFeed.getDescription());
+ remoteFeed.setLink(parsedFeed.getLink());
+ remoteFeed.setTitle(parsedFeed.getTitle());
+ generateIncludedCategory();
+
if (getRemoteFeed().isAccepted()) {
- getRemoteFeed().setPosts(parsedFeed.getPosts());
+ remoteFeed.setPosts(PostFilterTools.filterPostList(parsedFeed.getPosts(),
+ remoteFeed.getIncludeCategoryFilter()));
}
}
@@ -118,6 +230,8 @@
public void saveExisting() throws InvalidFeedTypeException {
getRemoteFeed().setLink(parsedFeed.getLink());
+ generateIncludedCategory();
+
entityManager.flush();
facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_INFO, "blog.feed.remote.address.updated",
@@ -127,12 +241,13 @@
}
@Restrict("#{identity.hasPermission('feed', 'edit', feedMod.feed, feedMod.feed.group)}")
- public void saveOnlyPostAuthorType() throws InvalidFeedTypeException {
+ public void savePartial() throws InvalidFeedTypeException {
PostAuthorType newPostAuthorType = getRemoteFeed().getPostAuthorType();
entityManager.refresh(getRemoteFeed());
getRemoteFeed().setPostAuthorType(newPostAuthorType);
+ generateIncludedCategory();
entityManager.flush();
Modified: trunk/src/action/org/jboss/blog/session/feed/posts/AggregatedFeedPosts.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/posts/AggregatedFeedPosts.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/action/org/jboss/blog/session/feed/posts/AggregatedFeedPosts.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -7,6 +7,7 @@
import org.jboss.blog.service.FeedsService;
import org.jboss.blog.service.GroupsService;
import org.jboss.blog.tools.GeneralTools;
+import org.jboss.blog.tools.PostFilterTools;
import org.jboss.blog.model.post.PostFilter;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
@@ -30,14 +31,6 @@
@In
private AggregatedFeedStack aggregatedFeedStack;
- private void filterPostList(List<? extends RestrictedPost> posts, PostFilter filter) {
- for (Iterator<? extends RestrictedPost> iter = posts.iterator(); iter.hasNext();) {
- if (!filter.filter(iter.next())) {
- iter.remove();
- }
- }
- }
-
@SuppressWarnings("unchecked")
public List<? extends RestrictedPost> getPosts(AggregatedFeed aggregatedFeed, int from, int to) {
if (aggregatedFeedStack.contains(aggregatedFeed)) {
@@ -87,10 +80,10 @@
}
// Apply the local filters
- filterPostList(feedPosts, feedsAndFilters.get(feed));
+ PostFilterTools.filterFromPostList(feedPosts, feedsAndFilters.get(feed));
// Apply the global filters
- filterPostList(feedPosts, globalFilter);
+ PostFilterTools.filterFromPostList(feedPosts, globalFilter);
posts.addAll(feedPosts);
}
Modified: trunk/src/action/org/jboss/blog/session/feed/update/RemoteFeedUpdate.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/update/RemoteFeedUpdate.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/action/org/jboss/blog/session/feed/update/RemoteFeedUpdate.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -7,6 +7,7 @@
import org.jboss.blog.session.merge.MergeServiceBean;
import org.jboss.blog.session.update.UpdateException;
import org.jboss.blog.session.feed.lock.FeedsLocksBean;
+import org.jboss.blog.tools.PostFilterTools;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
@@ -40,7 +41,8 @@
throw new UpdateException(e);
}
- mergeService.merge(feed, parsedFeed.getPosts());
+ mergeService.merge(feed, PostFilterTools.filterPostList(parsedFeed.getPosts(),
+ feed.getIncludeCategoryFilter()));
} finally {
feedLock.unlock();
}
Modified: trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/action/org/jboss/blog/session/update/UpdateHandler.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -5,7 +5,6 @@
import org.jboss.blog.model.Group;
import org.jboss.blog.service.GroupsService;
import org.jboss.blog.session.feed.type.FeedTypes;
-import org.jboss.blog.session.feed.InvalidFeedTypeException;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
@@ -43,7 +42,7 @@
feedTypes.getFeedDao(feed).update();
} catch (UpdateException e) {
updateManager.addFeedUpdateException(feed.getName(), e);
- } catch (InvalidFeedTypeException e) {
+ } catch (Exception e) {
updateManager.addFeedUpdateException(feed.getName(), new UpdateException(e));
}
}
Added: trunk/src/action/org/jboss/blog/tools/PostFilterTools.java
===================================================================
--- trunk/src/action/org/jboss/blog/tools/PostFilterTools.java (rev 0)
+++ trunk/src/action/org/jboss/blog/tools/PostFilterTools.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -0,0 +1,33 @@
+package org.jboss.blog.tools;
+
+import org.jboss.blog.model.RestrictedPost;
+import org.jboss.blog.model.post.PostFilter;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+public class PostFilterTools {
+ public static void filterFromPostList(List<? extends RestrictedPost> posts, PostFilter filter) {
+ for (Iterator<? extends RestrictedPost> iter = posts.iterator(); iter.hasNext();) {
+ if (!filter.filter(iter.next())) {
+ iter.remove();
+ }
+ }
+ }
+
+ public static <T extends RestrictedPost> List<T> filterPostList(List<T> posts, PostFilter filter) {
+ List<T> filtered = new ArrayList<T>();
+
+ for (T post : posts) {
+ if (filter.filter(post)) {
+ filtered.add(post);
+ }
+ }
+
+ return filtered;
+ }
+}
Modified: trunk/src/model/org/jboss/blog/model/feed/RemoteFeed.java
===================================================================
--- trunk/src/model/org/jboss/blog/model/feed/RemoteFeed.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/model/org/jboss/blog/model/feed/RemoteFeed.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -4,8 +4,15 @@
import org.hibernate.validator.NotEmpty;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.jboss.blog.tools.validator.Regexp;
+import org.jboss.blog.tools.StringTools;
+import org.jboss.blog.model.post.PostFilter;
+import org.jboss.blog.model.post.filter.CategoryRegexpFilter;
+import org.jboss.blog.model.post.filter.TotalFilter;
import javax.persistence.Entity;
+import javax.persistence.Column;
+import javax.persistence.Transient;
/**
* @author <a href="mailto:adam at warski.org">Adam Warski</a>
@@ -17,6 +24,13 @@
@Length(max = 512)
private String remoteLink;
+ @Regexp
+ @Column
+ private String includeCategoryRegexp;
+
+ @Transient
+ private PostFilter includeCategoryFilter;
+
public String getRemoteLink() {
return remoteLink;
}
@@ -24,4 +38,28 @@
public void setRemoteLink(String remoteLink) {
this.remoteLink = remoteLink;
}
+
+ public String getIncludeCategoryRegexp() {
+ return includeCategoryRegexp;
+ }
+
+ public void setIncludeCategoryRegexp(String includeCategoryRegexp) {
+ this.includeCategoryRegexp = includeCategoryRegexp;
+
+ synchronized(this) {
+ includeCategoryFilter = null;
+ }
+ }
+
+ public synchronized PostFilter getIncludeCategoryFilter() {
+ if (includeCategoryFilter == null) {
+ if (StringTools.isEmpty(includeCategoryRegexp)) {
+ includeCategoryFilter = new TotalFilter();
+ } else {
+ includeCategoryFilter = new CategoryRegexpFilter(includeCategoryRegexp);
+ }
+ }
+
+ return includeCategoryFilter;
+ }
}
Modified: trunk/src/model/org/jboss/blog/model/post/filter/AbstractRegexpFilter.java
===================================================================
--- trunk/src/model/org/jboss/blog/model/post/filter/AbstractRegexpFilter.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/model/org/jboss/blog/model/post/filter/AbstractRegexpFilter.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -14,6 +14,13 @@
protected transient Pattern pattern;
+ protected AbstractRegexpFilter() {
+ }
+
+ protected AbstractRegexpFilter(String regexp) {
+ setRegexp(regexp);
+ }
+
public String getRegexp() {
return regexp;
}
Modified: trunk/src/model/org/jboss/blog/model/post/filter/CategoryRegexpFilter.java
===================================================================
--- trunk/src/model/org/jboss/blog/model/post/filter/CategoryRegexpFilter.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/model/org/jboss/blog/model/post/filter/CategoryRegexpFilter.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -11,6 +11,13 @@
public class CategoryRegexpFilter extends AbstractRegexpFilter {
private static final long serialVersionUID = 1209854919382113132L;
+ public CategoryRegexpFilter() {
+ }
+
+ public CategoryRegexpFilter(String regexp) {
+ super(regexp);
+ }
+
public boolean filter(RestrictedPost post) {
for (RestrictedCategory cat : post.getCategories()) {
if (pattern.matcher(cat.getName()).matches()) {
Modified: trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -12,6 +12,7 @@
import org.jboss.blog.session.feed.InvalidFeedTypeException;
import org.jboss.blog.session.shotoku.ShotokuFeedService;
import org.jboss.blog.session.shotoku.PostContentTooLargeException;
+import org.jboss.blog.session.shotoku.ShotokuException;
import org.jboss.shotoku.exceptions.RepositoryException;
import javax.persistence.EntityManager;
@@ -105,7 +106,7 @@
}
setPathOk(true);
- } catch (RepositoryException e) {
+ } catch (ShotokuException e) {
setPathOk(false);
setPathException(e);
} catch (PostContentTooLargeException e) {
Modified: trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -7,11 +7,11 @@
import org.jboss.blog.session.feed.lock.FeedsLocksBean;
import org.jboss.blog.session.shotoku.ShotokuFeedService;
import org.jboss.blog.session.shotoku.PostContentTooLargeException;
+import org.jboss.blog.session.shotoku.ShotokuException;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
-import org.jboss.shotoku.exceptions.RepositoryException;
import java.util.concurrent.locks.Lock;
import java.util.List;
@@ -39,7 +39,7 @@
try {
posts = shotokuFeedService.getPosts(feed);
- } catch (RepositoryException e) {
+ } catch (ShotokuException e) {
throw new UpdateException(e);
} catch (PostContentTooLargeException e) {
throw new UpdateException(e);
Added: trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuException.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuException.java (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuException.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -0,0 +1,23 @@
+package org.jboss.blog.session.shotoku;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+public class ShotokuException extends Exception {
+ public ShotokuException() {
+ }
+
+ public ShotokuException(String message) {
+ super(message);
+ }
+
+ public ShotokuException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ShotokuException(Throwable cause) {
+ super(cause);
+ }
+}
+
+
Modified: trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -32,7 +32,7 @@
private LinkService linkService;
private void setEnclosureUrl(ShotokuFeed feed, Enclosure enclosure, String nodeName) {
- enclosure.setUrl(linkService.getServerAddress() + '/' + feed.getPodcastPrefix() + '/' + nodeName);
+ enclosure.setUrl(linkService.getServerAddress() + '/' + feed.getPodcastPrefix() + '/' + nodeName);
}
public void refreshEnclosureLinks(ShotokuFeed feed) {
@@ -49,56 +49,60 @@
}
}
- public List<Post> getPosts(ShotokuFeed feed) throws RepositoryException, PostContentTooLargeException {
- ContentManager cm = ContentManager.getContentManager(feed.getCmId(), feed.getCmPath());
+ public List<Post> getPosts(ShotokuFeed feed) throws ShotokuException, PostContentTooLargeException {
+ try {
+ ContentManager cm = ContentManager.getContentManager(feed.getCmId(), feed.getCmPath());
- List<Post> posts = new ArrayList<Post>();
+ List<Post> posts = new ArrayList<Post>();
- if (cm == null) {
- throw new RepositoryException("Couldn't initialize the specified content manager.");
- }
+ if (cm == null) {
+ throw new ShotokuException("Couldn't initialize the specified content manager.");
+ }
- Directory rootDir = cm.getRootDirectory();
- if (rootDir == null) {
- throw new RepositoryException("Couldn't get the root directory in the specified content manager.");
- }
+ Directory rootDir = cm.getRootDirectory();
+ if (rootDir == null) {
+ throw new ShotokuException("Couldn't get the root directory in the specified content manager.");
+ }
- for (Node node : cm.getRootDirectory().getNodes()) {
- Post post = new Post();
+ for (Node node : cm.getRootDirectory().getNodes()) {
+ Post post = new Post();
- post.setAuthor(node.getProperty("author"));
- post.setCategories(new ArrayList<Category>());
- post.setEnclosures(new ArrayList<Enclosure>());
- post.setImages(new ArrayList<Image>());
- post.setModified(node.getLastModificationDate());
- post.setPublished(node.getCreatedDate());
- post.setTitle(node.getProperty("title"));
+ post.setAuthor(node.getProperty("author"));
+ post.setCategories(new ArrayList<Category>());
+ post.setEnclosures(new ArrayList<Enclosure>());
+ post.setImages(new ArrayList<Image>());
+ post.setModified(node.getLastModificationDate());
+ post.setPublished(node.getCreatedDate());
+ post.setTitle(node.getProperty("title"));
- if (!StringTools.isEmpty(feed.getPodcastPrefix())) {
- post.setContent(node.getProperty("description"));
+ if (!StringTools.isEmpty(feed.getPodcastPrefix())) {
+ post.setContent(node.getProperty("description"));
- Enclosure enclosure = new Enclosure(post, null, node.getLength(), node.getMimeType());
- setEnclosureUrl(feed, enclosure, node.getName());
- post.getEnclosures().add(enclosure);
+ Enclosure enclosure = new Enclosure(post, null, node.getLength(), node.getMimeType());
+ setEnclosureUrl(feed, enclosure, node.getName());
+ post.getEnclosures().add(enclosure);
- String thumbnail = node.getProperty("thumbnail");
- if (!StringTools.isEmpty(thumbnail)) {
- post.getImages().add(new Image(post, linkService.getServerAddress() + '/' + thumbnail));
+ String thumbnail = node.getProperty("thumbnail");
+ if (!StringTools.isEmpty(thumbnail)) {
+ post.getImages().add(new Image(post, linkService.getServerAddress() + '/' + thumbnail));
+ }
+ } else {
+ if (node.getLength() > 1000000) {
+ throw new PostContentTooLargeException("The content for node: '" + node.getFullName() +
+ "' is too large for a post.");
+ }
+
+ post.setContent(node.getContent());
}
- } else {
- if (node.getLength() > 1000000) {
- throw new PostContentTooLargeException("The content for node: '" + node.getFullName() +
- "' is too large for a post.");
- }
- post.setContent(node.getContent());
+ posts.add(post);
}
- posts.add(post);
+ Collections.sort(posts);
+
+ return posts;
+ } catch (RepositoryException e) {
+ throw new ShotokuException(e);
}
-
- Collections.sort(posts);
-
- return posts;
}
}
Modified: trunk/src/shotoku/org/jboss/shotoku/web/ShotokuFilesystemResourceResolver.java
===================================================================
--- trunk/src/shotoku/org/jboss/shotoku/web/ShotokuFilesystemResourceResolver.java 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/src/shotoku/org/jboss/shotoku/web/ShotokuFilesystemResourceResolver.java 2008-03-25 13:24:53 UTC (rev 271)
@@ -2,7 +2,6 @@
import com.sun.facelets.impl.ResourceResolver;
-import javax.faces.context.FacesContext;
import java.net.MalformedURLException;
import java.net.URL;
Modified: trunk/view/manage/aggregated/filter_add.xhtml
===================================================================
--- trunk/view/manage/aggregated/filter_add.xhtml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/view/manage/aggregated/filter_add.xhtml 2008-03-25 13:24:53 UTC (rev 271)
@@ -13,11 +13,12 @@
</ui:define>
<ui:define name="body">
- <div class="QuickstartMargin" id="QuickStart">
+ <div class="TwoColumnBlogSubnav">
+ <h4>Tips</h4>
<ul>
<li>
An <a href="http://www.regular-expressions.info/javascriptexample.html" target="_blank">online regular
- expressions tester</a> in case you need help.
+ expressions tester</a> in case you need help.
</li>
</ul>
</div>
Modified: trunk/view/manage/feed_mod.xhtml
===================================================================
--- trunk/view/manage/feed_mod.xhtml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/view/manage/feed_mod.xhtml 2008-03-25 13:24:53 UTC (rev 271)
@@ -11,13 +11,9 @@
<div class="TwoColumnBlogSubnav">
<h4>Tips</h4>
<ul>
- <li>
+ <li class="last">
Please fill in all the details that are necessary to handle your feed.
</li>
- <li class="last">
- Also, choose an atom template that suites the type of your feed. Most of the time, 'standard' will
- suffice, however if you have a podcast, choose 'podcast'.
- </li>
</ul>
</div>
@@ -92,7 +88,9 @@
<h:message for="group" styleClass="error" />
</a:outputPanel>
- <div><s:link value="Add new group" action="#{groupMod.add}" /></div><br />
+ <s:div rendered="#{identity.hasPermission('group', 'add')}">
+ <s:link value="Add new group" action="#{groupMod.add}" /><br />
+ </s:div>
</h:panelGroup>
<h:outputLabel for="maxPostsInFeed">
Modified: trunk/view/manage/remote/remote_add.xhtml
===================================================================
--- trunk/view/manage/remote/remote_add.xhtml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/view/manage/remote/remote_add.xhtml 2008-03-25 13:24:53 UTC (rev 271)
@@ -27,7 +27,7 @@
<ui:include src="remote_mod.xhtml">
<ui:param name="new" value="true" />
- <ui:param name="showCaptcha" value="false" />
+ <ui:param name="showCaptcha" value="false" />
<ui:param name="backTo" value="/manage/index.html" />
</ui:include>
</ui:define>
Modified: trunk/view/manage/remote/remote_mod.xhtml
===================================================================
--- trunk/view/manage/remote/remote_mod.xhtml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/view/manage/remote/remote_mod.xhtml 2008-03-25 13:24:53 UTC (rev 271)
@@ -7,93 +7,139 @@
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:a="http://richfaces.org/a4j">
- <div class="adminforms">
- <h:form>
- <h:panelGrid columns="2">
- <h:panelGroup rendered="#{showCaptcha}">
- <span class="required">*</span>
- <h:graphicImage value="/seam/resource/captcha/#{captchaTools.id}" id="captchaGraphic"/>
- </h:panelGroup>
- <h:panelGroup rendered="#{showCaptcha}">
- <h:inputText id="verifyCaptcha" value="#{captcha.response}" required="true">
- <s:validate />
- </h:inputText>
- <a:outputPanel id="captchaMessage">
- <h:message for="verifyCaptcha" styleClass="error" />
- </a:outputPanel>
- </h:panelGroup>
+<div class="adminforms">
+<h:form>
+<h:panelGrid columns="2">
+ <h:panelGroup rendered="#{showCaptcha}">
+ <span class="required">*</span>
+ <h:graphicImage value="/seam/resource/captcha/#{captchaTools.id}" id="captchaGraphic"/>
+ </h:panelGroup>
+ <h:panelGroup rendered="#{showCaptcha}">
+ <h:inputText id="verifyCaptcha" value="#{captcha.response}" required="true">
+ <s:validate />
+ </h:inputText>
+ <a:outputPanel id="captchaMessage">
+ <h:message for="verifyCaptcha" styleClass="error" />
+ </a:outputPanel>
+ </h:panelGroup>
- <h:outputLabel><span class="required">*</span> Remote feed (atom/rss2) address:</h:outputLabel>
- <h:panelGroup>
- <h:inputText id="link" value="#{remoteFeedMod.remoteFeed.remoteLink}" required="true" size="55"
- maxlength="64">
- <s:validate />
- </h:inputText>
- <a:outputPanel id="linkMessage">
- <h:message for="link" styleClass="error" />
- </a:outputPanel>
- </h:panelGroup>
+ <h:outputLabel><span class="required">*</span> Remote feed (atom/rss2) address:</h:outputLabel>
+ <h:panelGroup id="addressBody">
+ <h:inputText id="link" value="#{remoteFeedMod.remoteFeed.remoteLink}" required="true" size="55"
+ maxlength="64" disabled="#{remoteFeedMod.parseOk}">
+ <s:validate />
+ </h:inputText>
+ <a:outputPanel id="linkMessage">
+ <h:message for="link" styleClass="error" />
+ </a:outputPanel>
+ </h:panelGroup>
- <h:outputLabel for="postAuthorType"><span class="required">*</span> Post author:</h:outputLabel>
- <h:panelGroup>
- <h:selectOneMenu id="postAuthorType" value="#{remoteFeedMod.remoteFeed.postAuthorType}"
- required="true" styleClass="selectwide">
- <s:enumItem enumValue="BLOG_AUTHOR_IF_MISSING" label="Overwrite with blog author when post
+ <h:outputLabel for="postAuthorType"><span class="required">*</span> Post author:</h:outputLabel>
+ <h:panelGroup>
+ <h:selectOneMenu id="postAuthorType" value="#{remoteFeedMod.remoteFeed.postAuthorType}"
+ required="true" styleClass="selectwide">
+ <s:enumItem enumValue="BLOG_AUTHOR_IF_MISSING" label="Overwrite with blog author when post
author is missing" />
- <s:enumItem enumValue="POST_AUTHOR" label="Always use original post author" />
- <s:enumItem enumValue="BLOG_AUTHOR" label="Always overwrite post author with blog author" />
- <s:convertEnum />
- <s:validate />
- </h:selectOneMenu>
- </h:panelGroup>
+ <s:enumItem enumValue="POST_AUTHOR" label="Always use original post author" />
+ <s:enumItem enumValue="BLOG_AUTHOR" label="Always overwrite post author with blog author" />
+ <s:convertEnum />
+ <s:validate />
+ </h:selectOneMenu>
+ </h:panelGroup>
- <h:panelGroup />
- <h:panelGroup id="parseStatus">
- <h:panelGroup rendered="#{remoteFeedMod.parseOk}">
- Parsing the feed was successfull! You can proceed.
- </h:panelGroup>
- <h:panelGroup rendered="#{!remoteFeedMod.parseOk and remoteFeedMod.parseException != null}">
- Parsing the feed failed, because of the following exception:
- #{remoteFeedMod.parseException.message}
- </h:panelGroup>
- </h:panelGroup>
- </h:panelGrid>
+ <h:outputLabel id="includeCategoryHeader">
+ <s:fragment rendered="#{remoteFeedMod.parseOk or !new}">
+ <span class="required">*</span> Include only posts from category:
+ </s:fragment>
+ </h:outputLabel>
+ <h:panelGroup id="includeCategoryBody">
+ <s:fragment rendered="#{remoteFeedMod.parseOk or !new}">
+ <h:selectOneMenu id="includeCategory" required="true" value="#{remoteFeedMod.includeCategory}"
+ style="width: 200px">
+ <f:selectItems value="#{remoteFeedMod.includeCategories}" />
+ <s:validate />
+ <a:support event="onchange" reRender="includeCategoryBody,postsIncluded,regexpHelp" ajaxSingle="true"
+ action="#{remoteFeedMod.generateVisiblePosts}" />
+ </h:selectOneMenu>
+ <h:inputText id="includeOtherCategory" rendered="#{remoteFeedMod.includeCategory == 'OTHER'}"
+ value="#{remoteFeedMod.includeOtherCategoryRegexp}" required="true">
+ <s:validate />
+ <a:support event="onblur" reRender="includeCategoryMessage,postsIncluded" ajaxSingle="true"
+ action="#{remoteFeedMod.generateVisiblePosts}" />
+ </h:inputText>
+ <a:outputPanel id="includeCategoryMessage">
+ <h:message for="includeCategory" styleClass="error" />
+ <h:message for="includeOtherCategory" styleClass="error" />
+ </a:outputPanel>
+ </s:fragment>
+ </h:panelGroup>
- <s:div id="proceed" styleClass="formbuttons">
- <ul>
- <s:fragment rendered="#{!remoteFeedMod.parseOk}">
- <li>
- <a:commandButton action="#{remoteFeedMod.parseFeed}" value="Read and parse the feed"
- styleClass="submit"
- reRender="parseStatus,proceed,linkMessage,link,captchaGraphic,captchaMessage,postAuthorType" />
- </li>
- </s:fragment>
- <s:fragment rendered="#{remoteFeedMod.parseOk and new}">
- <li>
- <h:commandButton value="Next »" action="#{remoteFeedMod.saveNew}"
- styleClass="submit_first" />
- </li>
- </s:fragment>
- <s:fragment rendered="#{remoteFeedMod.parseOk and !new}">
- <li>
- <h:commandButton value="Save" action="#{remoteFeedMod.saveExisting}"
- styleClass="submit" />
- </li>
- </s:fragment>
- <s:fragment rendered="#{!new}">
- <li>
- <h:commandButton value="Save only 'post author'" action="#{remoteFeedMod.saveOnlyPostAuthorType}"
- styleClass="submit" />
- </li>
- </s:fragment>
- <li>
- <s:button value="Cancel" view="#{backTo}" propagation="end" styleClass="submit" />
- </li>
- <li>
- <ui:include src="../../common/ajax_status.xhtml" />
- </li>
- </ul>
- </s:div>
- </h:form>
- </div>
+ <h:panelGroup />
+ <h:panelGroup id="parseStatus">
+ <h:panelGroup rendered="#{remoteFeedMod.parseOk}">
+ Parsing the feed was successfull! You can proceed.
+ </h:panelGroup>
+ <h:panelGroup rendered="#{!remoteFeedMod.parseOk and remoteFeedMod.parseException != null}">
+ Parsing the feed failed, because of the following exception:
+ #{remoteFeedMod.parseException.message}
+ </h:panelGroup>
+ </h:panelGroup>
+</h:panelGrid>
+
+<s:div id="proceed" styleClass="formbuttons">
+ <ul>
+ <s:fragment rendered="#{!remoteFeedMod.parseOk}">
+ <li>
+ <a:commandButton action="#{remoteFeedMod.parseFeed}" value="Read and parse the feed"
+ styleClass="submit"
+ reRender="parseStatus,proceed,linkMessage,link,captchaGraphic,captchaMessage,postAuthorType,includeCategoryHeader,includeCategoryBody,addressBody,postsIncluded" />
+ </li>
+ </s:fragment>
+ <s:fragment rendered="#{remoteFeedMod.parseOk and new}">
+ <li>
+ <h:commandButton value="Next »" action="#{remoteFeedMod.saveNew}"
+ styleClass="submit_first" />
+ </li>
+ </s:fragment>
+ <s:fragment rendered="#{remoteFeedMod.parseOk and !new}">
+ <li>
+ <h:commandButton value="Save all" action="#{remoteFeedMod.saveExisting}"
+ styleClass="submit" />
+ </li>
+ </s:fragment>
+ <s:fragment rendered="#{!new}">
+ <li>
+ <h:commandButton value="Save only 'Post author' and 'Include category'" action="#{remoteFeedMod.savePartial}"
+ styleClass="submit" />
+ </li>
+ </s:fragment>
+ <li>
+ <s:button value="Cancel" view="#{backTo}" propagation="end" styleClass="submit" />
+ </li>
+ <li>
+ <ui:include src="../../common/ajax_status.xhtml" />
+ </li>
+ </ul>
+</s:div>
+
+<s:div id="postsIncluded">
+ <s:fragment rendered="#{remoteFeedMod.parseOk}">
+ <h4>
+ <s:fragment rendered="#{new}">
+ The following posts will be saved initially:
+ </s:fragment>
+ <s:fragment rendered="#{!new}">
+ The following posts will be merged into current posts on the next update, after saving:
+ </s:fragment>
+ </h4>
+
+ <ul>
+ <ui:repeat var="post" value="#{remoteFeedMod.visiblePosts}">
+ <li>#{post.title}</li>
+ </ui:repeat>
+ </ul>
+ </s:fragment>
+</s:div>
+</h:form>
+</div>
</ui:composition>
Modified: trunk/view/manage/remote/remote_propose.xhtml
===================================================================
--- trunk/view/manage/remote/remote_propose.xhtml 2008-03-17 18:27:06 UTC (rev 270)
+++ trunk/view/manage/remote/remote_propose.xhtml 2008-03-25 13:24:53 UTC (rev 271)
@@ -18,9 +18,8 @@
<ul>
<li>
If you are blogging on a JBoss-related subject, you can aggregate your blog on JBoss.ORG!
- Very often blogs of the JBoss Community members include very valuable information,
- and we'd like to give it more visibility, so that other members of the Community can easily find
- it.
+ Blogs written by the JBoss Community members are very valuable, and we'd like
+ to make them much more visible!
</li>
<li>
#{messages['blog.feed.remote.adding.quickstart']}
@@ -32,7 +31,8 @@
</li>
<li>
If you are blogging on a wider area of subjects, please submit a feed of only jboss-related
- entries (for example a feed of one category/ tag).
+ entries (for example a feed of one category/ tag), or select a category after parsing the feed
+ (if category information is included in the entries of the feed).
</li>
<li class="last">
#{messages['blog.feed.remote.mod.authors']}
More information about the jboss-cvs-commits
mailing list