Return-Path: Delivered-To: apmail-incubator-roller-commits-archive@www.apache.org Received: (qmail 38425 invoked from network); 21 Oct 2005 21:53:56 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 21 Oct 2005 21:53:56 -0000 Received: (qmail 78579 invoked by uid 500); 21 Oct 2005 21:53:27 -0000 Delivered-To: apmail-incubator-roller-commits-archive@incubator.apache.org Received: (qmail 74760 invoked by uid 500); 21 Oct 2005 21:53:05 -0000 Mailing-List: contact roller-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: roller-dev@incubator.apache.org Delivered-To: mailing list roller-commits@incubator.apache.org Received: (qmail 72986 invoked by uid 99); 21 Oct 2005 21:51:44 -0000 X-ASF-Spam-Status: No, hits=1.4 required=10.0 tests=INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Fri, 21 Oct 2005 14:50:34 -0700 Received: (qmail 36930 invoked by uid 65534); 21 Oct 2005 21:50:13 -0000 Message-ID: <20051021215013.36929.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r327589 [21/72] - in /incubator/roller/branches/roller_1.x: ./ contrib/ contrib/lib/ contrib/plugins/ contrib/plugins/src/ contrib/plugins/src/org/ contrib/plugins/src/org/roller/ contrib/plugins/src/org/roller/presentation/ contrib/plugins... Date: Fri, 21 Oct 2005 21:46:28 -0000 To: roller-commits@incubator.apache.org From: snoopdave@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/HibernateWeblogManagerImpl.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/HibernateWeblogManagerImpl.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/HibernateWeblogManagerImpl.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/HibernateWeblogManagerImpl.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,807 @@ +/* + * Created on Jun 16, 2004 + */ +package org.roller.business.hibernate; + +import net.sf.hibernate.Criteria; +import net.sf.hibernate.HibernateException; +import net.sf.hibernate.Session; +import net.sf.hibernate.expression.Expression; +import net.sf.hibernate.expression.Junction; +import net.sf.hibernate.expression.Order; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.roller.RollerException; +import org.roller.business.PersistenceStrategy; +import org.roller.business.WeblogManagerImpl; +import org.roller.model.Roller; +import org.roller.model.RollerFactory; +import org.roller.pojos.Assoc; +import org.roller.pojos.CommentData; +import org.roller.pojos.RefererData; +import org.roller.pojos.WeblogCategoryAssoc; +import org.roller.pojos.WeblogCategoryData; +import org.roller.pojos.WeblogEntryData; +import org.roller.pojos.WebsiteData; +import org.roller.util.StringUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Hibernate queries. + * @author David M Johnson + */ +public class HibernateWeblogManagerImpl extends WeblogManagerImpl +{ + static final long serialVersionUID = -3730860865389981439L; + + private static Log mLogger = + LogFactory.getFactory().getInstance(HibernateWeblogManagerImpl.class); + + /** + * @param strategy + * @param roller + */ + public HibernateWeblogManagerImpl(PersistenceStrategy strategy) + { + super(strategy); + mLogger.debug("Instantiating Weblog Manager"); + } + + public List getComments(String entryId, boolean nospam) throws RollerException + { + if (entryId == null) + throw new RollerException("entryId is null"); + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(CommentData.class); + criteria.createAlias("weblogEntry","e"); + criteria.add(Expression.eq("e.id", entryId)); + if (nospam) + { + criteria.add( + Expression.not(Expression.eq("spam", Boolean.TRUE))); + } + criteria.addOrder(Order.asc("postTime")); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + + /* + * @see org.roller.model.WeblogManager#getNextEntry(org.roller.pojos.WeblogEntryData) + */ + public List getNextPrevEntries( + WeblogEntryData current, String catName, int maxEntries, boolean next) + throws RollerException + { + if (catName != null && catName.trim().equals("/")) + { + catName = null; + } + Junction conjunction = Expression.conjunction(); + conjunction.add(Expression.eq("website", current.getWebsite())); + conjunction.add(Expression.eq("publishEntry", Boolean.TRUE)); + + if (next) + { + conjunction.add(Expression.gt("pubTime", current.getPubTime())); + } + else + { + conjunction.add(Expression.lt("pubTime", current.getPubTime())); + } + + if (catName != null) + { + WeblogCategoryData category = + getWeblogCategoryByPath(current.getWebsite(), null, catName); + if (category != null) + { + conjunction.add(Expression.eq("category", category)); + } + else + { + throw new RollerException("Cannot find category: "+catName); + } + } + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + criteria.addOrder(Order.desc("pubTime")); + criteria.add(conjunction); + criteria.setMaxResults(maxEntries); + List results = criteria.list(); + return results; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getRootWeblogCategory(org.roller.pojos.WebsiteData) + */ + public WeblogCategoryData getRootWeblogCategory(WebsiteData website) + throws RollerException + { + if (website == null) + throw new RollerException("website is null"); + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.createAlias("category","c"); + + criteria.add(Expression.eq("c.website", website)); + criteria.add(Expression.isNull("ancestorCategory")); + criteria.add(Expression.eq("relation", WeblogCategoryAssoc.PARENT)); + + criteria.setMaxResults(1); + + List list = criteria.list(); + return ((WeblogCategoryAssoc)list.get(0)).getCategory(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getWeblogCategories( + * org.roller.pojos.WebsiteData, boolean) + */ + public List getWeblogCategories(WebsiteData website, boolean includeRoot) + throws RollerException + { + if (website == null) + throw new RollerException("website is null"); + + if (includeRoot) return getWeblogCategories(website); + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.createAlias("category", "c"); + criteria.add(Expression.eq("c.website", website)); + criteria.add(Expression.isNotNull("ancestorCategory")); + criteria.add(Expression.eq("relation", "PARENT")); + Iterator assocs = criteria.list().iterator(); + List cats = new ArrayList(); + while (assocs.hasNext()) + { + WeblogCategoryAssoc assoc = (WeblogCategoryAssoc) assocs.next(); + cats.add(assoc.getCategory()); + } + return cats; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + public List getWeblogCategories(WebsiteData website) throws RollerException + { + if (website == null) + throw new RollerException("website is null"); + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryData.class); + criteria.add(Expression.eq("website", website)); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getWeblogEntries( + * java.lang.String, + * java.util.Date, + * java.util.Date, + * java.lang.String, + * java.lang.String, + * java.lang.Integer) + */ + public List getWeblogEntries( + WebsiteData website, + Date startDate, + Date endDate, + String catName, + String status, + Integer maxEntries, + Boolean pinned) throws RollerException + { + WeblogCategoryData cat = null; + if (StringUtils.isNotEmpty(catName) && website != null) + { + cat = getWeblogCategoryByPath(website, catName); + if (cat == null) catName = null; + } + if (catName != null && catName.trim().equals("/")) + { + catName = null; + } + + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + + if (website != null) + { + criteria.add(Expression.eq("website", website)); + } + else + { + criteria.createAlias("website","w"); + criteria.add(Expression.eq("w.isEnabled", Boolean.TRUE)); + } + + if (startDate != null) + { + criteria.add( + Expression.ge("pubTime", startDate)); + } + + if (endDate != null) + { + criteria.add( + Expression.le("pubTime", endDate)); + } + + if (cat != null && website != null) + { + criteria.add(Expression.eq("category", cat)); + } + + if (status != null && status.equals(DRAFT_ONLY)) + { + criteria.add( + Expression.eq("publishEntry", Boolean.FALSE)); + } + else if (status != null && status.equals(PUB_ONLY)) + { + criteria.add( + Expression.eq("publishEntry", Boolean.TRUE)); + } + + if (pinned != null) + { + criteria.add(Expression.eq("pinnedToMain", pinned)); + } + + criteria.addOrder(Order.desc("pubTime")); + + if (maxEntries != null) + { + criteria.setMaxResults(maxEntries.intValue()); + } + return criteria.list(); + } + catch (HibernateException e) + { + mLogger.error(e); + throw new RollerException(e); + } + } + + /** + * Use Hibernate directly because Roller's Query API does too much allocation. + */ + public WeblogEntryData getWeblogEntryByAnchor( + WebsiteData website, String anchor) throws RollerException + { + if (website == null) + throw new RollerException("Website is null"); + + if (anchor == null) + throw new RollerException("Anchor is null"); + + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + criteria.add(Expression.conjunction() + .add(Expression.eq("website",website)) + .add(Expression.eq("anchor",anchor))); + criteria.addOrder(Order.desc("pubTime")); + criteria.setMaxResults(1); + try + { + List list = criteria.list(); + return list.size()!=0 ? (WeblogEntryData)list.get(0) : null; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + /** + * Gets the Date of the latest Entry publish time. + * + * @param userName User name of weblog or null for all users + * @param catName Category name of posts or null for all categories + * @return Date Of last publish time + * @throws RollerException + */ + public Date getWeblogLastPublishTime( String userName, String catName ) + throws RollerException + { + WeblogCategoryData cat = null; + Roller mRoller = RollerFactory.getRoller(); + if (userName != null) + { + WebsiteData website = mRoller.getUserManager().getWebsite(userName); + if (catName != null && website != null) + { + cat = getWeblogCategoryByPath(website, null, catName); + if (cat == null) catName = null; + } + if (catName != null && catName.trim().equals("/")) + { + catName = null; + } + } + + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + criteria.add(Expression.eq("publishEntry", Boolean.TRUE)); + criteria.add(Expression.le("pubTime", new Date())); + + try + { + if ( userName != null ) + { + WebsiteData website = mRoller.getUserManager().getWebsite(userName); + criteria.add(Expression.eq("website", website)); + } + + if ( cat != null ) + { + criteria.add(Expression.eq("category", cat)); + } + + criteria.addOrder(Order.desc("pubTime")); + criteria.setMaxResults(1); + List list = criteria.list(); + if (list.size() > 0) + { + return ((WeblogEntryData)list.get(0)).getPubTime(); + } + else + { + return null; + } + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + public void moveWeblogCategoryContents(String srcId, String destId) + throws RollerException + { + WeblogCategoryData srcCd = + (WeblogCategoryData) mStrategy.load( + srcId, WeblogCategoryData.class); + + WeblogCategoryData destCd = + (WeblogCategoryData) mStrategy.load( + destId, WeblogCategoryData.class); + + if (destCd.descendentOf(srcCd)) + { + throw new RollerException( + "ERROR cannot move parent category into it's own child"); + } + + // get all entries in category and subcats + List results = retrieveWeblogEntries(srcCd, true); + + // Loop through entries in src cat, assign them to dest cat + Iterator iter = results.iterator(); + WebsiteData website = destCd.getWebsite(); + while (iter.hasNext()) + { + WeblogEntryData entry = (WeblogEntryData) iter.next(); + entry.setCategory(destCd); + entry.setWebsite(website); + entry.save(); + } + + // Make sure website's default and bloggerapi categories + // are valid after the move + + if (srcCd.getWebsite().getDefaultCategory().getId().equals(srcId) + || srcCd.getWebsite().getDefaultCategory().descendentOf(srcCd)) + { + srcCd.getWebsite().setDefaultCategory(destCd); + } + + if (srcCd.getWebsite().getBloggerCategory().getId().equals(srcId) + || srcCd.getWebsite().getBloggerCategory().descendentOf(srcCd)) + { + srcCd.getWebsite().setBloggerCategory(destCd); + } + } + + public List retrieveWeblogEntries(WeblogCategoryData cat, boolean subcats) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + List entries = new LinkedList(); + + if (subcats) + { + // Get entries in subcategories + Criteria assocsQuery = + session.createCriteria(WeblogCategoryAssoc.class); + assocsQuery.add(Expression.eq("ancestorCategory", cat)); + Iterator assocs = assocsQuery.list().iterator(); + while (assocs.hasNext()) + { + WeblogCategoryAssoc assoc = (WeblogCategoryAssoc)assocs.next(); + Criteria entriesQuery = + session.createCriteria(WeblogEntryData.class); + entriesQuery.add( + Expression.eq("category", assoc.getCategory())); + Iterator entryIter = entriesQuery.list().iterator(); + while (entryIter.hasNext()) + { + WeblogEntryData entry = (WeblogEntryData)entryIter.next(); + entries.add(entry); + } + } + } + + // Get entries in category + Criteria entriesQuery = + session.createCriteria(WeblogEntryData.class); + entriesQuery.add(Expression.eq("category", cat)); + Iterator entryIter = entriesQuery.list().iterator(); + while (entryIter.hasNext()) + { + WeblogEntryData entry = (WeblogEntryData)entryIter.next(); + entries.add(entry); + } + return entries; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#removeWeblogEntryContents( + * org.roller.pojos.WeblogEntryData) + */ + public void removeWeblogEntryContents(WeblogEntryData entry) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + + // remove referers + Criteria refererQuery = session.createCriteria(RefererData.class); + refererQuery.add(Expression.eq("weblogEntry", entry)); + List entries = refererQuery.list(); + for (Iterator iter = entries.iterator(); iter.hasNext();) + { + RefererData referer = (RefererData) iter.next(); + referer.remove(); + } + + // remove comments + /* + Criteria commentQuery = session.createCriteria(RefererData.class); + commentQuery.add(Expression.eq("weblogEntry", entry)); + List comments = commentQuery.list(); + */ + List comments = RollerFactory.getRoller().getWeblogManager().getComments(entry.getId(), false); + for (Iterator iter = comments.iterator(); iter.hasNext();) + { + CommentData comment = (CommentData) iter.next(); + comment.remove(); + } + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#createAnchor( + * org.roller.pojos.WeblogEntryData) + */ + public String createAnchor(WeblogEntryData entry) throws RollerException + { + try + { + // Check for uniqueness of anchor + String base = entry.createAnchorBase(); + String name = base; + int count = 0; + + while (true) + { + if (count > 0) + { + name = base + count; + } + + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + criteria.add(Expression.eq("website", entry.getWebsite())); + criteria.add(Expression.eq("anchor", name)); + + List results = criteria.list(); + + if (results.size() < 1) + { + break; + } + else + { + count++; + } + } + return name; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#checkWeblogCategoryName(org.roller.pojos.WeblogCategoryData) + */ + public boolean isDuplicateWeblogCategoryName(WeblogCategoryData cat) + throws RollerException + { + // ensure that no sibling categories share the same name + WeblogCategoryData parent = + null == cat.getId() ? (WeblogCategoryData)cat.getNewParent() : cat.getParent(); + + if (null != parent) // don't worry about root + { + List sameNames; + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.createAlias("category", "c"); + criteria.add(Expression.eq("c.name", cat.getName())); + criteria.add(Expression.eq("ancestorCategory", parent)); + criteria.add(Expression.eq("relation", Assoc.PARENT)); + sameNames = criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + if (sameNames.size() > 1) + { + return true; + } + } + return false; + } + + /** + * @see org.roller.model.WeblogManager#isWeblogCategoryInUse(org.roller.pojos.WeblogCategoryData) + */ + public boolean isWeblogCategoryInUse(WeblogCategoryData cat) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogEntryData.class); + criteria.add(Expression.eq("category", cat)); + criteria.setMaxResults(1); + int entryCount = criteria.list().size(); + + if (entryCount > 0) + { + return true; + } + + Iterator cats = cat.getWeblogCategories().iterator(); + while (cats.hasNext()) + { + WeblogCategoryData childCat = (WeblogCategoryData)cats.next(); + if (childCat.isInUse()) + { + return true; + } + } + + if (cat.getWebsite().getBloggerCategory().equals(cat)) + { + return true; + } + + if (cat.getWebsite().getDefaultCategory().equals(cat)) + { + return true; + } + + return false; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + public boolean isDescendentOf( + WeblogCategoryData child, WeblogCategoryData ancestor) + throws RollerException + { + boolean ret = false; + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.add(Expression.eq("category", child)); + criteria.add(Expression.eq("ancestorCategory", ancestor)); + ret = criteria.list().size() > 0; + } + catch (HibernateException e) + { + throw new RollerException(e); + } + return ret; + } + + /** + * @see org.roller.model.WeblogManager#getWeblogCategoryParentAssoc( + * org.roller.pojos.WeblogCategoryData) + */ + public Assoc getWeblogCategoryParentAssoc(WeblogCategoryData cat) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.add(Expression.eq("category", cat)); + criteria.add(Expression.eq("relation", Assoc.PARENT)); + List parents = criteria.list(); + if (parents.size() > 1) + { + throw new RollerException("ERROR: more than one parent"); + } + else if (parents.size() == 1) + { + return (Assoc) parents.get(0); + } + else + { + return null; + } + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getWeblogCategoryChildAssocs( + * org.roller.pojos.WeblogCategoryData) + */ + public List getWeblogCategoryChildAssocs(WeblogCategoryData cat) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.add(Expression.eq("ancestorCategory", cat)); + criteria.add(Expression.eq("relation", Assoc.PARENT)); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getAllWeblogCategoryDecscendentAssocs( + * org.roller.pojos.WeblogCategoryData) + */ + public List getAllWeblogCategoryDecscendentAssocs(WeblogCategoryData cat) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.add(Expression.eq("ancestorCategory", cat)); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * @see org.roller.model.WeblogManager#getWeblogCategoryAncestorAssocs(org.roller.pojos.WeblogCategoryData) + */ + public List getWeblogCategoryAncestorAssocs(WeblogCategoryData cat) + throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(WeblogCategoryAssoc.class); + criteria.add(Expression.eq("category", cat)); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + + /** + * Get the maxCount most recent non-spam Comments. If a Website is presented + * only Comments for that site will be returned. + * + * @author lance.lavandowska + */ + public List getRecentComments(WebsiteData website, int maxCount) throws RollerException + { + try + { + Session session = ((HibernateStrategy)mStrategy).getSession(); + Criteria criteria = session.createCriteria(CommentData.class); + criteria.add( /* no spam ! */ + Expression.not(Expression.eq("spam", Boolean.TRUE))); + if (website != null) + { + criteria.createAlias("weblogEntry","e"); + criteria.add(Expression.eq("e.website", website)); + } + criteria.addOrder(Order.desc("postTime")); + criteria.setMaxResults(maxCount); + return criteria.list(); + } + catch (HibernateException e) + { + throw new RollerException(e); + } + } + +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/Messages.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/Messages.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/Messages.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/Messages.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,49 @@ +/* + * Created on Sep 14, 2003 + */ +package org.roller.business.hibernate; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @author dmj + */ +public class Messages +{ + + private static final String BUNDLE_NAME = + "org.roller.business.hibernate.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = + ResourceBundle.getBundle(BUNDLE_NAME); + + private Messages() + { + } + + public static String formatString(String key, String[] args) { + return MessageFormat.format(getString(key), (Object[])args); + } + + public static String formatString(String key, String arg0, String arg1) { + return MessageFormat.format(getString(key), (Object[])new String[]{arg0,arg1}); + } + + public static String formatString(String key, String arg) { + return MessageFormat.format(getString(key), (Object[])new String[]{arg}); + } + + public static String getString(String key) + { + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + } +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/messages.properties URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/messages.properties?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/messages.properties (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/messages.properties Fri Oct 21 14:27:36 2005 @@ -0,0 +1,21 @@ + +HibernateStrategy.openedSession=OPENED session: +HibernateStrategy.closedSession=OPENED session: + +HibernateStrategy.exceptionOpeningSession=EXCEPTION opening session +HibernateStrategy.exceptionClosingSession=EXCEPTION closing session + +HibernateStrategy.exceptionStoring=EXCEPTION storing object, id={0}, class={1} +HibernateStrategy.exceptionRetrieving=EXCEPTION retrieving object, id={0}, class={1} +HibernateStrategy.exceptionRemoving=EXCEPTION removing object, id={0}, class={1} + +HibernateStrategy.duringQuery=During QUERY + +HibernateStrategy.nullNotValidId=NULL is not a valid id +HibernateStrategy.nullNotValidClass=NULL is not a valid class +HibernateStrategy.nullNotValidQuery=NULL is not a valid query +HibernateStrategy.nullNotValidArgArray=NULL is not a valid arg array +HibernateStrategy.nullNotValidArrayType=NULL is not a valid type array + +HibernateStrategy.nullPassedIn=NULL passed into storeValueObject() + Added: incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/package.html URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/package.html?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/package.html (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/hibernate/package.html Fri Oct 21 14:27:36 2005 @@ -0,0 +1,9 @@ + + + + + + +Concrete and Hibernate-based implementaitons of business layer interfaces. + + Added: incubator/roller/branches/roller_1.x/src/org/roller/business/package.html URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/package.html?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/package.html (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/package.html Fri Oct 21 14:27:36 2005 @@ -0,0 +1,27 @@ + + + + + + +Abstract implementation of the business layer interfaces. + +

At this level we avoid dependance on specific persistence engines +(e.g. Hibernate). We do this by using an interface named +{@link org.roller.business.PersistenceStrategy PersistenceStrategy} +to store, retrieve and remove +{@link org.roller.pojos.PersistentObject PersistentObjects}.

+ +diagram of Roller persistence object and strategy + +

The diagram below illustrates the dependency relationships between the +{@link org.roller.pojos org.roller.pojos}, +{@link org.roller.model org.roller.model}, and +org.roller.business packages.

+ +diagram of Roller business and persistence layers + + + Added: incubator/roller/branches/roller_1.x/src/org/roller/business/roller-persistence.png URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/roller-persistence.png?rev=327589&view=auto ============================================================================== Binary file - no diff available. Propchange: incubator/roller/branches/roller_1.x/src/org/roller/business/roller-persistence.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: incubator/roller/branches/roller_1.x/src/org/roller/business/roller-services-impl.png URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/roller-services-impl.png?rev=327589&view=auto ============================================================================== Binary file - no diff available. Propchange: incubator/roller/branches/roller_1.x/src/org/roller/business/roller-services-impl.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/FieldConstants.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/FieldConstants.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/FieldConstants.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/FieldConstants.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,33 @@ +/* + * Created on Jul 19, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search; + + +/** + * @author aim4min + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public final class FieldConstants +{ + //~ Static fields/initializers ============================================= + + public static final String ANCHOR = "anchor"; + public static final String UPDATED = "updated"; + public static final String ID = "id"; + public static final String USERNAME = "username"; + public static final String CATEGORY = "cat"; + public static final String TITLE = "title"; + public static final String PUBLISHED = "published"; + public static final String CONTENT = "content"; + public static final String CONTENT_STORED = "content_stored"; + public static final String C_CONTENT = "comment"; + public static final String C_EMAIL = "email"; + public static final String C_NAME = "name"; + public static final String CONSTANT = "constant"; + public static final String CONSTANT_V = "v"; //must be lowercase, or match the transform rules of the analyzer +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/IndexUtil.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/IndexUtil.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/IndexUtil.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/IndexUtil.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,49 @@ +/* + * Created on Jul 20, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.Token; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.index.Term; +import org.roller.business.IndexManagerImpl; + +import java.io.IOException; +import java.io.StringReader; + +/** + * @author aim4min + * + * Class containing helper methods. + */ +public class IndexUtil { + + /** + * Create a lucene term from the first token of the input string. + * + * @param field The lucene document field to create a term with + * @param input The input you wish to convert into a term + * @return Lucene search term + */ + public static final Term getTerm(String field, String input) { + if (input==null || field==null) return null; + Analyzer analyer = IndexManagerImpl.getAnalyzer(); + TokenStream tokens = analyer.tokenStream(field, + new StringReader(input)); + + Token token = null; + Term term = null; + try { + token = tokens.next(); + } catch (IOException e) {} + if (token!=null) { + String termt = token.termText(); + term = new Term(field,termt); + } + return term; + } + +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/AddEntryOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/AddEntryOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/AddEntryOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/AddEntryOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,73 @@ +/* + * Created on Jul 16, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search.operations; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.index.IndexWriter; +import org.roller.business.IndexManagerImpl; +import org.roller.model.Roller; +import org.roller.model.RollerFactory; +import org.roller.pojos.WeblogEntryData; + + +/** + * @author aim4min + * + * An operation that adds a new log entry into the index. + */ +public class AddEntryOperation extends WriteToIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(AddEntryOperation.class); + + //~ Instance fields ======================================================== + + private WeblogEntryData data; + + //~ Constructors =========================================================== + + /** + * Adds a web log entry into the index. + */ + public AddEntryOperation(IndexManagerImpl mgr, WeblogEntryData data) + { + super(mgr); + this.data = data; + } + + //~ Methods ================================================================ + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + IndexWriter writer = beginWriting(); + Roller roller = RollerFactory.getRoller(); + try + { + if (writer != null) + { + writer.addDocument(getDocument(data)); + } + } + catch (IOException e) + { + mLogger.error("Problems adding doc to index", e); + } + finally + { + if (roller != null) roller.release(); + endWriting(); + } + } + +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/IndexOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/IndexOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/IndexOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/IndexOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1 @@ +/* * Created on Jul 16, 2003 * Authored by: Mindaugas Idzelis (min@idzelis.com) */ package org.roller.business.search.operations; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.roller.business.IndexManagerImpl; import org.roller.business.search.FieldConstants; import org.roller.pojos.CommentData; import org.roller.pojos.WeblogCategoryData; import org.roller.pojos.WeblogEntryData; import org.roller.util.Utilities; /** * @author aim4min * * This is the base class for all index operation. These operations include: * * SearchOperation AddWeblogOperation RemoveWeblogOperation * RebuildUserIndexOperation * */ public abstract class IndexOperation implements Runnable { private static Log mLogger = LogFactory.getFactory().getInstance(IndexOperation.class); //~ Instance fields // ======================================================== protected IndexManagerImpl manager; private IndexReader reader; private IndexWriter writer; //~ Constructors // =========================================================== public IndexOperation(IndexManagerImpl manager) { this.manager = manager; } //~ Methods // ================================================================ protected Document getDocument(WeblogEntryData data) { StringBuffer commentEmail = new StringBuffer(); StringBuffer commentContent = new StringBuffer(); StringBuffer commentName = new StringBuffer(); List comments = data.getComments(); if (comments != null) { for (Iterator cItr = comments.iterator(); cItr.hasNext();) { CommentData comment = (CommentData) cItr.next(); if (comment.getSpam() == null || !comment.getSpam().booleanValue()) { if (comment.getContent() != null) { commentContent.append(comment.getContent()); commentContent.append(","); } if (comment.getEmail() != null) { commentEmail.append(comment.getEmail()); commentEmail.append(","); } if (comment.getName() != null) { commentName.append(comment.getName()); commentName.append(","); } } } } Document doc = new Document(); doc.add(Field.Keyword(FieldConstants.ID, data.getId())); doc.add(Field.UnIndexed(FieldConstants.ANCHOR, data.getAnchor())); doc.add(Field.Text(FieldConstants.USERNAME, data.getWebsite().getUser() .getUserName())); doc.add(Field.Text(FieldConstants.TITLE, data.getTitle())); // index the entry text, but don't store it - moved to end of block doc.add(Field.UnStored(FieldConstants.CONTENT, data.getText())); // store an abbreviated version of the entry text, but don't index doc.add(Field.UnIndexed(FieldConstants.CONTENT_STORED, Utilities .truncateNicely(Utilities.removeHTML(data.getText()), 240, 260, "..."))); doc.add(Field.Keyword(FieldConstants.UPDATED, data.getUpdateTime() .toString())); doc.add(Field.Keyword(FieldConstants.PUBLISHED, data.getPubTime() .toString())); // index Comments doc.add(Field.UnStored(FieldConstants.C_CONTENT, commentContent .toString())); doc .add(Field.UnStored(FieldConstants.C_EMAIL, commentEmail .toString())); doc.add(Field.UnStored(FieldConstants.C_NAME, commentName.toString())); doc.add(Field.UnStored(FieldConstants.CONSTANT, FieldConstants.CONSTANT_V)); // index Category WeblogCategoryData categorydata = data.getCategory(); Field category = (categorydata == null) ? Field.UnStored( FieldConstants.CATEGORY, "") : Field.Text( FieldConstants.CATEGORY, categorydata.getName()); doc.add(category); return doc; } protected IndexReader beginDeleting() { try { reader = IndexReader.open(manager.getIndexDirectory()); } catch (IOException e) { } return reader; } protected void endDeleting() { if (reader != null) { try { reader.close(); } catch (IOException e) { } } } protected IndexWriter beginWriting() { try { writer = new IndexWriter(manager.getIndexDirectory(), IndexManagerImpl.getAnalyzer(), false); } catch (IOException e) { mLogger.error("ERROR creating writer"); } return writer; } protected void endWriting() { if (writer != null) { try { writer.close(); } catch (IOException e) { mLogger.error("ERROR closing writer",e); } } } public void run() { doRun(); } protected abstract void doRun(); } \ No newline at end of file Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReIndexEntryOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReIndexEntryOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReIndexEntryOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReIndexEntryOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,92 @@ +/* + * Created on Jul 16, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search.operations; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.roller.business.IndexManagerImpl; +import org.roller.business.search.FieldConstants; +import org.roller.model.Roller; +import org.roller.model.RollerFactory; +import org.roller.pojos.WeblogEntryData; + +/** + * @author aim4min + * + * An operation that adds a new log entry into the index. + */ +public class ReIndexEntryOperation extends WriteToIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(AddEntryOperation.class); + + //~ Instance fields ======================================================== + + private WeblogEntryData data; + + //~ Constructors =========================================================== + + /** + * Adds a web log entry into the index. + */ + public ReIndexEntryOperation(IndexManagerImpl mgr, WeblogEntryData data) + { + super(mgr); + this.data = data; + } + + //~ Methods ================================================================ + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + IndexReader reader = beginDeleting(); + try + { + if (reader != null) + { + Term term = new Term(FieldConstants.ID, data.getId()); + reader.delete(term); + } + } + catch (IOException e) + { + mLogger.error("Error deleting doc from index", e); + } + finally + { + endDeleting(); + } + + IndexWriter writer = beginWriting(); + Roller roller = RollerFactory.getRoller(); + try + { + if (writer != null) + { + writer.addDocument(getDocument(data)); + } + } + catch (IOException e) + { + mLogger.error("Problems adding doc to index", e); + } + finally + { + if (roller != null) roller.release(); + endWriting(); + } + } +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReadFromIndexOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReadFromIndexOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReadFromIndexOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/ReadFromIndexOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,47 @@ + +package org.roller.business.search.operations; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.roller.business.IndexManagerImpl; + +/** + * @author aim4min + */ +public abstract class ReadFromIndexOperation extends IndexOperation +{ + + /** + * @param manager + */ + public ReadFromIndexOperation(IndexManagerImpl mgr) + { + super(mgr); + } + + private static Log mLogger = LogFactory.getFactory().getInstance( + ReadFromIndexOperation.class); + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + public final void run() + { + try + { + manager.getReadWriteLock().readLock().acquire(); + doRun(); + } + catch (InterruptedException e) + { + mLogger.info("Error acquiring read lock on index", e); + } + finally + { + manager.getReadWriteLock().readLock().release(); + } + } + +} \ No newline at end of file Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RebuildUserIndexOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RebuildUserIndexOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RebuildUserIndexOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RebuildUserIndexOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,156 @@ +/* + * Created on Jul 16, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search.operations; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.roller.RollerException; +import org.roller.business.IndexManagerImpl; +import org.roller.business.search.FieldConstants; +import org.roller.business.search.IndexUtil; +import org.roller.model.Roller; +import org.roller.model.RollerFactory; +import org.roller.model.WeblogManager; +import org.roller.pojos.WeblogEntryData; +import org.roller.pojos.WebsiteData; + + +/** + * @author aim4min + * + * An index operation that rebuilds a given users index (or all indexes.) + */ +public class RebuildUserIndexOperation extends WriteToIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(RebuildUserIndexOperation.class); + + //~ Instance fields ======================================================== + + private WebsiteData website; + + //~ Constructors =========================================================== + + /** + * Create a new operation that will recreate an index. + * + * @param website The website to rebuild the index for, or null for all users. + */ + public RebuildUserIndexOperation(IndexManagerImpl mgr, WebsiteData website) + { + super(mgr); + this.website = website; + } + + //~ Methods ================================================================ + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + Date start = new Date(); + + IndexReader reader = beginDeleting(); + + try + { + if (reader != null) + { + String userName = null; + if (website != null && website.getUser() != null) + { + userName = website.getUser().getUserName(); + } + Term tUsername = + IndexUtil.getTerm(FieldConstants.USERNAME, userName); + + if (tUsername != null) + { + reader.delete(tUsername); + } + else + { + Term all = + IndexUtil.getTerm(FieldConstants.CONSTANT, + FieldConstants.CONSTANT_V); + reader.delete(all); + } + } + } + catch (IOException e) + { + mLogger.info("Problems deleting doc from index", e); + } + finally + { + endDeleting(); + } + + IndexWriter writer = beginWriting(); + + Roller roller = RollerFactory.getRoller(); + try + { + roller.begin(); + if (writer != null) + { + WeblogManager weblogManager = roller.getWeblogManager(); + + List entries = weblogManager .getWeblogEntries( + website, // userName + null, // startDate + new Date(), // endDate // don't index 'future' entries + null, // catName + WeblogManager.PUB_ONLY, // status + null); + + for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) + { + WeblogEntryData entry = (WeblogEntryData) wbItr.next(); + writer.addDocument(getDocument(entry)); + mLogger.debug( + MessageFormat.format("Indexed entry {0}: {1}", + new Object[] {entry.getPubTime(), entry.getAnchor()})); + } + } + } + catch (Exception e) + { + mLogger.error("ERROR adding doc to index", e); + } + finally + { + endWriting(); + if (roller != null) roller.release(); + } + + Date end = new Date(); + double length = (end.getTime() - start.getTime()) / (double) 1000; + + if (website == null) + { + mLogger.info( + "Completed rebuilding index for all users in '" + length + "' secs"); + } + else + { + mLogger.info("Completed rebuilding index for '" + + website.getUser().getUserName() + "' in '" + length + "' seconds"); + } + } +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveEntryOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveEntryOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveEntryOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveEntryOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,73 @@ +/* + * Created on Jul 16, 2003 + * Authored by: Mindaugas Idzelis (min@idzelis.com) + * + */ +package org.roller.business.search.operations; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.roller.business.IndexManagerImpl; +import org.roller.business.search.FieldConstants; +import org.roller.pojos.WeblogEntryData; + + +/** + * @author aim4min + * + * An operation that removes the weblog from the index. + */ +public class RemoveEntryOperation extends WriteToIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(RemoveEntryOperation.class); + + //~ Instance fields ======================================================== + + private WeblogEntryData data; + + //~ Constructors =========================================================== + + /** + * + */ + public RemoveEntryOperation(IndexManagerImpl mgr, WeblogEntryData data) + { + super(mgr); + this.data = data; + } + + //~ Methods ================================================================ + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + IndexReader reader = beginDeleting(); + try + { + if (reader != null) + { + Term term = new Term(FieldConstants.ID, data.getId()); + reader.delete(term); + } + } + catch (IOException e) + { + mLogger.error("Error deleting doc from index", e); + } + finally + { + endDeleting(); + } + } + + +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveUserIndexOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveUserIndexOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveUserIndexOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/RemoveUserIndexOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,97 @@ +/* + * Created on Jul 16, 2003 + * + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search.operations; + +import java.io.IOException; +import java.util.Date; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.roller.business.IndexManagerImpl; +import org.roller.business.search.FieldConstants; +import org.roller.business.search.IndexUtil; +import org.roller.pojos.UserData; + + +/** + * @author aim4min + * + * An index operation that rebuilds a given users index (or all indexes.) + */ +public class RemoveUserIndexOperation extends WriteToIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(RemoveUserIndexOperation.class); + + //~ Instance fields ======================================================== + + private UserData user; + + //~ Constructors =========================================================== + + /** + * Create a new operation that will recreate an index. + * + * @param website The website to rebuild the index for, or null for all users. + */ + public RemoveUserIndexOperation(IndexManagerImpl mgr, UserData user) + { + super(mgr); + this.user = user; + } + + //~ Methods ================================================================ + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + Date start = new Date(); + + IndexReader reader = beginDeleting(); + + try + { + if (reader != null) + { + String userName = null; + if (user != null) + { + userName = user.getUserName(); + } + Term tUsername = + IndexUtil.getTerm(FieldConstants.USERNAME, userName); + + if (tUsername != null) + { + reader.delete(tUsername); + } + } + } + catch (IOException e) + { + mLogger.info("Problems deleting doc from index", e); + } + finally + { + endDeleting(); + } + + Date end = new Date(); + double length = (end.getTime() - start.getTime()) / (double) 1000; + + if (user != null) + { + mLogger.info("Completed deleting indices for '" + + user.getUserName() + "' in '" + length + "' seconds"); + } + } +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/SearchOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/SearchOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/SearchOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/SearchOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,162 @@ +/* + * Created on Jul 18, 2003 + * Authored by: Mindaugas Idzelis (min@idzelis.com) + */ +package org.roller.business.search.operations; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.MultiFieldQueryParser; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Hits; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.TermQuery; +import org.roller.business.IndexManagerImpl; +import org.roller.business.search.FieldConstants; +import org.roller.business.search.IndexUtil; +import org.roller.model.IndexManager; + + +/** + * @author aim4min + * + * An operation that searches the index. + */ +public class SearchOperation extends ReadFromIndexOperation +{ + //~ Static fields/initializers ============================================= + + private static Log mLogger = + LogFactory.getFactory().getInstance(SearchOperation.class); + + private static String[] SEARCH_FIELDS = new String[]{ + FieldConstants.CONTENT, FieldConstants.TITLE, + FieldConstants.C_CONTENT, FieldConstants.CATEGORY + }; + + private static Sort SORTER = new Sort( new SortField( + FieldConstants.PUBLISHED, SortField.STRING, true) ); + + //~ Instance fields ======================================================== + + private String term; + private String username; + private String category; + private Hits searchresults; + private String parseError; + + //~ Constructors =========================================================== + + /** + * Create a new operation that searches the index. + */ + public SearchOperation(IndexManager mgr) + { + // TODO: finish moving IndexManager to backend, so this cast is not needed + super((IndexManagerImpl)mgr); + } + + //~ Methods ================================================================ + + public void setTerm(String term) + { + this.term = term; + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void doRun() + { + searchresults = null; + + IndexSearcher searcher = null; + + try + { + IndexReader reader = manager.getSharedIndexReader(); + searcher = new IndexSearcher(reader); + + Query query = + MultiFieldQueryParser.parse( + term, SEARCH_FIELDS, new StandardAnalyzer()); + + Term tUsername = + IndexUtil.getTerm(FieldConstants.USERNAME, username); + + if (tUsername != null) + { + BooleanQuery bQuery = new BooleanQuery(); + bQuery.add(query, true, false); + bQuery.add(new TermQuery(tUsername), true, false); + query = bQuery; + } + + Term tCategory = + IndexUtil.getTerm(FieldConstants.CATEGORY, category); + + if (tCategory != null) + { + BooleanQuery bQuery = new BooleanQuery(); + bQuery.add(query, true, false); + bQuery.add(new TermQuery(tCategory), true, false); + query = bQuery; + } + searchresults = searcher.search(query, null/*Filter*/, SORTER); + } + catch (IOException e) + { + mLogger.error("Error searching index", e); + parseError = e.getMessage(); + } + catch (ParseException e) + { + // who cares? + parseError = e.getMessage(); + } + // don't need to close the reader, since we didn't do any writing! + } + + public Hits getResults() + { + return searchresults; + } + + public int getResultsCount() + { + if (searchresults == null) return -1; + + return searchresults.length(); + } + + public String getParseError() + { + return parseError; + } + + /** + * @param string + */ + public void setUsername(String username) + { + this.username = username; + } + + /** + * @param parameter + */ + public void setCategory(String category) + { + this.category = category; + } + +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/WriteToIndexOperation.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/WriteToIndexOperation.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/WriteToIndexOperation.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/WriteToIndexOperation.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,54 @@ +/* + * Created on Aug 12, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.roller.business.search.operations; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.roller.business.IndexManagerImpl; + +/** + * @author aim4min + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public abstract class WriteToIndexOperation extends IndexOperation { + + /** + * @param manager + */ + public WriteToIndexOperation(IndexManagerImpl mgr) + { + super(mgr); + } + + private static Log mLogger = + LogFactory.getFactory().getInstance(WriteToIndexOperation.class); + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() + { + try + { + manager.getReadWriteLock().writeLock().acquire(); + mLogger.info("Starting search index operation"); + doRun(); + mLogger.info("Search index operation complete"); + } + catch (InterruptedException e) + { + mLogger.error("Error acquiring write lock on index", e); + } + finally + { + manager.getReadWriteLock().writeLock().release(); + } + manager.resetSharedReader(); + } +} Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/package.html URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/package.html?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/package.html (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/operations/package.html Fri Oct 21 14:27:36 2005 @@ -0,0 +1,9 @@ + + + + + + +Lucene-based search operations to be executed by ThreadManager.
+ + Added: incubator/roller/branches/roller_1.x/src/org/roller/business/search/package.html URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/search/package.html?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/search/package.html (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/search/package.html Fri Oct 21 14:27:36 2005 @@ -0,0 +1,9 @@ + + + + + + +Utilities needed by implementation of search interface. + + Added: incubator/roller/branches/roller_1.x/src/org/roller/business/utils/ConsistencyCheck.java URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/business/utils/ConsistencyCheck.java?rev=327589&view=auto ============================================================================== --- incubator/roller/branches/roller_1.x/src/org/roller/business/utils/ConsistencyCheck.java (added) +++ incubator/roller/branches/roller_1.x/src/org/roller/business/utils/ConsistencyCheck.java Fri Oct 21 14:27:36 2005 @@ -0,0 +1,315 @@ + +package org.roller.business.utils; + +import java.io.FileInputStream; +import java.sql.*; +import java.util.*; + +/** + * Roller database consistency checker.
+ * Don't run this unless you know what you are doing!
+ * + *

Configuration:
+ * + * Program looks in current directory for db.properties file with database + * connection properties driverClassName and connectionUrl. + * + * Program expects JDBC driver jar to be on classpath.

+ * + *

Usage:
+ * + * java -cp ./WEB-INF/lib/rollerbeans.jar org.roller.business.utils.ConsistencyCheck
+ * + *
Options:
+ * -v Verbose
+ * -d Delete orphans

+ */ +public class ConsistencyCheck +{ + /** + * Consistency checker, find and optionally delete orphans. + */ + public static void main(String[] args) throws Exception + { + Properties props = new Properties(); + props.load(new FileInputStream("rollerdb.properties")); + Connection con = createConnection(props,""); + + boolean delete = false; + boolean verbose = false; + if (args.length > 0) + { + if ("-purge".equals(args[0])) + { + delete = true; + } + else if ("-v".equals(args[0])) + { + verbose = true; + } + } + + findAndDeleteOrphans(con, delete, verbose); + } + + /** + * Create connection based on properties:
+ * - driverClassName
+ * - connectionUrl
+ * - userName
+ * - password
+ */ + public static Connection createConnection(Properties props, String prefix) + throws Exception + { + Connection con = null; + if (prefix == null) + { + prefix = ""; + } + String driverClassName = props.getProperty(prefix+"driverClassName"); + String connectionUrl = props.getProperty(prefix+"connectionUrl"); + String userName = props.getProperty(prefix+"userName"); + String password = props.getProperty(prefix+"password"); + + Class.forName(driverClassName); + if (userName != null && password != null) + { + con = DriverManager.getConnection(connectionUrl, userName, password); + } + else + { + con = DriverManager.getConnection(connectionUrl); + } + return con; + } + + /** Find and optionally delete all safely deletable orphans. */ + public static void findAndDeleteOrphans(Connection con, boolean delete, boolean verbose) + throws SQLException + { + // websites with bad user? + findOrphans(con, "website", "userid", "rolleruser", delete, verbose); + + // userroles with bad user? + findOrphans(con, "userrole", "userid", "rolleruser", delete, verbose); + + // folders with bad website? + findOrphans(con, "folder", "websiteid", "website", delete, verbose); + + // bookmarks with bad folder? + findOrphans(con, "bookmark", "folderid", "folder", delete, verbose); + + // weblogcategories with bad website? + findOrphans(con, "weblogcategory", "websiteid", "website", delete, verbose); + + // weblogcategoryassocs with bad category? + findOrphans(con, "weblogcategoryassoc", "categoryid", "weblogcategory", delete, verbose); + + // weblog entries with bad website? + findOrphans(con, "weblogentry", "websiteid", "website", delete, verbose); + + // comments with bad weblogentry? + findOrphans(con, "comment", "entryid", "weblogentry", delete, verbose); + + // Referers with bad website? + findOrphans(con, "referer", "websiteid", "website", delete, verbose); + + // Referers with bad website? + findOrphans(con, "referer", "entryid", "weblogentry", delete, verbose); + + if (delete) + { + correctWeblogEntries(con); + correctWebsites(con); + correctFolderTrees(con, delete); + } + } + + /** + * @param con + * @param delete + */ + private static void correctFolderTrees(Connection con, boolean delete) throws SQLException + { + PreparedStatement rootStatement = con.prepareStatement( + "select a.id from folder as f, folderassoc as a where "+ + "f.websiteid=? and f.id=a.folderid and "+ + "a.relation='PARENT' and a.ancestorid is null"); + PreparedStatement childrenStatement = con.prepareStatement( + "select id from folderassoc where ancestorid=?"); + + // loop through all websites + Statement websitesStatement = con.createStatement(); + ResultSet websitesResultSet = + websitesStatement.executeQuery("select id from website"); + while (websitesResultSet.next()) + { + String websiteId = websitesResultSet.getString(1); + //debug("Website "+websiteId); + + // find root folder(s) + List rootIds = new LinkedList(); + rootStatement.clearParameters(); + rootStatement.setString(1, websiteId); + ResultSet rootResultSet = rootStatement.executeQuery(); + while (rootResultSet.next()) + { + rootIds.add(rootResultSet.getString(1)); + } + if (rootIds.size() > 1) + { + // too many roots, need to figure out which are bogus + Iterator rootIter = rootIds.iterator(); + while (rootIter.hasNext()) + { + String rootId = (String)rootIter.next(); + childrenStatement.clearParameters(); + childrenStatement.setString(1, rootId); + ResultSet childrenResultSet = childrenStatement.executeQuery(); + List childIds = new LinkedList(); + while (childrenResultSet.next()) + { + childIds.add(childrenResultSet.getString(1)); + } + if (childIds.size() == 0) + { + debug("Folder "+rootId+" in website "+websiteId+"is a bogus root folder!"); + } + } + } + else if (rootIds.size() == 0) + { + debug("Website "+websiteId+" has no root folder!"); + } + } + } + + private static void correctWeblogEntries(Connection con) throws SQLException + { + List entries = findOrphans(con, "weblogentry", "categoryid", "weblogcategory", false, false); + Iterator entryIter = entries.iterator(); + while (entryIter.hasNext()) + { + String entryid = (String) entryIter.next(); + Statement websiteSt = con.createStatement(); + ResultSet websiteRs = websiteSt.executeQuery( + "select websiteid from weblogentry where id="+entryid); + websiteRs.first(); + String websiteid = websiteRs.getString(0); + + String rootid = getRootCategoryId(con, websiteid); + Statement st = con.createStatement(); + st.executeUpdate("update weblogentry set categoryid='"+rootid+"' " + +" where id='"+entryid+"'"); + } + } + + public static void correctWebsites(Connection con) throws SQLException + { + List websites = findOrphans(con, "website", "defaultcatid", "weblogcategory", false, false); + Iterator websiteIter = websites.iterator(); + while (websiteIter.hasNext()) + { + String websiteid = (String) websiteIter.next(); + String rootid = getRootCategoryId(con, websiteid); + Statement st = con.createStatement(); + st.executeUpdate("update website set defaultcatid='"+rootid+"' " + +" where id='"+websiteid+"'"); + } + + websites = findOrphans(con, "website", "bloggercatid", "weblogcategory", false, false); + websiteIter = websites.iterator(); + while (websiteIter.hasNext()) + { + String websiteid = (String) websiteIter.next(); + String rootid = getRootCategoryId(con, websiteid); + Statement st = con.createStatement(); + st.executeUpdate("update website set bloggercatid='"+rootid+"' " + +"where id='"+websiteid+"'"); + } + } + + public static String getRootCategoryId(Connection con, String websiteid) + throws SQLException + { + Statement st = con.createStatement(); + String query = + "select c.id from weblogcategory as c, weblogcategoryassoc as a " + +"where a.categoryid=c.id and a.ancestorid is null " + +"and c.websiteid ='"+websiteid+"'"; + //System.out.println(query); + ResultSet rs = st.executeQuery(query); + rs.next(); + return rs.getString(1); + } + + /** Find orphans, records in a manytable that refer to a onetable that + * no longer exists. + * @param con Database connection to be used. + * @param manytable Name of the manytable. + * @param fkname Name of the foreign key field in the manytable. + * @param onetable Name of the onetable. + * @param delete True if orphans in manytable are to be deleted. + * @return List of orphans found (will be empty if delete is true. + * @throws SQLException + */ + public static List findOrphans( + Connection con, String manytable, String fkname, String onetable, boolean delete, boolean verbose) + throws SQLException + { + List orphans = new LinkedList(); + + Statement stall = con.createStatement(); + ResultSet rsall = stall.executeQuery( + "select id,"+fkname+" as fk from "+manytable); + while (rsall.next()) + { + String id = rsall.getString("id"); + String fk = rsall.getString("fk"); + if (fk != null) + { + Statement stone = con.createStatement(); + ResultSet rsone = stone.executeQuery( + "select id from "+onetable+" where id='"+fk+"' limit 1"); + if (!rsone.next()) + { + orphans.add(id); + System.out.println(" Found orphan in "+manytable+" id="+id); + } + } + } + + if (!delete) + { + debug("Orphans found in "+manytable+" = "+orphans.size()); + if (verbose) + { + Iterator iter = orphans.iterator(); + while (iter.hasNext()) + { + String id = (String) iter.next(); + debug(" "+manytable+" id="+id); + } + } + } + else + { + debug("Deleting orphans found in "+manytable+" count = "+orphans.size()); + Iterator iter = orphans.iterator(); + while (iter.hasNext()) + { + String id = (String) iter.next(); + Statement stdel = con.createStatement(); + stdel.executeUpdate("delete from "+manytable+" where id='"+id+"'"); + } + orphans = new LinkedList(); + } + return orphans; + } + + private static void debug(String msg) + { + System.out.println("DEBUG: "+msg); + } +}