You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2006/05/02 00:23:34 UTC
svn commit: r398712 [2/32] - in /incubator/roller/trunk/src/org/apache: ./
roller/ roller/business/ roller/business/hibernate/
roller/business/referrers/ roller/business/runnable/
roller/business/search/ roller/business/search/operations/ roller/busine...
Added: incubator/roller/trunk/src/org/apache/roller/business/ThemeManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/ThemeManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/ThemeManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/ThemeManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,390 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * ThemeManagerImpl.java
+ *
+ * Created on June 27, 2005, 1:33 PM
+ */
+
+package org.apache.roller.business;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.ThemeNotFoundException;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.ThemeManager;
+import org.apache.roller.model.UserManager;
+import org.apache.roller.pojos.Theme;
+import org.apache.roller.pojos.ThemeTemplate;
+import org.apache.roller.pojos.WeblogTemplate;
+import org.apache.roller.pojos.WebsiteData;
+
+
+/**
+ * Base implementation of a ThemeManager.
+ *
+ * This particular implementation reads theme data off the filesystem
+ * and assumes that those themes are not changable at runtime.
+ *
+ * @author Allen Gilliland
+ */
+public class ThemeManagerImpl implements ThemeManager {
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ThemeManagerImpl.class);
+
+ private Map themes;
+
+
+ protected ThemeManagerImpl() {
+
+ // rather than be lazy we are going to load all themes from
+ // the disk preemptively during initialization and cache them
+ mLogger.debug("Initializing ThemeManagerImpl");
+
+ this.themes = this.loadAllThemesFromDisk();
+ mLogger.info("Loaded "+this.themes.size()+" themes from disk.");
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getTheme(java.lang.String)
+ */
+ public Theme getTheme(String name)
+ throws ThemeNotFoundException, RollerException {
+
+ Theme theme = (Theme) this.themes.get(name);
+ if(theme == null)
+ throw new ThemeNotFoundException("Couldn't find theme ["+name+"]");
+
+ return theme;
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getThemeById(java.lang.String)
+ */
+ public Theme getThemeById(String id)
+ throws ThemeNotFoundException, RollerException {
+
+ // In this implementation where themes come from the filesystem we
+ // know that the name and id for a theme are the same
+ return this.getTheme(id);
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getThemesList()
+ */
+ public List getThemesList() {
+
+ List themes = new ArrayList(this.themes.keySet());
+
+ // sort 'em ... the natural sorting order for Strings is alphabetical
+ Collections.sort(themes);
+
+ return themes;
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getEnabledThemesList()
+ */
+ public List getEnabledThemesList() {
+
+ Collection all_themes = this.themes.values();
+
+ // make a new list of only the enabled themes
+ List enabled_themes = new ArrayList();
+ Iterator it = all_themes.iterator();
+ Theme theme = null;
+ while(it.hasNext()) {
+ theme = (Theme) it.next();
+ if(theme.isEnabled())
+ enabled_themes.add(theme.getName());
+ }
+
+ // sort 'em ... the natural sorting order for Strings is alphabetical
+ Collections.sort(enabled_themes);
+
+ return enabled_themes;
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getTemplate(String, String)
+ */
+ public ThemeTemplate getTemplate(String theme_name, String template_name)
+ throws ThemeNotFoundException, RollerException {
+
+ // basically we just try and lookup the theme first, then template
+ Theme theme = this.getTheme(theme_name);
+
+ return theme.getTemplate(template_name);
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getTemplateById(java.lang.String)
+ */
+ public ThemeTemplate getTemplateById(String id)
+ throws ThemeNotFoundException, RollerException {
+
+ if(id == null)
+ throw new ThemeNotFoundException("Theme id was null");
+
+ // in our case we expect a template id to be <theme>:<template>
+ // so extract each piece and do the lookup
+ String[] split = id.split(":", 2);
+ if(split.length != 2)
+ throw new ThemeNotFoundException("Invalid theme id ["+id+"]");
+
+ return this.getTemplate(split[0], split[1]);
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ThemeManager#getTemplateByLink(java.lang.String)
+ */
+ public ThemeTemplate getTemplateByLink(String theme_name, String template_link)
+ throws ThemeNotFoundException, RollerException {
+
+ // basically we just try and lookup the theme first, then template
+ Theme theme = this.getTheme(theme_name);
+
+ return theme.getTemplateByLink(template_link);
+ }
+
+
+ /**
+ * This is a convenience method which loads all the theme data from
+ * themes stored on the filesystem in the roller webapp /themes/ directory.
+ */
+ private Map loadAllThemesFromDisk() {
+
+ Map themes = new HashMap();
+
+ // NOTE: we need to figure out how to get the roller context path
+ String themespath = RollerConfig.getProperty("context.realpath");
+ if(themespath.endsWith(File.separator))
+ themespath += "themes";
+ else
+ themespath += File.separator + "themes";
+
+ // first, get a list of the themes available
+ File themesdir = new File(themespath);
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ File file =
+ new File(dir.getAbsolutePath() + File.separator + name);
+ return file.isDirectory();
+ }
+ };
+ String[] themenames = themesdir.list(filter);
+
+ if(themenames == null)
+ themenames = new String[0];
+
+ // now go through each theme and read all it's templates
+ Theme theme = null;
+ for(int i=0; i < themenames.length; i++) {
+ try {
+ theme = this.loadThemeFromDisk(themenames[i],
+ themespath + File.separator + themenames[i]);
+ themes.put(theme.getName(), theme);
+ } catch (Throwable unexpected) {
+ // shouldn't happen, so let's learn why it did
+ mLogger.error("Problem reading theme " + themenames[i], unexpected);
+ }
+ }
+
+ return themes;
+ }
+
+ /**
+ * Another convenience method which knows how to load a single theme
+ * off the filesystem and return a Theme object
+ */
+ private Theme loadThemeFromDisk(String theme_name, String themepath) {
+
+ mLogger.info("Loading theme "+theme_name);
+
+ Theme theme = new Theme();
+ theme.setName(theme_name);
+ theme.setAuthor("Roller");
+ theme.setLastEditor("Roller");
+ theme.setEnabled(true);
+
+ // start by getting a list of the .vm files for this theme
+ File themedir = new File(themepath);
+ FilenameFilter filter = new FilenameFilter()
+ {
+ public boolean accept(File dir, String name)
+ {
+ return name.endsWith(".vm");
+ }
+ };
+ String[] templates = themedir.list(filter);
+
+ // go through each .vm file and read in its contents to a ThemeTemplate
+ String template_name = null;
+ ThemeTemplate theme_template = null;
+ for (int i=0; i < templates.length; i++) {
+ // strip off the .vm part
+ template_name = templates[i].substring(0, templates[i].length() - 3);
+ File template_file = new File(themepath + File.separator + templates[i]);
+
+ // Continue reading theme even if problem encountered with one file
+ String msg = "read theme template file ["+template_file+"]";
+ if(!template_file.exists() && !template_file.canRead()) {
+ mLogger.error("Couldn't " + msg);
+ continue;
+ }
+ char[] chars = null;
+ try {
+ FileReader reader = new FileReader(template_file);
+ chars = new char[(int) template_file.length()];
+ reader.read(chars);
+ } catch (Exception noprob) {
+ mLogger.error("Exception while attempting to " + msg);
+ if (mLogger.isDebugEnabled()) mLogger.debug(noprob);
+ continue;
+ }
+
+ // construct ThemeTemplate representing this file
+ theme_template = new ThemeTemplate(
+ theme_name+":"+template_name,
+ template_name,
+ template_name,
+ new String(chars),
+ template_name,
+ new Date(template_file.lastModified()));
+
+ // add it to the theme
+ theme.setTemplate(template_name, theme_template);
+ }
+
+ // use the last mod date of the last template file
+ // as the last mod date of the theme
+ theme.setLastModified(theme_template.getLastModified());
+
+ return theme;
+ }
+
+ /**
+ * Helper method that copies down the pages from a given theme into a
+ * users weblog templates.
+ *
+ * @param rreq Request wrapper.
+ * @param theme Name of theme to save.
+ * @throws RollerException
+ */
+ public void saveThemePages(WebsiteData website, Theme theme)
+ throws RollerException {
+
+ mLogger.debug("Setting custom templates for website: "+website.getName());
+
+ try {
+ UserManager userMgr = RollerFactory.getRoller().getUserManager();
+
+ Collection templates = theme.getTemplates();
+ Iterator iter = templates.iterator();
+ ThemeTemplate theme_template = null;
+ while ( iter.hasNext() ) {
+ theme_template = (ThemeTemplate) iter.next();
+
+ WeblogTemplate template = null;
+
+ if(theme_template.getName().equals(WeblogTemplate.DEFAULT_PAGE)) {
+ // this is the main Weblog template
+ try {
+ template = userMgr.getPage(website.getDefaultPageId());
+ } catch(Exception e) {
+ // user may not have a default page yet
+ }
+ } else {
+ // any other template
+ template = userMgr.getPageByName(website, theme_template.getName());
+ }
+
+
+ if (template != null) {
+ // User already has page by that name, so overwrite it.
+ template.setContents(theme_template.getContents());
+
+ } else {
+ // User does not have page by that name, so create new page.
+ template = new WeblogTemplate( null,
+ website, // website
+ theme_template.getName(), // name
+ theme_template.getDescription(), // description
+ theme_template.getName(), // link
+ theme_template.getContents(), // contents
+ new Date() // last mod
+ );
+ userMgr.savePage( template );
+ }
+ }
+
+ // now update this website's theme to custom
+ website.setEditorTheme(Theme.CUSTOM);
+
+ // if this is the first time someone is customizing a theme then
+ // we need to set a default page
+ if(website.getDefaultPageId() == null ||
+ website.getDefaultPageId().trim().equals("") ||
+ website.getDefaultPageId().equals("dummy")) {
+ // we have to go back to the db to figure out the id
+ WeblogTemplate template = userMgr.getPageByName(website, "Weblog");
+ if(template != null) {
+ mLogger.debug("Setting default page to "+template.getId());
+ website.setDefaultPageId(template.getId());
+ }
+ }
+
+ // we also want to set the weblogdayid
+ WeblogTemplate dayTemplate = userMgr.getPageByName(website, "_day");
+ if(dayTemplate != null) {
+ mLogger.debug("Setting default day page to "+dayTemplate.getId());
+ website.setWeblogDayPageId(dayTemplate.getId());
+ }
+
+ // save our updated website
+ userMgr.saveWebsite(website);
+
+ } catch (Exception e) {
+ mLogger.error("ERROR in action",e);
+ throw new RollerException( e );
+ }
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/ThreadManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/ThreadManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/ThreadManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/ThreadManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,109 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.roller.business;
+
+import EDU.oswego.cs.dl.util.concurrent.BoundedBuffer;
+import EDU.oswego.cs.dl.util.concurrent.DirectExecutor;
+import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
+import EDU.oswego.cs.dl.util.concurrent.ThreadFactory;
+
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.roller.model.ThreadManager;
+import org.apache.roller.util.DateUtil;
+
+/**
+ * Manage Roller's background thread use. Currently, Roller starts background
+ * threads for two purposes: 1) the nightly purge of referer counts and 2)
+ * following linkbacks (only occurs if linkbacks are enabled).
+ *
+ * @author aim4min
+ */
+public class ThreadManagerImpl implements ThreadManager
+{
+ private PooledExecutor backgroundExecutor;
+ private DirectExecutor nodelayExecutor;
+ private Timer scheduler;
+
+ public ThreadManagerImpl()
+ {
+ backgroundExecutor = new PooledExecutor(new BoundedBuffer(10), 25);
+ backgroundExecutor.setMinimumPoolSize(4);
+ backgroundExecutor.setKeepAliveTime(1000 * 60 * 5);
+ backgroundExecutor.waitWhenBlocked();
+ backgroundExecutor.createThreads(9);
+
+ backgroundExecutor.setThreadFactory(new ThreadFactory() {
+ public Thread newThread(Runnable command)
+ {
+ Thread t = new Thread(command);
+ t.setDaemon(false);
+ t.setName("Background Execution Threads");
+ t.setPriority(Thread.NORM_PRIORITY);
+
+ return t;
+ }
+ });
+
+ nodelayExecutor = new DirectExecutor();
+ scheduler = new Timer(true);
+ }
+
+ public void executeInBackground(Runnable runnable)
+ throws InterruptedException
+ {
+ backgroundExecutor.execute(runnable);
+ }
+
+ public void executeInForeground(Runnable runnable)
+ throws InterruptedException
+ {
+ nodelayExecutor.execute(runnable);
+ }
+
+ public void scheduleDailyTimerTask(TimerTask task)
+ {
+ scheduler.scheduleAtFixedRate(task,
+ DateUtil.getEndOfDay(new Date()), DateUtil.millisInDay);
+ }
+
+ public void scheduleHourlyTimerTask(TimerTask task)
+ {
+ scheduler.scheduleAtFixedRate(task, new Date(), 60*60*1000);
+ }
+
+ public void scheduleFixedRateTimerTask(TimerTask task, long delayMins, long periodMins) {
+ if (periodMins < MIN_RATE_INTERVAL_MINS) {
+ throw new IllegalArgumentException("Period (" + periodMins +
+ ") shorter than minimum allowed (" + MIN_RATE_INTERVAL_MINS + ")");
+ }
+ scheduler.scheduleAtFixedRate(task, delayMins * 60 * 1000, periodMins * 60 * 1000);
+ }
+
+ public void shutdown()
+ {
+ backgroundExecutor.shutdownAfterProcessingCurrentlyQueuedTasks();
+ scheduler.cancel();
+ }
+
+ public void release()
+ {
+ }
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateAutoPingManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateAutoPingManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateAutoPingManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateAutoPingManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.business.hibernate;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.criterion.Expression;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.AutoPingData;
+import org.apache.roller.pojos.PingTargetData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WebsiteData;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.config.PingConfig;
+import org.apache.roller.model.AutoPingManager;
+import org.apache.roller.model.PingQueueManager;
+import org.apache.roller.model.RollerFactory;
+
+
+/**
+ * Hibernate implementation of the AutoPingManager.
+ *
+ * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
+ */
+public class HibernateAutoPingManagerImpl implements AutoPingManager {
+
+ static final long serialVersionUID = 5420615676256979199L;
+
+ private static Log log = LogFactory.getLog(HibernateAutoPingManagerImpl.class);
+
+ private HibernatePersistenceStrategy strategy = null;
+
+
+ public HibernateAutoPingManagerImpl(HibernatePersistenceStrategy strat) {
+ this.strategy = strat;
+ }
+
+
+ public AutoPingData getAutoPing(String id) throws RollerException {
+ return (AutoPingData) strategy.load(id, AutoPingData.class);
+ }
+
+
+ public void saveAutoPing(AutoPingData autoPing) throws RollerException {
+ strategy.store(autoPing);
+ }
+
+
+ public void removeAutoPing(AutoPingData autoPing) throws RollerException {
+ //TODO: first remove all related category restrictions (category restrictions are not yet implemented)
+ strategy.remove(autoPing);
+ }
+
+
+ public void removeAutoPing(PingTargetData pingTarget, WebsiteData website) throws RollerException {
+ try {
+ Session session = strategy.getSession();
+ Criteria criteria = session.createCriteria(AutoPingData.class);
+
+ // Currently category restrictions are not yet implemented, so we
+ // return all auto ping configs for the website.
+ criteria.add(Expression.eq("pingTarget", pingTarget));
+ criteria.add(Expression.eq("website", website));
+ List matches = criteria.list();
+
+ // This should have at most one element, but we remove them all regardless.
+ this.removeAutoPings(matches);
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public void removeAutoPings(Collection autopings) throws RollerException {
+
+ // just go through the list and remove each auto ping
+ Iterator pings = autopings.iterator();
+ while (pings.hasNext()) {
+ this.strategy.remove((AutoPingData) pings.next());
+ }
+ }
+
+
+ public void removeAllAutoPings() throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(AutoPingData.class);
+ List allAutoPings = criteria.list();
+ this.removeAutoPings(allAutoPings);
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public void queueApplicableAutoPings(WeblogEntryData changedWeblogEntry) throws RollerException {
+ if (PingConfig.getSuspendPingProcessing()) {
+ if (log.isDebugEnabled()) log.debug("Ping processing is suspended. No auto pings will be queued.");
+ return;
+ }
+
+ // TODO: new manager method for addQueueEntries(list)?
+ PingQueueManager pingQueueMgr = RollerFactory.getRoller().getPingQueueManager();
+ List applicableAutopings = getApplicableAutoPings(changedWeblogEntry);
+ for (Iterator i = applicableAutopings.iterator(); i.hasNext(); ) {
+ AutoPingData autoPing = (AutoPingData) i.next();
+ pingQueueMgr.addQueueEntry(autoPing);
+ }
+ }
+
+
+ public List getAutoPingsByWebsite(WebsiteData website) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(AutoPingData.class);
+ // Currently category restrictions are not yet implemented, so we return all auto ping configs for the
+ // website.
+ criteria.add(Expression.eq("website", website));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public List getAutoPingsByTarget(PingTargetData pingTarget) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(AutoPingData.class);
+ // Currently category restrictions are not yet implemented, so we return all auto ping configs for the
+ // website.
+ criteria.add(Expression.eq("pingTarget", pingTarget));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public List getApplicableAutoPings(WeblogEntryData changedWeblogEntry) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(AutoPingData.class);
+ // Currently category restrictions are not yet implemented, so we return all auto ping configs for the
+ // website.
+ criteria.add(Expression.eq("website", changedWeblogEntry.getWebsite()));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public List getCategoryRestrictions(AutoPingData autoPing) throws RollerException {
+ return Collections.EMPTY_LIST;
+ }
+
+
+ public void setCategoryRestrictions(AutoPingData autoPing, Collection newCategories) {
+ // NOT YET IMPLEMENTED
+ return;
+ }
+
+
+ public void release() {}
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateBookmarkManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateBookmarkManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateBookmarkManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateBookmarkManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,544 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Jun 18, 2004
+ */
+package org.apache.roller.business.hibernate;
+
+import java.io.IOException;
+import java.io.StringReader;
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.criterion.Expression;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.Assoc;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.pojos.FolderAssoc;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.WebsiteData;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.apache.roller.model.BookmarkManager;
+import org.apache.roller.util.Utilities;
+
+
+/**
+ * Hibernate implementation of the BookmarkManager.
+ */
+public class HibernateBookmarkManagerImpl implements BookmarkManager {
+
+ static final long serialVersionUID = 5286654557062382772L;
+
+ private static Log log = LogFactory.getLog(HibernateBookmarkManagerImpl.class);
+
+ private HibernatePersistenceStrategy strategy = null;
+
+
+ /**
+ * @param pstrategy
+ * @param roller
+ */
+ public HibernateBookmarkManagerImpl(HibernatePersistenceStrategy strat) {
+ log.debug("Instantiating Hibernate Bookmark Manager");
+
+ this.strategy = strat;
+ }
+
+
+ public void saveBookmark(BookmarkData bookmark) throws RollerException {
+ this.strategy.store(bookmark);
+ }
+
+
+ public BookmarkData getBookmark(String id) throws RollerException {
+ BookmarkData bd = (BookmarkData)
+ strategy.load(id, BookmarkData.class);
+ // TODO: huh? why do we do this?
+ if (bd != null) bd.setBookmarkManager(this);
+ return bd;
+ }
+
+
+ public void removeBookmark(BookmarkData bookmark) throws RollerException {
+ this.strategy.remove(bookmark);
+ }
+
+ //------------------------------------------------------------ Folder CRUD
+
+
+ public void saveFolder(FolderData folder) throws RollerException {
+
+ if(isDuplicateFolderName(folder)) {
+ throw new RollerException("Duplicate folder name");
+ }
+
+ this.strategy.store(folder);
+ }
+
+
+ public void removeFolder(FolderData folder) throws RollerException {
+
+ this.strategy.remove(folder);
+ }
+
+
+ /**
+ * Retrieve folder and lazy-load it's sub-folders and bookmarks.
+ */
+ public FolderData getFolder(String id) throws RollerException {
+ return (FolderData)strategy.load(id, FolderData.class);
+ }
+
+ //------------------------------------------------------------ Operations
+
+ public void importBookmarks(WebsiteData website, String folderName, String opml)
+ throws RollerException {
+
+ String msg = "importBookmarks";
+ try {
+ // Build JDOC document OPML string
+ SAXBuilder builder = new SAXBuilder();
+ StringReader reader = new StringReader( opml );
+ Document doc = builder.build( reader );
+
+ FolderData newFolder = getFolder(website, folderName);
+ if (newFolder == null) {
+ newFolder = new FolderData(
+ getRootFolder(website), folderName, folderName, website);
+ this.strategy.store(newFolder);
+ }
+
+ // Iterate through children of OPML body, importing each
+ Element body = doc.getRootElement().getChild("body");
+ Iterator iter = body.getChildren().iterator();
+ while (iter.hasNext()) {
+ Element elem = (Element)iter.next();
+ importOpmlElement( website, elem, newFolder );
+ }
+
+ } catch (Exception ex) {
+ throw new RollerException(ex);
+ }
+ }
+
+ // convenience method used when importing bookmarks
+ // NOTE: this method does not commit any changes, that is done by importBookmarks()
+ private void importOpmlElement(
+ WebsiteData website, Element elem, FolderData parent)
+ throws RollerException {
+ String text = elem.getAttributeValue("text");
+ String title = elem.getAttributeValue("title");
+ String desc = elem.getAttributeValue("description");
+ String url = elem.getAttributeValue("url");
+ //String type = elem.getAttributeValue("type");
+ String xmlUrl = elem.getAttributeValue("xmlUrl");
+ String htmlUrl = elem.getAttributeValue("htmlUrl");
+
+ title = null!=title ? title : text;
+ desc = null!=desc ? desc : title;
+ xmlUrl = null!=xmlUrl ? xmlUrl : url;
+ url = null!=htmlUrl ? htmlUrl : url;
+
+ if (elem.getChildren().size()==0) {
+ // Leaf element. Store a bookmark
+ // Currently bookmarks must have at least a name and HTML url to be stored. Previous logic was
+ // trying to skip invalid ones, but was letting ones with an xml url and no html url through
+ // which could result in a db exception.
+ // TODO: Consider providing error feedback instead of silently skipping the invalid bookmarks here.
+ if (null != title && null != url) {
+ BookmarkData bd = new BookmarkData(parent,
+ title,
+ desc,
+ url,
+ xmlUrl,
+ new Integer(0),
+ new Integer(100),
+ null);
+ parent.addBookmark(bd);
+ // TODO: maybe this should be saving the folder?
+ this.strategy.store(bd);
+ }
+ } else {
+ // Store a folder
+ FolderData fd = new FolderData(
+ parent,
+ title,
+ desc,
+ parent.getWebsite());
+ this.strategy.store(fd);
+
+ // Import folder's children
+ Iterator iter = elem.getChildren("outline").iterator();
+ while ( iter.hasNext() ) {
+ Element subelem = (Element)iter.next();
+ importOpmlElement( website, subelem, fd );
+ }
+ }
+ }
+
+ //----------------------------------------------------------------
+ public void moveFolderContents(FolderData src, FolderData dest)
+ throws RollerException {
+
+ if (dest.descendentOf(src)) {
+ throw new RollerException(
+ "ERROR cannot move parent folder into it's own child");
+ }
+
+ try {
+ // Add to destination folder
+ LinkedList deleteList = new LinkedList();
+ Iterator srcBookmarks = src.getBookmarks().iterator();
+ while (srcBookmarks.hasNext()) {
+ BookmarkData bd = (BookmarkData)srcBookmarks.next();
+ deleteList.add(bd);
+
+ BookmarkData movedBd = new BookmarkData();
+ movedBd.setData(bd);
+ movedBd.setId(null);
+
+ dest.addBookmark(movedBd);
+ this.strategy.store(movedBd);
+ }
+
+ // Remove from source folder
+ Iterator deleteIter = deleteList.iterator();
+ while (deleteIter.hasNext()) {
+ BookmarkData bd = (BookmarkData)deleteIter.next();
+ src.removeBookmark(bd);
+ // TODO: this won't conflict with the bookmark we store above right?
+ this.strategy.remove(bd);
+ }
+
+ } catch (Exception ex) {
+ throw new RollerException(ex);
+ }
+ }
+
+ //----------------------------------------------------------------
+ public void removeFolderContents(FolderData src) throws RollerException {
+
+ // just go through the folder and remove each bookmark
+ Iterator srcBookmarks = src.getBookmarks().iterator();
+ while (srcBookmarks.hasNext()) {
+ BookmarkData bd = (BookmarkData)srcBookmarks.next();
+ this.strategy.remove(bd);
+ }
+ }
+
+ //---------------------------------------------------------------- Queries
+
+ public FolderData getFolder(WebsiteData website, String folderPath)
+ throws RollerException {
+ return getFolderByPath(website, null, folderPath);
+ }
+
+ public String getPath(FolderData folder) throws RollerException {
+ if (null == folder.getParent()) {
+ return "/";
+ } else {
+ String parentPath = getPath(folder.getParent());
+ parentPath = "/".equals(parentPath) ? "" : parentPath;
+ return parentPath + "/" + folder.getName();
+ }
+ }
+
+ public FolderData getFolderByPath(
+ WebsiteData website, FolderData folder, String path)
+ throws RollerException {
+ final Iterator folders;
+ final String[] pathArray = Utilities.stringToStringArray(path, "/");
+
+ if (folder == null && (null == path || "".equals(path.trim()))) {
+ throw new RollerException("Bad arguments.");
+ }
+
+ if (path.trim().equals("/")) {
+ return getRootFolder(website);
+ } else if (folder == null || path.trim().startsWith("/")) {
+ folders = getRootFolder(website).getFolders().iterator();
+ } else {
+ folders = folder.getFolders().iterator();
+ }
+
+ while (folders.hasNext()) {
+ FolderData possibleMatch = (FolderData)folders.next();
+ if (possibleMatch.getName().equals(pathArray[0])) {
+ if (pathArray.length == 1) {
+ return possibleMatch;
+ } else {
+ String[] subpath = new String[pathArray.length - 1];
+ System.arraycopy(pathArray, 1, subpath, 0, subpath.length);
+
+ String pathString= Utilities.stringArrayToString(subpath,"/");
+ return getFolderByPath(website, possibleMatch, pathString);
+ }
+ }
+ }
+
+ // The folder did not match and neither did any subfolders
+ return null;
+ }
+
+ //----------------------------------------------- FolderAssoc CRUD
+
+
+ public FolderAssoc retrieveFolderAssoc(String id) throws RollerException {
+ return (FolderAssoc)strategy.load(id, FolderAssoc.class);
+ }
+
+ public void release() {}
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#retrieveBookmarks(
+ * org.apache.roller.pojos.FolderData, boolean)
+ */
+ public List getBookmarks(FolderData folder, boolean subfolders)
+ throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ List bookmarks = new LinkedList();
+ if (subfolders) {
+ // get bookmarks in subfolders
+ Criteria assocsQuery = session
+ .createCriteria(FolderAssoc.class);
+ assocsQuery.add(Expression.eq("ancestorFolder", folder));
+ Iterator assocs = assocsQuery.list().iterator();
+ while (assocs.hasNext()) {
+ FolderAssoc assoc = (FolderAssoc) assocs.next();
+ Criteria bookmarksQuery = session
+ .createCriteria(BookmarkData.class);
+ bookmarksQuery.add(Expression.eq("folder", assoc
+ .getFolder()));
+ Iterator bookmarkIter = bookmarksQuery.list().iterator();
+ while (bookmarkIter.hasNext()) {
+ BookmarkData entry = (BookmarkData) bookmarkIter.next();
+ bookmarks.add(entry);
+ }
+ }
+ }
+
+ // get bookmarks in folder
+ Criteria bookmarksQuery = session
+ .createCriteria(BookmarkData.class);
+ bookmarksQuery.add(Expression.eq("folder", folder));
+ Iterator bookmarkIter = bookmarksQuery.list().iterator();
+ while (bookmarkIter.hasNext()) {
+ BookmarkData bookmark = (BookmarkData) bookmarkIter.next();
+ bookmarks.add(bookmark);
+ }
+ return bookmarks;
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ public FolderData getRootFolder(WebsiteData website) throws RollerException {
+ if (website == null)
+ throw new RollerException("website is null");
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.createAlias("folder", "f");
+ criteria.add(Expression.eq("f.website", website));
+ criteria.add(Expression.isNull("ancestorFolder"));
+ criteria.add(Expression.eq("relation", FolderAssoc.PARENT));
+ List results = criteria.list();
+ if (results.size() > 1) {
+ // Should not have more than one root
+ throw new RollerException(
+ "More than one root folder found for website "
+ + website.getId());
+ } else if (results.size() == 1) {
+ // Return root
+ return ((FolderAssoc) results.get(0)).getFolder();
+ }
+ return null;
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ public List getAllFolders(WebsiteData website) throws RollerException {
+ if (website == null)
+ throw new RollerException("Website is null");
+
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderData.class);
+ criteria.add(Expression.eq("website", website));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+
+ }
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#isDuplicateFolderName(org.apache.roller.pojos.FolderData)
+ */
+ public boolean isDuplicateFolderName(FolderData folder) throws RollerException {
+ // ensure that no sibling folders share the same name
+ boolean isNewFolder = (folder.getId() == null);
+ FolderData parent =
+ isNewFolder ? (FolderData)folder.getNewParent() : folder.getParent();
+
+ if (null != parent) {
+ List sameNames;
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.createAlias("folder", "f");
+ criteria.add(Expression.eq("f.name", folder.getName()));
+ criteria.add(Expression.eq("ancestorFolder", parent));
+ criteria.add(Expression.eq("relation", Assoc.PARENT));
+ sameNames = criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ // If we got some matches
+ if (sameNames.size() > 0) {
+ // if we're saving a new folder, any matches are dups
+ if (isNewFolder) return true;
+ // otherwise it's a dup it isn't the same one (one match with the same id).
+ if (!(sameNames.size() == 1 && folder.getId().equals(((FolderAssoc)sameNames.get(0)).getFolder().getId())))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#getFolderParentAssoc(
+ * org.apache.roller.pojos.FolderData)
+ */
+ public Assoc getFolderParentAssoc(FolderData folder) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.add(Expression.eq("folder", folder));
+ 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.apache.roller.model.BookmarkManager#getFolderChildAssocs(
+ * org.apache.roller.pojos.FolderData)
+ */
+ public List getFolderChildAssocs(FolderData folder) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.add(Expression.eq("ancestorFolder", folder));
+ criteria.add(Expression.eq("relation", Assoc.PARENT));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#getAllFolderDecscendentAssocs(
+ * org.apache.roller.pojos.FolderData)
+ */
+ public List getAllFolderDecscendentAssocs(FolderData folder) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.add(Expression.eq("ancestorFolder", folder));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#getFolderAncestorAssocs(
+ * org.apache.roller.pojos.FolderData)
+ */
+ public List getFolderAncestorAssocs(FolderData folder) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.add(Expression.eq("folder", folder));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ /**
+ * @see org.apache.roller.model.BookmarkManager#isFolderInUse(org.apache.roller.pojos.FolderData)
+ */
+ public boolean isFolderInUse(FolderData folder) throws RollerException {
+ try {
+ // We consider a folder to be "in use" if it contains any bookmarks or has
+ // any children.
+
+ // We first determine the number of bookmark entries.
+ // NOTE: This seems to be an attempt to optimize, rather than just use getBookmarks(),
+ // but I'm not sure that this optimization is really worthwhile, and it ignores
+ // caching in the case that the (lazy) getBookmarks has been done already. --agangolli
+ // TODO: condider changing to just use getBookmarks().size()
+
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(BookmarkData.class);
+ criteria.add(Expression.eq("folder", folder));
+ criteria.setMaxResults(1);
+ int entryCount = criteria.list().size();
+
+ // Return true if we have bookmarks or (, failing that, then checking) if we have children
+ return (entryCount > 0 || folder.getFolders().size() > 0);
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+ public boolean isDescendentOf(FolderData child, FolderData ancestor)
+ throws RollerException {
+ boolean ret = false;
+ try {
+ Session session = ((HibernatePersistenceStrategy)strategy).getSession();
+ Criteria criteria = session.createCriteria(FolderAssoc.class);
+ criteria.add(Expression.eq("folder", child));
+ criteria.add(Expression.eq("ancestorFolder", ancestor));
+ ret = criteria.list().size() > 0;
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ return ret;
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateConfigManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateConfigManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateConfigManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateConfigManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,107 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Jun 18, 2004
+ */
+package org.apache.roller.business.hibernate;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.RollerConfigData;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.model.ConfigManager;
+
+
+/**
+ * The *OLD* Roller configuration mechanism.
+ *
+ * This has been replaced by the PropertiesManager and the roller.properties
+ * file.
+ */
+public class HibernateConfigManagerImpl implements ConfigManager {
+
+ static final long serialVersionUID = -3674252864091781177L;
+
+ private static Log log = LogFactory.getLog(HibernateConfigManagerImpl.class);
+
+ private HibernatePersistenceStrategy strategy = null;
+
+
+ public HibernateConfigManagerImpl(HibernatePersistenceStrategy strategy) {
+ log.debug("Instantiating Hibernate Config Manager");
+
+ this.strategy = strategy;
+ }
+
+
+ /**
+ * @see org.apache.roller.model.ConfigManager#storeRollerConfig(org.apache.roller.pojos.RollerConfig)
+ */
+ public void storeRollerConfig(RollerConfigData data) throws RollerException {
+ // no longer supported
+ }
+
+
+ /**
+ * This isn't part of the ConfigManager Interface, because really
+ * we shouldn't ever delete the RollerConfig. This is mostly here
+ * to assist with unit testing.
+ */
+ public void removeRollerConfig(String id) throws RollerException {
+ // no longer supported
+ }
+
+
+ /**
+ * Fetch all RollerConfigs and return the first one, if any.
+ * Note: there should only be one!
+ * @see org.apache.roller.model.ConfigManager#getRollerConfig()
+ */
+ public RollerConfigData getRollerConfig() throws RollerException {
+
+ log.error("Someone is trying to use the old config!!\n"+
+ "This configuration mechanism has been deprecated\n"+
+ "You should see this message only once when you first upgrade\n"+
+ "your installation to roller 1.2\n\n"+
+ "If you continue to see this message please shoot us an email\n"+
+ "at roller-dev@incubator.apache.org with some output\n"+
+ "from your log files.\n");
+
+ try {
+ Session session = this.strategy.getSession();
+ Criteria criteria = session.createCriteria(RollerConfigData.class);
+ criteria.setMaxResults(1);
+ return (RollerConfigData) criteria.uniqueResult();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public RollerConfigData readFromFile(String file) {
+ return null;
+ }
+
+
+ public void release() {}
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePersistenceStrategy.java Mon May 1 15:23:02 2006
@@ -0,0 +1,403 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Mar 7, 2003
+ */
+package org.apache.roller.business.hibernate;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.Assoc;
+import org.apache.roller.pojos.HierarchicalPersistentObject;
+import org.apache.roller.pojos.PersistentObject;
+
+
+/**
+ * Base class for Hibernate persistence implementation.
+ *
+ * This class serves as a helper/util class for all of the Hibernate
+ * manager implementations by providing a set of basic persistence methods
+ * that can be easily reused.
+ *
+ */
+public class HibernatePersistenceStrategy {
+
+ static final long serialVersionUID = 2561090040518169098L;
+
+ private static SessionFactory sessionFactory = null;
+
+ private static Log log = LogFactory.getLog(HibernatePersistenceStrategy.class);
+
+
+ /**
+ * Construct using Hibernate Session Factory.
+ */
+ public HibernatePersistenceStrategy() throws Exception {
+
+ log.debug("Initializing Hibernate SessionFactory");
+
+ Configuration config = new Configuration();
+ config.configure("/hibernate.cfg.xml");
+ this.sessionFactory = config.buildSessionFactory();
+
+ }
+
+
+ /**
+ * Get persistence session on current thread.
+ *
+ * This will open a new Session if one is not already open, otherwise
+ * it will return the already open Session.
+ */
+ protected Session getSession() {
+
+ log.debug("Opening Hibernate Session");
+
+ // get Hibernate Session and make sure we are in a transaction
+ // this will join existing Session/Transaction if they exist
+ Session session = sessionFactory.getCurrentSession();
+ session.beginTransaction();
+
+ return session;
+ }
+
+
+ protected void flush() throws RollerException {
+
+ Session session = getSession();
+ try {
+ session.getTransaction().commit();
+ } catch(Throwable t) {
+ // uh oh ... failed persisting, gotta release
+ release();
+ }
+ }
+
+
+ /**
+ * Release database session, rollback any uncommitted changes.
+ *
+ * IMPORTANT: we don't want to open a transaction and force the use of a
+ * jdbc connection just to close the session and do a rollback, so this
+ * method must be sensitive about how the release is triggered.
+ *
+ * In particular we don't want to use our custom getSession() method which
+ * automatically begins a transaction. Instead we get a Session and check
+ * if there is already an active transaction that needs to be rolled back.
+ * If not then we can close the Session without ever getting a jdbc
+ * connection, which is important for scalability.
+ */
+ protected void release() {
+
+ try {
+ Session session = sessionFactory.getCurrentSession();
+
+ if(session != null && session.isOpen()) {
+
+ log.debug("Closing Hibernate Session");
+
+ try {
+ Transaction tx = session.getTransaction();
+
+ if(tx != null && tx.isActive()) {
+ log.debug("Forcing rollback on active transaction");
+ tx.rollback();
+ }
+ } catch(Throwable t) {
+ log.error("ERROR doing Hibernate rollback", t);
+ } finally {
+ if(session.isOpen()) {
+ session.close();
+ }
+ }
+ }
+ } catch(Throwable t) {
+ log.error("ERROR closing Hibernate Session", t);
+ }
+ }
+
+
+ /**
+ * Retrieve object. We return null if the object is not found.
+ */
+ protected PersistentObject load(String id, Class clazz) throws RollerException {
+
+ if(id == null || clazz == null) {
+ throw new RollerException("Cannot load objects when value is null");
+ }
+
+ return (PersistentObject) getSession().get(clazz, id);
+ }
+
+
+ /**
+ * Store object.
+ */
+ protected void store(PersistentObject obj) throws HibernateException {
+
+ if(obj == null) {
+ throw new HibernateException("Cannot save null object");
+ }
+
+ Session session = getSession();
+
+ // TODO BACKEND: this is wacky, we should double check logic here
+
+ // TODO BACKEND: better to use session.saveOrUpdate() here, if possible
+ if ( obj.getId() == null || obj.getId().trim().equals("") ) {
+ // Object has never been written to database, so save it.
+ // This makes obj into a persistent instance.
+ session.save(obj);
+ }
+
+ /*
+ * technically we shouldn't have any reason to support the saving
+ * of detached objects, so at some point we should re-evaluate this.
+ *
+ * objects should be re-attached before being saved again. it would
+ * be more appropriate to reject these kinds of saves because they are
+ * not really safe.
+ *
+ * NOTE: this may be coming from the way we use formbeans on the UI.
+ * we very commonly repopulate all data in a pojo (including id) from
+ * form data rather than properly loading the object from a Session
+ * then modifying its properties.
+ */
+ if ( !session.contains(obj) ) {
+
+ log.debug("storing detached object: "+obj.toString());
+
+ // Object has been written to database, but instance passed in
+ // is not a persistent instance, so must be loaded into session.
+ PersistentObject vo =
+ (PersistentObject)session.load(obj.getClass(),obj.getId());
+ vo.setData(obj);
+ obj = vo;
+ }
+
+ }
+
+
+ /**
+ * Remove object.
+ *
+ * TODO BACKEND: force the use of remove(Object) moving forward.
+ */
+ protected void remove(String id, Class clazz) throws HibernateException {
+
+ if(id == null || clazz == null) {
+ throw new HibernateException("Cannot remove object when values are null");
+ }
+
+ Session session = getSession();
+
+ PersistentObject obj = (PersistentObject) session.load(clazz,id);
+ session.delete(obj);
+ }
+
+
+ /**
+ * Remove object.
+ */
+ protected void remove(PersistentObject obj) throws HibernateException {
+
+ if(obj == null) {
+ throw new HibernateException("Cannot remove null object");
+ }
+
+ // TODO BACKEND: can hibernate take care of this check for us?
+ // what happens if object does not use id?
+ // can't remove transient objects
+ if (obj.getId() != null) {
+
+ getSession().delete(obj);
+ }
+ }
+
+
+ /**
+ * Store hierarchical object.
+ *
+ * NOTE: if the object has proper cascade setting then is all this necessary?
+ */
+ protected void store(HierarchicalPersistentObject obj)
+ throws HibernateException, RollerException {
+
+ if(obj == null) {
+ throw new HibernateException("Cannot save null object");
+ }
+
+ log.debug("Storing hierarchical object "+obj);
+
+ Session session = getSession();
+
+ HierarchicalPersistentObject mNewParent = obj.getNewParent();
+ boolean fresh = (obj.getId() == null || "".equals(obj.getId()));
+
+ if (fresh) {
+ // Object has never been written to database, so save it.
+ // This makes obj into a persistent instance.
+ session.save(obj);
+ }
+
+ if(!session.contains(obj)) {
+
+ // Object has been written to database, but instance passed in
+ // is not a persistent instance, so must be loaded into session.
+ HierarchicalPersistentObject vo =
+ (HierarchicalPersistentObject)session.load(obj.getClass(),obj.getId());
+ vo.setData(obj);
+ obj = vo;
+ }
+
+ if (fresh) {
+ // Every fresh cat needs a parent assoc
+ Assoc parentAssoc = obj.createAssoc(
+ obj, mNewParent, Assoc.PARENT);
+ this.store(parentAssoc);
+ } else if (null != mNewParent) {
+ // New parent must be added to parentAssoc
+ Assoc parentAssoc = obj.getParentAssoc();
+ if(parentAssoc == null)
+ log.error("parent assoc is null");
+ parentAssoc.setAncestor(mNewParent);
+ this.store(parentAssoc);
+ }
+
+ // Clear out existing grandparent associations
+ Iterator ancestors = obj.getAncestorAssocs().iterator();
+ while (ancestors.hasNext()) {
+ Assoc assoc = (Assoc)ancestors.next();
+ if (assoc.getRelation().equals(Assoc.GRANDPARENT)) {
+ this.remove(assoc);
+ }
+ }
+
+ // Walk parent assocations, creating new grandparent associations
+ int count = 0;
+ Assoc currentAssoc = obj.getParentAssoc();
+ while (null != currentAssoc.getAncestor()) {
+ if (count > 0) {
+ Assoc assoc = obj.createAssoc(obj,
+ currentAssoc.getAncestor(),
+ Assoc.GRANDPARENT);
+ this.store(assoc);
+ }
+ currentAssoc = currentAssoc.getAncestor().getParentAssoc();
+ count++;
+ }
+
+ Iterator children = obj.getChildAssocs().iterator();
+ while (children.hasNext()) {
+ Assoc assoc = (Assoc) children.next();
+
+ // resetting parent will cause reset of ancestors links
+ assoc.getObject().setParent(obj);
+
+ // recursively...
+ this.store(assoc.getObject());
+ }
+
+ // Clear new parent now that new parent has been saved
+ mNewParent = null;
+ }
+
+
+ /**
+ * Store assoc.
+ */
+ protected void store(Assoc assoc) throws HibernateException {
+
+ if(assoc == null) {
+ throw new HibernateException("Cannot save null object");
+ }
+
+ getSession().saveOrUpdate(assoc);
+ }
+
+
+ /**
+ * Remove hierarchical object.
+ *
+ * NOTE: if the object has proper cascade setting then is all this necessary?
+ */
+ protected void remove(HierarchicalPersistentObject obj) throws RollerException {
+
+ if(obj == null) {
+ throw new RollerException("Cannot remove null object");
+ }
+
+ log.debug("Removing hierarchical object "+obj.getId());
+
+ // loop to remove all descendents and associations
+ List toRemove = new LinkedList();
+ List assocs = obj.getAllDescendentAssocs();
+ for (int i=assocs.size()-1; i>=0; i--) {
+ Assoc assoc = (Assoc)assocs.get(i);
+ HierarchicalPersistentObject hpo = assoc.getObject();
+
+ // remove my descendent's parent and grandparent associations
+ Iterator ancestors = hpo.getAncestorAssocs().iterator();
+ while (ancestors.hasNext()) {
+ Assoc dassoc = (Assoc)ancestors.next();
+ this.remove(dassoc);
+ }
+
+ // remove decendent association and descendents
+ //assoc.remove();
+ toRemove.add(hpo);
+ }
+ Iterator removeIterator = toRemove.iterator();
+ while (removeIterator.hasNext()) {
+ PersistentObject po = (PersistentObject) removeIterator.next();
+ getSession().delete(po);
+ }
+
+ // loop to remove my own parent and grandparent associations
+ Iterator ancestors = obj.getAncestorAssocs().iterator();
+ while (ancestors.hasNext()) {
+ Assoc assoc = (Assoc)ancestors.next();
+ this.remove(assoc);
+ }
+
+ getSession().delete(obj);
+ }
+
+
+ /**
+ * Remove assoc.
+ */
+ protected void remove(Assoc assoc) throws HibernateException {
+
+ if(assoc == null) {
+ throw new HibernateException("Cannot save null object");
+ }
+
+ getSession().delete(assoc);
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingQueueManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingQueueManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingQueueManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingQueueManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+
+package org.apache.roller.business.hibernate;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.criterion.Expression;
+import org.hibernate.criterion.Order;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.AutoPingData;
+import org.apache.roller.pojos.PingQueueEntryData;
+import java.sql.Timestamp;
+import java.util.List;
+import org.apache.roller.model.PingQueueManager;
+
+
+/**
+ * Hibernate implementation of the PingQueueManager.
+ *
+ * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
+ */
+public class HibernatePingQueueManagerImpl implements PingQueueManager {
+
+ static final long serialVersionUID = -7660638707453106615L;
+
+ private static Log log = LogFactory.getLog(HibernatePingQueueManagerImpl.class);
+
+ private HibernatePersistenceStrategy strategy = null;
+
+
+ public HibernatePingQueueManagerImpl(HibernatePersistenceStrategy strat) {
+ this.strategy = strat;
+ }
+
+
+ public PingQueueEntryData getQueueEntry(String id) throws RollerException {
+ return (PingQueueEntryData) strategy.load(id, PingQueueEntryData.class);
+ }
+
+
+ public void saveQueueEntry(PingQueueEntryData pingQueueEntry) throws RollerException {
+ log.debug("Storing ping queue entry: " + pingQueueEntry);
+ strategy.store(pingQueueEntry);
+ }
+
+
+ public void removeQueueEntry(PingQueueEntryData pingQueueEntry) throws RollerException {
+ log.debug("Removing ping queue entry: " + pingQueueEntry);
+ strategy.remove(pingQueueEntry);
+ }
+
+
+ public void addQueueEntry(AutoPingData autoPing) throws RollerException {
+ log.debug("Creating new ping queue entry for auto ping configuration: " + autoPing);
+
+ // First check if there is an existing ping queue entry for the same target and website
+ if (isAlreadyQueued(autoPing)) {
+ log.debug("A ping queue entry is already present for this ping target and website: " + autoPing);
+ return;
+ }
+
+ Timestamp now = new Timestamp(System.currentTimeMillis());
+ PingQueueEntryData pingQueueEntry =
+ new PingQueueEntryData(null, now, autoPing.getPingTarget(), autoPing.getWebsite(), 0);
+ this.saveQueueEntry(pingQueueEntry);
+ }
+
+
+ public List getAllQueueEntries() throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(PingQueueEntryData.class);
+ criteria.addOrder(Order.asc("entryTime"));
+
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException("ERROR retrieving queue entries.", e);
+ }
+ }
+
+
+ // private helper to determine if an has already been queued for the same website and ping target.
+ private boolean isAlreadyQueued(AutoPingData autoPing) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(PingQueueEntryData.class);
+ criteria.add(Expression.eq("pingTarget", autoPing.getPingTarget()));
+ criteria.add(Expression.eq("website", autoPing.getWebsite()));
+ return !criteria.list().isEmpty();
+ } catch (HibernateException e) {
+ throw new RollerException("ERROR determining if preexisting queue entry is present.",e);
+ }
+ }
+
+
+ public void release() {}
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingTargetManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingTargetManagerImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingTargetManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernatePingTargetManagerImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.business.hibernate;
+
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.criterion.Expression;
+import org.hibernate.criterion.Order;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.PingTargetData;
+import org.apache.roller.pojos.WebsiteData;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Collection;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.model.AutoPingManager;
+import org.apache.roller.model.PingTargetManager;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.pojos.AutoPingData;
+import org.apache.roller.pojos.PingQueueEntryData;
+
+
+/**
+ * Hibernate implementation of the PingTargetManager.
+ *
+ * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
+ */
+public class HibernatePingTargetManagerImpl implements PingTargetManager {
+
+ static final long serialVersionUID = 121008492583382718L;
+
+ private static Log log = LogFactory.getLog(HibernatePingTargetManagerImpl.class);
+
+ private HibernatePersistenceStrategy strategy = null;
+
+
+ public HibernatePingTargetManagerImpl(HibernatePersistenceStrategy strat) {
+ this.strategy = strat;
+ }
+
+
+ public void removePingTarget(String id) throws RollerException {
+
+ PingTargetData pingTarget = getPingTarget(id);
+
+ // remove contents and then target
+ this.removePingTargetContents(pingTarget);
+ strategy.remove(pingTarget);
+ }
+
+
+ public void removePingTarget(PingTargetData pingTarget) throws RollerException {
+ this.strategy.remove(pingTarget);
+ }
+
+
+ /**
+ * Convenience method which removes any queued pings or auto pings that
+ * reference the given ping target.
+ */
+ private void removePingTargetContents(PingTargetData ping)
+ throws RollerException {
+
+ Session session = this.strategy.getSession();
+
+ // Remove the website's ping queue entries
+ Criteria criteria = session.createCriteria(PingQueueEntryData.class);
+ criteria.add(Expression.eq("pingTarget", ping));
+ List queueEntries = criteria.list();
+
+ // Remove the website's auto ping configurations
+ AutoPingManager autoPingMgr = RollerFactory.getRoller().getAutopingManager();
+ List autopings = autoPingMgr.getAutoPingsByTarget(ping);
+ Iterator it = autopings.iterator();
+ while(it.hasNext()) {
+ this.strategy.remove((AutoPingData) it.next());
+ }
+ }
+
+
+ /**
+ * @see org.apache.roller.model.PingTargetManager#removeAllCustomPingTargets()
+ */
+ public void removeAllCustomPingTargets() throws RollerException {
+
+ try {
+ Session session = strategy.getSession();
+ Criteria criteria = session.createCriteria(PingTargetData.class);
+ criteria.add(Expression.isNotNull("website"));
+ List allCustomTargets = criteria.list();
+ removeTargets(allCustomTargets);
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ // Private helper to remove a collection of targets.
+ private void removeTargets(Collection customTargets) throws RollerException {
+
+ // just go through the list and remove each auto ping
+ Iterator targets = customTargets.iterator();
+ while (targets.hasNext()) {
+ this.strategy.remove((PingTargetData) targets.next());
+ }
+ }
+
+
+ public void savePingTarget(PingTargetData pingTarget) throws RollerException {
+ strategy.store(pingTarget);
+ }
+
+
+ public PingTargetData getPingTarget(String id) throws RollerException {
+ return (PingTargetData) strategy.load(id, PingTargetData.class);
+ }
+
+
+ public boolean isNameUnique(PingTargetData pingTarget) throws RollerException {
+ String name = pingTarget.getName();
+ if (name == null || name.trim().length() == 0) return false;
+
+ String id = pingTarget.getId();
+
+ // Determine the set of "brother" targets (custom or common) among which this name should be unique.
+ List brotherTargets = null;
+ WebsiteData website = pingTarget.getWebsite();
+ if (website == null) {
+ brotherTargets = getCommonPingTargets();
+ } else {
+ brotherTargets = getCustomPingTargets(website);
+ }
+
+ // Within that set of targets, fail if there is a target with the same name and that target doesn't
+ // have the same id.
+ for (Iterator i = brotherTargets.iterator(); i.hasNext();) {
+ PingTargetData brother = (PingTargetData) i.next();
+ // Fail if it has the same name but not the same id.
+ if (brother.getName().equals(name) && (id == null || !brother.getId().equals(id))) {
+ return false;
+ }
+ }
+ // No conflict found
+ return true;
+ }
+
+
+ public boolean isUrlWellFormed(PingTargetData pingTarget) throws RollerException {
+ String url = pingTarget.getPingUrl();
+ if (url == null || url.trim().length() == 0) return false;
+ try {
+ URL parsedUrl = new URL(url);
+ // OK. If we get here, it parses ok. Now just check that the protocol is http and there is a host portion.
+ boolean isHttp = parsedUrl.getProtocol().equals("http");
+ boolean hasHost = (parsedUrl.getHost() != null) && (parsedUrl.getHost().trim().length() > 0);
+ return isHttp && hasHost;
+ } catch (MalformedURLException e) {
+ return false;
+ }
+ }
+
+
+ public boolean isHostnameKnown(PingTargetData pingTarget) throws RollerException {
+ String url = pingTarget.getPingUrl();
+ if (url == null || url.trim().length() == 0) return false;
+ try {
+ URL parsedUrl = new URL(url);
+ String host = parsedUrl.getHost();
+ if (host == null || host.trim().length() == 0) return false;
+ InetAddress addr = InetAddress.getByName(host);
+ return true;
+ } catch (MalformedURLException e) {
+ return false;
+ } catch (UnknownHostException e) {
+ return false;
+ }
+ }
+
+
+ /**
+ * @see org.apache.roller.model.PingTargetManager#getCommonPingTargets()
+ */
+ public List getCommonPingTargets() throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(PingTargetData.class);
+ criteria.add(Expression.isNull("website"));
+ criteria.addOrder(Order.asc("name"));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+
+ }
+
+
+ /**
+ * @see org.apache.roller.model.PingTargetManager#getCustomPingTargets(org.apache.roller.pojos.WebsiteData)
+ */
+ public List getCustomPingTargets(WebsiteData website) throws RollerException {
+ try {
+ Session session = ((HibernatePersistenceStrategy) strategy).getSession();
+ Criteria criteria = session.createCriteria(PingTargetData.class);
+ criteria.add(Expression.eq("website", website));
+ criteria.addOrder(Order.asc("name"));
+ return criteria.list();
+ } catch (HibernateException e) {
+ throw new RollerException(e);
+ }
+ }
+
+
+ public void release() {}
+
+}