roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r189695 [43/67] - in /incubator/roller/trunk: ./ contrib/ contrib/lib/ contrib/plugins/ contrib/plugins/src/ contrib/plugins/src/org/ contrib/plugins/src/org/roller/ contrib/plugins/src/org/roller/presentation/ contrib/plugins/src/org/roller/presentation/velocity/ contrib/plugins/src/org/roller/presentation/velocity/plugins/ contrib/plugins/src/org/roller/presentation/velocity/plugins/acronyms/ contrib/plugins/src/org/roller/presentation/velocity/plugins/bookmarks/ contrib/plugins/src/org/roller/presentation/velocity/plugins/email/ contrib/plugins/src/org/roller/presentation/velocity/plugins/jspwiki/ contrib/plugins/src/org/roller/presentation/velocity/plugins/radeox/ contrib/plugins/src/org/roller/presentation/velocity/plugins/readmore/ contrib/plugins/src/org/roller/presentation/velocity/plugins/smileys/ contrib/plugins/src/org/roller/presentation/velocity/plugins/textile/ contrib/plugins/src/org/roller/presentation/velocity/plugins/topictag/ custom/ custom/src/ custom/web/ docs/ docs/images/ docs/installguide/ docs/installguide/old/ docs/userguide/ docs/userguide/images/ docs/userguide/old/ metadata/ metadata/database/ metadata/database/hibernate/ metadata/xdoclet/ nbproject/ personal/ personal/eclipse/ personal/testing/ sandbox/ sandbox/planetroller/ sandbox/planetroller/metadata/ sandbox/planetroller/metadata/database/ sandbox/planetroller/src/ sandbox/planetroller/src/org/ sandbox/planetroller/src/org/roller/ sandbox/planetroller/src/org/roller/tools/ sandbox/planetroller/src/org/roller/tools/planet/ sandbox/planetroller/templates/ sandbox/planetroller/test/ sandbox/planetroller/test/org/ sandbox/planetroller/test/org/roller/ sandbox/planetroller/test/org/roller/model/ sandbox/planetroller/test/org/roller/tools/ sandbox/planetroller/test/org/roller/tools/planet/ sandbox/planetroller/testdata/ sandbox/planetroller/testdata/cache/ sandbox/planetroller/testdata/output/ sandbox/standalone/ sandbox/standalone/jspwiki/ sandbox/standalone/jspwiki/default/ sandbox/standalone/jspwiki/default/images/ sandbox/standalone/lib/ sandbox/standalone/src/ sandbox/standalone/src/org/ sandbox/standalone/src/org/roller/ sandbox/standalone/src/org/roller/jspwiki/ sandbox/standalone/src/org/roller/tomcat/ sandbox/standalone/src/org/roller/util/ sandbox/standalone/tests/ sandbox/standalone/tests/org/ sandbox/standalone/tests/org/roller/ sandbox/standalone/tests/org/roller/util/ sandbox/standalone/tomcat/ src/ src/org/ src/org/roller/ src/org/roller/business/ src/org/roller/business/hibernate/ src/org/roller/business/search/ src/org/roller/business/search/operations/ src/org/roller/business/utils/ src/org/roller/config/ src/org/roller/config/runtime/ src/org/roller/model/ src/org/roller/pojos/ src/org/roller/presentation/ src/org/roller/presentation/atomapi/ src/org/roller/presentation/bookmarks/ src/org/roller/presentation/bookmarks/actions/ src/org/roller/presentation/bookmarks/formbeans/ src/org/roller/presentation/bookmarks/tags/ src/org/roller/presentation/filters/ src/org/roller/presentation/forms/ src/org/roller/presentation/newsfeeds/ src/org/roller/presentation/pagecache/ src/org/roller/presentation/pagecache/rollercache/ src/org/roller/presentation/pings/ src/org/roller/presentation/planet/ src/org/roller/presentation/tags/ src/org/roller/presentation/tags/calendar/ src/org/roller/presentation/tags/menu/ src/org/roller/presentation/util/ src/org/roller/presentation/velocity/ src/org/roller/presentation/weblog/ src/org/roller/presentation/weblog/actions/ src/org/roller/presentation/weblog/formbeans/ src/org/roller/presentation/weblog/tags/ src/org/roller/presentation/website/ src/org/roller/presentation/website/actions/ src/org/roller/presentation/website/formbeans/ src/org/roller/presentation/website/tags/ src/org/roller/presentation/xmlrpc/ src/org/roller/util/ src/org/roller/util/rome/ tests/ tests/org/ tests/org/roller/ tests/org/roller/ant/ tests/org/roller/business/ tests/org/roller/presentation/ tests/org/roller/presentation/atomapi/ tests/org/roller/presentation/bookmarks/ tests/org/roller/presentation/filters/ tests/org/roller/presentation/velocity/ tests/org/roller/presentation/velocity/plugins/ tests/org/roller/presentation/velocity/plugins/smileys/ tests/org/roller/presentation/velocity/plugins/textile/ tests/org/roller/presentation/weblog/ tests/org/roller/presentation/xmlrpc/ tests/org/roller/util/ tests/org/roller/util/rome/ tools/ tools/buildtime/ tools/buildtime/ant-1.6.2/ tools/buildtime/findbugs/ tools/buildtime/findbugs/lib/ tools/buildtime/findbugs/plugin/ tools/buildtime/mockrunner-0.3/ tools/buildtime/mockrunner-0.3/lib/ tools/buildtime/mockrunner-0.35/ tools/buildtime/mockrunner-0.35/lib/ tools/buildtime/tomcat-4.1.24/ tools/buildtime/xdoclet-1.2/ tools/buildtime/xdoclet-1.2/lib/ tools/hibernate-2.1/ tools/hibernate-2.1/lib/ tools/lib/ tools/standard-1.0.3/ tools/standard-1.0.3/lib/ tools/standard-1.0.3/tld/ tools/struts-1.2.4/ tools/struts-1.2.4/lib/ web/ web/WEB-INF/ web/WEB-INF/classes/ web/WEB-INF/classes/flavors/ web/WEB-INF/classes/themes/ web/bookmarks/ web/editor/ web/editor/images/ web/images/ web/images/editor/ web/images/midas/ web/images/preview/ web/images/smileys/ web/planet/ web/tags/ web/templates/ web/theme/ web/theme/images/ web/theme/lavender/ web/theme/scripts/ web/theme/scripts/classes/ web/themes/ web/themes/basic/ web/themes/berkley/ web/themes/berkley/images/ web/themes/brushedmetal/ web/themes/brushedmetal/images/ web/themes/cheb/ web/themes/cheb/images/ web/themes/cheb/scripts/ web/themes/clean/ web/themes/currency-i18n/ web/themes/currency-i18n/images/ web/themes/currency/ web/themes/currency/images/ web/themes/grey2/ web/themes/moonshine/ web/themes/movablemanila/ web/themes/movablemanila/images/ web/themes/pacifica/ web/themes/robot/ web/themes/rolling/ web/themes/rolling/images/ web/themes/sotto/ web/themes/sotto/images/ web/themes/sotto/styles/ web/themes/sunsets/ web/themes/sunsets/images/ web/themes/sunsets/scripts/ web/themes/sunsets/styles/ web/themes/werner/ web/themes/x2/ web/themes/x2/images/ web/themes/x2/scripts/ web/themes/x2/styles/ web/weblog/ web/website/
Date Thu, 09 Jun 2005 03:19:20 GMT
Added: incubator/roller/trunk/src/org/roller/util/RegexUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/RegexUtil.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/RegexUtil.java (added)
+++ incubator/roller/trunk/src/org/roller/util/RegexUtil.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,32 @@
+/*
+ * Created on Nov 8, 2003
+ *
+ */
+package org.roller.util;
+import org.apache.commons.codec.binary.Hex;
+
+import java.io.UnsupportedEncodingException;
+import java.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 emails: 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 match 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("UTF8"));
            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/src/org/roller/util/RollerMessages.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/RollerMessages.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/RollerMessages.java (added)
+++ incubator/roller/trunk/src/org/roller/util/RollerMessages.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,104 @@
+package org.roller.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Holds collection of error messages and collection of status messages.
+ * @author David M Johnson
+ */
+public class RollerMessages
+{
+    private List mErrors = new ArrayList();
+    private List mMessages = new ArrayList();
+    
+    public RollerMessages() 
+    {
+    }
+    public void addError(String key)
+    {
+        mErrors.add(new RollerMessage(key, null));
+    }
+    public void addError(String key, String arg)
+    {
+        mErrors.add(new RollerMessage(key, new String[]{arg}));
+    }
+    public void addError(String key, String[] args)
+    {
+        mErrors.add(new RollerMessage(key, args));
+    }
+    public void addMessage(String key)
+    {
+        mMessages.add(new RollerMessage(key, null));
+    }
+    public void addMessage(String key, String arg)
+    {
+        mMessages.add(new RollerMessage(key, new String[]{arg}));
+    }
+    public void addMessage(String key, String[] args)
+    {
+        mMessages.add(new RollerMessage(key, args));
+    }
+    public Iterator getErrors()
+    {
+        return mErrors.iterator();
+    }
+    public Iterator getMessages()
+    {
+        return mMessages.iterator();
+    }
+    public int getErrorCount() 
+    {
+        return mErrors.size();
+    }
+    public int getMessageCount() 
+    {
+        return mMessages.size();
+    }
+    public String toString() 
+    {
+        StringBuffer sb = new StringBuffer();
+        Iterator msgs = mMessages.iterator();
+        while (msgs.hasNext())
+        {
+            RollerMessage msg = (RollerMessage) msgs.next();
+            sb.append(msg.getKey());
+            sb.append(" : ");
+        }
+        Iterator errs = mErrors.iterator();
+        while (errs.hasNext())
+        {
+            RollerMessage msg = (RollerMessage) errs.next();
+            sb.append(msg.getKey());
+            sb.append(" : ");
+        }
+        return sb.toString();
+    }
+    public static class RollerMessage
+    {
+        private String mKey;
+        private String[] mArgs;
+        public RollerMessage(String key, String[] args)
+        {
+            mKey = key;
+            mArgs = args;
+        }
+        public String[] getArgs()
+        {
+            return mArgs;
+        }
+        public void setArgs(String[] args)
+        {
+            mArgs = args;
+        }
+        public String getKey()
+        {
+            return mKey;
+        }
+        public void setKey(String key)
+        {
+            mKey = key;
+        }
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/StringUtils.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/StringUtils.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/StringUtils.java (added)
+++ incubator/roller/trunk/src/org/roller/util/StringUtils.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,56 @@
+/*
+ * Created on Jun 3, 2004
+ */
+package org.roller.util;
+
+/**
+ * @author lance.lavandowska
+ */
+public class StringUtils
+{
+    public static boolean isEmpty(String str)
+    {
+        if (str == null) return true;
+        return "".equals(str.trim());
+    }
+    
+    public static boolean isNotEmpty(String str)
+    {
+        return !isEmpty(str);
+    }
+    
+    public static String[] split(String str1, String str2)
+    {
+       return org.apache.commons.lang.StringUtils.split(str1, str2);
+    }
+    
+    public static String replace(String src, String target, String rWith)
+    {
+        return org.apache.commons.lang.StringUtils.replace(src, target, rWith);
+    }
+    
+    public static String replace(String src, String target, String rWith, int maxCount)
+    {
+        return org.apache.commons.lang.StringUtils.replace(src, target, rWith, maxCount);
+    }
+    
+    public static boolean equals(String str1, String str2) 
+    {
+        return org.apache.commons.lang.StringUtils.equals(str1, str2);
+    }
+    
+    public static boolean isAlphanumeric(String str)
+    {
+        return org.apache.commons.lang.StringUtils.isAlphanumeric(str);
+    }
+    
+    public static String[] stripAll(String[] strs) 
+    {
+        return org.apache.commons.lang.StringUtils.stripAll(strs);
+    }
+    
+    public static String left(String str, int length)
+    {
+        return org.apache.commons.lang.StringUtils.left(str, length);
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/Technorati.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/Technorati.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/Technorati.java (added)
+++ incubator/roller/trunk/src/org/roller/util/Technorati.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2005 David M Johnson
+ *
+ * Licensed 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.
+ */
+package org.roller.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import org.jdom.xpath.XPath;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/** Simple Technorati wrapper for Java. @author David M Johnson */
+public class Technorati {
+    private String mKey = null;
+
+    public Technorati(String key) {
+        mKey = key;
+    }
+    
+    public Technorati(String key, String proxy, int proxyPort) {
+        this(key);
+        System.setProperty("proxySet", "true");
+        System.setProperty("http.proxyHost", proxy);
+        System.setProperty("http.proxyPort", Integer.toString(proxyPort)); 
+    }
+
+    /** Looks for key in classpath using "/technorati.license" */
+    public Technorati() throws Exception {
+        InputStream is = getClass().getResourceAsStream("/technorati.license");
+        BufferedReader br = new BufferedReader(new InputStreamReader(is));
+        mKey = br.readLine();       
+    }
+
+    public Technorati(String proxy, int proxyPort) throws Exception {
+        this();
+        System.setProperty("proxySet", "true");
+        System.setProperty("http.proxyHost", proxy);
+        System.setProperty("http.proxyPort", Integer.toString(proxyPort)); 
+    }
+    
+    public Result getLinkCosmos(String url) throws Exception {
+        return new Result("http://api.technorati.com/cosmos",url,"links");
+    }
+
+    public Result getWeblogCosmos(String url) throws Exception {
+        return new Result("http://api.technorati.com/cosmos",url,"weblog");
+    }
+
+    public Result getBloginfo(String url) throws Exception {
+        return new Result("http://api.technorati.com/bloginfo",url,null);
+    }
+
+    public Result getOutbound(String url) throws Exception {
+        return new Result("http://api.technorati.com/outbound",url,null);
+    }
+
+    /** Technorati result with header info and collection of weblog items */
+    public class Result {
+        private Weblog mWeblog = null;
+        private Collection mWeblogs = new ArrayList();
+
+        protected Result(String apiUrl, String url, String type) throws Exception {
+            Map args = new HashMap();
+            args.put("url", url);
+            args.put("type", type);
+            args.put("format", "xml");
+            args.put("key", mKey);
+
+            int start = 0;
+            boolean repeat = true;
+            XPath itemsPath = XPath.newInstance("/tapi/document/item/weblog");            
+
+            while (repeat) {
+                 Document doc = getRawResults(apiUrl,args);               
+                Element elem = doc.getRootElement();                          
+                String error = getString(elem,"/tapi/document/result/error");
+                if ( error != null ) throw new Exception(error);
+                if (mWeblog == null) {
+                    XPath p = XPath.newInstance("/tapi/document/result/weblog");
+                    Element w = (Element) p.selectSingleNode(doc);
+                    mWeblog = new Weblog(w);
+                }
+                int count=0;
+                Iterator iter = itemsPath.selectNodes(doc).iterator();
+                while (iter.hasNext()) {
+                    Element element = (Element) iter.next();
+                    Weblog w = new Weblog(element);
+                    mWeblogs.add(w);
+                    count++;
+                }
+                if ( count < 20 ) { 
+                    repeat = false;
+                }
+                else {
+                    start += 20;
+                    args.put("start",new Integer(start));
+                }
+            }
+        }
+
+        public Weblog getWeblog() {return mWeblog;}
+        public Collection getWeblogs() {return mWeblogs;}
+    }
+
+    /** Technorati weblog representation */
+    public class Weblog {
+        private String mName = null;
+        private String mUrl = null;
+        private String mRssurl = null;
+        private String mLastupdate = null;
+        private String mNearestpermalink = null;
+        private String mExcerpt = null;
+        private int mInboundlinks = 0;
+        private int mInboundblogs = 0;
+
+        public Weblog(Element elem) throws Exception {
+            mName = getString(elem,"name");
+            mUrl = getString(elem,"url");
+            mRssurl = getString(elem,"rssurl");
+            mLastupdate = getString(elem,"lastupdate");
+            mNearestpermalink = getString(elem,"nearestpermalink");
+            mExcerpt = getString(elem,"excerpt");
+            try { 
+                mInboundlinks = getInt(elem,"inboundlinks");
+            } catch (Exception ignored) {}
+            try { 
+                mInboundblogs = getInt(elem,"inboundblogs");
+            } catch (Exception ignored) {}
+        }
+
+        public String getName() {return mName;}
+        public String getUrl() {return mUrl;}
+        public String getRssurl() {return mRssurl;}
+        public int getInboundblogs() {return mInboundblogs;}
+        public int getInboundlinks() {return mInboundlinks;}
+        public String getLastupdate() {return mLastupdate;}
+        public String getNearestpermalink() {return mNearestpermalink;}
+        public String getExcerpt() {return mExcerpt;}
+    }
+    
+    protected Document getRawResults(String urlString, Map args) throws Exception {
+        int count = 0;
+        Iterator keys = args.keySet().iterator();
+        while (keys.hasNext()) {
+            String sep = count++==0 ? "?" : "&";
+            String name = (String)keys.next();
+            if ( args.get(name) != null ) {
+                urlString += sep + name + "=" + args.get(name);                         
+            }
+        }
+        URL url = new URL(urlString);
+        URLConnection conn = url.openConnection();
+        conn.connect();
+        SAXBuilder builder = new SAXBuilder();
+        return builder.build(conn.getInputStream());
+    }
+    
+    protected String getString(Element elem, String path) throws Exception {
+        XPath xpath = XPath.newInstance(path);
+        Element e = (Element)xpath.selectSingleNode(elem);
+        return e!=null ? e.getText() : null;
+    }
+    
+    protected int getInt(Element elem, String path) throws Exception {
+        XPath xpath = XPath.newInstance(path);
+        Element e = (Element)xpath.selectSingleNode(elem);
+        return e!=null ? Integer.parseInt(e.getText()) : 0;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/TimeZoneComparator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/TimeZoneComparator.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/TimeZoneComparator.java (added)
+++ incubator/roller/trunk/src/org/roller/util/TimeZoneComparator.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,2 @@
+package org.roller.util;
+import java.util.TimeZone;
import java.util.Comparator;
import java.io.Serializable;

public class TimeZoneComparator implements Comparator, Serializable
{
    public int compare(Object obj1, Object obj2)
    {
        if (obj1 instanceof TimeZone && obj2 instanceof TimeZone)
        {
            TimeZone zone1 = (TimeZone)obj1;
            TimeZone zone2 = (TimeZone)obj2;
            int compName = zone1.getDisplayName().compareTo(zone2.getDisplayName());
            if (compName == 0)
            {
				return zone1.getID().compareTo(zone2.getID());
			}
            return compName;
        }
        return 0;
    }

    /* Do Comparators need to implement equals()? -Lance
    public boolean equals(Object obj)
    {
        if (obj instanceof TimeZoneComparator)
        {
            if (obj.equals(this)) return true;
        }
        return false;
    }
    */
}
\ No newline at end of file

Added: incubator/roller/trunk/src/org/roller/util/Utilities.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/Utilities.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/Utilities.java (added)
+++ incubator/roller/trunk/src/org/roller/util/Utilities.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,1123 @@
+package org.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.URLEncoder;
+import java.security.MessageDigest;
+import java.util.Date;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * General purpose utilities. 
+ * 
+ * <pre>
+ * Includes TextToHTML methods dondated by Erik Thauvin - "Donated to the 
+ * Roller Weblogger project for publication under the terms of the Roller 
+ * Software License. 
+ * Copyright (C) 2002-2003 by Erik C. Thauvin (erik@thauvin.net).
+ * All rights reserved.
+ * </pre>
+ * 
+ * @author David M Johnson
+ * @author Lance Lavandowska
+ * @author Matt Raible (added encryption methods)
+ */
+public class Utilities
+{
+    /** The <code>Log</code> instance for this class. */
+    private static Log mLogger = LogFactory.getLog(Utilities.class);
+    
+    /** Pattern for matching HTML links */
+    private static Pattern mLinkPattern = 
+        Pattern.compile("<a href=.*?>", Pattern.CASE_INSENSITIVE);
+    
+    /**
+     * Utility methods for calling StringUtils since it cannot be 
+     * instantiated and Utilties can.
+     */
+    public static boolean isNotEmpty(String str)
+    {
+        return StringUtils.isNotEmpty(str);
+    }
+    
+    //------------------------------------------------------------------------
+    /** 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 escapseAmpersand 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 = stringReplace(s, "&", "&amp;");
+        }
+        s = stringReplace(s, "&nbsp;", " ");
+        s = stringReplace(s, "\"", "&quot;");
+        s = stringReplace(s, "<", "&lt;");
+        s = stringReplace(s, ">", "&gt;");
+        return s;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * 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;
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Format date in ISO-8601 format.
+     */
+    public static String formatIso8601Date(Date d)
+    {
+        return DateUtil.formatIso8601(d);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Format date in ISO-8601 format.
+     */
+    public static String formatIso8601Day(Date d)
+    {
+        return DateUtil.formatIso8601Day(d);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return a date in RFC-822 format.
+     */
+    public static String formatRfc822Date(Date date) 
+    {
+        return DateUtil.formatRfc822(date);
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Return a date in RFC-822 format.
+     */
+    public static String format8charsDate(Date date) 
+    {
+        return DateUtil.format8chars(date);
+    }
+
+	//------------------------------------------------------------------------
+	/**
+	 * 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 pathArray
+     * @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;
+    }
+    
+    //------------------------------------------------------------------------
+    /**
+     * Replace occurrences of str1 in string str with str2 
+     */
+    public static String stringReplace(String str, String str1, String str2)
+    {
+        String ret = StringUtils.replace(str,str1,str2);
+        return ret;
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Replace occurrences of str1 in string str with str2
+     * @param str String to operate on 
+     * @param str1 String to be replaced
+     * @param str2 String to be used as replacement
+     * @param maxCount Number of times to replace, 0 for all
+     */
+    public static String stringReplace(
+        String str,
+        String str1,
+        String str2,
+        int maxCount)
+    {
+        String ret = StringUtils.replace(str,str1,str2,maxCount);
+        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 
+    {
+        sun.misc.BASE64Encoder encoder = new sun.misc.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 
+    {
+        sun.misc.BASE64Decoder dec = new sun.misc.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: Henri Yandell bayard@generationjava.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 <alexis.moussine-pouchkine@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 RegexUtil.encodeEmail(str);
+    }
+
+    /**
+     * Converts a character to HTML or XML entity.
+     *
+     * @param ch The character to convert.
+     * @param xml Convert the character to XML if set to true.
+     * @author Erik C. Thauvin
+     *
+     * @return The converted string.
+     */
+    public static final String charToHTML(char ch, boolean xml)
+    {
+        int c;
+
+        // Convert left bracket
+        if (ch == '<')
+        {
+            return ("&lt;");
+        }
+
+        // Convert left bracket
+        else if (ch == '>')
+        {
+            return ("&gt;");
+        }
+
+        // Convert ampersand
+        else if (ch == '&')
+        {
+            return ("&amp;");
+        }
+
+        // Commented out to eliminate redundant numeric character codes (ROL-507)
+        // High-ASCII character
+        //else if (ch >= 128)
+        //{
+            //c = ch;
+            //return ("&#" + c + ';');
+        //}
+
+        // Convert double quote
+        else if (xml && (ch == '"'))
+        {
+            return ("&quot;");
+        }
+
+        // Convert single quote
+        else if (xml && (ch == '\''))
+        {
+            return ("&#39;");
+        }
+
+        // No conversion
+        else
+        {
+            // Return character as string
+            return (String.valueOf(ch));
+        }
+    }
+
+    /**
+     * Converts a text string to HTML or XML entities.
+     *
+     * @author Erik C. Thauvin
+     * @param text The string to convert.
+     * @param xml Convert the string to XML if set to true.
+     *
+     * @return The converted string.
+     */
+    public static final String textToHTML(String text, boolean xml)
+    {
+        final StringBuffer html = new StringBuffer();
+
+        // Loop thru each characters of the text
+        for (int i = 0; i < text.length(); i++)
+        {
+            // Convert character to HTML/XML
+            html.append(charToHTML(text.charAt(i), xml));
+        }
+
+        // Return HTML/XML string
+        return html.toString();
+    }
+
+    /**
+     * Converts a text string to HTML or XML entities.
+     *
+     * @param text The string to convert.
+     * @author Erik C. Thauvin
+     * @return The converted string.
+     */
+    public static final String textToHTML(String text)
+    {
+        return textToHTML(text, false);
+    }
+
+    /**
+     * Converts a text string to XML entities.
+     *
+     * @param text The string to convert.
+     * @author Erik C. Thauvin
+     * @return The converted string.
+     */
+    public static final String textToXML(String text)
+    {
+        return textToHTML(text, true);
+    }
+
+    /**
+     * Converts a text string to HTML or XML entities.
+     * @param text The string to convert.
+     * @return The converted string.
+     */
+    public static final String textToCDATA(String text)
+    {
+        final StringBuffer html = new StringBuffer();
+
+        // Loop thru each characters of the text
+        for (int i = 0; i < text.length(); i++)
+        {
+            // Convert character to HTML/XML
+            html.append(charToCDATA(text.charAt(i)));
+        }
+
+        // Return HTML/XML string
+        return html.toString();
+    }
+
+    /**
+     * Converts a character to CDATA character.
+     * @param ch The character to convert.
+     * @return The converted string.
+     */
+    public static final String charToCDATA(char ch)
+    {
+        int c;
+
+        if (ch >= 128)
+        {
+            c = ch;
+
+            return ("&#" + c + ';');
+        }
+
+        // No conversion
+        else
+        {
+            // Return character as string
+            return (String.valueOf(ch));
+        }
+    }
+    
+    public static final String encode(String s) 
+    {
+        try 
+        {
+            return URLEncoder.encode(s, "utf-8");
+        } 
+        catch (UnsupportedEncodingException e) 
+        {
+            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;
+    }
+    
+    /** 
+     * Code (stolen from Pebble) to add rel="nofollow" string to all links in HTML.
+     */
+    public static String addNofollow(String html) 
+    {
+        if (html == null || html.length() == 0) 
+        {
+            return html;
+        }
+        Matcher m = mLinkPattern.matcher(html);
+        StringBuffer buf = new StringBuffer();
+        while (m.find()) 
+        {
+            int start = m.start();
+            int end = m.end();
+            String link = html.substring(start, end);
+            buf.append(html.substring(0, start));
+            if (link.indexOf("rel=\"nofollow\"") == -1) 
+            {
+                buf.append(
+                    link.substring(0, link.length() - 1) + " rel=\"nofollow\">");
+            } 
+            else 
+            {
+                buf.append(link);
+            }            
+            html = html.substring(end, html.length());
+            m = mLinkPattern.matcher(html);
+        }
+        buf.append(html);
+        return buf.toString();
+    }
+    
+    public static String unescapeHTML(String str) 
+    {
+        return StringEscapeUtils.unescapeHtml(str);
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/XSLTransform.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/XSLTransform.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/XSLTransform.java (added)
+++ incubator/roller/trunk/src/org/roller/util/XSLTransform.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ */
+package org.roller.util;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+/**
+ * Run an XSL transform (from the Java Almanac)
+ * @author Dave Johnson
+ */
+public class XSLTransform
+{
+    public static void main(String[] args)
+    {
+        if (args.length < 3)
+        {
+            System.out.println("USAGE: infile outfile xslfile");
+            System.exit(-1);
+        }
+        String inFilename = args[0];
+        String outFilename = args[1];
+        String xslFilename = args[2];
+        try
+        {
+            // Create transformer factory
+            TransformerFactory factory = TransformerFactory.newInstance();
+
+            // Use the factory to create a template containing the xsl file
+            Templates template = factory.newTemplates(new StreamSource(
+                    new FileInputStream(xslFilename)));
+
+            // Use the template to create a transformer
+            Transformer xformer = template.newTransformer();
+
+            // Prepare the input and output files
+            Source source = new StreamSource(new FileInputStream(inFilename));
+            Result result = new StreamResult(new FileOutputStream(outFilename));
+
+            // Apply the xsl file to the source file and write the result to the
+            // output file
+            xformer.transform(source, result);
+        }
+        catch (FileNotFoundException e)
+        {
+            e.printStackTrace();
+        }
+        catch (TransformerConfigurationException e)
+        {
+            // An error occurred in the XSL file
+            e.printStackTrace();
+        }
+        catch (TransformerException e)
+        {
+            // An error occurred while applying the XSL file
+            // Get location of error in input file
+            SourceLocator locator = e.getLocator();
+            int col = locator.getColumnNumber();
+            int line = locator.getLineNumber();
+            String publicId = locator.getPublicId();
+            String systemId = locator.getSystemId();
+            System.out.println("ERROR: line = "+line+" col = "+col);
+        }
+    }
+}
\ No newline at end of file

Added: incubator/roller/trunk/src/org/roller/util/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/package.html (added)
+++ incubator/roller/trunk/src/org/roller/util/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+This package is home to general purpose utility classes, especially those that 
+are truly generic and have no dependency on Roller.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/util/rome/ContentModule.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/ContentModule.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/ContentModule.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/ContentModule.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import com.sun.syndication.feed.module.Module;
+
+public interface ContentModule extends Module {
+    public static final String URI = "http://purl.org/rss/1.0/modules/content/";
+    public String getEncoded();
+    public void setEncoded(String encoded);
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/ContentModuleGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/ContentModuleGenerator.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/ContentModuleGenerator.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/ContentModuleGenerator.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleGenerator;
+
+public class ContentModuleGenerator implements ModuleGenerator {
+    private static final Namespace CONTENT_NS  = 
+        Namespace.getNamespace(ContentModule.URI);
+
+    public String getNamespaceUri() {
+        return ContentModule.URI;
+    }
+
+    private static final Set NAMESPACES;
+
+    static {
+        Set nss = new HashSet();
+        nss.add(CONTENT_NS);
+        NAMESPACES = Collections.unmodifiableSet(nss);
+    }
+
+    public Set getNamespaces() {
+        return NAMESPACES;
+    }
+
+    public void generate(Module module, Element element) {
+        ContentModule fm = (ContentModule)module;
+        if (fm.getEncoded() != null) {
+            element.addContent(generateSimpleElement("encoding", fm.getEncoded()));
+        }
+    }
+
+    protected Element generateSimpleElement(String name, String value)  {
+        Element element = new Element(name, CONTENT_NS);
+        element.addContent(value);
+        return element;
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/ContentModuleImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/ContentModuleImpl.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/ContentModuleImpl.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/ContentModuleImpl.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import com.sun.syndication.feed.module.ModuleImpl;
+
+public class ContentModuleImpl extends ModuleImpl implements ContentModule {
+    private String _encoded;
+
+    public ContentModuleImpl() {
+        super(ContentModule.class,ContentModule.URI);
+    }
+    public String getEncoded() {
+        return _encoded;
+    }
+    public void setEncoded(String encoded) {
+        _encoded = encoded;
+    }
+    public Class getInterface() {
+        return ContentModule.class;
+    }
+    public void copyFrom(Object obj) {
+        ContentModule sm = (ContentModule) obj;
+        setEncoded(sm.getEncoded());
+    }
+
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/ContentModuleParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/ContentModuleParser.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/ContentModuleParser.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/ContentModuleParser.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleParser;
+
+public class ContentModuleParser implements ModuleParser {
+
+    public String getNamespaceUri() {
+        return ContentModule.URI;
+    }
+
+    public Namespace getContentNamespace() {
+        return Namespace.getNamespace(ContentModule.URI);
+    }
+    public Module parse(Element dcRoot) {
+        boolean foundSomething = false;
+        ContentModule fm = new ContentModuleImpl();
+
+        Element e = dcRoot.getChild("encoded", getContentNamespace());
+        if (e != null) {
+            foundSomething = true;
+            fm.setEncoded(e.getText());
+        }
+        return (foundSomething) ? fm : null;
+    }
+}
+

Added: incubator/roller/trunk/src/org/roller/util/rome/DiskFeedInfoCache.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/DiskFeedInfoCache.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/DiskFeedInfoCache.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/DiskFeedInfoCache.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ */
+package org.roller.util.rome;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.sun.syndication.fetcher.impl.FeedFetcherCache;
+import com.sun.syndication.fetcher.impl.SyndFeedInfo;
+
+/**
+ * @author David M. Johnson
+ */
+public class DiskFeedInfoCache implements FeedFetcherCache
+{
+    private static Log logger = 
+        LogFactory.getFactory().getInstance(DiskFeedInfoCache.class);
+    
+    protected String cachePath = null;
+    public DiskFeedInfoCache(String cachePath)
+    {
+        this.cachePath = cachePath;
+    }
+    public SyndFeedInfo getFeedInfo(URL url)
+    {
+        SyndFeedInfo info = null;
+        String fileName = cachePath + File.separator + "feed_" + url.hashCode();
+        FileInputStream fis;
+        try
+        {
+            fis = new FileInputStream(fileName);
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            info = (SyndFeedInfo)ois.readObject();
+            fis.close();
+        }
+        catch (FileNotFoundException fnfe)
+        {
+            logger.debug("Cache miss for " + url.toString());
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+            // Error writing to cahce is fatal
+            throw new RuntimeException("Attempting to read from cache", cnfe);
+        }
+        catch (IOException fnfe)
+        {
+            // Error writing to cahce is fatal
+            throw new RuntimeException("Attempting to read from cache", fnfe);
+        }
+        if (info == null) logger.info("Cache MISS!");
+        return info;
+    }
+
+    public void setFeedInfo(URL url, SyndFeedInfo feedInfo)
+    {
+        String fileName = cachePath + File.separator + "feed_" + url.hashCode();
+        FileOutputStream fos;
+        try
+        {
+            fos = new FileOutputStream(fileName);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(feedInfo);
+            fos.flush();
+            fos.close();
+        }
+        catch (Exception e)
+        {
+            // Error writing to cahce is fatal
+            throw new RuntimeException("Attempting to write to cache", e);
+        }
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091N.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091N.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091N.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091N.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import com.sun.syndication.feed.rss.Item;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.impl.ConverterForRSS091Userland;
+
+/**
+ */
+public class PlanetConverterForRSS091N extends ConverterForRSS091Userland {
+
+    public PlanetConverterForRSS091N() {
+        this("rss_0.91N");
+    }
+    protected PlanetConverterForRSS091N(String type) {
+        super(type);
+    }
+    protected SyndEntry createSyndEntry(Item item) {
+        SyndEntry entry = super.createSyndEntry(item);
+        entry.setPublishedDate(item.getPubDate()); 
+        return entry;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091U.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091U.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091U.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS091U.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import com.sun.syndication.feed.rss.Item;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.impl.ConverterForRSS091Userland;
+
+/**
+ */
+public class PlanetConverterForRSS091U extends ConverterForRSS091Userland {
+
+    public PlanetConverterForRSS091U() {
+        this("rss_0.91U");
+    }
+
+    protected PlanetConverterForRSS091U(String type) {
+        super(type);
+    }
+    protected SyndEntry createSyndEntry(Item item) {
+        SyndEntry entry = super.createSyndEntry(item);
+        entry.setPublishedDate(item.getPubDate()); 
+        return entry;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS20.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS20.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS20.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/PlanetConverterForRSS20.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import java.util.Date;
+
+import com.sun.syndication.feed.WireFeed;
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.rss.Channel;
+import com.sun.syndication.feed.rss.Item;
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.impl.ConverterForRSS20;
+
+/**
+ * Workaround Rome bug.
+ */
+public class PlanetConverterForRSS20 extends ConverterForRSS20 {
+
+    public PlanetConverterForRSS20() {
+        this("rss_2.0");
+    }
+    protected PlanetConverterForRSS20(String type) {
+        super(type);
+    }
+    protected SyndEntry createSyndEntry(Item item) {
+        DCModule dcm = (DCModule)item.getModule(DCModule.URI);
+        Date dcdate = dcm != null ? dcm.getDate() : null;
+        SyndEntry syndEntry = super.createSyndEntry(item);
+        if (dcdate != null)
+        {
+            ((DCModule)syndEntry.getModule(DCModule.URI)).setDate(dcdate);
+        }
+        return syndEntry;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091NParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091NParser.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091NParser.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091NParser.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import org.jdom.Element;
+
+import com.sun.syndication.feed.rss.Item;
+import com.sun.syndication.io.impl.DateParser;
+import com.sun.syndication.io.impl.RSS091UserlandParser;
+
+/**
+ */
+public class PlanetRSS091NParser extends RSS091UserlandParser {
+
+    public PlanetRSS091NParser() {
+        this("rss_0.91N");
+    }
+
+    protected PlanetRSS091NParser(String type) {
+        super(type);
+    }
+
+    protected Item parseItem(Element rssRoot,Element eItem) {
+        Item item = super.parseItem(rssRoot, eItem);
+        Element e = eItem.getChild("pubDate",getRSSNamespace());
+        if (e!=null) {
+            item.setPubDate(DateParser.parseRFC822(e.getText()));
+        }
+        return item;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091UParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091UParser.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091UParser.java (added)
+++ incubator/roller/trunk/src/org/roller/util/rome/PlanetRSS091UParser.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * Licensed 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.
+ *
+ */
+package org.roller.util.rome;
+
+import org.jdom.Element;
+
+import com.sun.syndication.feed.rss.Item;
+import com.sun.syndication.io.impl.DateParser;
+import com.sun.syndication.io.impl.RSS091UserlandParser;
+
+/**
+ */
+public class PlanetRSS091UParser extends RSS091UserlandParser {
+
+    public PlanetRSS091UParser() {
+        this("rss_0.91U");
+    }
+
+    protected PlanetRSS091UParser(String type) {
+        super(type);
+    }
+
+    protected Item parseItem(Element rssRoot,Element eItem) {
+        Item item = super.parseItem(rssRoot, eItem);
+        Element e = eItem.getChild("pubDate",getRSSNamespace());
+        if (e!=null) {
+            item.setPubDate(DateParser.parseRFC822(e.getText()));
+        }
+        return item;
+    }
+}

Added: incubator/roller/trunk/tests/bookmarks.opml
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/tests/bookmarks.opml?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/tests/bookmarks.opml (added)
+++ incubator/roller/trunk/tests/bookmarks.opml Wed Jun  8 20:18:46 2005
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- OPML generated by Radio UserLand v8.0.5 on Sun, 23 Feb 2003 16:40:40 GMT -->
+<opml version="1.1">
	<head>
		<title>scriptingNewsLeftLinks.opml</title>
		<dateCreated>Sat, 05 Jan 2002 19:26:01 GMT</dateCreated>
		<dateModified>Sun, 23 Feb 2003 16:40:39 GMT</dateModified>
		<ownerName>Dave Winer</ownerName>
		<ownerEmail>dave@userland.com</ownerEmail>
		<expansionState></expansionState>
		<vertScrollState>6</vertScrollState>
		<windowTop>61</windowTop>
		<windowLeft>207</windowLeft>
		<windowBottom>860</windowBottom>
		<windowRight>354</windowRight>
		</head>
	<body>
		<outline text="Updates" type="link" url="http://www.weblogs.com/"/>
		<outline text="DaveNet" type="link" url="http://davenet.userland.com/"/>
		<outline text="Radio" type="link" url="http://radio.userland.com/"/>
		<outline text="Harvard" type="link" url="http://blogs.law.harvard.edu/"/>
		<outline text="Outliners" type="link" url="http://www.outliners.com/"/>
		<outline text="Radio CS" type="link" url="http://rcs.userland.com/"/>
		<outline text="Directory" type="link" url="http://www.userland.com/directory/71"/>
		<outline text="Frontier" type="link" url="http://frontier.userland.com/news/"/>
		<outline text="Weblogs" type="link" url="http://newhome.weblogs.com/"/>
		<outline text="Manila" type="link" url="http://manila.userland.com/"/>
		<outline text="Mail Pages" type="link" url="http://mailpages.scripting.com/"/>
		<outline text="RSS" type="link" url="http://backend.userland.com/rss"/>
	</body>
</opml>
\ No newline at end of file

Added: incubator/roller/trunk/tests/org/roller/BlacklistTest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/tests/org/roller/BlacklistTest.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/tests/org/roller/BlacklistTest.java (added)
+++ incubator/roller/trunk/tests/org/roller/BlacklistTest.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,111 @@
+/*
+ * Created on Nov 12, 2003
+ */
+package org.roller;
+
+import org.roller.business.FileManagerTest;
+import org.roller.util.Blacklist;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * @author lance
+ */
+public class BlacklistTest extends TestCase
+{
+    private Blacklist blacklist;
+
+	/**
+	 * 
+	 */
+	public BlacklistTest()
+	{
+		super();
+	}
+
+	/**
+	 * @param arg0
+	 */
+	public BlacklistTest(String arg0)
+	{
+		super(arg0);
+	}
+    
+    /**
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        blacklist = Blacklist.getBlacklist(null,null);
+    }
+
+    /**
+     * @see TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        //System.out.println(blacklist);
+    }
+    
+    public void testIsBlacklisted0()
+    {
+        assertFalse(blacklist.isBlacklisted("four score and seven years ago.com"));
+    }
+    
+    // test non-regex
+    public void testIsBlacklisted1()
+    {
+        assertTrue(blacklist.isBlacklisted("00000-online-casino.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted2()
+    {
+        assertTrue(blacklist.isBlacklisted("www.lsotr.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted3()
+    {
+        assertTrue(blacklist.isBlacklisted("www.lsotr.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted4()
+    {
+        assertTrue(blacklist.isBlacklisted("blow-job.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted5()
+    {
+        assertTrue(blacklist.isBlacklisted("buymoreonline.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted6()
+    {
+        assertTrue(blacklist.isBlacklisted("diet-enlargement.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted7()
+    {
+        assertTrue(blacklist.isBlacklisted("viagra.com"));
+    }
+    
+    // test the regex patterns
+    public void testIsBlacklisted8()
+    {
+        assertTrue(blacklist.isBlacklisted("ragazze-something.com"));
+    }
+
+    public static Test suite()
+    {
+        return new TestSuite(BlacklistTest.class);
+    }
+}

Added: incubator/roller/trunk/tests/org/roller/DateTest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/tests/org/roller/DateTest.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/tests/org/roller/DateTest.java (added)
+++ incubator/roller/trunk/tests/org/roller/DateTest.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,43 @@
+/*
+ * Created on Mar 10, 2004
+ */
+package org.roller;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.roller.business.FileManagerTest;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * @author dmj
+ */
+public class DateTest extends TestCase
+{
+
+    public static void main(String[] args)
+    {
+        junit.textui.TestRunner.run(DateTest.class);
+    }
+    
+    public void testDate() throws Exception
+    {
+        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
+        Date newDate = df.parse("5/8/1964");
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(newDate);
+        cal.set(Calendar.HOUR_OF_DAY, 11);
+        cal.set(Calendar.MINUTE, 39);
+        cal.set(Calendar.SECOND, 0);
+        System.out.println(cal.getTime().toString());
+    }
+
+    public static Test suite()
+    {
+        return new TestSuite(DateTest.class);
+    }
+}



Mime
View raw message