You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by ag...@apache.org on 2008/06/28 21:18:57 UTC

svn commit: r672574 [4/16] - in /roller/planet/core/trunk: ./ lib/ lib/buildtime/ lib/jakarta-taglibs-standard-1.1.2/ lib/jakarta-taglibs-standard-1.1.2/lib/ lib/jakarta-taglibs-standard-1.1.2/tld/ lib/openjpa-0.9.7/ lib/rome-0.9/ lib/spring-1.2/ lib/s...

Modified: roller/planet/core/trunk/src/java/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/META-INF/persistence.xml?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/META-INF/persistence.xml (original)
+++ roller/planet/core/trunk/src/java/META-INF/persistence.xml Sat Jun 28 12:18:17 2008
@@ -1,15 +1,18 @@
 <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
     
-    <persistence-unit name ="PlanetPU" transaction-type = "RESOURCE_LOCAL">
+    <persistence-unit name="PlanetPU" transaction-type="RESOURCE_LOCAL">
         <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
         <!--
-        <provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
         <provider>org.hibernate.ejb.HibernatePersistence</provider>
         -->
         
         <mapping-file>org/apache/roller/planet/pojos/RuntimeConfigProperty.orm.xml</mapping-file>
         
+        <mapping-file>org/apache/roller/planet/pojos/User.orm.xml</mapping-file>
+        <mapping-file>org/apache/roller/planet/pojos/UserRole.orm.xml</mapping-file>
+        
         <mapping-file>org/apache/roller/planet/pojos/Planet.orm.xml</mapping-file>
+        <mapping-file>org/apache/roller/planet/pojos/PlanetPermission.orm.xml</mapping-file>
         <mapping-file>org/apache/roller/planet/pojos/PlanetGroup.orm.xml</mapping-file>
         <mapping-file>org/apache/roller/planet/pojos/Subscription.orm.xml</mapping-file>
         <mapping-file>org/apache/roller/planet/pojos/SubscriptionEntry.orm.xml</mapping-file> 

Added: roller/planet/core/trunk/src/java/application.properties
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/application.properties?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/application.properties (added)
+++ roller/planet/core/trunk/src/java/application.properties Sat Jun 28 12:18:17 2008
@@ -0,0 +1,34 @@
+
+# General
+
+yes=yes
+no=no
+
+
+# Menubar
+
+menubar.loggedInAs=logged in as
+menubar.logout=logout
+menubar.login=Login
+menubar.register=Register
+menubar.mainMenu=Main Menu
+menubar.globalConfig=Global Config
+menubar.userAdmin=User Admin
+
+
+# Footer
+
+footer.productName=Powered by <a href="http://roller.apache.org">Apache Roller Planet</a> Version {0}
+footer.reportIssue=Report an Issue
+footer.userGuide=User Guide
+footer.mailingLists=Mailing Lists
+
+
+# Denied (Access Denied Page)
+
+denied.title=Permission Denied
+
+denied.prompt=Possible causes:
+denied.reason0=You followed a link to something you do not have access to view.
+denied.reason1=You tried to save an object from "stale" web page, \
+left by an earlier login.

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/PlanetException.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/PlanetException.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/PlanetException.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/PlanetException.java Sat Jun 28 12:18:17 2008
@@ -18,17 +18,21 @@
 
 package org.apache.roller.planet;
 
-import org.apache.roller.RollerException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
 
 
 /**
  * A base exception class for Roller Planet.
  */
-public class PlanetException extends RollerException {
+public class PlanetException extends Exception {
+    
+    private final Throwable mRootCause;
     
     
     public PlanetException() {
         super();
+        mRootCause = null;
     }
     
     
@@ -39,6 +43,7 @@
      */
     public PlanetException(String s) {
         super(s);
+        mRootCause = null;
     }
     
     
@@ -50,6 +55,7 @@
      */
     public PlanetException(String s, Throwable t) {
         super(s, t);
+        mRootCause = t;
     }
     
     
@@ -60,6 +66,78 @@
      */
     public PlanetException(Throwable t) {
         super(t);
+        mRootCause = t;
+    }
+    
+    
+    
+    
+    /**
+     * Get root cause object, or null if none.
+     * @return Root cause or null if none.
+     */
+    public Throwable getRootCause() {
+        return mRootCause;
+    }
+    
+    
+    /**
+     * Get root cause message.
+     * @return Root cause message.
+     */
+    public String getRootCauseMessage() {
+        String rcmessage = null;
+        if (getRootCause()!=null) {
+            if (getRootCause().getCause()!=null) {
+                rcmessage = getRootCause().getCause().getMessage();
+            }
+            rcmessage = (rcmessage == null) ? getRootCause().getMessage() : rcmessage;
+            rcmessage = (rcmessage == null) ? super.getMessage() : rcmessage;
+            rcmessage = (rcmessage == null) ? "NONE" : rcmessage;
+        }
+        return rcmessage;
+    }
+    
+    
+    /**
+     * Print stack trace for exception and for root cause exception if htere is one.
+     * @see java.lang.Throwable#printStackTrace()
+     */
+    @Override
+    public void printStackTrace() {
+        super.printStackTrace();
+        if (mRootCause != null) {
+            System.out.println("--- ROOT CAUSE ---");
+            mRootCause.printStackTrace();
+        }
+    }
+    
+    
+    /**
+     * Print stack trace for exception and for root cause exception if htere is one.
+     * @param s Stream to print to.
+     */
+    @Override
+    public void printStackTrace(PrintStream s) {
+        super.printStackTrace(s);
+        if (mRootCause != null) {
+            s.println("--- ROOT CAUSE ---");
+            mRootCause.printStackTrace(s);
+        }
+    }
+    
+    
+    /**
+     * Print stack trace for exception and for root cause exception if htere is one.
+     * @param s Writer to write to.
+     */
+    @Override
+    public void printStackTrace(PrintWriter s) {
+        super.printStackTrace(s);
+        if (null != mRootCause) {
+            s.println("--- ROOT CAUSE ---");
+            mRootCause.printStackTrace(s);
+        }
     }
     
 }

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AbstractManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AbstractManagerImpl.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AbstractManagerImpl.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AbstractManagerImpl.java Sat Jun 28 12:18:17 2008
@@ -20,21 +20,25 @@
 
 
 /**
- * Provides base implementations for release() and shutdown() so that manager
+ * Provides base implementations for lifecycle methods so that manager
  * implemenations can just override them if needed.
  */
-public abstract class AbstractManagerImpl implements Manager {
+public abstract class AbstractManagerImpl 
+        implements AggregatorLifecycleAware, PersistenceLifecycleAware {
+    
     
     public void initialize() throws InitializationException {
         // no-op
     }
     
+    public void flush() throws PlanetPersistenceException {
+        // no-op
+    }
     
     public void release() {
         // no-op
     }
     
-    
     public void shutdown() {
         // no-op
     }

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/Aggregator.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/Aggregator.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/Aggregator.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/Aggregator.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,97 @@
+/*
+ * 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.planet.business;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.planet.business.fetcher.FeedFetcher;
+import org.apache.roller.planet.config.PlanetConfig;
+
+
+/**
+ * The main entry point interface of the Planet business tier.
+ */
+public abstract class Aggregator extends AbstractManagerImpl {
+    
+    private static Log log = LogFactory.getLog(Aggregator.class);
+    
+    
+    @Override
+    public void initialize() throws InitializationException {
+        
+        log.info("Initializing Roller Planet business tier");
+        
+        getPropertiesManager().initialize();
+        getPlanetManager().initialize();
+        
+        // we always need to do a flush after initialization because it's
+        // possible that some changes need to be persisted
+        try {
+            flush();
+        } catch(PlanetPersistenceException ex) {
+            throw new InitializationException("Error flushing after initialization", ex);
+        }
+        
+        log.info("Roller Planet business tier successfully initialized");
+    }
+    
+    
+    @Override
+    public void shutdown() {
+        // just do a release
+        this.release();
+    }
+    
+    
+    /**
+     * Get configuration for this Aggregator.
+     */
+    public abstract PlanetConfig getConfig();
+    
+    
+    /**
+     * Get UserManager associated with this Aggregator instance.
+     */
+    public abstract UserManager getUserManager();
+    
+    
+    /**
+     * Get PlanetManager associated with this Aggregator instance.
+     */
+    public abstract PlanetManager getPlanetManager();
+    
+    
+    /**
+     * Get PropertiesManager.
+     */
+    public abstract PropertiesManager getPropertiesManager();
+    
+    
+    /**
+     * Get the configured URLStrategy.
+     */
+    public abstract URLStrategy getURLStrategy();
+    
+    
+    /**
+     * Get the configured FeedFetcher.
+     */
+    public abstract FeedFetcher getFeedFetcher();
+    
+}

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorFactory.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorFactory.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorFactory.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorFactory.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,144 @@
+/*
+ * 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.planet.business;
+
+import java.lang.reflect.Constructor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.planet.business.startup.PlanetStartup;
+import org.apache.roller.planet.config.PlanetConfig; 
+
+
+/**
+ * Provides access to the Aggregator instance.
+ */
+public abstract class AggregatorFactory {
+    
+    private static Log log = LogFactory.getLog(AggregatorFactory.class);
+    
+    // our configured aggregator provider
+    private static AggregatorProvider aggregatorProvider = null;
+    
+    
+    // non-instantiable
+    private AggregatorFactory() {
+        // hello planetary citizens
+    }
+    
+    
+    
+    /**
+     * Static accessor for the instance of Roller
+     */
+    public static Aggregator getAggregator() {
+        if (aggregatorProvider == null) {
+            throw new IllegalStateException("Roller Planet has not been bootstrapped yet");
+        }
+        
+        return aggregatorProvider.getAggregator();
+    }
+    
+    
+    /**
+     * True if bootstrap process was completed, False otherwise.
+     */
+    public static boolean isBootstrapped() {
+        return (aggregatorProvider != null);
+    }
+    
+    
+    /**
+     * Convience method for looking up the default provider.
+     *
+     * This method is meant to be used in conjunction with the bootstrap() method
+     * to bootstrap the application in it's default configuration.  i.e.
+     * 
+     * AggregatorFactory.bootstrap(AggregatorFactory.getDefaultProvider(config));
+     *
+     * @throws IllegalStateException If the app has not been properly prepared yet.
+     * @throws BootstrapException If an error happens during the bootstrap process.
+     */
+    public static final AggregatorProvider getDefaultProvider(PlanetConfig config) 
+            throws BootstrapException {
+        
+        // if the app hasn't been properly started so far then bail
+        if (!PlanetStartup.isPrepared()) {
+            throw new IllegalStateException("Cannot bootstrap until application has been properly prepared");
+        }
+        
+        // lookup our default provider and instantiate it
+        AggregatorProvider defaultProvider;
+        String providerClassname = config.getProperty("planet.provider.class");
+        if(providerClassname != null) {
+            try {
+                Class providerClass = Class.forName(providerClassname);
+                Constructor constructor = providerClass.getConstructor(PlanetConfig.class);
+                defaultProvider = (AggregatorProvider) constructor.newInstance(config);
+            } catch (Exception ex) {
+                throw new BootstrapException("Error instantiating default provider: "+providerClassname, ex);
+            }
+        } else {
+            throw new NullPointerException("No provider specified in config property 'planet.provider.class'");
+        }
+        
+        return defaultProvider;
+    }
+    
+    
+    /**
+     * Bootstrap the Roller Planet business tier, uses specified AggregatorProvider.
+     *
+     * Bootstrapping the application effectively instantiates all the necessary
+     * pieces of the business tier and wires them together so that the app is 
+     * ready to run.
+     *
+     * @throws IllegalStateException If the app has not been properly prepared yet.
+     * @throws BootstrapException If an error happens during the bootstrap process.
+     */
+    public static final void bootstrap(AggregatorProvider provider) 
+            throws BootstrapException {
+        
+        // if the app hasn't been properly started so far then bail
+        if (!PlanetStartup.isPrepared()) {
+            throw new IllegalStateException("Cannot bootstrap until application has been properly prepared");
+        }
+        
+        if (provider == null) {
+            throw new NullPointerException("PlanetProvider is null");
+        }
+        
+        log.info("Bootstrapping Roller Planet business tier");
+        
+        log.info("Planet Provider = "+provider.getClass().getName());
+        
+        // save reference to provider
+        aggregatorProvider = provider;
+        
+        // bootstrap planet provider
+        aggregatorProvider.bootstrap();
+        
+        // make sure we are all set
+        if(aggregatorProvider.getAggregator() == null) {
+            throw new BootstrapException("Bootstrapping failed, Planet instance is null");
+        }
+        
+        log.info("Roller Planet business tier successfully bootstrapped");
+    }
+    
+}

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorLifecycleAware.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorLifecycleAware.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorLifecycleAware.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorLifecycleAware.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,39 @@
+/*
+ * 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.planet.business;
+
+
+/**
+ * Aggregator lifecycle methods.  Allows implementors to be part of application 
+ * lifecycle.
+ */
+public interface AggregatorLifecycleAware {
+    
+    /**
+     * Initialize.  Called once during application startup.
+     */
+    public void initialize() throws InitializationException;
+    
+    
+    /**
+     * Shutdown.  Called once during application shutdown.
+     */
+    public void shutdown();
+    
+}

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorProvider.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorProvider.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorProvider.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/AggregatorProvider.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.planet.business;
+
+
+/**
+ * Provides access to a Planet instance.
+ */
+public interface AggregatorProvider {
+    
+    /**
+     * Trigger bootstrapping.
+     */
+    public void bootstrap() throws BootstrapException;
+    
+    
+    /**
+     * Get a Planet instance.
+     */
+    public Aggregator getAggregator();
+    
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/DatabaseProvider.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/DatabaseProvider.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/DatabaseProvider.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/DatabaseProvider.java Sat Jun 28 12:18:17 2008
@@ -80,18 +80,18 @@
      * Reads configuraiton, loads driver or locates data-source and attempts
      * to get test connecton so that we can fail early.
      */ 
-    public DatabaseProvider() throws StartupException {
+    public DatabaseProvider(PlanetConfig config) throws StartupException {
         
         String connectionTypeString = 
-                PlanetConfig.getProperty("database.configurationType"); 
+                config.getProperty("database.configurationType"); 
         if ("jdbc".equals(connectionTypeString)) {
             type = ConfigurationType.JDBC_PROPERTIES;
         }
-        jndiName =          PlanetConfig.getProperty("database.jndi.name");
-        jdbcDriverClass =   PlanetConfig.getProperty("database.jdbc.driverClass");
-        jdbcConnectionURL = PlanetConfig.getProperty("database.jdbc.connectionURL");
-        jdbcUsername =      PlanetConfig.getProperty("database.jdbc.username");
-        jdbcPassword =      PlanetConfig.getProperty("database.jdbc.password");
+        jndiName =          config.getProperty("database.jndi.name");
+        jdbcDriverClass =   config.getProperty("database.jdbc.driverClass");
+        jdbcConnectionURL = config.getProperty("database.jdbc.connectionURL");
+        jdbcUsername =      config.getProperty("database.jdbc.username");
+        jdbcPassword =      config.getProperty("database.jdbc.password");
         
         successMessage("SUCCESS: Got parameters. Using configuration type " + type);
 

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/GuiceAggregatorProvider.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/GuiceAggregatorProvider.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/GuiceAggregatorProvider.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/GuiceAggregatorProvider.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,93 @@
+/*
+ * 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.planet.business;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import java.lang.reflect.Constructor;
+import org.apache.roller.planet.config.PlanetConfig;
+
+
+/**
+ * A Guice specific implementation of a AggregatorProvider.
+ */
+public class GuiceAggregatorProvider implements AggregatorProvider {
+    
+    // Guice injector
+    private final Injector injector;
+    
+    // maintain our own singleton instance of Aggregator
+    private Aggregator aggregatorInstance = null;
+    
+    
+    /**
+     * Instantiate a new GuiceAggregatorProvider using default guice module 
+     * configured in PlanetConfig via 'guice.backend.module' property.
+     */
+    public GuiceAggregatorProvider(PlanetConfig config) {
+        String moduleClassname = config.getProperty("guice.backend.module");
+        injector = loadGuiceInjector(config, moduleClassname);
+    }
+    
+    
+    /**
+     * Instantiate a new GuiceAggregatorProvider using the given Guice module.
+     *
+     * @param moduleClassname The full classname of the Guice module to use.
+     */
+    public GuiceAggregatorProvider(PlanetConfig config, String moduleClassname) {
+        injector = loadGuiceInjector(config, moduleClassname);
+    }
+    
+    
+    private Injector loadGuiceInjector(PlanetConfig config, String moduleClassname) {
+        
+        if(moduleClassname == null) {
+            throw new NullPointerException("moduleClassname cannot be null");
+        }
+        
+        try {
+            Class moduleClass = Class.forName(moduleClassname);
+            Constructor constructor = moduleClass.getConstructor(PlanetConfig.class);
+            Module module = (Module) constructor.newInstance(config);
+            return Guice.createInjector(module);
+        } catch (Throwable e) {                
+            // Fatal misconfiguration, cannot recover
+            throw new RuntimeException("Error instantiating backend module " + moduleClassname, e);
+        }
+    }
+    
+    
+    /**
+     * @inheritDoc
+     */
+    public void bootstrap() {
+        aggregatorInstance =  injector.getInstance(Aggregator.class);
+    }
+    
+    
+    /**
+     * @inheritDoc
+     */
+    public Aggregator getAggregator() {
+        return aggregatorInstance;
+    }
+    
+}

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MailProvider.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MailProvider.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MailProvider.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MailProvider.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,121 @@
+/*
+ * 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.planet.business;
+
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.apache.roller.planet.business.startup.StartupException;
+import org.apache.roller.planet.config.PlanetConfig;
+
+
+/**
+ * Provides access to a javax.mail.Session for sending email.
+ */
+public class MailProvider {
+    
+    public static final String JNDI = "jndi";
+    public static final String PROPERTIES = "properties";
+    
+    private final Session session;
+
+    
+    public MailProvider(PlanetConfig config) throws StartupException {
+        
+        String configurationType = config.getProperty("mail.configurationType");
+        if (JNDI.equals(configurationType)) { 
+            String jndiName = config.getProperty("mail.jndiName");
+            try {
+                Context ctx = (Context) new InitialContext();
+                session = (Session) ctx.lookup(jndiName);
+            } catch (NamingException ex) {
+                throw new StartupException("ERROR looking up mail-session with JNDI name: " + jndiName, ex);
+            }
+            
+        } else if (PROPERTIES.equals(configurationType)) {
+            String mailHostname = config.getProperty("mail.hostname");
+            String mailUsername = config.getProperty("mail.username");
+            String mailPassword = config.getProperty("mail.password");
+            int mailPort = config.getIntProperty("mail.port", -1);
+
+            Properties props = new Properties();
+            props.put("mail.transport.protocol", "smtp");
+            props.put("mail.smtp.host", mailHostname);
+            if (mailPort != -1) {
+                props.put("mail.smtp.port", ""+mailPort);
+            }
+            if (mailUsername != null && mailPassword != null) {
+                props.put("mail.smtp.auth", "true");   
+            }
+            
+            // TODO: should we use authenticator here?
+            session = Session.getDefaultInstance(props, null);
+            
+        } else {
+            throw new StartupException("Invalid MailProvider configurationType: "+configurationType);
+        }
+        
+        // test transport
+        Transport transport = null;
+        try {
+            transport = session.getTransport();
+            transport.connect();
+        } catch (Throwable t) {
+            throw new StartupException("ERROR connecting to mail server", t);
+        } finally {
+            if(transport != null) {
+                try {
+                    transport.close();
+                } catch (MessagingException ex) {
+                    // swallowed
+                }
+            }
+        }
+        
+    }
+    
+    
+    /**
+     * Get a mail Session.
+     */
+    public Session getSession() {
+        return session;
+    }
+    
+    
+    class PlanetMailAuthenticator extends Authenticator {
+        private final PasswordAuthentication passauth;
+        
+        public PlanetMailAuthenticator(String username, String password) {
+            this.passauth = new PasswordAuthentication(username, password);
+        }
+        
+        @Override
+        protected PasswordAuthentication getPasswordAuthentication() {
+            return passauth;
+        }
+    }
+    
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MultiPlanetURLStrategy.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MultiPlanetURLStrategy.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MultiPlanetURLStrategy.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/MultiPlanetURLStrategy.java Sat Jun 28 12:18:17 2008
@@ -22,9 +22,7 @@
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import org.apache.roller.planet.config.PlanetRuntimeConfig;
 
 
 /**
@@ -44,9 +42,9 @@
         
         StringBuffer url = new StringBuffer();
         
-        PlanetManager mgr = PlanetFactory.getPlanet().getPlanetManager();
+        PlanetManager mgr = AggregatorFactory.getAggregator().getPlanetManager();
         
-        url.append(PlanetRuntimeConfig.getProperty("site.absoluteurl"));
+        url.append(AggregatorFactory.getAggregator().getConfig().getProperty("site.absoluteurl"));
         url.append("/").append(planet).append("/");
         
         return url.toString();

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PersistenceLifecycleAware.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PersistenceLifecycleAware.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PersistenceLifecycleAware.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PersistenceLifecycleAware.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,23 @@
+
+package org.apache.roller.planet.business;
+
+/**
+ * Persistence lifecycle methods.  Allows implementors to be aware of persistence
+ * session management.
+ *
+ * @author ag92114
+ */
+public interface PersistenceLifecycleAware {
+    
+    /**
+     * Flush object states.
+     */
+    public void flush() throws PlanetPersistenceException;
+    
+    
+    /**
+     * Session Release.  Called once at the end of each persistence session.
+     */
+    public void release();
+    
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetManager.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetManager.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetManager.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetManager.java Sat Jun 28 12:18:17 2008
@@ -18,140 +18,135 @@
 
 package org.apache.roller.planet.business;
 
-import java.io.Serializable;
 import java.util.Date;
-import java.util.Iterator;
 import java.util.List;
-import org.apache.roller.planet.PlanetException;
 import org.apache.roller.planet.pojos.Planet;
 import org.apache.roller.planet.pojos.SubscriptionEntry;
 import org.apache.roller.planet.pojos.PlanetGroup;
 import org.apache.roller.planet.pojos.Subscription;
+import org.apache.roller.planet.pojos.User;
 
 
 /**
  * Manages Planets, Groups, Subscriptions, and Entries.
  */
-public interface PlanetManager extends Manager {
+public interface PlanetManager extends AggregatorLifecycleAware {
     
     
-    public void savePlanet(Planet planet) throws PlanetException;
+    public void savePlanet(Planet planet) throws PlanetPersistenceException;
     
     
-    public void deletePlanet(Planet planet) throws PlanetException;
+    public void deletePlanet(Planet planet) throws PlanetPersistenceException;
     
     
-    public Planet getPlanet(String handle) throws PlanetException;
+    public Planet getPlanet(String handle) throws PlanetPersistenceException;
     
     
-    public Planet getPlanetById(String id) throws PlanetException;
+    public Planet getPlanetById(String id) throws PlanetPersistenceException;
     
     
-    public List getPlanets() throws PlanetException;
+    public List<Planet> getPlanets() throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get planets that a given user is member of.
+     * 
+     * @param user User which we are looking up planet membership for.
+     * 
+     * @returns List of Planet objects.
+     */
+    public List<Planet> getPlanets(User user) throws PlanetPersistenceException;
     
     
     /**
      * Save new or update existing a group
      */
-    public void saveGroup(PlanetGroup sub) throws PlanetException;
+    public void saveGroup(PlanetGroup sub) throws PlanetPersistenceException;
     
     
     /** 
      * Delete group and any subscriptions that are orphaned. 
      */
-    public void deleteGroup(PlanetGroup group) throws PlanetException;
+    public void deleteGroup(PlanetGroup group) throws PlanetPersistenceException;
     
     
-    public PlanetGroup getGroup(Planet planet, String handle) throws PlanetException;
+    public PlanetGroup getGroup(Planet planet, String handle) throws PlanetPersistenceException;
     
     
     /**
      * Get group by ID rather than handle.
      */
-    public PlanetGroup getGroupById(String id) throws PlanetException;
+    public PlanetGroup getGroupById(String id) throws PlanetPersistenceException;
     
     
     /**
      * Save or update a subscription
      */
-    public void saveSubscription(Subscription sub) throws PlanetException;
+    public void saveSubscription(Subscription sub) throws PlanetPersistenceException;
     
     
     /** 
      * Delete subscription, remove it from groups, cache, etc. 
      */
-    public void deleteSubscription(Subscription group) throws PlanetException;
+    public void deleteSubscription(Subscription group) throws PlanetPersistenceException;
     
     
     /**
      * Get subscription by feedUrl.
      */
-    public Subscription getSubscription(String feedUrl) throws PlanetException;
+    public Subscription getSubscription(String feedUrl) throws PlanetPersistenceException;
     
     
     /**
      * Get subscription by ID rather than feedUrl.
      */
-    public Subscription getSubscriptionById(String id) throws PlanetException;
+    public Subscription getSubscriptionById(String id) throws PlanetPersistenceException;
     
     
     /**
      * Get all subscriptions.
      */
-    public List getSubscriptions() throws PlanetException;
+    public List getSubscriptions() throws PlanetPersistenceException;
     
     
     /**
      * Get total number of subscriptions.
      */
-    public int getSubscriptionCount() throws PlanetException;
-    
-    
-    /**
-     * Get top X subscriptions.
-     */
-    public List getTopSubscriptions(int offset, int len) throws PlanetException;
-    
-    
-    /**
-     * Get top X subscriptions, restricted by group.
-     */
-    public List getTopSubscriptions(PlanetGroup group, int offset, int len) 
-        throws PlanetException;
+    public int getSubscriptionCount() throws PlanetPersistenceException;
     
     
     /**
      * Save new or update existing entry
      */
-    public void saveEntry(SubscriptionEntry entry) throws PlanetException;
+    public void saveEntry(SubscriptionEntry entry) throws PlanetPersistenceException;
     
     
     /** 
      * Delete entry. 
      */
-    public void deleteEntry(SubscriptionEntry entry) throws PlanetException;
+    public void deleteEntry(SubscriptionEntry entry) throws PlanetPersistenceException;
     
     
     /**
      * Delete all entries for a subscription.
      *
      * @param subscription The subscription to delete entries from.
-     * @throws PlanetException If there is a problem doing the delete.
+     * @throws PlanetPersistenceException If there is a problem doing the delete.
      */
-    public void deleteEntries(Subscription sub) throws PlanetException;
+    public void deleteEntries(Subscription sub) throws PlanetPersistenceException;
     
     
     /**
      * Lookup an entry by id.
      */
-    public SubscriptionEntry getEntryById(String id) throws PlanetException;
+    public SubscriptionEntry getEntryById(String id) throws PlanetPersistenceException;
     
     
     /**
      * Get entries in a single feed as list of SubscriptionEntry objects.
      */
     public List getEntries(Subscription sub, int offset, int len) 
-        throws PlanetException;
+        throws PlanetPersistenceException;
     
     
     /**
@@ -162,7 +157,7 @@
      * @param len Maximum number of results to return (for paging)
      */
     public List getEntries(PlanetGroup group, int offset, int len) 
-        throws PlanetException;
+        throws PlanetPersistenceException;
     
     
     /**
@@ -179,6 +174,6 @@
                            Date startDate, 
                            Date endDate,
                            int offset, 
-                           int len) throws PlanetException;
+                           int len) throws PlanetPersistenceException;
     
 }

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetPersistenceException.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetPersistenceException.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetPersistenceException.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PlanetPersistenceException.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,30 @@
+
+package org.apache.roller.planet.business;
+
+import org.apache.roller.planet.PlanetException;
+
+
+/**
+ * Exception thrown as a result of a persistence problem.
+ *
+ * @author ag92114
+ */
+public class PlanetPersistenceException extends PlanetException {
+    
+    public PlanetPersistenceException() {
+        super();
+    }
+    
+    public PlanetPersistenceException(String s) {
+        super(s);
+    }
+    
+    public PlanetPersistenceException(Throwable t) {
+        super(t);
+    }
+    
+    public PlanetPersistenceException(String s, Throwable t) {
+        super(s, t);
+    }
+    
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PropertiesManager.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PropertiesManager.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PropertiesManager.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/PropertiesManager.java Sat Jun 28 12:18:17 2008
@@ -19,36 +19,35 @@
 package org.apache.roller.planet.business;
 
 import java.util.Map;
-import org.apache.roller.planet.PlanetException;
 import org.apache.roller.planet.pojos.RuntimeConfigProperty;
 
 
 /**
  * Manages global runtime properties.
  */
-public interface PropertiesManager extends Manager {
+public interface PropertiesManager extends AggregatorLifecycleAware {
     
     /** 
      * Save a single property 
      */
-    public void saveProperty(RuntimeConfigProperty property) throws PlanetException;
+    public void saveProperty(RuntimeConfigProperty property) throws PlanetPersistenceException;
     
     
     /** 
      * Save a list of properties 
      */
-    public void saveProperties(Map properties) throws PlanetException;
+    public void saveProperties(Map properties) throws PlanetPersistenceException;
     
     
     /** 
      * Retrieve a single property by name 
      */
-    public RuntimeConfigProperty getProperty(String name) throws PlanetException;
+    public RuntimeConfigProperty getProperty(String name) throws PlanetPersistenceException;
     
     
     /** 
      * Retrieve a list of all properties 
      */
-    public Map getProperties() throws PlanetException;
+    public Map getProperties() throws PlanetPersistenceException;
     
 }

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/UserManager.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/UserManager.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/UserManager.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/UserManager.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,230 @@
+/*
+ * 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.planet.business;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.roller.planet.pojos.Planet;
+import org.apache.roller.planet.pojos.PlanetPermission;
+import org.apache.roller.planet.pojos.User;
+
+
+/**
+ * Manages users, roles, and permissions.
+ */
+public interface UserManager {
+    
+    /**
+     * Add a new user.
+     * 
+     * This method is used to provide supplemental data to new user accounts,
+     * such as adding the proper roles for the user.  This method should see
+     * if the new user is the first user and give that user the admin role if so.
+     *
+     * @param newUser User object to be added.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public void addUser(User newUser) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Save a user.
+     *
+     * @param user User to be saved.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public void saveUser(User user) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Remove a user.
+     *
+     * @param user User to be removed.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public void removeUser(User user) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Lookup a user by ID.
+     * 
+     * @param id ID of user to lookup.
+     * @returns UsUserhe user, or null if not found.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public User getUser(String id) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Lookup a user by UserName.
+     * 
+     * This lookup is restricted to 'enabled' users by default.  So this method
+     * should return null if the user is found but is not enabled.
+     * 
+     * @param userName User Name of user to lookup.
+     * @returns UsUserhe user, or null if not found or is disabled.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public User getUserByUserName(String userName) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Lookup a user by UserName with the given enabled status.
+     * 
+     * @param userName User Name of user to lookup.
+     * @returns UsUserhe user, or null if not found or doesn't match 
+     *   the proper enabled status.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public User getUserByUserName(String userName, Boolean enabled)
+        throws PlanetPersistenceException;
+    
+    
+    /**
+     * Lookup a group of users.
+     * 
+     * The lookup may be constrained to users with a certain enabled status,
+     * to users created within a certain date range, and the results can be
+     * confined to a certain offset & length for paging abilities.
+     * 
+     * @param Planet Confine results to users with permission to a certain Planet.
+     * @param enabled True for enabled only, False for disabled only (or null for all)
+     * @param startDate Restrict to those created after startDate (or null for all)
+     * @param endDate Restrict to those created before startDate (or null for all)
+     * @param offset The index of the first result to return.
+     * @param length The number of results to return.
+     * @returns List A list of UserDatUsers which match the criteria.
+     * @throws PlanetPersistenceException If there is a problem.
+     */
+    public List getUsers(
+            Planet Planet,
+            Boolean enabled,
+            Date    startDate,
+            Date    endDate,
+            int     offset,
+            int     length) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Lookup users whose usernames or email addresses start with a string.
+     *
+     * @param startsWith String to match userNames and emailAddresses against
+     * @param offset     Offset into results (for paging)
+     * @param length     Max to return (for paging)
+     * @param enabled    True for only enalbed, false for disabled, null for all
+     * @return List of (up to length) users that match startsWith string
+     */
+    public List getUsersStartingWith(String startsWith,
+            Boolean enabled, int offset, int length) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Save permissions object.
+     */
+    public void savePermissions(PlanetPermission perms) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Remove permissions object.
+     */
+    public void removePermissions(PlanetPermission perms) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get permissions object by id.
+     */
+    public PlanetPermission getPermissions(String id) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get pending permissions for user.
+     * @param user User (not null)
+     * @returns List of PermissionsData objects.
+     */
+    public List getPendingPermissions(User user) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get pending permissions for planet.
+     * @param planet planet (not null)
+     * @returns List of PermissionsData objects.
+     */
+    public List getPendingPermissions(Planet user) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get permissions of user in planet.
+     * @param planet planet (not null)
+     * @param user    User (not null)
+     * @return        PermissionsData object
+     */
+    public PlanetPermission getPermissions(Planet planet, User user)
+        throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get all permissions in planet
+     * @param planet planet (not null)
+     * @return        PermissionsData object
+     */
+    public List getAllPermissions(Planet planet) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Get all permissions of user
+     * @param user User (not null)
+     * @return     PermissionsData object
+     */
+    public List getAllPermissions(User user) throws PlanetPersistenceException;
+    
+    
+    /**
+     * Invite user to join a planet with specific permissions
+     * @param planet planet to be joined (persistent instance)
+     * @param user    User to be invited (persistent instance)
+     * @param perms   Permissions mask (see statics in PermissionsData)
+     * @return        New PermissionsData object, with pending=true
+     */
+    public PlanetPermission inviteUser(Planet planet, User user, short perms)
+        throws PlanetPersistenceException;
+    
+    
+    /**
+     * Retire user from a planet
+     * @param planet planet to be retired from (persistent instance)
+     * @param user    User to be retired (persistent instance)
+     */
+    public void retireUser(Planet planet, User user)
+        throws PlanetPersistenceException;
+    
+    
+    /**
+     * Revoke role of user
+     * @param roleName Name of the role to be revoked
+     * @param user    User for whom the role is to be revoked
+     */
+    public void revokeRole(String roleName, User user)
+        throws PlanetPersistenceException;
+        
+    
+    /**
+     * Does the user have the specified permissions on the planet?
+     */
+    public boolean hasPermissions(User user, Planet planet, short mask);
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/fetcher/RomeFeedFetcher.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/fetcher/RomeFeedFetcher.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/fetcher/RomeFeedFetcher.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/fetcher/RomeFeedFetcher.java Sat Jun 28 12:18:17 2008
@@ -39,7 +39,7 @@
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.roller.planet.config.PlanetConfig;
+import org.apache.roller.planet.business.AggregatorFactory;
 import org.apache.roller.planet.pojos.SubscriptionEntry;
 import org.apache.roller.planet.pojos.Subscription;
 import org.apache.roller.planet.util.rome.DiskFeedInfoCache;
@@ -114,7 +114,7 @@
             FeedFetcherCache feedCache = getRomeFetcherCache();
             try {
                 SyndFeedInfo feedInfo = feedCache.getFeedInfo(new URL(newSub.getFeedURL()));
-                if(feedInfo.getLastModified() != null) {
+                if(feedInfo != null && feedInfo.getLastModified() != null) {
                     long lastUpdatedLong = ((Long)feedInfo.getLastModified()).longValue();
                     if (lastUpdatedLong != 0) {
                         newSub.setLastUpdated(new Date(lastUpdatedLong));
@@ -241,7 +241,7 @@
     // get a feed fetcher cache, if possible
     private FeedFetcherCache getRomeFetcherCache() {
         
-        String cacheDirPath = PlanetConfig.getProperty("cache.dir");
+        String cacheDirPath = AggregatorFactory.getAggregator().getConfig().getProperty("cache.dir");
         
         // can't continue without cache dir
         if (cacheDirPath == null) {

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/GuiceJPAAggregatorModule.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/GuiceJPAAggregatorModule.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/GuiceJPAAggregatorModule.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/GuiceJPAAggregatorModule.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,62 @@
+/*
+ * 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.planet.business.jpa;
+
+import com.google.inject.Binder;
+import com.google.inject.Module;
+import org.apache.roller.planet.business.fetcher.FeedFetcher;
+import org.apache.roller.planet.business.MultiPlanetURLStrategy;
+import org.apache.roller.planet.business.Aggregator;
+import org.apache.roller.planet.business.PlanetManager;
+import org.apache.roller.planet.business.PropertiesManager;
+import org.apache.roller.planet.business.fetcher.RomeFeedFetcher;
+import org.apache.roller.planet.business.URLStrategy;
+import org.apache.roller.planet.business.UserManager;
+import org.apache.roller.planet.config.PlanetConfig;
+
+
+/**
+ * Guice module for configuring JPA as Roller-backend.
+ */
+public class GuiceJPAAggregatorModule implements Module {
+    
+    private final PlanetConfig config;
+    
+    
+    public GuiceJPAAggregatorModule(PlanetConfig config) {
+        this.config = config;
+    }
+    
+    
+    public void configure(Binder binder) {
+        
+        binder.bind(PlanetConfig.class).toInstance(config);
+        binder.bind(URLStrategy.class).to(MultiPlanetURLStrategy.class);
+        
+        binder.bind(Aggregator.class).to(JPAAggregatorImpl.class);
+        
+        binder.bind(JPAPersistenceStrategy.class); 
+        
+        binder.bind(UserManager.class).to(JPAUserManagerImpl.class);
+        binder.bind(PlanetManager.class).to(JPAPlanetManagerImpl.class);   
+        binder.bind(PropertiesManager.class).to(JPAPropertiesManagerImpl.class);
+        binder.bind(FeedFetcher.class).to(RomeFeedFetcher.class);
+    }
+    
+}

Added: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAAggregatorImpl.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAAggregatorImpl.java?rev=672574&view=auto
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAAggregatorImpl.java (added)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAAggregatorImpl.java Sat Jun 28 12:18:17 2008
@@ -0,0 +1,135 @@
+/*
+* 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.planet.business.jpa;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.planet.PlanetException;
+import org.apache.roller.planet.business.URLStrategy;
+import org.apache.roller.planet.business.Aggregator;
+import org.apache.roller.planet.business.PlanetManager;
+import org.apache.roller.planet.business.fetcher.FeedFetcher;
+import org.apache.roller.planet.business.PlanetPersistenceException;
+import org.apache.roller.planet.business.PropertiesManager;
+import org.apache.roller.planet.business.UserManager;
+import org.apache.roller.planet.config.PlanetConfig;
+
+
+/**
+ * Implements Planet, the entry point interface for the Roller-Planet business 
+ * tier APIs using the Java Persistence API (JPA).
+ */
+@com.google.inject.Singleton
+public class JPAAggregatorImpl extends Aggregator {   
+    
+    private static Log log = LogFactory.getLog(JPAAggregatorImpl.class);
+    
+    // configuration
+    private final PlanetConfig config;
+    
+    // a persistence utility class
+    private final JPAPersistenceStrategy strategy;
+        
+    // references to the managers we maintain
+    private final UserManager userManager;
+    private final PlanetManager planetManager;
+    private final PropertiesManager propertiesManager;
+    
+    // url strategy
+    private final URLStrategy urlStrategy;
+    
+    // feed fetcher
+    private final FeedFetcher feedFetcher;
+    
+        
+    @com.google.inject.Inject  
+    protected JPAAggregatorImpl(
+            JPAPersistenceStrategy strategy,
+            PlanetConfig      config,
+            UserManager       userManager,
+            PlanetManager     planetManager, 
+            PropertiesManager propertiesManager,
+            URLStrategy       urlStrategy,
+            FeedFetcher       feedFetcher) throws PlanetException {
+        
+        this.strategy = strategy;
+        
+        this.config = config;
+        
+        this.userManager = userManager;
+        this.propertiesManager = propertiesManager;
+        this.planetManager = planetManager;
+        
+        this.urlStrategy = urlStrategy;
+        this.feedFetcher = feedFetcher;
+        
+        // need to inject propertiesManager into config to enable
+        // access to runtime config properties via PlanetConfig
+        config.setPropertiesManager(propertiesManager);
+    }
+    
+    
+    @Override
+    public void flush() throws PlanetPersistenceException {
+        this.strategy.flush();
+    }
+
+    
+    @Override
+    public void release() {
+        this.strategy.release();
+    }
+    
+    
+    public PlanetConfig getConfig() {
+        return config;
+    }
+    
+    
+    public UserManager getUserManager() {
+        return userManager;
+    }
+    
+    
+    /**
+     * @see org.apache.roller.business.Roller#getBookmarkManager()
+     */
+    public PlanetManager getPlanetManager() {
+        return planetManager;
+    }
+
+     
+    /**
+     * @see org.apache.roller.business.Roller#getBookmarkManager()
+     */
+    public PropertiesManager getPropertiesManager() {
+        return propertiesManager;
+    }
+    
+    
+    public URLStrategy getURLStrategy() {
+        return this.urlStrategy;
+    }
+    
+    
+    public FeedFetcher getFeedFetcher() {
+        return this.feedFetcher;
+    }
+    
+}

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPersistenceStrategy.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPersistenceStrategy.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPersistenceStrategy.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPersistenceStrategy.java Sat Jun 28 12:18:17 2008
@@ -1,4 +1,3 @@
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  *  contributor license agreements.  The ASF licenses this file to You
@@ -35,11 +34,8 @@
 import javax.persistence.Persistence;
 import javax.persistence.PersistenceException;
 import javax.persistence.Query;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.apache.roller.planet.PlanetException;
 import org.apache.roller.planet.business.DatabaseProvider;
+import org.apache.roller.planet.business.PlanetPersistenceException;
 import org.apache.roller.planet.business.startup.PlanetStartup;
 import org.apache.roller.planet.config.PlanetConfig;
 
@@ -50,9 +46,7 @@
 @com.google.inject.Singleton
 public class JPAPersistenceStrategy {
     
-    private static Log logger = 
-        LogFactory.getFactory().getInstance(JPAPersistenceStrategy.class);
-    
+    private static Log log = LogFactory.getLog(JPAPersistenceStrategy.class);
     
     /**
      * The thread local EntityManager.
@@ -62,108 +56,98 @@
     /**
      * The EntityManagerFactory for this Roller instance.
      */
-    protected EntityManagerFactory emf;
+    private final EntityManagerFactory emf;
     
             
     /**
      * Construct by finding JPA EntityManagerFactory.
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
-    protected JPAPersistenceStrategy() throws PlanetException {
-
-        String jpaConfigurationType = PlanetConfig.getProperty("jpa.configurationType");
-        if ("jndi".equals(jpaConfigurationType)) {
-            String emfJndiName = "java:comp/env/" + PlanetConfig.getProperty("jpa.emf.jndi.name");
-            try {
-                emf = (EntityManagerFactory) new InitialContext().lookup(emfJndiName);
-            } catch (NamingException e) {
-                throw new PlanetException("Could not look up EntityManagerFactory in jndi at " + emfJndiName, e);
-            }
-        } else {
-            DatabaseProvider dbProvider = PlanetStartup.getDatabaseProvider();
-
-            // Pull in any properties defined in JMAEMF.properties config file
-            Properties emfProps = loadPropertiesFromResourceName(
-                    "JPAEMF.properties", getContextClassLoader());
+    @com.google.inject.Inject 
+    protected JPAPersistenceStrategy(PlanetConfig config) throws PlanetPersistenceException {
 
-            // Add all OpenJPA and Toplinks properties found in RollerConfig
-            Enumeration keys = PlanetConfig.keys();
-            while (keys.hasMoreElements()) {
-                String key = (String) keys.nextElement();
-                if (key.startsWith("openjpa.") || key.startsWith("toplink.")) {
-                    String value = PlanetConfig.getProperty(key);
-                    logger.info(key + ": " + value);
-                    emfProps.setProperty(key, value);
-                }
+        // Pull in any properties defined in JMAEMF.properties config file
+        Properties emfProps = loadPropertiesFromResourceName(
+                "JPAEMF.properties", getContextClassLoader());
+
+        // Add all OpenJPA or Hibernate properties
+        Enumeration keys = config.keys();
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            if (key.startsWith("openjpa.") || key.startsWith("hibernate.")) {
+                String value = config.getProperty(key);
+                emfProps.setProperty(key, value);
             }
+        }
+        
+        DatabaseProvider dbProvider = PlanetStartup.getDatabaseProvider();
+        if (dbProvider.getType() == DatabaseProvider.ConfigurationType.JNDI_NAME) {
+            // We're doing JNDI, so set OpenJPA JNDI name property
+            String jndiName = "java:comp/env/" + dbProvider.getJndiName();
+            emfProps.setProperty("openjpa.ConnectionFactoryName", jndiName);
 
-            if (dbProvider.getType() == DatabaseProvider.ConfigurationType.JNDI_NAME) {
-                // We're doing JNDI, so set OpenJPA JNDI name property
-                String jndiName = "java:comp/env/" + dbProvider.getJndiName();
-                emfProps.setProperty("openjpa.ConnectionFactoryName", jndiName);
-
-            } else {
-                // So set JDBD properties for OpenJPA
-                emfProps.setProperty("openjpa.ConnectionDriverName", dbProvider.getJdbcDriverClass());
-                emfProps.setProperty("openjpa.ConnectionURL", dbProvider.getJdbcConnectionURL());
-                emfProps.setProperty("openjpa.ConnectionUserName", dbProvider.getJdbcUsername());
-                emfProps.setProperty("openjpa.ConnectionPassword", dbProvider.getJdbcPassword());
-
-                // And Toplink JPA
-                emfProps.setProperty("toplink.jdbc.driver", dbProvider.getJdbcDriverClass());
-                emfProps.setProperty("toplink.jdbc.url", dbProvider.getJdbcConnectionURL());
-                emfProps.setProperty("toplink.jdbc.user", dbProvider.getJdbcUsername());
-                emfProps.setProperty("toplink.jdbc.password", dbProvider.getJdbcPassword());
-
-                // And Hibernate JPA
-                emfProps.setProperty("hibernate.connection.driver_class", dbProvider.getJdbcDriverClass());
-                emfProps.setProperty("hibernate.connection.url", dbProvider.getJdbcConnectionURL());
-                emfProps.setProperty("hibernate.connection.username", dbProvider.getJdbcUsername());
-                emfProps.setProperty("hibernate.connection.password", dbProvider.getJdbcPassword());
-            }
+        } else {
+            // So set JDBD properties for OpenJPA
+            emfProps.setProperty("openjpa.ConnectionDriverName", dbProvider.getJdbcDriverClass());
+            emfProps.setProperty("openjpa.ConnectionURL", dbProvider.getJdbcConnectionURL());
+            emfProps.setProperty("openjpa.ConnectionUserName", dbProvider.getJdbcUsername());
+            emfProps.setProperty("openjpa.ConnectionPassword", dbProvider.getJdbcPassword());
+
+            // And Hibernate JPA
+            emfProps.setProperty("hibernate.connection.driver_class", dbProvider.getJdbcDriverClass());
+            emfProps.setProperty("hibernate.connection.url", dbProvider.getJdbcConnectionURL());
+            emfProps.setProperty("hibernate.connection.username", dbProvider.getJdbcUsername());
+            emfProps.setProperty("hibernate.connection.password", dbProvider.getJdbcPassword());
+        }
 
-            try {
-                this.emf = Persistence.createEntityManagerFactory("PlanetPU", emfProps);
-            } catch (PersistenceException pe) {
-                logger.error("ERROR: creating entity manager", pe);
-                throw new PlanetException(pe);
-            }
+        try {
+            this.emf = Persistence.createEntityManagerFactory("PlanetPU", emfProps);
+        } catch (PersistenceException pe) {
+            throw new PlanetPersistenceException("Error creating JPA Entity Manager Factory", pe);
         }
     }
           
     
     /**
      * Flush changes to the datastore, commit transaction, release em.
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
-    public void flush() throws PlanetException {
+    public void flush() throws PlanetPersistenceException {
+        
+        log.debug("Committing current transaction");
+        
         try {
             EntityManager em = getEntityManager(true);
             em.getTransaction().commit();
         } catch (PersistenceException pe) {
-            throw new PlanetException(pe);
+            throw new PlanetPersistenceException(pe);
         }
     }
     
+    
     /**
      * Release database session, rolls back any uncommitted changes.
      */
     public void release() {
         EntityManager em = getEntityManager(false);
         if (isTransactionActive(em)) {
+            log.debug("Forcing rollback on active transaction");
             em.getTransaction().rollback();
         }
+        
+        log.debug("Closing JPA EntityManager");
         em.close();
         setThreadLocalEntityManager(null);
     }
     
+    
     /**
      * Store object using an existing transaction.
      * @param obj the object to persist
      * @return the object persisted
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
-    public Object store(Object obj) throws PlanetException {
+    public Object store(Object obj) throws PlanetPersistenceException {
         EntityManager em = getEntityManager(true);
         if (!em.contains(obj)) {
             // If entity is not managed we can assume it is new
@@ -172,34 +156,37 @@
         return obj;
     }
     
+    
     /**
      * Remove object from persistence storage.
      * @param clazz the class of object to remove
      * @param id the id of the object to remove
-     * @throws PlanetException on any error deleting object
+     * @throws PlanetPersistenceException on any error deleting object
      */
-    public void remove(Class clazz, String id) throws PlanetException {
+    public void remove(Class clazz, String id) throws PlanetPersistenceException {
         EntityManager em = getEntityManager(true);
         Object po = em.find(clazz, id);
         em.remove(po);
     }
     
+    
     /**
      * Remove object from persistence storage.
      * @param po the persistent object to remove
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
-    public void remove(Object po) throws PlanetException {
+    public void remove(Object po) throws PlanetPersistenceException {
         EntityManager em = getEntityManager(true);
         em.remove(po);
     }
     
+    
     /**
      * Remove object from persistence storage.
      * @param pos the persistent objects to remove
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
-    public void removeAll(Collection pos) throws PlanetException {
+    public void removeAll(Collection pos) throws PlanetPersistenceException {
         EntityManager em = getEntityManager(true);
         for (Iterator iterator = pos.iterator(); iterator.hasNext();) {
             Object obj = iterator.next();
@@ -207,15 +194,16 @@
         }
     }    
     
+    
     /**
      * Retrieve object, no transaction needed.
      * @param clazz the class of object to retrieve
      * @param id the id of the object to retrieve
      * @return the object retrieved
-     * @throws PlanetException on any error retrieving object
+     * @throws PlanetPersistenceException on any error retrieving object
      */
     public Object load(Class clazz, String id)
-    throws PlanetException {
+    throws PlanetPersistenceException {
         EntityManager em = getEntityManager(false);
         return em.find(clazz, id);
     }
@@ -269,10 +257,10 @@
     /**
      * Get named query with FlushModeType.COMMIT
      * @param queryName the name of the query
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
     public Query getNamedQuery(String queryName)
-    throws PlanetException {
+    throws PlanetPersistenceException {
         EntityManager em = getEntityManager(false);
         Query q = em.createNamedQuery(queryName);
         // Never flush for queries. Roller code assumes this behavior
@@ -283,10 +271,10 @@
     /**
      * Create query from queryString with FlushModeType.COMMIT
      * @param queryString the quuery
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
     public Query getDynamicQuery(String queryString)
-    throws PlanetException {
+    throws PlanetPersistenceException {
         EntityManager em = getEntityManager(false);
         Query q = em.createQuery(queryString);
         // Never flush for queries. Roller code assumes this behavior
@@ -297,10 +285,10 @@
     /**
      * Get named update query with default flush mode
      * @param queryName the name of the query
-     * @throws org.apache.roller.planet.PlanetException on any error
+     * @throws org.apache.roller.planet.PlanetPersistenceException on any error
      */
     public Query getNamedUpdate(String queryName)
-    throws PlanetException {
+    throws PlanetPersistenceException {
         EntityManager em = getEntityManager(true);
         Query q = em.createNamedQuery(queryName);
         return q;
@@ -311,22 +299,22 @@
      * @param resourceName The name of the resource containing properties
      * @param cl Classloeder to be used to locate the resouce
      * @return A properties object
-     * @throws PlanetException
+     * @throws PlanetPersistenceException
      */
     protected static Properties loadPropertiesFromResourceName(
-            String resourceName, ClassLoader cl) throws PlanetException {
+            String resourceName, ClassLoader cl) throws PlanetPersistenceException {
         Properties props = new Properties();
         InputStream in = null;
         in = cl.getResourceAsStream(resourceName);
         if (in == null) {
             //TODO: Check how i18n is done in roller
-            throw new PlanetException(
+            throw new PlanetPersistenceException(
                     "Could not locate properties to load " + resourceName);
         }
         try {
             props.load(in);
         } catch (IOException ioe) {
-            throw new PlanetException(
+            throw new PlanetPersistenceException(
                     "Could not load properties from " + resourceName);
         } finally {
             if (in != null) {

Modified: roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPlanetManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPlanetManagerImpl.java?rev=672574&r1=672573&r2=672574&view=diff
==============================================================================
--- roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPlanetManagerImpl.java (original)
+++ roller/planet/core/trunk/src/java/org/apache/roller/planet/business/jpa/JPAPlanetManagerImpl.java Sat Jun 28 12:18:17 2008
@@ -31,13 +31,15 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import org.apache.roller.planet.PlanetException;
 import org.apache.roller.planet.business.PlanetManager;
+import org.apache.roller.planet.business.PlanetPersistenceException;
 import org.apache.roller.planet.pojos.Planet;
 import org.apache.roller.planet.pojos.SubscriptionEntry;
 import org.apache.roller.planet.pojos.PlanetGroup;
 import org.apache.roller.planet.pojos.Subscription;
 import org.apache.roller.planet.business.AbstractManagerImpl;
+import org.apache.roller.planet.pojos.User;
+
 
 /**
  * Manages Planet Roller objects and entry aggregations in a database.
@@ -64,39 +66,37 @@
     }
     
     
-    public void saveGroup(PlanetGroup group) throws PlanetException {
+    public void saveGroup(PlanetGroup group) throws PlanetPersistenceException {
         strategy.store(group);
     }
     
-    public void saveEntry(SubscriptionEntry entry) throws PlanetException {
+    public void saveEntry(SubscriptionEntry entry) throws PlanetPersistenceException {
         strategy.store(entry);
     }
     
     public void saveSubscription(Subscription sub)
-    throws PlanetException {
+    throws PlanetPersistenceException {
         Subscription existing = getSubscription(sub.getFeedURL());
         if (existing == null || (existing.getId().equals(sub.getId()))) {
             strategy.store(sub);
         } else {
-            throw new PlanetException("ERROR: duplicate feed URLs not allowed");
+            throw new PlanetPersistenceException("ERROR: duplicate feed URLs not allowed");
         }
     }
     
-    public void deleteEntry(SubscriptionEntry entry) throws PlanetException {
+    public void deleteEntry(SubscriptionEntry entry) throws PlanetPersistenceException {
         strategy.remove(entry);
     }
     
-    public void deleteGroup(PlanetGroup group) throws PlanetException {
+    public void deleteGroup(PlanetGroup group) throws PlanetPersistenceException {
         strategy.remove(group);
     }
     
-    public void deleteSubscription(Subscription sub)
-    throws PlanetException {
+    public void deleteSubscription(Subscription sub) throws PlanetPersistenceException {
         strategy.remove(sub);
     }
     
-    public Subscription getSubscription(String feedUrl)
-    throws PlanetException {
+    public Subscription getSubscription(String feedUrl) throws PlanetPersistenceException {
         Query q = strategy.getNamedQuery("Subscription.getByFeedURL");
         q.setParameter(1, feedUrl);
         try {
@@ -106,56 +106,24 @@
         }
     }
     
-    public Subscription getSubscriptionById(String id)
-    throws PlanetException {
-        return (Subscription) strategy.load(
-                Subscription.class, id);
+    public Subscription getSubscriptionById(String id) throws PlanetPersistenceException {
+        return (Subscription) strategy.load(Subscription.class, id);
     }
     
-    public Iterator getAllSubscriptions() {
-        try {
-            return ((List)strategy.getNamedQuery(
-                    "Subscription.getAll").getResultList()).iterator();
-        } catch (Throwable e) {
-            throw new RuntimeException(
-                    "ERROR fetching subscription collection", e);
-        }
+    public List getSubscriptions() throws PlanetPersistenceException {
+        Query q = strategy.getNamedQuery("Subscription.getAllOrderByFeedURL");
+        return q.getResultList();
     }
     
-    public int getSubscriptionCount() throws PlanetException {
-        Query q = strategy.getNamedQuery("Subscription.getAll");
-        return q.getResultList().size();
-    }
-    
-    public List getTopSubscriptions(int offset, int length)
-    throws PlanetException {
-        return getTopSubscriptions(null, offset, length);
-    }
-    
-    /**
-     * Get top X subscriptions, restricted by group.
-     */
-    public List getTopSubscriptions(
-            PlanetGroup group, int offset, int len) throws PlanetException {
-        List result = null;
-        if (group != null) {
-            Query q = strategy.getNamedQuery(
-                    "Subscription.getByGroupOrderByInboundBlogsDesc");
-            q.setParameter(1, group);
-            if (offset != 0) q.setFirstResult(offset);
-            if (len != -1) q.setMaxResults(len);
-            result = q.getResultList();
-        } else {
-            Query q = strategy.getNamedQuery(
-                    "Subscription.getAllOrderByInboundBlogsDesc");
-            if (offset != 0) q.setFirstResult(offset);
-            if (len != -1) q.setMaxResults(len);
-            result = q.getResultList();
-        }
-        return result;
+    // TODO: change this to return a long
+    public int getSubscriptionCount() throws PlanetPersistenceException {
+        Query q = strategy.getNamedQuery("Subscription.getCount");
+        List results = q.getResultList();
+        return ((Long) results.get(0)).intValue();
     }
     
-    public PlanetGroup getGroup(String handle) throws PlanetException {
+    
+    public PlanetGroup getGroup(String handle) throws PlanetPersistenceException {
         Query q = strategy.getNamedQuery("PlanetGroup.getByHandle");
         q.setParameter(1, handle);
         try {
@@ -165,18 +133,16 @@
         }
     }
     
-    public PlanetGroup getGroupById(String id) throws PlanetException {
+    public PlanetGroup getGroupById(String id) throws PlanetPersistenceException {
         return (PlanetGroup) strategy.load(PlanetGroup.class, id);
     }        
     
-    public void release() {}
     
-    
-    public void savePlanet(Planet planet) throws PlanetException {
+    public void savePlanet(Planet planet) throws PlanetPersistenceException {
         strategy.store(planet);
     }
     
-    public Planet getPlanet(String handle) throws PlanetException {
+    public Planet getPlanet(String handle) throws PlanetPersistenceException {
         Query q = strategy.getNamedQuery("Planet.getByHandle");
         q.setParameter(1, handle);
         try {
@@ -186,15 +152,21 @@
         }
     }
     
-    public Planet getPlanetById(String id) throws PlanetException {
+    public Planet getPlanetById(String id) throws PlanetPersistenceException {
         return (Planet)strategy.load(Planet.class, id);
     }
     
-    public List getPlanets() throws PlanetException {
+    public List getPlanets() throws PlanetPersistenceException {
         return (List)strategy.getNamedQuery("Planet.getAll").getResultList();
     }
     
-    public List getGroupHandles(Planet planet) throws PlanetException {
+    public List getPlanets(User user) throws PlanetPersistenceException {
+        Query q = strategy.getNamedQuery("Planet.getByUser");
+        q.setParameter(1, user);
+        return q.getResultList();
+    }
+    
+    public List getGroupHandles(Planet planet) throws PlanetPersistenceException {
         List handles = new ArrayList();
         Iterator list = getGroups(planet).iterator();
         while (list.hasNext()) {
@@ -204,13 +176,13 @@
         return handles;
     }
     
-    public List getGroups(Planet planet) throws PlanetException {
+    public List getGroups(Planet planet) throws PlanetPersistenceException {
         Query q = strategy.getNamedQuery("PlanetGroup.getByPlanet");
         q.setParameter(1, planet.getHandle());
         return q.getResultList();
     }
     
-    public PlanetGroup getGroup(Planet planet, String handle) throws PlanetException {
+    public PlanetGroup getGroup(Planet planet, String handle) throws PlanetPersistenceException {
         Query q = strategy.getNamedQuery("PlanetGroup.getByPlanetAndHandle");
         q.setParameter(1, planet.getHandle());
         q.setParameter(2, handle);
@@ -221,12 +193,13 @@
         }
     }
     
-    public void deletePlanet(Planet planet) throws PlanetException {
+    public void deletePlanet(Planet planet) throws PlanetPersistenceException {
+        // groups and permissions are removed by JPA cascading
         strategy.remove(planet);
     }
     
     public void deleteEntries(Subscription sub) 
-        throws PlanetException {
+        throws PlanetPersistenceException {
         Iterator entries = sub.getEntries().iterator();
         while(entries.hasNext()) {
             strategy.remove(entries.next());
@@ -236,18 +209,14 @@
         sub.getEntries().clear();
     }
     
-    public List getSubscriptions() throws PlanetException {
-        Query q = strategy.getNamedQuery("Subscription.getAllOrderByFeedURL");
-        return q.getResultList();
-    }
 
-    public SubscriptionEntry getEntryById(String id) throws PlanetException {
+    public SubscriptionEntry getEntryById(String id) throws PlanetPersistenceException {
         return (SubscriptionEntry) strategy.load(SubscriptionEntry.class, id);
     }
 
-    public List getEntries(Subscription sub, int offset, int len) throws PlanetException {            
+    public List getEntries(Subscription sub, int offset, int len) throws PlanetPersistenceException {            
         if(sub == null) {
-            throw new PlanetException("subscription cannot be null");
+            throw new PlanetPersistenceException("subscription cannot be null");
         }
         Query q = strategy.getNamedQuery("SubscriptionEntry.getBySubscription");
         q.setParameter(1, sub);
@@ -256,15 +225,15 @@
         return q.getResultList();
     }
 
-    public List getEntries(PlanetGroup group, int offset, int len) throws PlanetException {
+    public List getEntries(PlanetGroup group, int offset, int len) throws PlanetPersistenceException {
         return getEntries(group, null, null, offset, len);
     }
 
-    public List getEntries(PlanetGroup group, Date startDate, Date endDate, int offset, int len) throws PlanetException {
+    public List getEntries(PlanetGroup group, Date startDate, Date endDate, int offset, int len) throws PlanetPersistenceException {
         StringBuffer queryString = new StringBuffer();
                 
         if(group == null) {
-            throw new PlanetException("group cannot be null or empty");
+            throw new PlanetPersistenceException("group cannot be null or empty");
         }
         
         List ret = null;
@@ -277,8 +246,8 @@
             sb.append("SELECT e FROM SubscriptionEntry e ");
             sb.append("JOIN e.subscription.groups g ");
                         
-            params.add(size++, group.getHandle());
-            sb.append("WHERE g.handle = ?").append(size);
+            params.add(size++, group.getId());
+            sb.append("WHERE g.id = ?").append(size);
             
             if (startDate != null) {
                 params.add(size++, new Timestamp(startDate.getTime()));
@@ -309,14 +278,9 @@
                     +((endTime-startTime)/1000.0)+" seconds");
             
         } catch (Throwable e) {
-            throw new PlanetException(e);
+            throw new PlanetPersistenceException(e);
         }
         
         return ret;
     }
 }
-
-
-
-
-