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 2006/12/11 20:51:02 UTC

svn commit: r485845 [2/3] - in /incubator/roller/trunk: ./ metadata/database/hibernate/ sandbox/planetroller/ sandbox/planetroller/nbproject/ sandbox/planetroller/src/org/apache/roller/ sandbox/planetroller/src/org/apache/roller/planet/business/ sandbo...

Copied: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java (from r483703, incubator/roller/trunk/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java)
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java?view=diff&rev=485845&p1=incubator/roller/trunk/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java&r1=483703&p2=incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java&r2=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/tasks/TechnoratiRankingsTask.java Mon Dec 11 11:50:59 2006
@@ -22,15 +22,11 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Iterator;
-import java.util.Properties;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.roller.RollerException;
-import org.apache.roller.business.runnable.RollerTask;
-import org.apache.roller.config.RollerConfig;
+import org.apache.roller.planet.business.PlanetFactory;
 import org.apache.roller.planet.business.PlanetManager;
-import org.apache.roller.business.RollerFactory;
-import org.apache.roller.business.UserManager;
+import org.apache.roller.planet.config.PlanetConfig;
 import org.apache.roller.planet.pojos.PlanetConfigData;
 import org.apache.roller.planet.pojos.PlanetSubscriptionData;
 import org.apache.roller.util.Technorati;
@@ -39,79 +35,20 @@
 /**
  * Rank each subscription by populating Technorati inbound blog and link counts.
  */
-public class TechnoratiRankingsTask extends RollerTask {
+public class TechnoratiRankingsTask implements Runnable {
     
     private static Log log = LogFactory.getLog(TechnoratiRankingsTask.class);
     
-    // a String description of when to start this task
-    private String startTimeDesc = "startOfDay";
-    
-    // interval at which the task is run, default is 5 minutes
-    private int interval = 1440;
-    
-    // lease time given to task lock, default is 30 minutes
-    private int leaseTime = 30;
-    
-    
-    public String getName() {
-        return "TechnoratiRankingsTask";
-    }
-    
-    public Date getStartTime(Date currentTime) {
-        return getAdjustedTime(currentTime, startTimeDesc);
-    }
-    
-    public int getInterval() {
-        return this.interval;
-    }
-    
-    public int getLeaseTime() {
-        return this.leaseTime;
-    }
-    
-    
-    public void init() throws RollerException {
-        
-        // get relevant props
-        Properties props = this.getTaskProperties();
-        
-        // extract start time
-        String startTimeStr = props.getProperty("startTime");
-        if(startTimeStr != null) {
-            this.startTimeDesc = startTimeStr;
-        }
-        
-        // extract interval
-        String intervalStr = props.getProperty("interval");
-        if(intervalStr != null) {
-            try {
-                this.interval = Integer.parseInt(intervalStr);
-            } catch (NumberFormatException ex) {
-                log.warn("Invalid interval: "+intervalStr);
-            }
-        }
-        
-        // extract lease time
-        String leaseTimeStr = props.getProperty("leaseTime");
-        if(leaseTimeStr != null) {
-            try {
-                this.leaseTime = Integer.parseInt(leaseTimeStr);
-            } catch (NumberFormatException ex) {
-                log.warn("Invalid leaseTime: "+leaseTimeStr);
-            }
-        }
-    }
-    
     
     /**
      * Loop through all subscriptions get get Technorati rankings for each
      */
-    public void runTask() {
+    public void run() {
         
         int count = 0;
         int errorCount = 0;
         try {
-            PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+            PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
             PlanetConfigData config = planet.getConfiguration();
             Technorati technorati = null;
             try {
@@ -131,9 +68,8 @@
                 return;
             }
             
-            UserManager userManager = RollerFactory.getRoller().getUserManager();
             try {
-                int limit = RollerConfig.getIntProperty(
+                int limit = PlanetConfig.getIntProperty(
                         "planet.aggregator.technorati.limit", 500);
                 int userCount = planet.getSubscriptionCount();
                 int mod = (userCount / limit) + 1;
@@ -186,30 +122,14 @@
                 }
                 
                 // all done, flush results to db
-                RollerFactory.getRoller().flush();
+                PlanetFactory.getPlanet().flush();
                 
             } finally {
-                RollerFactory.getRoller().release();
+                PlanetFactory.getPlanet().release();
             }
             
         } catch (Exception e) {
             log.error("ERROR ranking subscriptions", e);
-        }
-    }
-    
-    
-    /** 
-     * Task may be run from the command line 
-     */
-    public static void main(String[] args) {
-        try {
-            TechnoratiRankingsTask task = new TechnoratiRankingsTask();
-            task.init();
-            task.run();
-            System.exit(0);
-        } catch (Throwable t) {
-            t.printStackTrace();
-            System.exit(-1);
         }
     }
     

Modified: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/ConfigForm.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/ConfigForm.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/ConfigForm.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/ConfigForm.java Mon Dec 11 11:50:59 2006
@@ -67,6 +67,8 @@
             }
             planet.getPlanetManager().saveConfiguration(dbconfig);
         } else {
+            // id must be null when saving new objects
+            planetConfig.setId(null);
             planet.getPlanetManager().saveConfiguration(planetConfig);
         }         
         planet.flush();

Modified: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/GroupForm.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/GroupForm.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/GroupForm.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/GroupForm.java Mon Dec 11 11:50:59 2006
@@ -82,6 +82,8 @@
             dbgroup.setDescription(group.getDescription());
             planet.getPlanetManager().saveGroup(dbgroup);
         } else {
+            // id must be null when saving new objects
+            group.setId(null);
             planet.getPlanetManager().saveGroup(group); 
         }
         planet.flush();

Modified: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/SubscriptionForm.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/SubscriptionForm.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/SubscriptionForm.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/planet/ui/forms/SubscriptionForm.java Mon Dec 11 11:50:59 2006
@@ -89,7 +89,9 @@
             if (existingSub != null) {
                 subscription = existingSub;
             }
-            else { 
+            else {
+                // id must be null when saving new objects
+                subscription.setId(null);
                 pmgr.saveSubscription(subscription);
             }
             PlanetGroupData group = pmgr.getGroupById(groupid);

Added: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/MailUtil.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/MailUtil.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/MailUtil.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/MailUtil.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,316 @@
+/*
+* 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.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.SendFailedException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.Address;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import org.apache.commons.lang.StringUtils;
+
+public class MailUtil extends Object {
+   
+	private static Log mLogger = 
+		LogFactory.getFactory().getInstance(MailUtil.class);
+
+    // agangolli: Incorporated suggested changes from Ken Blackler.
+
+    /**
+     * This method is used to send a Message with a pre-defined
+     * mime-type.
+     * 
+     * @param from e-mail address of sender
+     * @param to e-mail address(es) of recipients
+     * @param subject subject of e-mail
+     * @param content the body of the e-mail
+     * @param mimeType type of message, i.e. text/plain or text/html
+     * @throws MessagingException the exception to indicate failure
+     */
+    public static void sendMessage
+    (
+    	Session session,
+        String from,
+        String[] to,
+        String[] cc,
+        String[] bcc,
+        String subject,
+        String content,
+        String mimeType
+    ) 
+    throws MessagingException
+    {
+        Message message = new MimeMessage(session);
+
+        // n.b. any default from address is expected to be determined by caller.
+        if (! StringUtils.isEmpty(from)) {
+			InternetAddress sentFrom = new InternetAddress(from);
+			message.setFrom(sentFrom);
+			if (mLogger.isDebugEnabled()) mLogger.debug("e-mail from: " + sentFrom);
+        }
+
+		if (to!=null)
+		{
+			InternetAddress[] sendTo = new InternetAddress[to.length];
+	
+			for (int i = 0; i < to.length; i++) 
+			{
+				sendTo[i] = new InternetAddress(to[i]);
+				if (mLogger.isDebugEnabled()) mLogger.debug("sending e-mail to: " + to[i]);
+			}
+			message.setRecipients(Message.RecipientType.TO, sendTo);
+		}
+
+		if (cc != null) 
+		{
+			InternetAddress[] copyTo = new InternetAddress[cc.length];
+
+			for (int i = 0; i < cc.length; i++) 
+			{
+				copyTo[i] = new InternetAddress(cc[i]);
+				if (mLogger.isDebugEnabled()) mLogger.debug("copying e-mail to: " + cc[i]);
+			}
+			message.setRecipients(Message.RecipientType.CC, copyTo);
+		}	        
+
+		if (bcc != null) 
+		{
+			InternetAddress[] copyTo = new InternetAddress[bcc.length];
+
+			for (int i = 0; i < bcc.length; i++) 
+			{
+				copyTo[i] = new InternetAddress(bcc[i]);
+				if (mLogger.isDebugEnabled()) mLogger.debug("blind copying e-mail to: " + bcc[i]);
+			}
+			message.setRecipients(Message.RecipientType.BCC, copyTo);
+		}	        
+        message.setSubject((subject == null) ? "(no subject)" : subject);
+        message.setContent(content, mimeType);
+        message.setSentDate(new java.util.Date()); 
+
+		// First collect all the addresses together.
+        Address[] remainingAddresses = message.getAllRecipients();
+        int nAddresses = remainingAddresses.length;
+        boolean bFailedToSome = false;
+        
+        SendFailedException sendex = new SendFailedException("Unable to send message to some recipients");
+        
+		// Try to send while there remain some potentially good addresses
+		do
+        {
+			// Avoid a loop if we are stuck
+			nAddresses = remainingAddresses.length;
+
+			try
+			{
+				// Send to the list of remaining addresses, ignoring the addresses attached to the message
+		        Transport.send(message,remainingAddresses);
+			}
+			catch(SendFailedException ex)
+			{
+				bFailedToSome=true;
+				sendex.setNextException(ex);
+				
+				// Extract the remaining potentially good addresses
+				remainingAddresses=ex.getValidUnsentAddresses();
+			}
+        } while (remainingAddresses!=null && remainingAddresses.length>0 && remainingAddresses.length!=nAddresses);
+        
+        if (bFailedToSome) throw sendex;
+    }
+
+    /**
+     * This method is used to send a Text Message.
+     * 
+     * @param from e-mail address of sender
+     * @param to e-mail addresses of recipients
+     * @param subject subject of e-mail
+     * @param content the body of the e-mail
+     * @throws MessagingException the exception to indicate failure
+     */
+    public static void sendTextMessage
+    (
+    	Session session,
+        String from,
+        String[] to,
+        String[] cc,
+        String[] bcc,
+        String subject,
+        String content
+    ) 
+    throws MessagingException
+    {
+        sendMessage(session, from, to, cc, bcc, subject, content, "text/plain; charset=utf-8");
+    }
+    
+	/**
+	 * This method overrides the sendTextMessage to specify
+	 * one receiver and mulitple cc recipients.
+	 * 
+	 * @param from e-mail address of sender
+	 * @param to e-mail addresses of recipients
+	 * @param subject subject of e-mail
+	 * @param content the body of the e-mail
+	 * @throws MessagingException the exception to indicate failure
+	 */
+	public static void sendTextMessage
+	(
+		Session session,
+		String from,
+		String to,
+		String[] cc,
+        String[] bcc,
+		String subject,
+		String content
+	) 
+	throws MessagingException
+	{
+        String[] recipient = null;
+		if (to!=null) recipient = new String[] {to};
+
+		sendMessage(session, from, recipient, cc, bcc, subject, content, "text/plain; charset=utf-8");
+	}
+	
+    /**
+	 * This method overrides the sendTextMessage to specify
+	 * only one receiver and cc recipients, rather than 
+	 * an array of recipients.
+     * 
+     * @param from e-mail address of sender
+     * @param to e-mail address of recipient
+     * @param cc e-mail address of cc recipient
+     * @param subject subject of e-mail
+     * @param content the body of the e-mail
+     * @throws MessagingException the exception to indicate failure
+     */
+    public static void sendTextMessage
+    (
+    	Session session,
+        String from,
+        String to,
+        String cc,
+        String bcc,
+        String subject,
+        String content
+    ) 
+    throws MessagingException
+    {
+        String[] recipient = null;
+        String[] copy = null;
+        String[] bcopy = null;
+
+		if (to!=null) recipient = new String[] {to};
+		if (cc!=null) copy = new String[] {cc};
+		if (bcc!=null) bcopy = new String[] {bcc};
+
+        sendMessage(session, from, recipient, copy, bcopy, subject, content, "text/plain; charset=utf-8");
+    }
+    
+    /**
+     * This method is used to send a HTML Message
+     * 
+     * @param from e-mail address of sender
+     * @param to e-mail address(es) of recipients
+     * @param subject subject of e-mail
+     * @param content the body of the e-mail
+     * @throws MessagingException the exception to indicate failure
+     */
+    public static void sendHTMLMessage
+    (
+    	Session session,
+        String from,
+        String[] to,
+        String[] cc,
+        String[] bcc,
+        String subject,
+        String content
+    ) 
+    throws MessagingException
+    {
+        sendMessage(session, from, to, cc, bcc, subject, content, "text/html; charset=utf-8");
+    }
+    
+    /**
+     * This method overrides the sendHTMLMessage to specify
+     * only one sender, rather than an array of senders.
+     * 
+     * @param from e-mail address of sender
+     * @param to e-mail address of recipients
+     * @param subject subject of e-mail
+     * @param content the body of the e-mail
+     * @throws MessagingException the exception to indicate failure
+     */
+	public static void sendHTMLMessage
+    (
+    	Session session,
+        String from,
+        String to,
+        String cc,
+        String bcc,
+        String subject,
+        String content
+    ) 
+    throws MessagingException
+    {
+        String[] recipient = null;
+        String[] copy = null;
+        String[] bcopy = null;
+
+		if (to!=null) recipient = new String[] {to};
+		if (cc!=null) copy = new String[] {cc};
+		if (bcc!=null) bcopy = new String[] {bcc};
+
+        sendMessage(session, from, recipient, copy, bcopy, subject, content, "text/html; charset=utf-8");
+    }
+    
+	/**
+	 * This method overrides the sendHTMLMessage to specify
+	 * one receiver and mulitple cc recipients.
+	 * 
+	 * @param from e-mail address of sender
+	 * @param to e-mail address of recipient
+	 * @param cc e-mail addresses of recipients
+	 * @param subject subject of e-mail
+	 * @param content the body of the e-mail
+	 * @throws MessagingException the exception to indicate failure
+	 */
+	public static void sendHTMLMessage
+	(
+		Session session,
+		String from,
+		String to,
+		String[] cc,
+		String[] bcc,
+		String subject,
+		String content
+	) 
+	throws MessagingException
+	{
+        String[] recipient = null;
+		if (to!=null) recipient = new String[] {to};
+
+		sendMessage(session, from, recipient, cc, bcc, subject, content, "text/html; charset=utf-8");
+	}
+}
+

Added: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/PropertyExpander.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/PropertyExpander.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/PropertyExpander.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/PropertyExpander.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,86 @@
+/*
+ * 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.util;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Property expansion utility.  This utility provides static methods to expand properties appearing in strings.
+ *
+ * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a> (Portions based on code from David Graff submitted for
+ *         ROL-613)
+ * @since Roller 1.3
+ */
+public class PropertyExpander {
+    private PropertyExpander() {
+    }
+
+    // The pattern for a system property.  Matches ${property.name}, with the interior matched reluctantly.
+    private static final Pattern EXPANSION_PATTERN = Pattern.compile("(\\$\\{([^}]+?)\\})", java.util.regex.Pattern.MULTILINE);
+
+    /**
+     * Expand property expressions in the input.  Expands property expressions of the form <code>${propertyname}</code>
+     * in the input, replacing each such expression with the value associated to the respective key
+     * <code>propertyname</code> in the supplied map.  If for a given expression, the property is undefined (has null
+     * value) in the map supplied, that expression is left unexpanded in the resulting string.
+     * <p/>
+     * Note that expansion is not recursive.  If the value of one property contains another expression, the expression
+     * appearing in the value will not be expanded further.
+     *
+     * @param input the input string.  This may be null, in which case null is returned.
+     * @param props the map of property values to use for expansion.  This map should have <code>String</code> keys and
+     *              <code>String</code> values.  Any object of class {@link java.util.Properties} works here, as will
+     *              other implementations of such maps.
+     * @return the result of replacing property expressions with the values of the corresponding properties from the
+     *         supplied property map, null if the input string is null.
+     */
+    public static String expandProperties(String input, Map props) {
+        if (input == null) return null;
+
+        Matcher matcher = EXPANSION_PATTERN.matcher(input);
+
+        StringBuffer expanded = new StringBuffer(input.length());
+        while (matcher.find()) {
+            String propName = matcher.group(2);
+            String value = (String) props.get(propName);
+            // if no value is found, use a value equal to the original expression
+            if (value == null) value = matcher.group(0);
+            // Fake a literal replacement since Matcher.quoteReplacement() is not present in 1.4.
+            matcher.appendReplacement(expanded, "");
+            expanded.append(value);
+        }
+        matcher.appendTail(expanded);
+
+        return expanded.toString();
+    }
+
+    /**
+     * Expand system properties in the input string.  This is equivalent to calling <code>expandProperties(input,
+     * System.getProperties())</code>.
+     *
+     * @param input
+     * @return the result of replacing property expressions with the values of the corresponding system properties.
+     * @see System#getProperties()
+     */
+    public static String expandSystemProperties(String input) {
+        return expandProperties(input, System.getProperties());
+    }
+}

Added: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/RegexUtil.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/RegexUtil.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/RegexUtil.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/RegexUtil.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1 @@
+/*
* 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 Nov 8, 2003
 *
 */
package org.apache.roller.util;
import org.apache.commons.codec.binary.Hex;

import java.io.UnsupportedEncodingException;
import ja
 va.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author lance
 */
public class RegexUtil
{
    public static final Pattern mailtoPattern = Pattern.compile("mailto:([a-zA-Z0-9\\.]+@[a-zA-Z0-9\\.]+\\.[a-zA-Z0-9]+)");
    public static final Pattern emailPattern = Pattern.compile("\\b[a-zA-Z0-9\\.]+(@)([a-zA-Z0-9\\.]+)(\\.)([a-zA-Z0-9]+)\\b");
    
    public static String encodeEmail(String str)
    {
        // obfuscate mailto's: turns them into hex encoded,
        // so that browsers can still understand the mailto link
        Matcher mailtoMatch = mailtoPattern.matcher(str);
        while (mailtoMatch.find())
        {
            String email = mailtoMatch.group(1);
            //System.out.println("email=" + email);
            String hexed = encode(email);
            str = str.replaceFirst("mailto:"+email, "mailto:"+hexed);
        }
        
        return obfuscateEmail(str);
    }

    /**
     * obfuscate plaintext emai
 ls: makes them
     * "human-readable" - still too easy for
     * machines to parse however.
     * 
     * @param str
     * @return
     */
    public static String obfuscateEmail(String str)
    {
        Matcher emailMatch = emailPattern.matcher(str);
        while (emailMatch.find())
        {
            String at = emailMatch.group(1);
            //System.out.println("at=" + at);
            str = str.replaceFirst(at, "-AT-");
            
            String dot = emailMatch.group(2) + emailMatch.group(3) + emailMatch.group(4);
            String newDot = emailMatch.group(2) + "-DOT-" + emailMatch.group(4);
            //System.out.println("dot=" + dot);
            str = str.replaceFirst(dot, newDot);
        }
        return str;
    }
    
    /**
     * Return the specified match "groups" from the pattern.
     * For each group matched a String will be entered in the ArrayList.
     * 
     * @param pattern The Pattern to use.
     * @param match The String to m
 atch against.
     * @param group The group number to return in case of a match.
     * @return
     */
    public static ArrayList getMatches(Pattern pattern, String match, int group)
    {
        ArrayList matches = new ArrayList();
        Matcher matcher = pattern.matcher(match);
        while (matcher.find()) 
        {
            matches.add( matcher.group(group) );
        }
        return matches;
    }

	/**
     * Thanks to the folks at Blojsom (http://sf.net/projects/blojsom)
     * for showing me what I was doing wrong with the Hex class.
     * 
	 * @param email
	 * @return
	 */
	public static String encode(String email)
	{
        StringBuffer result = new StringBuffer();
        try {
            char[] hexString = Hex.encodeHex(email.getBytes("UTF-8"));
            for (int i = 0; i < hexString.length; i++) {
                if (i % 2 == 0) {
                    result.append("%");
                }
                result.append(hexString[i]);
            }
 
        } catch (UnsupportedEncodingException e) {
            return email;
        }

        return result.toString();
	}
}
\ No newline at end of file

Added: incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/Utilities.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/Utilities.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/Utilities.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/src/org/apache/roller/util/Utilities.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,854 @@
+package org.apache.roller.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+/**
+ * General purpose utilities, not for use in templates.
+ */
+public class Utilities {
+    /** The <code>Log</code> instance for this class. */
+    private static Log mLogger = LogFactory.getLog(Utilities.class);
+    
+    public final static String TAG_SPLIT_CHARS = " ,\n\r\f\t";
+      
+    //------------------------------------------------------------------------
+    /** Strip jsessionid off of a URL */
+    public static String stripJsessionId( String url ) {
+        // Strip off jsessionid found in referer URL
+        int startPos = url.indexOf(";jsessionid=");
+        if ( startPos != -1 ) {
+            int endPos = url.indexOf("?",startPos);
+            if ( endPos == -1 ) {
+                url = url.substring(0,startPos);
+            } else {
+                url = url.substring(0,startPos)
+                + url.substring(endPos,url.length());
+            }
+        }
+        return url;
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Escape, but do not replace HTML.
+     * The default behaviour is to escape ampersands.
+     */
+    public static String escapeHTML(String s) {
+        return escapeHTML(s, true);
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Escape, but do not replace HTML.
+     * @param escapeAmpersand Optionally escape
+     * ampersands (&amp;).
+     */
+    public static String escapeHTML(String s, boolean escapeAmpersand) {
+        // got to do amp's first so we don't double escape
+        if (escapeAmpersand) {
+            s = StringUtils.replace(s, "&", "&amp;");
+        }
+        s = StringUtils.replace(s, "&nbsp;", " ");
+        s = StringUtils.replace(s, "\"", "&quot;");
+        s = StringUtils.replace(s, "<", "&lt;");
+        s = StringUtils.replace(s, ">", "&gt;");
+        return s;
+    }
+     
+    public static String unescapeHTML(String str) {
+        return StringEscapeUtils.unescapeHtml(str);
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Remove occurences of html, defined as any text
+     * between the characters "&lt;" and "&gt;".  Replace
+     * any HTML tags with a space.
+     */
+    public static String removeHTML(String str) {
+        return removeHTML(str, true);
+    }
+    
+    /**
+     * Remove occurences of html, defined as any text
+     * between the characters "&lt;" and "&gt;".
+     * Optionally replace HTML tags with a space.
+     *
+     * @param str
+     * @param addSpace
+     * @return
+     */
+    public static String removeHTML(String str, boolean addSpace) {
+        if (str == null) return "";
+        StringBuffer ret = new StringBuffer(str.length());
+        int start = 0;
+        int beginTag = str.indexOf("<");
+        int endTag = 0;
+        if (beginTag == -1)
+            return str;
+        
+        while (beginTag >= start) {
+            if (beginTag > 0) {
+                ret.append(str.substring(start, beginTag));
+                
+                // replace each tag with a space (looks better)
+                if (addSpace) ret.append(" ");
+            }
+            endTag = str.indexOf(">", beginTag);
+            
+            // if endTag found move "cursor" forward
+            if (endTag > -1) {
+                start = endTag + 1;
+                beginTag = str.indexOf("<", start);
+            }
+            // if no endTag found, get rest of str and break
+            else {
+                ret.append(str.substring(beginTag));
+                break;
+            }
+        }
+        // append everything after the last endTag
+        if (endTag > -1 && endTag + 1 < str.length()) {
+            ret.append(str.substring(endTag + 1));
+        }
+        return ret.toString().trim();
+    }
+    
+    //------------------------------------------------------------------------
+    /** Run both removeHTML and escapeHTML on a string.
+     * @param s String to be run through removeHTML and escapeHTML.
+     * @return String with HTML removed and HTML special characters escaped.
+     */
+    public static String removeAndEscapeHTML( String s ) {
+        if ( s==null ) return "";
+        else return Utilities.escapeHTML( Utilities.removeHTML(s) );
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Autoformat.
+     */
+    public static String autoformat(String s) {
+        String ret = StringUtils.replace(s, "\n", "<br />");
+        return ret;
+    }
+        
+    //------------------------------------------------------------------------
+    /**
+     * Replaces occurences of non-alphanumeric characters with an underscore.
+     */
+    public static String replaceNonAlphanumeric(String str) {
+        return replaceNonAlphanumeric(str, '_');
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Replaces occurences of non-alphanumeric characters with a
+     * supplied char.
+     */
+    public static String replaceNonAlphanumeric(String str, char subst) {
+        StringBuffer ret = new StringBuffer(str.length());
+        char[] testChars = str.toCharArray();
+        for (int i = 0; i < testChars.length; i++) {
+            if (Character.isLetterOrDigit(testChars[i])) {
+                ret.append(testChars[i]);
+            } else {
+                ret.append( subst );
+            }
+        }
+        return ret.toString();
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Remove occurences of non-alphanumeric characters.
+     */
+    public static String removeNonAlphanumeric(String str) {
+        StringBuffer ret = new StringBuffer(str.length());
+        char[] testChars = str.toCharArray();
+        for (int i = 0; i < testChars.length; i++) {
+            // MR: Allow periods in page links
+            if (Character.isLetterOrDigit(testChars[i]) ||
+                    testChars[i] == '.') {
+                ret.append(testChars[i]);
+            }
+        }
+        return ret.toString();
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * @param stringArray
+     * @param delim
+     * @return
+     */
+    public static String stringArrayToString(String[] stringArray, String delim) {
+        String ret = "";
+        for (int i = 0; i < stringArray.length; i++) {
+            if (ret.length() > 0)
+                ret = ret + delim + stringArray[i];
+            else
+                ret = stringArray[i];
+        }
+        return ret;
+    }
+    
+    //--------------------------------------------------------------------------
+    /** Convert string to string array. */
+    public static String[] stringToStringArray(String instr, String delim)
+    throws NoSuchElementException, NumberFormatException {
+        StringTokenizer toker = new StringTokenizer(instr, delim);
+        String stringArray[] = new String[toker.countTokens()];
+        int i = 0;
+        
+        while (toker.hasMoreTokens()) {
+            stringArray[i++] = toker.nextToken();
+        }
+        return stringArray;
+    }
+    
+    //--------------------------------------------------------------------------
+    /** Convert string to integer array. */
+    public static int[] stringToIntArray(String instr, String delim)
+    throws NoSuchElementException, NumberFormatException {
+        StringTokenizer toker = new StringTokenizer(instr, delim);
+        int intArray[] = new int[toker.countTokens()];
+        int i = 0;
+        
+        while (toker.hasMoreTokens()) {
+            String sInt = toker.nextToken();
+            int nInt = Integer.parseInt(sInt);
+            intArray[i++] = new Integer(nInt).intValue();
+        }
+        return intArray;
+    }
+    
+    //-------------------------------------------------------------------
+    /** Convert integer array to a string. */
+    public static String intArrayToString(int[] intArray) {
+        String ret = "";
+        for (int i = 0; i < intArray.length; i++) {
+            if (ret.length() > 0)
+                ret = ret + "," + Integer.toString(intArray[i]);
+            else
+                ret = Integer.toString(intArray[i]);
+        }
+        return ret;
+    }
+    
+    //------------------------------------------------------------------------
+    public static void copyFile(File from, File to) throws IOException {
+        InputStream in = null;
+        OutputStream out = null;
+        
+        try {
+            in = new FileInputStream(from);
+        } catch (IOException ex) {
+            throw new IOException(
+                    "Utilities.copyFile: opening input stream '"
+                    + from.getPath()
+                    + "', "
+                    + ex.getMessage());
+        }
+        
+        try {
+            out = new FileOutputStream(to);
+        } catch (Exception ex) {
+            try {
+                in.close();
+            } catch (IOException ex1) {
+            }
+            throw new IOException(
+                    "Utilities.copyFile: opening output stream '"
+                    + to.getPath()
+                    + "', "
+                    + ex.getMessage());
+        }
+        
+        copyInputToOutput(in, out, from.length());
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Utility method to copy an input stream to an output stream.
+     * Wraps both streams in buffers. Ensures right numbers of bytes copied.
+     */
+    public static void copyInputToOutput(
+            InputStream input,
+            OutputStream output,
+            long byteCount)
+            throws IOException {
+        int bytes;
+        long length;
+        
+        BufferedInputStream in = new BufferedInputStream(input);
+        BufferedOutputStream out = new BufferedOutputStream(output);
+        
+        byte[] buffer;
+        buffer = new byte[8192];
+        
+        for (length = byteCount; length > 0;) {
+            bytes = (int) (length > 8192 ? 8192 : length);
+            
+            try {
+                bytes = in.read(buffer, 0, bytes);
+            } catch (IOException ex) {
+                try {
+                    in.close();
+                    out.close();
+                } catch (IOException ex1) {
+                }
+                throw new IOException(
+                        "Reading input stream, " + ex.getMessage());
+            }
+            
+            if (bytes < 0)
+                break;
+            
+            length -= bytes;
+            
+            try {
+                out.write(buffer, 0, bytes);
+            } catch (IOException ex) {
+                try {
+                    in.close();
+                    out.close();
+                } catch (IOException ex1) {
+                }
+                throw new IOException(
+                        "Writing output stream, " + ex.getMessage());
+            }
+        }
+        
+        try {
+            in.close();
+            out.close();
+        } catch (IOException ex) {
+            throw new IOException("Closing file streams, " + ex.getMessage());
+        }
+    }
+    
+    //------------------------------------------------------------------------
+    public static void copyInputToOutput(
+            InputStream input,
+            OutputStream output)
+            throws IOException {
+        BufferedInputStream in = new BufferedInputStream(input);
+        BufferedOutputStream out = new BufferedOutputStream(output);
+        byte buffer[] = new byte[8192];
+        for (int count = 0; count != -1;) {
+            count = in.read(buffer, 0, 8192);
+            if (count != -1)
+                out.write(buffer, 0, count);
+        }
+        
+        try {
+            in.close();
+            out.close();
+        } catch (IOException ex) {
+            throw new IOException("Closing file streams, " + ex.getMessage());
+        }
+    }
+    
+    /**
+     * Encode a string using algorithm specified in web.xml and return the
+     * resulting encrypted password. If exception, the plain credentials
+     * string is returned
+     *
+     * @param password Password or other credentials to use in authenticating
+     *        this username
+     * @param algorithm Algorithm used to do the digest
+     *
+     * @return encypted password based on the algorithm.
+     */
+    public static String encodePassword(String password, String algorithm) {
+        byte[] unencodedPassword = password.getBytes();
+        
+        MessageDigest md = null;
+        
+        try {
+            // first create an instance, given the provider
+            md = MessageDigest.getInstance(algorithm);
+        } catch (Exception e) {
+            mLogger.error("Exception: " + e);
+            return password;
+        }
+        
+        md.reset();
+        
+        // call the update method one or more times
+        // (useful when you don't know the size of your data, eg. stream)
+        md.update(unencodedPassword);
+        
+        // now calculate the hash
+        byte[] encodedPassword = md.digest();
+        
+        StringBuffer buf = new StringBuffer();
+        
+        for (int i = 0; i < encodedPassword.length; i++) {
+            if ((encodedPassword[i] & 0xff) < 0x10) {
+                buf.append("0");
+            }
+            
+            buf.append(Long.toString(encodedPassword[i] & 0xff, 16));
+        }
+        
+        return buf.toString();
+    }
+    
+    /**
+     * Encode a string using Base64 encoding. Used when storing passwords
+     * as cookies.
+     *
+     * This is weak encoding in that anyone can use the decodeString
+     * routine to reverse the encoding.
+     *
+     * @param str
+     * @return String
+     * @throws IOException
+     */
+    public static String encodeString(String str) throws IOException {
+        BASE64Encoder encoder = new BASE64Encoder();
+        String encodedStr = encoder.encodeBuffer(str.getBytes());
+        
+        return (encodedStr.trim());
+    }
+    
+    /**
+     * Decode a string using Base64 encoding.
+     *
+     * @param str
+     * @return String
+     * @throws IOException
+     */
+    public static String decodeString(String str) throws IOException {
+        BASE64Decoder dec = new BASE64Decoder();
+        String value = new String(dec.decodeBuffer(str));
+        
+        return (value);
+    }
+    
+    /**
+     * Strips HTML and truncates.
+     */
+    public static String truncate(
+            String str, int lower, int upper, String appendToEnd) {
+        // strip markup from the string
+        String str2 = removeHTML(str, false);
+        
+        // quickly adjust the upper if it is set lower than 'lower'
+        if (upper < lower) {
+            upper = lower;
+        }
+        
+        // now determine if the string fits within the upper limit
+        // if it does, go straight to return, do not pass 'go' and collect $200
+        if(str2.length() > upper) {
+            // the magic location int
+            int loc;
+            
+            // first we determine where the next space appears after lower
+            loc = str2.lastIndexOf(' ', upper);
+            
+            // now we'll see if the location is greater than the lower limit
+            if(loc >= lower) {
+                // yes it was, so we'll cut it off here
+                str2 = str2.substring(0, loc);
+            } else {
+                // no it wasnt, so we'll cut it off at the upper limit
+                str2 = str2.substring(0, upper);
+                loc = upper;
+            }
+            
+            // the string was truncated, so we append the appendToEnd String
+            str2 = str2 + appendToEnd;
+        }
+        
+        return str2;
+    }
+    
+    /**
+     * This method based on code from the String taglib at Apache Jakarta:
+     * http://cvs.apache.org/viewcvs/jakarta-taglibs/string/src/org/apache/taglibs/string/util/StringW.java?rev=1.16&content-type=text/vnd.viewcvs-markup
+     * Copyright (c) 1999 The Apache Software Foundation.
+     * Author: timster@mac.com
+     *
+     * @param str
+     * @param lower
+     * @param upper
+     * @param appendToEnd
+     * @return
+     */
+    public static String truncateNicely(String str, int lower, int upper, String appendToEnd) {
+        // strip markup from the string
+        String str2 = removeHTML(str, false);
+        boolean diff = (str2.length() < str.length());
+        
+        // quickly adjust the upper if it is set lower than 'lower'
+        if(upper < lower) {
+            upper = lower;
+        }
+        
+        // now determine if the string fits within the upper limit
+        // if it does, go straight to return, do not pass 'go' and collect $200
+        if(str2.length() > upper) {
+            // the magic location int
+            int loc;
+            
+            // first we determine where the next space appears after lower
+            loc = str2.lastIndexOf(' ', upper);
+            
+            // now we'll see if the location is greater than the lower limit
+            if(loc >= lower) {
+                // yes it was, so we'll cut it off here
+                str2 = str2.substring(0, loc);
+            } else {
+                // no it wasnt, so we'll cut it off at the upper limit
+                str2 = str2.substring(0, upper);
+                loc = upper;
+            }
+            
+            // HTML was removed from original str
+            if (diff) {
+                
+                // location of last space in truncated string
+                loc = str2.lastIndexOf(' ', loc);
+                
+                // get last "word" in truncated string (add 1 to loc to eliminate space
+                String str3 = str2.substring(loc+1);
+                
+                // find this fragment in original str, from 'loc' position
+                loc = str.indexOf(str3, loc) + str3.length();
+                
+                // get truncated string from original str, given new 'loc'
+                str2 = str.substring(0, loc);
+                
+                // get all the HTML from original str after loc
+                str3 = extractHTML(str.substring(loc));
+                
+                // remove any tags which generate visible HTML
+                // This call is unecessary, all HTML has already been stripped
+                //str3 = removeVisibleHTMLTags(str3);
+                
+                // append the appendToEnd String and
+                // add extracted HTML back onto truncated string
+                str = str2 + appendToEnd + str3;
+            } else {
+                // the string was truncated, so we append the appendToEnd String
+                str = str2 + appendToEnd;
+            }
+            
+        }
+        
+        return str;
+    }
+    
+    public static String truncateText(String str, int lower, int upper, String appendToEnd) {
+        // strip markup from the string
+        String str2 = removeHTML(str, false);
+        boolean diff = (str2.length() < str.length());
+        
+        // quickly adjust the upper if it is set lower than 'lower'
+        if(upper < lower) {
+            upper = lower;
+        }
+        
+        // now determine if the string fits within the upper limit
+        // if it does, go straight to return, do not pass 'go' and collect $200
+        if(str2.length() > upper) {
+            // the magic location int
+            int loc;
+            
+            // first we determine where the next space appears after lower
+            loc = str2.lastIndexOf(' ', upper);
+            
+            // now we'll see if the location is greater than the lower limit
+            if(loc >= lower) {
+                // yes it was, so we'll cut it off here
+                str2 = str2.substring(0, loc);
+            } else {
+                // no it wasnt, so we'll cut it off at the upper limit
+                str2 = str2.substring(0, upper);
+                loc = upper;
+            }
+            // the string was truncated, so we append the appendToEnd String
+            str = str2 + appendToEnd;
+        }
+        return str;
+    }
+    
+    /**
+     * @param str
+     * @return
+     */
+    private static String stripLineBreaks(String str) {
+        // TODO: use a string buffer, ignore case !
+        str = str.replaceAll("<br>", "");
+        str = str.replaceAll("<br/>", "");
+        str = str.replaceAll("<br />", "");
+        str = str.replaceAll("<p></p>", "");
+        str = str.replaceAll("<p/>","");
+        str = str.replaceAll("<p />","");
+        return str;
+    }
+    
+    /**
+     * Need need to get rid of any user-visible HTML tags once all text has been
+     * removed such as &lt;BR&gt;. This sounds like a better approach than removing
+     * all HTML tags and taking the chance to leave some tags un-closed.
+     *
+     * WARNING: this method has serious performance problems a
+     *
+     * @author Alexis Moussine-Pouchkine <al...@france.sun.com>
+     * @author Lance Lavandowska
+     * @param str the String object to modify
+     * @return the new String object without the HTML "visible" tags
+     */
+    private static String removeVisibleHTMLTags(String str) {
+        str = stripLineBreaks(str);
+        StringBuffer result = new StringBuffer(str);
+        StringBuffer lcresult = new StringBuffer(str.toLowerCase());
+        
+        // <img should take care of smileys
+        String[] visibleTags = {"<img"}; // are there others to add?
+        int stringIndex;
+        for ( int j = 0 ;  j < visibleTags.length ; j++ ) {
+            while ( (stringIndex = lcresult.indexOf(visibleTags[j])) != -1 ) {
+                if ( visibleTags[j].endsWith(">") )  {
+                    result.delete(stringIndex, stringIndex+visibleTags[j].length() );
+                    lcresult.delete(stringIndex, stringIndex+visibleTags[j].length() );
+                } else {
+                    // need to delete everything up until next closing '>', for <img for instance
+                    int endIndex = result.indexOf(">", stringIndex);
+                    if (endIndex > -1) {
+                        // only delete it if we find the end!  If we don't the HTML may be messed up, but we
+                        // can't safely delete anything.
+                        result.delete(stringIndex, endIndex + 1 );
+                        lcresult.delete(stringIndex, endIndex + 1 );
+                    }
+                }
+            }
+        }
+        
+        // TODO:  This code is buggy by nature.  It doesn't deal with nesting of tags properly.
+        // remove certain elements with open & close tags
+        String[] openCloseTags = {"li", "a", "div", "h1", "h2", "h3", "h4"}; // more ?
+        for (int j = 0; j < openCloseTags.length; j++) {
+            // could this be better done with a regular expression?
+            String closeTag = "</"+openCloseTags[j]+">";
+            int lastStringIndex = 0;
+            while ( (stringIndex = lcresult.indexOf( "<"+openCloseTags[j], lastStringIndex)) > -1) {
+                lastStringIndex = stringIndex;
+                // Try to find the matching closing tag  (ignores possible nesting!)
+                int endIndex = lcresult.indexOf(closeTag, stringIndex);
+                if (endIndex > -1) {
+                    // If we found it delete it.
+                    result.delete(stringIndex, endIndex+closeTag.length());
+                    lcresult.delete(stringIndex, endIndex+closeTag.length());
+                } else {
+                    // Try to see if it is a self-closed empty content tag, i.e. closed with />.
+                    endIndex = lcresult.indexOf(">", stringIndex);
+                    int nextStart = lcresult.indexOf("<", stringIndex+1);
+                    if (endIndex > stringIndex && lcresult.charAt(endIndex-1) == '/' && (endIndex < nextStart || nextStart == -1)) {
+                        // Looks like it, so remove it.
+                        result.delete(stringIndex, endIndex + 1);
+                        lcresult.delete(stringIndex, endIndex + 1);
+                        
+                    }
+                }
+            }
+        }
+        
+        return result.toString();
+    }
+    
+    /**
+     * Extract (keep) JUST the HTML from the String.
+     * @param str
+     * @return
+     */
+    public static String extractHTML(String str) {
+        if (str == null) return "";
+        StringBuffer ret = new StringBuffer(str.length());
+        int start = 0;
+        int beginTag = str.indexOf("<");
+        int endTag = 0;
+        if (beginTag == -1)
+            return str;
+        
+        while (beginTag >= start) {
+            endTag = str.indexOf(">", beginTag);
+            
+            // if endTag found, keep tag
+            if (endTag > -1) {
+                ret.append( str.substring(beginTag, endTag+1) );
+                
+                // move start forward and find another tag
+                start = endTag + 1;
+                beginTag = str.indexOf("<", start);
+            }
+            // if no endTag found, break
+            else {
+                break;
+            }
+        }
+        return ret.toString();
+    }
+    
+    
+    public static String hexEncode(String str) {
+        if (StringUtils.isEmpty(str)) return str;
+        
+        return RegexUtil.encode(str);
+    }
+    
+    public static String encodeEmail(String str) {
+        return str!=null ? RegexUtil.encodeEmail(str) : null;
+    }
+
+    /**
+     * URL encoding.
+     * @param s a string to be URL-encoded
+     * @return URL encoding of s using character encoding UTF-8; null if s is null.
+     */
+    public static final String encode(String s) {
+        try {
+            if (s != null)
+                return URLEncoder.encode(s, "UTF-8");
+            else
+                return s;
+        } catch (UnsupportedEncodingException e) {
+            // Java Spec requires UTF-8 be in all Java environments, so this should not happen
+            return s;
+        }
+    }
+
+    /**
+     * URL decoding.
+     * @param s a URL-encoded string to be URL-decoded
+     * @return URL decoded value of s using character encoding UTF-8; null if s is null.
+     */
+    public static final String decode(String s) {
+        try {
+            if (s != null)
+                return URLDecoder.decode(s, "UTF-8");
+            else
+                return s;
+        } catch (UnsupportedEncodingException e) {
+            // Java Spec requires UTF-8 be in all Java environments, so this should not happen
+            return s;
+        }
+    }
+
+    /**
+     * @param string
+     * @return
+     */
+    public static int stringToInt(String string) {
+        try {
+            return Integer.valueOf(string).intValue();
+        } catch (NumberFormatException e) {
+            mLogger.debug("Invalid Integer:" + string);
+        }
+        return 0;
+    }
+                    
+    /**
+     * Convert a byte array into a Base64 string (as used in mime formats)
+     */
+    public static String toBase64(byte[] aValue) {
+        
+        final String m_strBase64Chars =
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+        
+        int byte1;
+        int byte2;
+        int byte3;
+        int iByteLen = aValue.length;
+        StringBuffer tt = new StringBuffer();
+        
+        for (int i = 0; i < iByteLen; i += 3) {
+            boolean bByte2 = (i + 1) < iByteLen;
+            boolean bByte3 = (i + 2) < iByteLen;
+            byte1 = aValue[i] & 0xFF;
+            byte2 = (bByte2) ? (aValue[i + 1] & 0xFF) : 0;
+            byte3 = (bByte3) ? (aValue[i + 2] & 0xFF) : 0;
+            
+            tt.append(m_strBase64Chars.charAt(byte1 / 4));
+            tt.append(m_strBase64Chars.charAt((byte2 / 16) + ((byte1 & 0x3) * 16)));
+            tt.append(((bByte2) ? m_strBase64Chars.charAt((byte3 / 64) + ((byte2 & 0xF) * 4)) : '='));
+            tt.append(((bByte3) ? m_strBase64Chars.charAt(byte3 & 0x3F) : '='));
+        }
+        
+        return tt.toString();
+    }
+    
+    /**
+     * @param tag
+     * @return
+     */
+    public static String stripInvalidTagCharacters(String tag) {
+        if (tag == null)
+            throw new NullPointerException();
+
+        StringBuffer sb = new StringBuffer();
+        char[] charArray = tag.toCharArray();
+        for (int i = 0; i < charArray.length; i++) {
+            char c = charArray[i];
+
+            // fast-path exclusions quotes and commas are obvious
+            switch (c) {
+            case 34: // "
+            case 44: // ,
+                continue;
+            }
+
+            if ((33 <= c && c <= 126) || Character.isUnicodeIdentifierPart(c)
+                    || Character.isUnicodeIdentifierStart(c)) {
+                sb.append(charArray[i]);
+            }
+        }
+        return sb.toString();
+    }
+        
+    public static String normalizeTag(String tag, Locale locale) {
+        tag = Utilities.stripInvalidTagCharacters(tag);
+        return locale == null ? tag.toLowerCase() : tag.toLowerCase(locale);        
+    }
+    
+    /**
+     * @param tags
+     * @return
+     */
+    public static List splitStringAsTags(String tags)  {
+        String[] tagsarr = StringUtils.split(tags, TAG_SPLIT_CHARS);
+        if(tagsarr == null)
+            return Collections.EMPTY_LIST;
+        return Arrays.asList(tagsarr);
+    }
+}

Added: incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StartDerbyTask.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StartDerbyTask.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StartDerbyTask.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StartDerbyTask.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,71 @@
+/*
+ * 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.ant;
+
+import java.io.PrintWriter;
+import org.apache.derby.drda.NetworkServerControl;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Ant Task to start Derby
+ * @author Dave Johnson
+ */
+public class StartDerbyTask extends Task {
+    private String database = null;
+    private String port = null;
+    
+    public void execute() throws BuildException {
+        try {
+            System.out.println("Stopping Derby");
+            System.setProperty("derby.system.home", database);
+            System.setProperty("derby.drda.portNumber", port);
+            System.setProperty("derby.drda.host", "localhost");
+            NetworkServerControl server = new NetworkServerControl();
+            server.start(new PrintWriter(System.out));
+            try {Thread.sleep(2000);} catch (Exception ignored) {}
+        } catch (Exception e) {
+            throw new BuildException("Unable to load Derby driver");
+        }
+        
+    }
+    /**
+     * @return Returns the database.
+     */
+    public String getDatabase() {
+        return database;
+    }
+    /**
+     * @param database The database to set.
+     */
+    public void setDatabase(String database) {
+        this.database = database;
+    }
+    /**
+     * @return Returns the port.
+     */
+    public String getPort() {
+        return port;
+    }
+    /**
+     * @param port The port to set.
+     */
+    public void setPort(String port) {
+        this.port = port;
+    }
+}

Added: incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StopDerbyTask.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StopDerbyTask.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StopDerbyTask.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/ant/StopDerbyTask.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,55 @@
+/*
+ * 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.ant;
+
+import org.apache.derby.drda.NetworkServerControl;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Ant Task to stop Derby
+ * @author Dave Johnson
+ */
+public class StopDerbyTask extends Task {
+    private String port = null;
+    public void execute() throws BuildException {
+        try {
+            System.out.println("Stopping Derby");
+            System.setProperty("derby.drda.portNumber", port);
+            System.setProperty("derby.drda.host", "localhost");
+            NetworkServerControl server = new NetworkServerControl();
+            server.shutdown();
+            try {Thread.sleep(2000);} catch (Exception ignored) {}
+
+        } catch (Exception e) {
+            throw new BuildException(e.getMessage());
+        }
+    }
+    /**
+     * @return Returns the port.
+     */
+    public String getPort() {
+        return port;
+    }
+    /**
+     * @param port The port to set.
+     */
+    public void setPort(String port) {
+        this.port = port;
+    }
+}

Added: incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/TestUtils.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/TestUtils.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/TestUtils.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/TestUtils.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,48 @@
+/*
+* 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;
+
+import org.apache.roller.planet.business.Planet;
+import org.apache.roller.planet.business.PlanetFactory;
+
+
+/**
+ * Utility class for unit test classes.
+ */
+public final class TestUtils {
+    
+    
+    /**
+     * Convenience method that simulates the end of a typical session.
+     *
+     * Normally this would be triggered by the end of the response in the webapp
+     * but for unit tests we need to do this explicitly.
+     *
+     * @param flush true if you want to flush changes to db before releasing
+     */
+    public static void endSession(boolean flush) throws Exception {
+        
+        if(flush) {
+            PlanetFactory.getPlanet().flush();
+        }
+        
+        PlanetFactory.getPlanet().release();
+    }
+    
+}

Copied: incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetManagerTest.java (from r483703, incubator/roller/trunk/tests/org/apache/roller/business/PlanetManagerTest.java)
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetManagerTest.java?view=diff&rev=485845&p1=incubator/roller/trunk/tests/org/apache/roller/business/PlanetManagerTest.java&r1=483703&p2=incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetManagerTest.java&r2=485845
==============================================================================
--- incubator/roller/trunk/tests/org/apache/roller/business/PlanetManagerTest.java (original)
+++ incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetManagerTest.java Mon Dec 11 11:50:59 2006
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.apache.roller.business;
+package org.apache.roller.planet.business;
 
 import java.io.File;
 import java.sql.Timestamp;
@@ -27,11 +27,10 @@
 import junit.framework.TestSuite;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.roller.TestUtils;
-import org.apache.roller.config.RollerConfig;
+import org.apache.roller.planet.TestUtils;
+import org.apache.roller.planet.business.Planet;
+import org.apache.roller.planet.business.PlanetFactory;
 import org.apache.roller.planet.business.PlanetManager;
-import org.apache.roller.business.Roller;
-import org.apache.roller.business.RollerFactory;
 import org.apache.roller.planet.pojos.PlanetConfigData;
 import org.apache.roller.planet.pojos.PlanetEntryData;
 import org.apache.roller.planet.pojos.PlanetGroupData;
@@ -45,15 +44,13 @@
     
     public static Log log = LogFactory.getLog(PlanetManagerTest.class);
     
-    private Roller roller = null;
-    
     static {
         try {
             // planet config should always exist
             PlanetConfigData config = new PlanetConfigData();
             config.setTitle("test_title");
             config.setAdminEmail("test_admin_email");
-            RollerFactory.getRoller().getPlanetManager().saveConfiguration(config);
+            PlanetFactory.getPlanet().getPlanetManager().saveConfiguration(config);
             TestUtils.endSession(true);
         } catch (Exception ex) {
             log.error(ex);
@@ -74,7 +71,7 @@
     
     public void testConfigurationStorage() throws Exception {
         
-        PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+        PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
         
         {   // retrieve config
             PlanetConfigData config = planet.getConfiguration();
@@ -100,7 +97,7 @@
     
     public void testGroupStorage() throws Exception {
         
-        PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+        PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
         
         {   // save group
             PlanetGroupData group = new PlanetGroupData();
@@ -130,7 +127,7 @@
     
     public void testSubscriptionStorage() throws Exception {
         
-        PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+        PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
         
         {   // save subscriptions and a group
             PlanetSubscriptionData sub = new PlanetSubscriptionData();
@@ -202,7 +199,7 @@
     
     public void testSubscriptionEntryStorage() throws Exception {
         
-        PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+        PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
         
         {   // save subscription
             PlanetSubscriptionData sub = new PlanetSubscriptionData();
@@ -281,7 +278,7 @@
     
     public void testRefreshEntries() throws Exception {
         
-        PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+        PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
         
         String feed_url1 = "http://rollerweblogger.org/roller/feed/entries/rss";
         
@@ -330,7 +327,7 @@
     public void _testAggregations() throws Exception {
         
         try {
-            PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+            PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
             
             String feed_url1 = "http://rollerweblogger.org/roller/feed/entries/rss";
             String feed_url2 = "http://blogs.sun.com/main/feed/entries/atom";
@@ -395,7 +392,7 @@
     public void testSubscriptionCount() throws Exception {
         
         try {
-            PlanetManager planet = RollerFactory.getRoller().getPlanetManager();
+            PlanetManager planet = PlanetFactory.getPlanet().getPlanetManager();
             
             String feed_url1 = "http://rollerweblogger.org/roller/feed/entries/rss";
             String feed_url2 = "http://blogs.sun.com/main/feed/entries/atom";

Added: incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetTestSuite.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetTestSuite.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetTestSuite.java (added)
+++ incubator/roller/trunk/sandbox/planetroller/test/org/apache/roller/planet/business/PlanetTestSuite.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,49 @@
+/*
+ * 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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Test core business services.
+ *
+ * The core business services are the things which allow the business layer as
+ * a whole to function.  Examples would be the PropertiesManager which is
+ * involved in servicing the core application config.
+ *
+ * Tests from from this suite should only include things that are not part of
+ * or dependent on the core weblog platform, i.e. you don't need a user or a
+ * weblog to do them.
+ */
+public class PlanetTestSuite {
+    
+    public static Test suite() {
+
+        TestSuite suite = new TestSuite();
+	
+        // TODO: add a test for PlanetConfig
+        
+        suite.addTestSuite(PlanetManagerTest.class);
+
+        return suite;
+    }
+    
+}

Added: incubator/roller/trunk/sandbox/planetroller/testdata/planet-custom.properties
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/testdata/planet-custom.properties?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/testdata/planet-custom.properties (added)
+++ incubator/roller/trunk/sandbox/planetroller/testdata/planet-custom.properties Mon Dec 11 11:50:59 2006
@@ -0,0 +1,6 @@
+
+jdbc.driverClass=org.apache.derby.jdbc.ClientDriver
+jdbc.connectionURL=jdbc:derby://localhost:3219/roller
+jdbc.username=APP
+jdbc.password=APP
+hibernate.dialect=org.hibernate.dialect.DerbyDialect
\ No newline at end of file

Modified: incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/classes/hibernate.cfg.xml
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/classes/hibernate.cfg.xml?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/classes/hibernate.cfg.xml (original)
+++ incubator/roller/trunk/sandbox/planetroller/web/WEB-INF/classes/hibernate.cfg.xml Mon Dec 11 11:50:59 2006
@@ -27,10 +27,12 @@
                         
         <!-- you can override the dialect via planet-custom.properties -->
         <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
-
+        
+        <property name="show_sql">true</property>
+        
         <!-- use thread local Session context -->
-        <property name="hibernate.current_session_context_class">thread</property>
-        <property name="show_sql">false</property>
+        <!--<property name="hibernate.current_session_context_class">thread</property>-->
+        <property name="hibernate.current_session_context_class">org.apache.roller.business.hibernate.ThreadLocalSessionContextNoAutoClose</property>
 
         <!-- Hibernate L2 Caching -->
         <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

Modified: incubator/roller/trunk/src/org/apache/roller/business/Roller.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/business/Roller.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/Roller.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/business/Roller.java Mon Dec 11 11:50:59 2006
@@ -28,7 +28,6 @@
 import org.apache.roller.business.referrers.ReferrerQueueManager;
 import org.apache.roller.business.runnable.ThreadManager;
 import org.apache.roller.business.search.IndexManager;
-import org.apache.roller.planet.business.PlanetManager;
 
 
 /** 
@@ -113,12 +112,6 @@
      * Get IndexManager associated with this Roller instance.
      */
     public IndexManager getIndexManager();
-    
-    
-    /**
-     * Get PlanetManager associated with this Roller instance.
-     */
-    public PlanetManager getPlanetManager();
     
     
     /**

Modified: incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerImpl.java Mon Dec 11 11:50:59 2006
@@ -29,7 +29,6 @@
 import org.apache.roller.business.pings.AutoPingManager;
 import org.apache.roller.business.pings.PingQueueManager;
 import org.apache.roller.business.pings.PingTargetManager;
-import org.apache.roller.planet.business.PlanetManager;
 import org.apache.roller.business.PropertiesManager;
 import org.apache.roller.business.referrers.RefererManager;
 import org.apache.roller.business.Roller;
@@ -57,7 +56,6 @@
     private BookmarkManager bookmarkManager = null;
     private ConfigManager configManager = null;
     private PropertiesManager propertiesManager = null;
-    private PlanetManager planetManager = null;
     private RefererManager refererManager = null;
     private UserManager userManager = null;
     private WeblogManager weblogManager = null;
@@ -215,17 +213,6 @@
             pingQueueManager = new HibernatePingQueueManagerImpl(strategy);
         }
         return pingQueueManager;
-    }
-    
-    
-    /**
-     * @see org.apache.roller.model.Roller#getPlanetManager()
-     */
-    public PlanetManager getPlanetManager() {
-        if ( planetManager == null ) {
-            planetManager = new HibernateRollerPlanetManagerImpl(strategy);
-        }
-        return planetManager;
     }
     
     

Added: incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetImpl.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetImpl.java?view=auto&rev=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetImpl.java Mon Dec 11 11:50:59 2006
@@ -0,0 +1,71 @@
+/*
+* 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.hibernate;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.planet.config.PlanetConfig;
+import org.apache.roller.planet.business.Planet;
+import org.apache.roller.planet.business.PlanetManager;
+import org.apache.roller.planet.business.hibernate.HibernatePersistenceStrategy;
+
+
+/**
+ * A Hibernate specific implementation of the Roller business layer.
+ */
+public class HibernateRollerPlanetImpl extends HibernatePlanetImpl {   
+    
+    private static Log log = LogFactory.getLog(HibernateRollerPlanetImpl.class);
+    
+    // our singleton instance
+    private static HibernateRollerPlanetImpl me = null;
+    
+        
+    /**
+     * Create HibernatePlanetImpl using Hibernate XML config file or config
+     * file plus JDBC overrides from planet-custom.properties.
+     */
+    protected HibernateRollerPlanetImpl() throws RollerException {
+        super();
+    }
+    
+    
+    /**
+     * Instantiates and returns an instance of HibernatePlanetImpl.
+     */
+    public static Planet instantiate() throws RollerException {
+        if (me == null) {
+            log.debug("Instantiating HibernateRollerPlanetImpl");
+            me = new HibernateRollerPlanetImpl();
+        }
+        
+        return me;
+    }
+    
+    
+    public PlanetManager getPlanetManager() {
+        if ( planetManager == null ) {
+            planetManager = new HibernateRollerPlanetManagerImpl(strategy);  
+        }
+        return planetManager;
+    }
+    
+}

Copied: incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetManagerImpl.java (from r483703, incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerPlanetManagerImpl.java)
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetManagerImpl.java?view=diff&rev=485845&p1=incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerPlanetManagerImpl.java&r1=483703&p2=incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetManagerImpl.java&r2=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/business/hibernate/HibernateRollerPlanetManagerImpl.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/planet/business/hibernate/HibernateRollerPlanetManagerImpl.java Mon Dec 11 11:50:59 2006
@@ -16,14 +16,13 @@
  * directory of this distribution.
  */
 
-package org.apache.roller.business.hibernate;
+package org.apache.roller.planet.business.hibernate;
 
 import com.sun.syndication.fetcher.FeedFetcher;
 import com.sun.syndication.fetcher.impl.FeedFetcherCache;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -38,6 +37,7 @@
 import org.apache.roller.business.UserManager;
 import org.apache.roller.business.WeblogManager;
 import org.apache.roller.planet.business.hibernate.HibernatePlanetManagerImpl;
+import org.apache.roller.planet.business.hibernate.HibernatePersistenceStrategy;
 import org.apache.roller.planet.pojos.PlanetEntryData;
 import org.apache.roller.planet.pojos.PlanetSubscriptionData;
 import org.apache.roller.pojos.WeblogEntryData;
@@ -144,8 +144,25 @@
                     try {
                         WeblogEntryData rollerEntry =
                                 (WeblogEntryData)entryIter.next();
-                        PlanetEntryData entry =
-                                new PlanetEntryData(rollerEntry, sub, pagePlugins);
+                        
+                        PlanetEntryData entry = new PlanetEntryData();
+                        entry.setSubscription(sub);
+                        
+                        String content = "";
+                        if (!StringUtils.isEmpty(rollerEntry.getText())) {
+                            content = rollerEntry.getText();
+                        } else {
+                            content = rollerEntry.getSummary();
+                        }
+                        content = ppmgr.applyWeblogEntryPlugins(pagePlugins, rollerEntry, content);
+                        
+                        entry.setAuthor(rollerEntry.getCreator().getFullName());
+                        entry.setTitle(rollerEntry.getTitle());
+                        entry.setPubTime(rollerEntry.getPubTime());
+                        entry.setText(content);
+                        entry.setPermalink(rollerEntry.getPermalink());
+                        entry.setCategoriesString(rollerEntry.getCategory().getPath());
+        
                         saveEntry(entry);
                         newEntries.add(entry);
                     } catch (Exception e) {

Modified: incubator/roller/trunk/src/org/apache/roller/planet/tasks/RefreshEntriesTask.java
URL: http://svn.apache.org/viewvc/incubator/roller/trunk/src/org/apache/roller/planet/tasks/RefreshEntriesTask.java?view=diff&rev=485845&r1=485844&r2=485845
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/planet/tasks/RefreshEntriesTask.java (original)
+++ incubator/roller/trunk/src/org/apache/roller/planet/tasks/RefreshEntriesTask.java Mon Dec 11 11:50:59 2006
@@ -24,9 +24,8 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.RollerException;
 import org.apache.roller.business.runnable.RollerTask;
-import org.apache.roller.business.Roller;
-import org.apache.roller.business.RollerFactory;
-import org.apache.roller.config.RollerConfig;
+import org.apache.roller.planet.business.PlanetFactory;
+import org.apache.roller.planet.config.PlanetConfig;
 
 
 /**
@@ -98,14 +97,13 @@
     
     public void runTask() {
         try {
-            Roller roller = RollerFactory.getRoller();
-            roller.getPlanetManager().refreshEntries(
-                RollerConfig.getProperty("planet.aggregator.cache.dir"));
-            roller.flush();
+            PlanetFactory.getPlanet().getPlanetManager().refreshEntries(
+                PlanetConfig.getProperty("planet.aggregator.cache.dir"));
+            PlanetFactory.getPlanet().flush();
         } catch (RollerException e) {
             log.error("ERROR refreshing entries", e);
         } finally {
-            RollerFactory.getRoller().release();
+            PlanetFactory.getPlanet().release();
         }
     }