[jboss-cvs] JBossBlog SVN: r322 - in trunk: src/action/org/jboss/blog/session/tools and 6 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Aug 26 07:22:51 EDT 2008
Author: adamw
Date: 2008-08-26 07:22:51 -0400 (Tue, 26 Aug 2008)
New Revision: 322
Added:
trunk/src/action/org/jboss/blog/session/tools/AdminBean.java
Modified:
trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
trunk/src/action/org/jboss/blog/session/view/FeedViewBean.java
trunk/src/action/org/jboss/blog/session/xml/velocity/tools/XmlTools.java
trunk/src/model/org/jboss/blog/model/Post.java
trunk/src/tools/org/jboss/blog/tools/StringTools.java
trunk/view/manage/index.xhtml
trunk/view/manage/template/template_mod.xhtml
Log:
JBBLOG-71 fix, removing and checking duplicate posts
Modified: trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -4,6 +4,7 @@
import org.jboss.blog.model.Post;
import org.jboss.blog.model.Enclosure;
import org.jboss.blog.model.Image;
+import org.jboss.blog.model.RestrictedPost;
import org.jboss.blog.service.FeedsService;
import org.jboss.blog.service.PostNotFoundException;
import org.jboss.blog.service.LinkService;
@@ -73,6 +74,22 @@
events.raiseEvent("org.jboss.blog.post.added", post);
}
+ private boolean checkNewPost(Post post, PostsIterator<RestrictedPost> mergeTo, PostsIterator<Post> mergeFrom) {
+ int currentPostSize = entityManager
+ .createQuery("select p from Post p where p.published = :p and p.title = :t")
+ .setParameter("p", post.getPublished())
+ .setParameter("t", post.getTitle())
+ .getResultList().size();
+
+ if (currentPostSize > 0) {
+ log.warn("Trying to save a duplicate post, merge to: #1, merge from: #2!", mergeTo.getCurrent(),
+ mergeFrom.getCurrent());
+ return false;
+ } else {
+ return true;
+ }
+ }
+
/**
* Merges the given posts; checks for changes in:
* - author
@@ -145,20 +162,24 @@
* @param posts A <b>sorted</b> list of posts, that should be merged to <code>feed</code>.
*/
public void merge(Feed feed, List<Post> posts) {
- ListPostsIterator<Post> mergeFrom = new ListPostsIterator<Post>(posts);
- FeedsServicePostsIterator mergeTo = new FeedsServicePostsIterator(feedsService, feed, posts.size()+1);
+ PostsIterator<Post> mergeFrom = new ListPostsIterator<Post>(posts);
+ PostsIterator<RestrictedPost> mergeTo = new FeedsServicePostsIterator(feedsService, feed, posts.size()+1);
while (!mergeFrom.finished()) {
if (mergeTo.finished()) {
// no more current posts
- savePost(feed, mergeFrom.getCurrent());
+ if (checkNewPost(mergeFrom.getCurrent(), mergeTo, mergeFrom)) {
+ savePost(feed, mergeFrom.getCurrent());
+ }
mergeFrom.next();
} else {
int compare = mergeTo.getCurrent().compareTo(mergeFrom.getCurrent());
if (compare > 0) {
// mergeTo post is before mergeFrom post
- savePost(feed, mergeFrom.getCurrent());
+ if (checkNewPost(mergeFrom.getCurrent(), mergeTo, mergeFrom)) {
+ savePost(feed, mergeFrom.getCurrent());
+ }
mergeFrom.next();
} else if (compare == 0) {
try {
Added: trunk/src/action/org/jboss/blog/session/tools/AdminBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/tools/AdminBean.java (rev 0)
+++ trunk/src/action/org/jboss/blog/session/tools/AdminBean.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -0,0 +1,93 @@
+package org.jboss.blog.session.tools;
+
+import org.jboss.seam.annotations.*;
+import org.jboss.seam.annotations.security.Restrict;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.faces.FacesMessages;
+import org.jboss.seam.log.Log;
+import org.jboss.blog.model.Group;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.model.feed.Feed;
+import org.jboss.blog.tools.StringTools;
+import org.jboss.blog.service.GroupsService;
+import org.jboss.blog.session.cache.CacheManager;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+ at Scope(ScopeType.STATELESS)
+ at Name("adminBean")
+ at AutoCreate
+public class AdminBean {
+ @In
+ private GroupsService groupsService;
+
+ @In
+ private EntityManager entityManager;
+
+ @In
+ private CacheManager cacheManager;
+
+ @In
+ private FacesMessages facesMessages;
+
+ @Logger
+ private Log log;
+
+ @Restrict("#{identity.hasPermission('admin', null)}")
+ public void fixHtml() {
+ for (Group group : groupsService.getAllGroups()) {
+ for (Feed feed : groupsService.acceptedFeeds(group)) {
+ for (Post post : feed.getPosts()) {
+ post.setContent(StringTools.fixHtml(post.getContent()));
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Restrict("#{identity.hasPermission('admin', null)}")
+ public void removeDuplicates() {
+ List<Object[]> results = (List<Object[]>) entityManager
+ .createQuery("select title, published, count(*) from Post p group by p.title, p.published")
+ .getResultList();
+
+ int removedDuplicates = 0;
+
+ for (Object[] result : results) {
+ if (((Number) result[2]).intValue() > 1) {
+ log.info("Duplicate post with title: " + result[0] + ", published: " + result[1] +
+ ", count: " + result[2]);
+
+ removedDuplicates += ((Number) result[2]).intValue();
+
+ String titleAsId = StringTools.convertTitleToLink(result[0].toString());
+
+ // Checking that a "first" post exists
+ List firstPostResult = entityManager
+ .createQuery("select p from Post p where p.titleAsId = :titleAsId")
+ .setParameter("titleAsId", titleAsId)
+ .getResultList();
+
+ if (firstPostResult.size() != 1) {
+ log.info("No first post with titleAsId = " + titleAsId + "!");
+ } else {
+ entityManager
+ .createQuery("delete from Post p where p.titleAsId like :titleAsIdLike " +
+ "and p.titleAsId != :titleAsId and p.published = :published")
+ .setParameter("titleAsIdLike", titleAsId + "%")
+ .setParameter("titleAsId", titleAsId)
+ .setParameter("published", result[1])
+ .executeUpdate();
+ }
+ }
+ }
+
+ cacheManager.evictAll();
+
+ facesMessages.add("Removed " + removedDuplicates + " duplicate posts.");
+ }
+}
Modified: trunk/src/action/org/jboss/blog/session/view/FeedViewBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/view/FeedViewBean.java 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/src/action/org/jboss/blog/session/view/FeedViewBean.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -1,17 +1,12 @@
package org.jboss.blog.session.view;
import org.jboss.blog.model.feed.Feed;
-import org.jboss.blog.model.Post;
import org.jboss.blog.model.RestrictedPost;
-import org.jboss.blog.model.Group;
import org.jboss.blog.service.FeedsService;
-import org.jboss.blog.service.GroupsService;
-import org.jboss.blog.tools.StringTools;
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.seam.annotations.security.Restrict;
import java.util.List;
import java.io.Serializable;
@@ -25,9 +20,6 @@
@In
private FeedsService feedsService;
- @In
- private GroupsService groupsService;
-
private Feed feed;
private int from;
@@ -72,20 +64,4 @@
public int getNextFrom() {
return from + feed.getMaxPostsOnPage();
}
-
- /**
- * TODO
- * Remove in the future!
- * @Deprecated
- */
- @Restrict("#{identity.hasPermission('admin', null)}")
- public void fixHtml() {
- for (Group group : groupsService.getAllGroups()) {
- for (Feed feed : groupsService.acceptedFeeds(group)) {
- for (Post post : feed.getPosts()) {
- post.setContent(StringTools.fixHtml(post.getContent()));
- }
- }
- }
- }
}
Modified: trunk/src/action/org/jboss/blog/session/xml/velocity/tools/XmlTools.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/xml/velocity/tools/XmlTools.java 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/src/action/org/jboss/blog/session/xml/velocity/tools/XmlTools.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -4,6 +4,7 @@
import org.jboss.blog.model.Post;
import org.jboss.blog.model.XmlType;
import org.jboss.blog.service.LinkService;
+import org.jboss.blog.tools.StringTools;
import org.jboss.seam.Component;
import java.text.SimpleDateFormat;
@@ -30,6 +31,10 @@
return cal.getTime();
}
+ public String escape(String toEscape) {
+ return StringTools.escape(toEscape);
+ }
+
private LinkService getLinkService() {
return (LinkService) Component.getInstance("linkService");
}
Modified: trunk/src/model/org/jboss/blog/model/Post.java
===================================================================
--- trunk/src/model/org/jboss/blog/model/Post.java 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/src/model/org/jboss/blog/model/Post.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -223,4 +223,8 @@
return result;
}
}
+
+ public String toString() {
+ return "Post(title = " + title + ", published = " + published + ", titleAsId = " + titleAsId + ")";
+ }
}
Modified: trunk/src/tools/org/jboss/blog/tools/StringTools.java
===================================================================
--- trunk/src/tools/org/jboss/blog/tools/StringTools.java 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/src/tools/org/jboss/blog/tools/StringTools.java 2008-08-26 11:22:51 UTC (rev 322)
@@ -13,6 +13,8 @@
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
+import java.text.StringCharacterIterator;
+import java.text.CharacterIterator;
/**
* @author Adam Warski (adam at warski dot org)
@@ -149,4 +151,87 @@
return s;
}
}
+
+ /**
+ * Escape characters for text appearing in HTML markup.
+ *
+ * <P>This method exists as a defence against Cross Site Scripting (XSS) hacks.
+ * This method escapes all characters recommended by the Open Web App
+ * Security Project -
+ * <a href='http://www.owasp.org/index.php/Cross_Site_Scripting'>link</a>.
+ *
+ * <P>The following characters are replaced with corresponding HTML
+ * character entities :
+ * <table border='1' cellpadding='3' cellspacing='0'>
+ * <tr><th> Character </th><th> Encoding </th></tr>
+ * <tr><td> < </td><td> < </td></tr>
+ * <tr><td> > </td><td> > </td></tr>
+ * <tr><td> & </td><td> & </td></tr>
+ * <tr><td> " </td><td> "</td></tr>
+ * <tr><td> ' </td><td> '</td></tr>
+ * <tr><td> ( </td><td> (</td></tr>
+ * <tr><td> ) </td><td> )</td></tr>
+ * <tr><td> # </td><td> #</td></tr>
+ * <tr><td> % </td><td> %</td></tr>
+ * <tr><td> ; </td><td> ;</td></tr>
+ * <tr><td> + </td><td> + </td></tr>
+ * <tr><td> - </td><td> - </td></tr>
+ * </table>
+ *
+ * <P>Note that JSTL's {@code <c:out>} escapes <em>only the first
+ * five</em> of the above characters.
+ *
+ * @author http://www.javapractices.com/topic/TopicAction.do;jsessionid=A293F4E3A21E476DC8488FED3DE883A0?Id=96
+ */
+ public static String escape(String toEscape){
+ final StringBuilder result = new StringBuilder();
+ final StringCharacterIterator iterator = new StringCharacterIterator(toEscape);
+ char character = iterator.current();
+ while (character != CharacterIterator.DONE ){
+ if (character == '<') {
+ result.append("<");
+ }
+ else if (character == '>') {
+ result.append(">");
+ }
+ else if (character == '&') {
+ result.append("&");
+ }
+ else if (character == '\"') {
+ result.append(""");
+ }
+ else if (character == '\'') {
+ result.append("'");
+ }
+ else if (character == '(') {
+ result.append("(");
+ }
+ else if (character == ')') {
+ result.append(")");
+ }
+ else if (character == '#') {
+ result.append("#");
+ }
+ else if (character == '%') {
+ result.append("%");
+ }
+ else if (character == ';') {
+ result.append(";");
+ }
+ else if (character == '+') {
+ result.append("+");
+ }
+ else if (character == '-') {
+ result.append("-");
+ }
+ else {
+ //the char is not a special one
+ //add it to the result as is
+ result.append(character);
+ }
+ character = iterator.next();
+ }
+ return result.toString();
+ }
+
}
Modified: trunk/view/manage/index.xhtml
===================================================================
--- trunk/view/manage/index.xhtml 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/view/manage/index.xhtml 2008-08-26 11:22:51 UTC (rev 322)
@@ -68,7 +68,8 @@
<s:fragment rendered="#{identity.hasPermission('admin', null)}">
<dt>Global posts operations:</dt>
<hr />
- <dd><s:link value="Fix html in all posts" action="#{feedView.fixHtml}" /></dd>
+ <dd><s:link value="Fix html in all posts" action="#{adminBean.fixHtml}" /></dd>
+ <dd><s:link value="Remove duplicates" action="#{adminBean.removeDuplicates}" /></dd>
<dd><s:link value="Re-index posts (for search)" action="#{postSearch.reindex}" /></dd>
</s:fragment>
<dt>Existing feed operations:</dt>
Modified: trunk/view/manage/template/template_mod.xhtml
===================================================================
--- trunk/view/manage/template/template_mod.xhtml 2008-06-27 14:26:06 UTC (rev 321)
+++ trunk/view/manage/template/template_mod.xhtml 2008-08-26 11:22:51 UTC (rev 322)
@@ -95,6 +95,8 @@
a link to a feed of the given type</li>
<li>$tools.postLink(org.jboss.blog.model.Post) - generates a link to the html version of the
given post</li>
+ <li>$tools.escape(java.util.String) - escapes special charaters, like &, which can be
+ found in links</li>
</ul>
</li>
</ul>
More information about the jboss-cvs-commits
mailing list