You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2005/06/09 05:19:20 UTC
svn commit: r189695 [42/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/
Added: incubator/roller/trunk/src/org/roller/util/CommentSpamChecker.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/CommentSpamChecker.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/CommentSpamChecker.java (added)
+++ incubator/roller/trunk/src/org/roller/util/CommentSpamChecker.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,90 @@
+package org.roller.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.business.ThreadManagerImpl;
+import org.roller.model.RollerFactory;
+import org.roller.model.ThreadManager;
+import org.roller.pojos.CommentData;
+
+/**
+ * Created on Mar 9, 2004
+ * @author lance.lavandowska
+ */
+public class CommentSpamChecker
+{
+ private static Log mLogger = LogFactory.getLog(CommentSpamChecker.class);
+ private Blacklist blacklist = Blacklist.getBlacklist(null,null);
+
+ // -----------------------------------------------------------------------
+ /**
+ * Runs comment check on comment, sets spam flag on comment.
+ */
+ public void testComment(CommentData comment)
+ {
+ try
+ {
+ // by using the OR conditional it'll test each
+ // one in order and fall into the body without
+ // having to test each and every condition.
+ // Not sure which is the optimal order to check, though.
+ boolean isSpam = blacklist.isBlacklisted(comment.getUrl());
+ isSpam = blacklist.isBlacklisted(comment.getContent())?true:isSpam;
+ isSpam = blacklist.isBlacklisted(comment.getEmail())?true:isSpam;
+
+ if (isSpam)
+ {
+ comment.setSpam(Boolean.TRUE);
+ comment.save();
+ RollerFactory.getRoller().commit();
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.error("Processing Comment",e);
+ }
+ finally
+ {
+ RollerFactory.getRoller().release();
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Spawns thread to run comment check.
+ */
+ public void testComment(CommentData comment, ThreadManager threadMgr)
+ {
+ try
+ {
+ if (threadMgr != null)
+ {
+ threadMgr.executeInBackground(new CommentCheckerRunnable(comment));
+ }
+ else
+ {
+ mLogger.warn("No thread manager found.");
+ }
+ }
+ catch (InterruptedException e) {
+ mLogger.warn("Interrupted during Comment Spam check",e);
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Runnable to run spam check on it's own thread.
+ */
+ private class CommentCheckerRunnable implements Runnable
+ {
+ private CommentData mComment = null;
+ public CommentCheckerRunnable( CommentData comment)
+ {
+ mComment = comment;
+ }
+ public void run()
+ {
+ testComment(mComment);
+ }
+ }
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/DateUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/DateUtil.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/DateUtil.java (added)
+++ incubator/roller/trunk/src/org/roller/util/DateUtil.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1 @@
+package org.roller.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* General purpose date utilities.
* @author Mark Saarinen
* @author Lance Lavandowska
*/
public abstract class DateUtil extends Object
{
public static final long millisInDay = 86400000;
// some static date formats
private static SimpleDateFormat[] mDateFormats = loadDateFormats();
private static final SimpleDateFormat mFormat8chars =
new SimpleDateFormat("yyyyMMdd");
private static final SimpleDateFormat mFormatIso8601Day =
new SimpleDateFormat("yyyy-MM-dd");
private static final SimpleDateFormat mFormatIso8601 =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
// http://www.w3.org/Protocols/rfc822/Overview.html#z28
// Using Locale.US to fix ROL-725 and ROL-628
private static final SimpleDateFormat mFormatRfc822 =
new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US);
private static SimpleDateFormat[] loadDateFormats()
{
SimpleDateFormat[] temp = {
//new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS a"),
new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy"), // standard Date.toString() results
new SimpleDateFormat("M/d/yy hh:mm:ss"),
new SimpleDateFormat("M/d/yyyy hh:mm:ss"),
new SimpleDateFormat("M/d/yy hh:mm a"),
new SimpleDateFormat("M/d/yyyy hh:mm a"),
new SimpleDateFormat("M/d/yy HH:mm"),
new SimpleDateFormat("M/d/yyyy HH:mm"),
new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"),
new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS"),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"), // standard Timestamp.toString() results
new SimpleDateFormat("M-d-yy HH:mm"),
new SimpleDateFormat("M-d-yyyy HH:mm"),
new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"),
new SimpleDateFormat("M/d/yy"),
new SimpleDateFormat("M/d/yyyy"),
new SimpleDateFormat("M-d-yy"),
new SimpleDateFormat("M-d-yyyy"),
new SimpleDateFormat("MMMM d, yyyyy"),
new SimpleDateFormat("MMM d, yyyyy")
};
return temp;
}
//-----------------------------------------------------------------------
/**
* Gets the array of SimpleDateFormats that DateUtil knows about.
**/
private static SimpleDateFormat[] getFormats()
{
return mDateFormats;
}
//-----------------------------------------------------------------------
/**
* Returns a Date set to the last possible millisecond of the day, just
* before midnight. If a null day is passed in, a new Date is created.
* midnight (00m 00h 00s)
*/
public static Date getEndOfDay(Date day)
{
return getEndOfDay(day,Calendar.getInstance());
}
public static Date getEndOfDay(Date day,Calendar cal)
{
if (day == null) day = new Date();
cal.setTime(day);
cal.set(Calendar.HOUR_OF_DAY, cal.getMaximum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getMaximum(Calendar.MILLISECOND));
return cal.getTime();
}
//-----------------------------------------------------------------------
/**
* Returns a Date set to the first possible millisecond of the day, just
* after midnight. If a null day is passed in, a new Date is created.
* midnight (00m 00h 00s)
*/
public static Date getStartOfDay(Date day)
{
return getStartOfDay(day, Calendar.getInstance());
}
/**
* Returns a Date set to the first possible millisecond of the day, just
* after midnight. If a null day is passed in, a new Date is created.
* midnight (00m 00h 00s)
*/
public static Date getStartOfDay(Date day, Calendar cal)
{
if (day == null) day = new Date();
cal.setTime(day);
cal.set(Calendar.HOUR_OF_DAY, cal.getMinimum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
return cal.getTime();
}
/**
* Returns a Date set just to Noon, to the closest possible millisecond
* of the day. If a null day is passed in, a new Date is created.
* nnoon (00m 12h 00s)
*/
public static Date getNoonOfDay(Date day, Calendar cal)
{
if (day == null) day = new Date();
cal.setTime(day);
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
return cal.getTime();
}
//-----------------------------------------------------------------------
public static Date parseFromFormats(String aValue)
{
if (StringUtils.isEmpty(aValue)) return null;
// get DateUtil's formats
SimpleDateFormat formats[] = DateUtil.getFormats();
if (formats == null) return null;
// iterate over the array and parse
Date myDate = null;
for (int i = 0; i <formats.length; i++)
{
try
{
myDate = DateUtil.parse(aValue, formats[i]);
//if (myDate instanceof Date)
return myDate;
}
catch (Exception e)
{
// do nothing because we want to try the next
// format if current one fails
}
}
// haven't returned so couldn't parse
return null;
}
//-----------------------------------------------------------------------
public static java.sql.Timestamp parseTimestampFromFormats(String aValue)
{
if (StringUtils.isEmpty(aValue)) return null;
// call the regular Date formatter
Date myDate = DateUtil.parseFromFormats(aValue);
if (myDate != null) return new java.sql.Timestamp(myDate.getTime());
return null;
}
//-----------------------------------------------------------------------
/**
* Returns a java.sql.Timestamp equal to the current time
**/
public static java.sql.Timestamp now()
{
return new java.sql.Timestamp(new java.util.Date().getTime());
}
//-----------------------------------------------------------------------
/**
* Returns a string the represents the passed-in date parsed
* according to the passed-in format. Returns an empty string
* if the date or the format is null.
**/
public static String format(Date aDate, SimpleDateFormat aFormat)
{
if (aDate == null || aFormat == null ) { return ""; }
synchronized (aFormat)
{
return aFormat.format(aDate);
}
}
//-----------------------------------------------------------------------
/**
* Tries to take the passed-in String and format it as a date string in the
* the passed-in format.
**/
public static String formatDateString(String aString, SimpleDateFormat aFormat)
{
if (StringUtils.isEmpty(aString) || aFormat == null) return "";
try
{
java.sql.Timestamp aDate = parseTimestampFromFormats(aString);
if (aDate != null)
{
return DateUtil.format(aDate, aFormat);
}
}
catch (Exception e)
{
// Could not parse aString.
}
return "";
}
//-----------------------------------------------------------------------
/**
* Returns a Date using the passed-in string and format. Returns null if the string
* is null or empty or if the format is null. The string must match the format.
**/
public static Date parse(String aValue, SimpleDateFormat aFormat) throws ParseException
{
if (StringUtils.isEmpty(aValue) || aFormat == null)
{
return null;
}
return aFormat.parse(aValue);
}
//-----------------------------------------------------------------------
/**
* Returns true if endDate is after startDate or if startDate equals endDate
* or if they are the same date. Returns false if either value is null.
**/
public static boolean isValidDateRange(Date startDate, Date endDate)
{
return isValidDateRange(startDate, endDate, true);
}
//-----------------------------------------------------------------------
/**
* Returns true if endDate is after startDate or if startDate equals endDate.
* Returns false if either value is null. If equalOK, returns true if the
* dates are equal.
**/
public static boolean isValidDateRange(Date startDate, Date endDate, boolean equalOK)
{
// false if either value is null
if (startDate == null || endDate == null) { return false; }
if (equalOK)
{
// true if they are equal
if (startDate.equals(endDate)) { return true; }
}
// true if endDate after startDate
if (endDate.after(startDate)) { return true; }
return false;
}
//-----------------------------------------------------------------------
// returns full timestamp format
public static java.text.SimpleDateFormat defaultTimestampFormat()
{
return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
}
//-----------------------------------------------------------------------
// convenience method returns minimal date format
public static java.text.SimpleDateFormat get8charDateFormat()
{
return DateUtil.mFormat8chars;
}
//-----------------------------------------------------------------------
// convenience method returns minimal date format
public static java.text.SimpleDateFormat defaultDateFormat()
{
return DateUtil.friendlyDateFormat(true);
}
//-----------------------------------------------------------------------
// convenience method
public static String defaultTimestamp(Date date)
{
return DateUtil.format(date, DateUtil.defaultTimestampFormat());
}
//-----------------------------------------------------------------------
// convenience method
public static String defaultDate(Date date)
{
return DateUtil.format(date, DateUtil.defaultDateFormat());
}
//-----------------------------------------------------------------------
// convenience method returns long friendly timestamp format
public static java.text.SimpleDateFormat friendlyTimestampFormat()
{
return new java.text.SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
}
//-----------------------------------------------------------------------
// convenience method returns long friendly formatted timestamp
public static String friendlyTimestamp(Date date)
{
return DateUtil.format(date, DateUtil.friendlyTimestampFormat());
}
//-----------------------------------------------------------------------
// convenience method returns long friendly formatted timestamp
public static String format8chars(Date date)
{
return DateUtil.format(date, mFormat8chars);
}
//-----------------------------------------------------------------------
// convenience method returns long friendly formatted timestamp
public static String formatIso8601Day(Date date)
{
return DateUtil.format(date, mFormatIso8601Day);
}
//-----------------------------------------------------------------------
public static String formatRfc822(Date date)
{
return DateUtil.format(date,mFormatRfc822);
}
//-----------------------------------------------------------------------
// This is a hack, but it seems to work
public static String formatIso8601(Date date)
{
if (date == null) return "";
// Add a colon 2 chars before the end of the string
// to make it a valid ISO-8601 date.
String str = DateUtil.format(date,mFormatIso8601);
StringBuffer sb = new StringBuffer();
sb.append( str.substring(0,str.length()-2) );
sb.append( ":" );
sb.append( str.substring(str.length()-2) );
return sb.toString();
}
//-----------------------------------------------------------------------
// convenience method returns minimal date format
public static java.text.SimpleDateFormat minimalDateFormat()
{
return DateUtil.friendlyDateFormat(true);
}
//-----------------------------------------------------------------------
// convenience method using minimal date format
public static String minimalDate(Date date)
{
return DateUtil.format(date, DateUtil.minimalDateFormat());
}
//-----------------------------------------------------------------------
// convenience method that returns friendly data format
// using full month, day, year digits.
public static java.text.SimpleDateFormat fullDateFormat()
{
return DateUtil.friendlyDateFormat(false);
}
//-----------------------------------------------------------------------
public static String fullDate(Date date)
{
return DateUtil.format(date, DateUtil.fullDateFormat());
}
//-----------------------------------------------------------------------
/** Returns a "friendly" date format.
* @param mimimalFormat Should the date format allow single digits.
**/
public static java.text.SimpleDateFormat friendlyDateFormat(boolean minimalFormat)
{
if (minimalFormat)
{
return new java.text.SimpleDateFormat("d.M.yy");
}
return new java.text.SimpleDateFormat("dd.MM.yyyy");
}
//-----------------------------------------------------------------------
/**
* Format the date using the "friendly" date format.
*/
public static String friendlyDate(Date date, boolean minimalFormat)
{
return DateUtil.format(date, DateUtil.friendlyDateFormat(minimalFormat));
}
//-----------------------------------------------------------------------
// convenience method
public static String friendlyDate(Date date)
{
return DateUtil.format(date, DateUtil.friendlyDateFormat(true));
}
public static Date parseIso8601(String value) throws Exception
{
return ISO8601DateParser.parse(value);
}
}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/ISO8601DateParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/ISO8601DateParser.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/ISO8601DateParser.java (added)
+++ incubator/roller/trunk/src/org/roller/util/ISO8601DateParser.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * 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.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * ISO 8601 date parsing utility. Designed for parsing the ISO subset used in
+ * Dublin Core, RSS 1.0, and Atom.
+ *
+ * @author <a href="mailto:burton@apache.org">Kevin A. Burton (burtonator)</a>
+ * @version $Id: ISO8601DateParser.java,v 1.2 2005/06/03 20:25:29 snoopdave Exp $
+ */
+public class ISO8601DateParser {
+
+ // 2004-06-14T19:GMT20:30Z
+ // 2004-06-20T06:GMT22:01Z
+
+ private static SimpleDateFormat df
+ = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
+
+ // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
+ //
+ // http://www.intertwingly.net/wiki/pie/DateTime
+ //
+ // http://www.w3.org/TR/NOTE-datetime
+ //
+ // Different standards may need different levels of granularity in the date and
+ // time, so this profile defines six levels. Standards that reference this
+ // profile should specify one or more of these granularities. If a given
+ // standard allows more than one granularity, it should specify the meaning of
+ // the dates and times with reduced precision, for example, the result of
+ // comparing two dates with different precisions.
+
+ // The formats are as follows. Exactly the components shown here must be
+ // present, with exactly this punctuation. Note that the "T" appears literally
+ // in the string, to indicate the beginning of the time element, as specified in
+ // ISO 8601.
+
+ // Year:
+ // YYYY (eg 1997)
+ // Year and month:
+ // YYYY-MM (eg 1997-07)
+ // Complete date:
+ // YYYY-MM-DD (eg 1997-07-16)
+ // Complete date plus hours and minutes:
+ // YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
+ // Complete date plus hours, minutes and seconds:
+ // YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
+ // Complete date plus hours, minutes, seconds and a decimal fraction of a
+ // second
+ // YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
+
+ // where:
+
+ // YYYY = four-digit year
+ // MM = two-digit month (01=January, etc.)
+ // DD = two-digit day of month (01 through 31)
+ // hh = two digits of hour (00 through 23) (am/pm NOT allowed)
+ // mm = two digits of minute (00 through 59)
+ // ss = two digits of second (00 through 59)
+ // s = one or more digits representing a decimal fraction of a second
+ // TZD = time zone designator (Z or +hh:mm or -hh:mm)
+ public static Date parse( String input ) throws java.text.ParseException {
+
+ //NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks
+ //things a bit. Before we go on we have to repair this.
+
+ //this is zero time so we need to add that TZ indicator for
+ if ( input.endsWith( "Z" ) ) {
+ input = input.substring( 0, input.length() - 1) + "GMT-00:00";
+ } else {
+ int inset = 6;
+
+ String s0 = input.substring( 0, input.length() - inset );
+ String s1 = input.substring( input.length() - inset, input.length() );
+
+ input = s0 + "GMT" + s1;
+ }
+
+ return df.parse( input );
+
+ }
+
+ public static String toString( Date date ) {
+
+ TimeZone tz = TimeZone.getTimeZone( "UTC" );
+
+ df.setTimeZone( tz );
+
+ String output = df.format( date );
+
+ int inset0 = 9;
+ int inset1 = 6;
+
+ String s0 = output.substring( 0, output.length() - inset0 );
+ String s1 = output.substring( output.length() - inset1, output.length() );
+
+ String result = s0 + s1;
+
+ result = result.replaceAll( "UTC", "+00:00" );
+
+ return result;
+
+ }
+
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/LRUCache.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/LRUCache.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/LRUCache.java (added)
+++ incubator/roller/trunk/src/org/roller/util/LRUCache.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,21 @@
+/*
+ * Created on Jun 15, 2004
+ */
+package org.roller.util;
+
+import java.util.Map;
+
+// David Flanaghan: http://www.davidflanagan.com/blog/000014.html
+public class LRUCache extends java.util.LinkedHashMap
+{
+ protected int maxsize;
+ public LRUCache(int maxsize)
+ {
+ super(maxsize*4/3 + 1, 0.75f, true);
+ this.maxsize = maxsize;
+ }
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > this.maxsize;
+ }
+}
+
Added: incubator/roller/trunk/src/org/roller/util/LRUCache2.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/LRUCache2.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/LRUCache2.java (added)
+++ incubator/roller/trunk/src/org/roller/util/LRUCache2.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,160 @@
+package org.roller.util;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+/**
+ * LRU cache with per-entry timeout logic.
+ *
+ * @author Dave Johnson
+ */
+public class LRUCache2
+{
+ private long timeout;
+ private Map cache = null;
+ private Environment environment = null;
+
+ /**
+ * Create cache.
+ *
+ * @param maxsize
+ * Maximum number of entries in cache.
+ * @param timeout
+ * Entry timeout in milli-seconds.
+ */
+ public LRUCache2(int maxsize, long timeout)
+ {
+ this.environment = new DefaultEnvironment();
+ this.timeout = timeout;
+ this.cache = new LRULinkedHashMap(maxsize);
+ }
+
+ /**
+ * Create cache that uses custom environment.
+ *
+ * @param maxsize
+ * Maximum number of entries in cache.
+ * @param timeout
+ * Entry timeout in milli-seconds.
+ */
+ public LRUCache2(Environment environment, int maxsize, long timeout)
+ {
+ this.environment = environment;
+ this.timeout = timeout;
+ this.cache = new LRULinkedHashMap(maxsize);
+ }
+
+ public synchronized void put(Object key, Object value)
+ {
+ CacheEntry entry = new CacheEntry(value, environment
+ .getCurrentTimeInMillis());
+ cache.put(key, entry);
+ }
+
+ public Object get(Object key)
+ {
+ Object value = null;
+ CacheEntry entry = null;
+ synchronized(this)
+ {
+ entry = (CacheEntry) cache.get(key);
+ }
+ if (entry != null)
+ {
+ if (environment.getCurrentTimeInMillis() - entry.getTimeCached() < timeout)
+ {
+ value = entry.getValue();
+ }
+ else
+ {
+ cache.remove(entry);
+ }
+ }
+ return value;
+ }
+
+ public synchronized void purge()
+ {
+ cache.clear();
+ }
+
+ public synchronized void purge(String[] patterns)
+ {
+ List purgeList = new ArrayList();
+ Iterator keys = cache.keySet().iterator();
+ while (keys.hasNext())
+ {
+ String key = (String) keys.next();
+ for (int i = 0; i < patterns.length; i++)
+ {
+ if (key.indexOf(patterns[i]) != -1)
+ {
+ purgeList.add(key);
+ break;
+ }
+ }
+ }
+ Iterator purgeIter = purgeList.iterator();
+ while (purgeIter.hasNext())
+ {
+ String key = (String) purgeIter.next();
+ cache.remove(key);
+ }
+ }
+
+ public int size()
+ {
+ return cache.size();
+ }
+ public interface Environment
+ {
+ public long getCurrentTimeInMillis();
+ }
+ public static class DefaultEnvironment implements Environment
+ {
+ public long getCurrentTimeInMillis()
+ {
+ return System.currentTimeMillis();
+ }
+ }
+ private static class CacheEntry
+ {
+ private Object value;
+ private long timeCached = -1;
+
+ public CacheEntry(Object value, long timeCached)
+ {
+ this.timeCached = timeCached;
+ this.value = value;
+ }
+
+ public long getTimeCached()
+ {
+ return timeCached;
+ }
+
+ public Object getValue()
+ {
+ return value;
+ }
+ }
+
+ // David Flanaghan: http://www.davidflanagan.com/blog/000014.html
+ private static class LRULinkedHashMap extends LinkedHashMap
+ {
+ protected int maxsize;
+
+ public LRULinkedHashMap(int maxsize)
+ {
+ super(maxsize * 4 / 3 + 1, 0.75f, true);
+ this.maxsize = maxsize;
+ }
+
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ {
+ return this.size() > this.maxsize;
+ }
+ }
+}
Added: incubator/roller/trunk/src/org/roller/util/LinkbackExtractor.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/LinkbackExtractor.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/LinkbackExtractor.java (added)
+++ incubator/roller/trunk/src/org/roller/util/LinkbackExtractor.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,408 @@
+package org.roller.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.HTML.Tag;
+import javax.swing.text.html.HTMLEditorKit.Parser;
+import javax.swing.text.html.HTMLEditorKit.ParserCallback;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.sun.syndication.feed.synd.SyndEntry;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedInput;
+
+/**
+ * Parses HTML file for referring linkback title and excerpt.
+ *
+ * @author David M Johnson
+ */
+public class LinkbackExtractor
+{
+ private static Log mLogger = LogFactory.getFactory().getInstance(
+ LinkbackExtractor.class);
+ private boolean mFound = false;
+ private String mTitle = "";
+ private String mRssLink = null;
+ private String mExcerpt = null;
+ private String mPermalink = null;
+ private int mStart = 0;
+ private int mEnd = 0;
+ private int mMaxExcerpt = 500; // characters
+ private String mRequestURL = null;
+ private String mRequestURLWWW = null;
+ private String mRefererURL;
+
+ //------------------------------------------------------------------------
+ /**
+ * Extract referring page title, excerpt, and permalink.
+ *
+ * @param refererUrl
+ * @param requestUrl
+ */
+ public LinkbackExtractor(String refererURL, String requestURL)
+ throws MalformedURLException, IOException
+ {
+ try
+ {
+ extractByParsingHtml(refererURL, requestURL);
+ if (mRssLink != null)
+ {
+ extractByParsingRss(mRssLink, requestURL);
+ }
+ }
+ catch (Exception e)
+ {
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Extracting linkback", e);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ private void extractByParsingHtml(String refererURL, String requestURL)
+ throws MalformedURLException, IOException
+ {
+ URL url = new URL(refererURL);
+ InputStream is = url.openStream();
+
+ mRefererURL = refererURL;
+
+ if (requestURL.startsWith("http://www."))
+ {
+ mRequestURLWWW = requestURL;
+ mRequestURL = "http://" + mRequestURLWWW.substring(11);
+ }
+ else
+ {
+ mRequestURL = requestURL;
+ mRequestURLWWW = "http://www." + mRequestURL.substring(7);
+ }
+
+ // Trick gets Swing's HTML parser
+ Parser parser = (new HTMLEditorKit() {
+ public Parser getParser()
+ {
+ return super.getParser();
+ }
+ }).getParser();
+
+ // Read HTML file into string
+ StringBuffer sb = new StringBuffer();
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ try
+ {
+ String line = null;
+ while ((line = br.readLine()) != null)
+ {
+ sb.append(line);
+ }
+ }
+ finally
+ {
+ br.close();
+ }
+
+ // Parse HTML string to find title and start and end position
+ // of the referring excerpt.
+ StringReader sr = new StringReader(sb.toString());
+ parser.parse(sr, new LinkbackCallback(), true);
+
+ if (mStart != 0 && mEnd != 0 && mEnd > mStart)
+ {
+ mExcerpt = sb.toString().substring(mStart, mEnd);
+ mExcerpt = Utilities.removeHTML(mExcerpt);
+
+ if (mExcerpt.length() > mMaxExcerpt)
+ {
+ mExcerpt = mExcerpt.substring(0, mMaxExcerpt) + "...";
+ }
+ }
+
+ if (mTitle.startsWith(">") && mTitle.length() > 1)
+ {
+ mTitle = mTitle.substring(1);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ private void extractByParsingRss(String rssLink, String requestURL)
+ throws IllegalArgumentException, MalformedURLException, FeedException, IOException
+ {
+ SyndFeedInput feedInput = new SyndFeedInput();
+ SyndFeed feed = feedInput.build(
+ new InputStreamReader(new URL(rssLink).openStream()));
+ Iterator itemIter = feed.getEntries().iterator();
+ String feedTitle = feed.getTitle();
+
+ int count = 0;
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Feed parsed, title: " + feedTitle);
+ }
+
+ while (itemIter.hasNext())
+ {
+ count++;
+ SyndEntry item = (SyndEntry) itemIter.next();
+ if (item.getDescription().getValue().indexOf(requestURL) != -1)
+ {
+ mFound = true;
+ mPermalink = item.getLink().toString();
+ if (feedTitle != null && feedTitle.trim().length() > 0)
+ {
+ mTitle = feedTitle + ": " + item.getTitle();
+ }
+ else
+ {
+ mTitle = item.getTitle();
+ }
+ mExcerpt = item.getDescription().getValue();
+ mExcerpt = Utilities.removeHTML(mExcerpt);
+ if (mExcerpt.length() > mMaxExcerpt)
+ {
+ mExcerpt = mExcerpt.substring(0, mMaxExcerpt) + "...";
+ }
+ break;
+ }
+ }
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Parsed " + count + " articles, found linkback="
+ + mFound);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Returns the excerpt.
+ *
+ * @return String
+ */
+ public String getExcerpt()
+ {
+ return mExcerpt;
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Returns the title.
+ *
+ * @return String
+ */
+ public String getTitle()
+ {
+ return mTitle;
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Returns the permalink.
+ *
+ * @return String
+ */
+ public String getPermalink()
+ {
+ return mPermalink;
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Sets the permalink.
+ *
+ * @param permalink
+ * The permalink to set
+ */
+ public void setPermalink(String permalink)
+ {
+ mPermalink = permalink;
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Parser callback that finds title and excerpt. As we walk through the HTML
+ * tags, we keep track of the most recently encountered divider tag in the
+ * mStart field. Once we find the referring permalink, we set the mFound
+ * flag. After that, we look for the next divider tag and save it's position
+ * in the mEnd field.
+ */
+ private final class LinkbackCallback extends ParserCallback
+ {
+ // Dividers
+ private Tag[] mDivTags = { Tag.TD, Tag.DIV, Tag.SPAN,
+ Tag.BLOCKQUOTE, Tag.P, Tag.LI,
+ Tag.BR, Tag.HR, Tag.PRE, Tag.H1,
+ Tag.H2, Tag.H3, Tag.H4, Tag.H5,
+ Tag.H6 };
+
+ private List mList = Arrays.asList(mDivTags);
+
+ private Tag mCurrentTag = null;
+
+ /**
+ * Look for divider tags and for the permalink.
+ *
+ * @param tag
+ * HTML tag
+ * @param atts
+ * Attributes of that tag
+ * @param pos
+ * Tag's position in file
+ */
+ public void handleStartTag(Tag tag, MutableAttributeSet atts, int pos)
+ {
+ if (mList.contains(tag) && !mFound)
+ {
+ mStart = pos;
+ }
+ else if (mList.contains(tag) && mFound && mEnd == 0)
+ {
+ mEnd = pos;
+ }
+ else if (tag.equals(Tag.A))
+ {
+ String href = (String) atts.getAttribute(HTML.Attribute.HREF);
+ if (href == null)
+ return;
+ int hashPos = href.lastIndexOf('#');
+ if (hashPos != -1)
+ {
+ href = href.substring(0, hashPos);
+ }
+ if (href != null
+ && (href.equals(mRequestURL) || href
+ .equals(mRequestURLWWW)))
+ {
+ mFound = true;
+ }
+ else
+ {
+ /*
+ * if (mLogger.isDebugEnabled()) { mLogger.debug("No match:
+ * "+href); }
+ */
+ }
+ }
+ mCurrentTag = tag;
+ }
+
+ /**
+ * Needed to handle SPAN tag.
+ */
+ public void handleSimpleTag(Tag tag, MutableAttributeSet atts, int pos)
+ {
+ if (mList.contains(tag) && mFound && mEnd == 0)
+ {
+ mEnd = pos;
+ }
+ else if (tag.equals(Tag.LINK))
+ {
+ // Look out for RSS autodiscovery link
+ String title = (String) atts.getAttribute(HTML.Attribute.TITLE);
+ String type = (String) atts.getAttribute(HTML.Attribute.TYPE);
+ if (title != null && type != null
+ && type.equals("application/rss+xml")
+ && title.equals("RSS"))
+ {
+ mRssLink = (String) atts.getAttribute(HTML.Attribute.HREF);
+
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Found RSS link " + mRssLink);
+ }
+
+ if (mRssLink.startsWith("/") && mRssLink.length() > 1)
+ {
+ try
+ {
+ URL url = new URL(mRefererURL);
+ mRssLink = url.getProtocol() + "://"
+ + url.getHost() + ":" + url.getPort()
+ + mRssLink;
+ }
+ catch (MalformedURLException e)
+ {
+ mRssLink = null;
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Determining RSS URL", e);
+ }
+ }
+ }
+ else if (!mRssLink.startsWith("http"))
+ {
+ int slash = mRefererURL.lastIndexOf("/");
+ if (slash != -1)
+ {
+ mRssLink = mRefererURL.substring(0, slash) + "/"
+ + mRssLink;
+ }
+ }
+ if (mLogger.isDebugEnabled())
+ {
+ mLogger.debug("Qualified RSS link is " + mRssLink);
+ }
+ }
+ }
+ }
+
+ /**
+ * Stop at the very first divider tag after the permalink.
+ *
+ * @param tag
+ * End tag
+ * @param pos
+ * Position in HTML file
+ */
+ public void handleEndTag(Tag tag, int pos)
+ {
+ if (mList.contains(tag) && mFound && mEnd == 0)
+ {
+ mEnd = pos;
+ }
+ else if (mList.contains(tag) && !mFound)
+ {
+ mStart = pos;
+ }
+ else
+ {
+ mCurrentTag = null;
+ }
+ }
+
+ /**
+ * Get the page title
+ */
+ public void handleText(char[] data, int pos)
+ {
+ if (mCurrentTag != null && mCurrentTag.equals(Tag.TITLE))
+ {
+ String newText = new String(data);
+ if (mTitle.length() < 50)
+ {
+ mTitle += newText;
+ }
+ }
+ }
+ }
+}
+
Added: incubator/roller/trunk/src/org/roller/util/LocaleComparator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/LocaleComparator.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/LocaleComparator.java (added)
+++ incubator/roller/trunk/src/org/roller/util/LocaleComparator.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,3 @@
+package org.roller.util;
import java.util.Locale;
import java.util.Comparator;
import java.io.Serializable;
public class LocaleComparator implements Comparator, Serializable
{
public int compare(Object obj1, Object obj2)
{
if (obj1 instanceof Locale && obj2 instanceof Locale)
{
Locale locale1 = (Locale)obj1;
Locale locale2 = (Locale)obj2;
int compName = locale1.getDisplayName().compareTo(locale2.getDisplayName());
if (compName == 0)
{
return locale1.toString().compareTo(locale2.toString());
}
return compName;
}
+ return 0;
}
/* Do Comparators need to implement equals()? -Lance
public boolean equals(Object obj)
{
if (obj instanceof LocaleComparator)
{
if (obj.equals(this)) return true;
}
return false;
}
*/
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/MD5Encoder.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/MD5Encoder.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/MD5Encoder.java (added)
+++ incubator/roller/trunk/src/org/roller/util/MD5Encoder.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * 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;
+
+
+/**
+ * Encode an MD5 digest into a String.
+ * <p>
+ * The 128 bit MD5 hash is converted into a 32 character long String.
+ * Each character of the String is the hexadecimal representation of 4 bits
+ * of the digest.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.1 $ $Date: 2005/06/01 19:51:22 $
+ */
+
+public final class MD5Encoder {
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ private static final char[] hexadecimal =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'};
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
+ *
+ * @param binaryData Array containing the digest
+ * @return Encoded MD5, or null if encoding failed
+ */
+ public String encode( byte[] binaryData ) {
+
+ if (binaryData.length != 16)
+ return null;
+
+ char[] buffer = new char[32];
+
+ for (int i=0; i<16; i++) {
+ int low = (int) (binaryData[i] & 0x0f);
+ int high = (int) ((binaryData[i] & 0xf0) >> 4);
+ buffer[i*2] = hexadecimal[high];
+ buffer[i*2 + 1] = hexadecimal[low];
+ }
+
+ return new String(buffer);
+
+ }
+
+
+}
+
Added: incubator/roller/trunk/src/org/roller/util/MailUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/MailUtil.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/MailUtil.java (added)
+++ incubator/roller/trunk/src/org/roller/util/MailUtil.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,298 @@
+package org.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;
+
+
+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);
+
+ // 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/src/org/roller/util/OldRollerConfig.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/OldRollerConfig.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/OldRollerConfig.java (added)
+++ incubator/roller/trunk/src/org/roller/util/OldRollerConfig.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1 @@
+package org.roller.util;
import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.betwixt.io.BeanReader;
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.roller.RollerException;
import org.roller.pojos.RollerConfigData;
import org.xml.sax.SAXException;
/**
* Configuration object for Roller. Reads and writes roller-config.xml.
* This file is a relic of the old days, back when we used to store the Roller
* configuration in an XML file. In Roller 0.9.9 and later, this file only
* exists to allow use to read only roller-config.xml files on startup and
* copy them into the database.
*/
public class OldRollerConfig implements java.io.Serializable
{
static final long serialVersionUID = -6625873343838437510L;
private static Log mLogger =
LogFactory.getFactory().getInstance( OldRollerConfig.class );
/**
* Absolute URL for site, for cases where infered absolute URL doesn't
* work.
*/
protected String mAbsoluteURL = null;
/** Should Roller cache return RSS pages. */
protected boolean mRssUseCache = false;
/** Duration to cache RSS pages (in seconds). */
protected int mRssCacheTime = 3000;
/** Does Roller allow the creation of new users. */
protected boolean mNewUserAllowed = false;
/** List of usernames with Admin priviledges. */
protected List mAdminUsers = new ArrayList();
/** Where to get data for creating new users (new-user.xml). */
protected String mNewUserData = "/templates";
/** Where to get Themes presented to new users. */
protected String mNewUserThemes = "/themes";
/** List of "editor pages" for the Weblog entry editor. */
protected List mEditorPages = new ArrayList();
/** Dis/enble RSS aggregation capabilities. */
protected boolean mEnableAggregator = false;
/** Are file uploads enabled. */
protected boolean mUploadEnabled = false;
/** The maximum size of each user's upload directory. */
protected Float mUploadMaxDirMB = new Float( "2" );
/** The maximum size allowed per uploaded file. */
protected Float mUploadMaxFileMB = new Float( ".5" );
/**
* List of permitted file extensions (not including the "dot"). This
* attribute is mutually exclusive with uploadForbid.
*/
protected List mUploadAllow = new ArrayList();
/**
* List of forbidden file extensions (not including the "dot"). This
* attribute is mutually exclusive with uploadAllow.
*/
protected List mUploadForbid = new ArrayList();
/**
* Directory where uploaded files will be stored. May end with a slash.
* Optional, this value will default to RollerContext.USER_RESOURCES. If
* specified, should be a full path on the system harddrive or relative to
* the WebApp.
*/
protected String mUploadDir = "";
/**
* The path from which the webserver will serve upload files. This values
* must not end in a slash.
*/
protected String uploadPath = "/resources";
protected boolean mMemDebug = false;
/**
* Determines if the Comment page will "autoformat" comments. That is,
* replace carriage-returns with <br />.
*/
protected boolean mAutoformatComments = false;
/** Determines if the Comment page will escape html in comments. */
protected boolean mEscapeCommentHtml = false;
/** Determines if e-mailing comments is enabled. */
protected boolean mEmailComments = false;
/** Enable linkback extraction. */
protected boolean mEnableLinkback = false;
/** Name of this site */
protected String mSiteName = "Roller-based Site";
/** Description of this site */
protected String mSiteDescription = "Roller-based Site";
/** Site administrator's email address */
protected String mEmailAddress = "";
/** Lucene index directory */
protected String mIndexDir =
"${user.home}" + File.separator + "roller-index";
/**
* Flag for encrypting passwords
*/
protected boolean mEncryptPasswords = false;
/** Algorithm for encrypting passwords */
protected String mAlgorithm = "SHA";
public OldRollerConfig()
{
}
public OldRollerConfig( RollerConfigData rConfig )
{
this.setAbsoluteURL( rConfig.getAbsoluteURL() );
this.setRssUseCache( rConfig.getRssUseCache().booleanValue() );
this.setRssCacheTime( rConfig.getRssCacheTime().intValue() );
this.setNewUserAllowed( rConfig.getNewUserAllowed().booleanValue() );
this.setNewUserThemes( rConfig.getUserThemes() );
this.setEditorPages( rConfig.getEditorPagesList() );
this.setEnableAggregator( rConfig.getEnableAggregator().booleanValue() );
this.setUploadEnabled( rConfig.getUploadEnabled().booleanValue() );
this.setUploadMaxDirMB( new Float( rConfig.getUploadMaxDirMB()
.doubleValue() ) );
this.setUploadMaxFileMB( new Float( rConfig.getUploadMaxFileMB()
.doubleValue() ) );
this.setUploadAllow( Arrays.asList( rConfig.uploadAllowArray() ) );
this.setUploadForbid( Arrays.asList( rConfig.uploadForbidArray() ) );
this.setUploadDir( rConfig.getUploadDir() );
this.setUploadPath( rConfig.getUploadPath() );
this.setMemDebug( rConfig.getMemDebug().booleanValue() );
this.setAutoformatComments( rConfig.getAutoformatComments()
.booleanValue() );
this.setEscapeCommentHtml( rConfig.getEscapeCommentHtml()
.booleanValue() );
this.setEmailComments( rConfig.getEmailComments().booleanValue() );
this.setEnableLinkback( rConfig.getEnableLinkback().booleanValue() );
this.setSiteName( rConfig.getSiteName() );
this.setSiteDescription( rConfig.getSiteDescription() );
this.setEmailAddress( rConfig.getEmailAddress() );
this.setIndexDir( rConfig.getIndexDir() );
this.setEncryptPasswords( rConfig.getEncryptPasswords().booleanValue() );
this.setAlgorithm( rConfig.getAlgorithm() );
}
//-------------------------------------- begin requisite getters & setters
public String getAbsoluteURL()
{
return mAbsoluteURL;
}
public void setAbsoluteURL( String string )
{
mAbsoluteURL = string;
}
public boolean getRssUseCache()
{
return mRssUseCache;
}
public void setRssUseCache( boolean use )
{
mRssUseCache = use;
}
public int getRssCacheTime()
{
return mRssCacheTime;
}
public void setRssCacheTime( int cacheTime )
{
mRssCacheTime = cacheTime;
}
public boolean getNewUserAllowed()
{
return mNewUserAllowed;
}
public void setNewUserAllowed( boolean use )
{
mNewUserAllowed = use;
}
public List getAdminUsers()
{
return mAdminUsers;
}
/**
* @param _adminUsers
*/
public void setAdminUsers( List _adminUsers )
{
mAdminUsers = _adminUsers;
}
/**
* @param ignore
*/
public void addAdminUsers( String ignore )
{
mAdminUsers.add( ignore );
}
public String getNewUserData()
{
return mNewUserData;
}
/**
* @param str
*/
public void setNewUserData( String str )
{
mNewUserData = str;
}
public String getNewUserThemes()
{
return mNewUserThemes;
}
/**
* @param str
*/
public void setNewUserThemes( String str )
{
mNewUserThemes = str;
}
public List getEditorPages()
{
return mEditorPages;
}
/**
* @param _editorPages
*/
public void setEditorPages( List _editorPages )
{
mEditorPages = _editorPages;
}
/**
* @param ignore
*/
public void addEditorPages( String ignore )
{
mEditorPages.add( ignore );
}
public boolean getEnableAggregator()
{
return mEnableAggregator;
}
public void setEnableAggregator( boolean use )
{
mEnableAggregator = use;
}
public boolean getUploadEnabled()
{
return mUploadEnabled;
}
public void setUploadEnabled( boolean use )
{
mUploadEnabled = use;
}
public Float getUploadMaxDirMB()
{
return mUploadMaxDirMB;
}
public void setUploadMaxDirMB( Float use )
{
mUploadMaxDirMB = use;
}
public Float getUploadMaxFileMB()
{
return mUploadMaxFileMB;
}
public void setUploadMaxFileMB( Float use )
{
mUploadMaxFileMB = use;
}
public List getUploadAllow()
{
return mUploadAllow;
}
/**
* @param _uploadAllow
*/
public void setUploadAllow( List _uploadAllow )
{
mUploadAllow = _uploadAllow;
}
/**
* @param ignore
*/
public void addUploadAllow( String ignore )
{
mUploadAllow.add( ignore );
}
public List getUploadForbid()
{
return mUploadForbid;
}
/**
* @param _uploadForbid
*/
public void setUploadForbid( List _uploadForbid )
{
mUploadForbid = _uploadForbid;
}
/**
* @param ignore
*/
public void addUploadForbid( String ignore )
{
mUploadForbid.add( ignore );
}
public String getUploadDir()
{
return mUploadDir;
}
/**
* @param str
*/
public void setUploadDir( String str )
{
mUploadDir = str;
}
public String getUploadPath()
{
return uploadPath;
}
/**
* @param str
*/
public void setUploadPath( String str )
{
uploadPath = str;
}
public boolean getMemDebug()
{
return mMemDebug;
}
/**
* Set memory debugging on or off.
*
* @param memDebug The mMemDebug to set
*/
public void setMemDebug( boolean memDebug )
{
mMemDebug = memDebug;
}
public boolean getAutoformatComments()
{
return mAutoformatComments;
}
/**
* @param value
*/
public void setAutoformatComments( boolean value )
{
mAutoformatComments = value;
}
public boolean getEscapeCommentHtml()
{
return mEscapeCommentHtml;
}
/**
* @param value
*/
public void setEscapeCommentHtml( boolean value )
{
mEscapeCommentHtml = value;
}
/**
* @return boolean
*/
public boolean getEmailComments()
{
return mEmailComments;
}
/**
* Sets the emailComments.
*
* @param emailComments The emailComments to set
*/
public void setEmailComments( boolean emailComments )
{
this.mEmailComments = emailComments;
}
/**
* Enable linkback.
*
* @return
*/
public boolean isEnableLinkback()
{
return mEnableLinkback;
}
/**
* Enable linkback.
*
* @param b
*/
public void setEnableLinkback( boolean b )
{
mEnableLinkback = b;
}
/**
* @return
*/
public String getSiteDescription()
{
return mSiteDescription;
}
/**
* @return
*/
public String getSiteName()
{
return mSiteName;
}
/**
* @param string
*/
public void setSiteDescription( String string )
{
mSiteDescription = string;
}
/**
* @param string
*/
public void setSiteName( String string )
{
mSiteName = string;
}
/**
* @return
*/
public String getEmailAddress()
{
return mEmailAddress;
}
/**
* @param emailAddress
*/
public void setEmailAddress( String emailAddress )
{
mEmailAddress = emailAddress;
}
/**
* @return the index directory
*/
public String getIndexDir()
{
return mIndexDir;
}
/**
* @param indexDir new index directory
*/
public void setIndexDir( String indexDir )
{
mIndexDir = indexDir;
}
public boolean getEncryptPasswords()
{
return mEncryptPasswords;
}
public void setEncryptPasswords( boolean use )
{
mEncryptPasswords = use;
}
/**
* @return the algorithm for encrypting passwords
*/
public String getAlgorithm()
{
return mAlgorithm;
}
/**
* @param algorithm, the new algorithm
*/
public void setAlgorithm( String algorithm )
{
mAlgorithm = algorithm;
}
//---------------------------------------- end requisite getters & setters
/**
* Convenience method for getAdminUsers.
*
* @return
*/
public String[] adminUsersArray()
{
if ( mAdminUsers == null )
{
mAdminUsers = new ArrayList();
}
return (String[]) mAdminUsers.toArray( new String[mAdminUsers.size()] );
}
/**
* Convenience method for getEditorPages.
*
* @return
*/
public String[] editorPagesArray()
{
if ( mEditorPages == null )
{
mEditorPages = new ArrayList();
}
return (String[]) mEditorPages.toArray( new String[mEditorPages.size()] );
}
/**
* Convenience method for getUploadAllow.
*
* @return
*/
public String[] uploadAllowArray()
{
if ( mUploadAllow == null )
{
mUploadAllow = new ArrayList();
}
return (String[]) mUploadAllow.toArray( new String[mUploadAllow.size()] );
}
/**
* Convenience method for getUploadForbid.
*
* @return
*/
public String[] uploadForbidArray()
{
if ( mUploadForbid == null )
{
mUploadForbid = new ArrayList();
}
return (String[]) mUploadForbid.toArray( new String[mUploadForbid.size()] );
}
public void updateValues( OldRollerConfig child )
{
this.mAbsoluteURL = child.getAbsoluteURL();
this.mRssUseCache = child.getRssUseCache();
this.mRssCacheTime = child.getRssCacheTime();
this.mNewUserAllowed = child.getNewUserAllowed();
this.mAdminUsers = child.getAdminUsers();
this.mNewUserData = child.getNewUserData();
this.mNewUserThemes = child.getNewUserThemes();
this.mEditorPages = child.getEditorPages();
this.mEnableAggregator = child.getEnableAggregator();
this.mUploadEnabled = child.getUploadEnabled();
this.mUploadMaxDirMB = child.getUploadMaxDirMB();
this.mUploadMaxFileMB = child.getUploadMaxFileMB();
this.mUploadAllow = child.getUploadAllow();
this.mUploadForbid = child.getUploadForbid();
this.mUploadDir = child.getUploadDir();
this.uploadPath = child.getUploadPath();
this.mMemDebug = child.getMemDebug();
this.mAutoformatComments = child.getAutoformatComments();
this.mEscapeCommentHtml = child.getEscapeCommentHtml();
this.mEmailComments = child.getEmailComments();
this.mEnableLinkback = child.isEnableLinkback();
this.mSiteName = child.getSiteName();
this.mSiteDescription = child.getSiteDescription();
this.mEmailAddress = child.getEmailAddress();
this.mIndexDir = child.getIndexDir();
this.mEncryptPasswords = child.getEncryptPasswords();
this.mAlgorithm = child.getAlgorithm();
}
/**
* nice output for debugging
*
* @return
*/
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append( "RollerConfig \n" );
Class clazz = getClass();
Field[] fields = clazz.getDeclaredFields();
try
{
AccessibleObject.setAccessible( fields, true );
for ( int i = 0; i < fields.length; i++ )
{
buf.append( "\t[" + fields[i].getName() + "=" +
fields[i].get( this ) + "], \n" );
}
}
catch ( Exception e )
{
// ignored!
}
return buf.toString();
}
/**
* Read the RollerConfig from a file, as specified by a String path.
*
* @param path
*
* @return
*/
public static OldRollerConfig readConfig( String path )
{
InputStream in = null;
try
{
in = new FileInputStream( path );
return OldRollerConfig.readConfig( in );
}
catch ( Exception e )
{
System.out.println( "Exception reading RollerConfig: " +
e.getMessage() );
}
finally
{
try
{
if ( in != null )
{
in.close();
}
}
catch ( java.io.IOException ioe )
{
System.err.println( "RollerConfig.writeConfig() unable to close InputStream" );
}
}
return new OldRollerConfig();
}
/**
* Read the RollerConfig from a file, as specified by an InputStream.
*
* @param in
*
* @return
*
* @throws RuntimeException
*/
public static OldRollerConfig readConfig( InputStream in )
{
try
{
BeanReader reader = new BeanReader();
reader.setDebug(99);
reader.registerBeanClass( OldRollerConfig.class );
return (OldRollerConfig) reader.parse( in );
}
catch ( IOException e )
{
throw new RuntimeException( "FATAL ERROR reading RollerConfig inputstream.",
e );
}
catch ( SAXException e )
{
throw new RuntimeException( "FATAL ERROR parsing RollerConfig, file is corrupted?",
e );
}
catch ( IntrospectionException e )
{
throw new RuntimeException( "FATAL ERROR introspecting RollerConfig bean.",
e );
}
}
/**
* Write RollerConfig to file, as specified by a String path.
*
* @param path
*
* @throws RollerException
*/
public void writeConfig( String path ) throws RollerException
{
FileOutputStream out = null;
try
{
out = new FileOutputStream( path );
writeConfig( out );
}
catch ( FileNotFoundException e )
{
throw new RollerException( "ERROR file not found: " + path, e );
}
finally
{
try
{
if ( out != null )
{
out.close();
}
}
catch ( java.io.IOException ioe )
{
System.err.println( "RollerConfig.writeConfig() unable to close OutputStream" );
}
}
}
/**
* Write RollerConfig to file, as specified by an OutputStream.
*
* @param out
*
* @throws RollerException
*/
public void writeConfig( OutputStream out ) throws RollerException
{
BeanWriter writer = new BeanWriter( out );
writer.enablePrettyPrint();
writer.setIndent( " " );
writer.setWriteIDs( false );
try
{
writer.write( this );
}
catch ( IOException e )
{
throw new RollerException( "ERROR writing to roller-config.xml stream.",
e );
}
catch ( SAXException e )
{
throw new RollerException( "ERROR writing to roller-config.xml stream.",
e );
}
catch ( IntrospectionException e )
{
throw new RollerException( "ERROR introspecting RollerConfig bean.",
e );
}
}
/**
* test stuff
*
* @param args
*/
public static void main( String[] args )
{
String basedir = System.getProperty( "basedir" );
String path = "build/roller/WEB-INF/roller-config.xml";
path = new java.io.File( basedir, path ).getAbsolutePath();
if ( ( args.length > 0 ) && args[0].equals( "read" ) )
{
OldRollerConfig.readConfig( path );
}
else if ( ( args.length > 0 ) && args[0].equals( "write" ) ) // write
{
path = "build/roller/WEB-INF/roller-config-test.xml";
path = new java.io.File( basedir, path ).getAbsolutePath();
OldRollerConfig bean = new OldRollerConfig();
try
{
bean.writeConfig( path );
}
catch ( Exception e )
{
mLogger.error( "Unexpected exception", e );
}
}
else // both
{
OldRollerConfig bean = OldRollerConfig.readConfig( path );
path = "build/roller/WEB-INF/roller-config-test.xml";
path = new java.io.File( basedir, path ).getAbsolutePath();
try
{
bean.writeConfig( path );
}
catch ( Exception e )
{
mLogger.error( "Unexpected exception", e );
}
}
System.out.println( "RollerConfig.main completed" );
}
}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/PojoUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/PojoUtil.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/PojoUtil.java (added)
+++ incubator/roller/trunk/src/org/roller/util/PojoUtil.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,26 @@
+package org.roller.util;
+
+/**
+ * This class contains helper methods
+ * for Roller pojos (only?)
+**/
+public abstract class PojoUtil
+{
+ public static boolean equals(boolean lEquals, Object a, Object b)
+ {
+ if (a == null)
+ {
+ lEquals = lEquals && (b == null);
+ }
+ else
+ {
+ lEquals = lEquals && a.equals(b);
+ }
+ return lEquals;
+ }
+
+ public static int addHashCode(int result, Object a)
+ {
+ return (37 * result) + ((a != null) ? a.hashCode() : 0);
+ }
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/roller/util/RandomGUID.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/util/RandomGUID.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/util/RandomGUID.java (added)
+++ incubator/roller/trunk/src/org/roller/util/RandomGUID.java Wed Jun 8 20:18:46 2005
@@ -0,0 +1,230 @@
+package org.roller.util;
+/*
+ * RandomGUID from http://www.javaexchange.com/aboutRandomGUID.html
+ * @version 1.2.1 11/05/02
+ * @author Marc A. Mnich
+ *
+ * From www.JavaExchange.com, Open Software licensing
+ *
+ * 11/05/02 -- Performance enhancement from Mike Dubman.
+ * Moved InetAddr.getLocal to static block. Mike has measured
+ * a 10 fold improvement in run time.
+ * 01/29/02 -- Bug fix: Improper seeding of nonsecure Random object
+ * caused duplicate GUIDs to be produced. Random object
+ * is now only created once per JVM.
+ * 01/19/02 -- Modified random seeding and added new constructor
+ * to allow secure random feature.
+ * 01/14/02 -- Added random function seeding with JVM run time
+ *
+ */
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Random;
+
+/*
+ * In the multitude of java GUID generators, I found none that
+ * guaranteed randomness. GUIDs are guaranteed to be globally unique
+ * by using ethernet MACs, IP addresses, time elements, and sequential
+ * numbers. GUIDs are not expected to be random and most often are
+ * easy/possible to guess given a sample from a given generator.
+ * SQL Server, for example generates GUID that are unique but
+ * sequencial within a given instance.
+ *
+ * GUIDs can be used as security devices to hide things such as
+ * files within a filesystem where listings are unavailable (e.g. files
+ * that are served up from a Web server with indexing turned off).
+ * This may be desireable in cases where standard authentication is not
+ * appropriate. In this scenario, the RandomGUIDs are used as directories.
+ * Another example is the use of GUIDs for primary keys in a database
+ * where you want to ensure that the keys are secret. Random GUIDs can
+ * then be used in a URL to prevent hackers (or users) from accessing
+ * records by guessing or simply by incrementing sequential numbers.
+ *
+ * There are many other possiblities of using GUIDs in the realm of
+ * security and encryption where the element of randomness is important.
+ * This class was written for these purposes but can also be used as a
+ * general purpose GUID generator as well.
+ *
+ * RandomGUID generates truly random GUIDs by using the system's
+ * IP address (name/IP), system time in milliseconds (as an integer),
+ * and a very large random number joined together in a single String
+ * that is passed through an MD5 hash. The IP address and system time
+ * make the MD5 seed globally unique and the random number guarantees
+ * that the generated GUIDs will have no discernable pattern and
+ * cannot be guessed given any number of previously generated GUIDs.
+ * It is generally not possible to access the seed information (IP, time,
+ * random number) from the resulting GUIDs as the MD5 hash algorithm
+ * provides one way encryption.
+ *
+ * ----> Security of RandomGUID: <-----
+ * RandomGUID can be called one of two ways -- with the basic java Random
+ * number generator or a cryptographically strong random generator
+ * (SecureRandom). The choice is offered because the secure random
+ * generator takes about 3.5 times longer to generate its random numbers
+ * and this performance hit may not be worth the added security
+ * especially considering the basic generator is seeded with a
+ * cryptographically strong random seed.
+ *
+ * Seeding the basic generator in this way effectively decouples
+ * the random numbers from the time component making it virtually impossible
+ * to predict the random number component even if one had absolute knowledge
+ * of the System time. Thanks to Ashutosh Narhari for the suggestion
+ * of using the static method to prime the basic random generator.
+ *
+ * Using the secure random option, this class compies with the statistical
+ * random number generator tests specified in FIPS 140-2, Security
+ * Requirements for Cryptographic Modules, secition 4.9.1.
+ *
+ * I converted all the pieces of the seed to a String before handing
+ * it over to the MD5 hash so that you could print it out to make
+ * sure it contains the data you expect to see and to give a nice
+ * warm fuzzy. If you need better performance, you may want to stick
+ * to byte[] arrays.
+ *
+ * I believe that it is important that the algorithm for
+ * generating random GUIDs be open for inspection and modification.
+ * This class is free for all uses.
+ *
+ *
+ * - Marc
+ */
+
+public class RandomGUID extends Object {
+
+ public String valueBeforeMD5 = "";
+ public String valueAfterMD5 = "";
+ private static Random myRand;
+ private static SecureRandom mySecureRand;
+
+ private static String s_id;
+
+ /*
+ * Static block to take care of one time secureRandom seed.
+ * It takes a few seconds to initialize SecureRandom. You might
+ * want to consider removing this static block or replacing
+ * it with a "time since first loaded" seed to reduce this time.
+ * This block will run only once per JVM instance.
+ */
+
+ static {
+ mySecureRand = new SecureRandom();
+ long secureInitializer = mySecureRand.nextLong();
+ myRand = new Random(secureInitializer);
+ try {
+ s_id = InetAddress.getLocalHost().toString();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ /*
+ * Default constructor. With no specification of security option,
+ * this constructor defaults to lower security, high performance.
+ */
+ public RandomGUID() {
+ getRandomGUID(false);
+ }
+
+ /*
+ * Constructor with security option. Setting secure true
+ * enables each random number generated to be cryptographically
+ * strong. Secure false defaults to the standard Random function seeded
+ * with a single cryptographically strong random number.
+ */
+ public RandomGUID(boolean secure) {
+ getRandomGUID(secure);
+ }
+
+ /*
+ * Method to generate the random GUID
+ */
+ private void getRandomGUID(boolean secure) {
+ MessageDigest md5 = null;
+ StringBuffer sbValueBeforeMD5 = new StringBuffer();
+
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Error: " + e);
+ }
+
+ try {
+ long time = System.currentTimeMillis();
+ long rand = 0;
+
+ if (secure) {
+ rand = mySecureRand.nextLong();
+ } else {
+ rand = myRand.nextLong();
+ }
+
+ // This StringBuffer can be a long as you need; the MD5
+ // hash will always return 128 bits. You can change
+ // the seed to include anything you want here.
+ // You could even stream a file through the MD5 making
+ // the odds of guessing it at least as great as that
+ // of guessing the contents of the file!
+ sbValueBeforeMD5.append(s_id);
+ sbValueBeforeMD5.append(":");
+ sbValueBeforeMD5.append(Long.toString(time));
+ sbValueBeforeMD5.append(":");
+ sbValueBeforeMD5.append(Long.toString(rand));
+
+ valueBeforeMD5 = sbValueBeforeMD5.toString();
+ md5.update(valueBeforeMD5.getBytes());
+
+ byte[] array = md5.digest();
+ StringBuffer sb = new StringBuffer();
+ for (int j = 0; j < array.length; ++j) {
+ int b = array[j] & 0xFF;
+ if (b < 0x10) sb.append('0');
+ sb.append(Integer.toHexString(b));
+ }
+
+ valueAfterMD5 = sb.toString();
+
+ } catch (Exception e) {
+ System.out.println("Error:" + e);
+ }
+ }
+
+
+ /*
+ * Convert to the standard format for GUID
+ * (Useful for SQL Server UniqueIdentifiers, etc.)
+ * Example: C2FEEEAC-CFCD-11D1-8B05-00600806D9B6
+ */
+ public String toString() {
+ String raw = valueAfterMD5.toUpperCase();
+ StringBuffer sb = new StringBuffer();
+ sb.append(raw.substring(0, 8));
+ sb.append("-");
+ sb.append(raw.substring(8, 12));
+ sb.append("-");
+ sb.append(raw.substring(12, 16));
+ sb.append("-");
+ sb.append(raw.substring(16, 20));
+ sb.append("-");
+ sb.append(raw.substring(20));
+
+ return sb.toString();
+ }
+
+ /*
+ * Demonstraton and self test of class
+ */
+ public static void main(String args[]) {
+ for (int i=0; i< 100; i++) {
+ RandomGUID myGUID = new RandomGUID();
+ System.out.println("Seeding String=" + myGUID.valueBeforeMD5);
+ System.out.println("rawGUID=" + myGUID.valueAfterMD5);
+ System.out.println("RandomGUID=" + myGUID.toString());
+ }
+ }
+}