You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2006/06/20 17:05:19 UTC

svn commit: r415691 [3/3] - in /incubator/roller/branches/roller_3.0: contrib/plugins/src/org/apache/roller/presentation/velocity/plugins/readmore/ metadata/database/ nbproject/ src/org/apache/roller/business/ src/org/apache/roller/business/hibernate/ ...

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/util/DateUtil.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/util/DateUtil.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/util/DateUtil.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/util/DateUtil.java Tue Jun 20 08:05:15 2006
@@ -1,18 +1 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-*  contributor license agreements.  The ASF licenses this file to You
-* under the Apache License, Version 2.0 (the "License"); you may not
-* use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.  For additional information regarding
-* copyright in this work, please see the NOTICE file in the top level
-* directory of this distribution.
-*/
-package org.apache.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 mFormat6chars = 
        new SimpleDateFormat("yyyyMM");

    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 Sim
 pleDateFormat("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 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 getEndOfMonth(Date day)
	{
		return getEndOfMonth(day,Calendar.getInstance());
	}
	public static Date getEndOfMonth(Date day,Calendar cal)
	{
		if (day == null) day = new Date();
		cal.setTime(da
 y);
        
        // set time to end of 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));
        
        // set time to first day of month
        cal.set(Calendar.DAY_OF_MONTH, 1);
        
        // add one month
        cal.add(Calendar.MONTH, 1);
        
        // back up one day
        cal.add(Calendar.DAY_OF_MONTH, -1);
        
        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("yyy
 y-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 get6charDateFormat()
    {
        return DateUtil.mFormat6chars;
    }

    //-----------------------------------------------------------------------
    // 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
+/*
* Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.  For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.roller.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util
 .Locale;
import org.apache.commons.lang.StringUtils;

/**
 * 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 mFormat6chars = 
        new SimpleDateFormat("yyyyMM");

    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 SimpleDateForma
 t("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(D
 ate 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 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 getEndOfMonth(Date day)
	{
		return getEndOfMonth(day,Calendar.getInstance());
	}
	public static Date getEndOfMonth(Date day,Calendar cal)
	{
		if (day == null) day = new Date();
		cal.setTime(day);
        
        // set time to end of 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));
        
        // set time to first day of month
        cal.set(Calendar.DAY_OF_MONTH, 1);
        
        // add one month
        cal.add(Calendar.MONTH, 1);
        
        // back up one day
        cal.add(Calendar.DAY_OF_MONTH, -1);
        
        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 n
 ull;
    }

    //-----------------------------------------------------------------------
    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.
    **/
    p
 ublic 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 st
 artDate 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");
    }

    //-----------------------------------------------------------------------
    // conveni
 ence 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 get6charDateFormat()
    {
        return DateUtil.mFormat6chars;
    }

    //-----------------------------------------------------------------------
    // 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 frie
 ndlyDate(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

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/util/LinkbackExtractor.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/util/LinkbackExtractor.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/util/LinkbackExtractor.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/util/LinkbackExtractor.java Tue Jun 20 08:05:15 2006
@@ -42,6 +42,7 @@
 import com.sun.syndication.feed.synd.SyndFeed;
 import com.sun.syndication.io.FeedException;
 import com.sun.syndication.io.SyndFeedInput;
+import org.apache.roller.util.Utilities;
 
 /**
  * Parses HTML file for referring linkback title and excerpt.

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/util/MailUtil.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/util/MailUtil.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/util/MailUtil.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/util/MailUtil.java Tue Jun 20 08:05:15 2006
@@ -28,7 +28,7 @@
 import javax.mail.Address;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
-
+import org.apache.commons.lang.StringUtils;
 
 public class MailUtil extends Object {
    

Propchange: incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/atomprotocol/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jun 20 08:05:15 2006
@@ -0,0 +1 @@
+.LCKRollerAtomHandler.java~

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/BloggerAPIHandler.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/BloggerAPIHandler.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/BloggerAPIHandler.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/BloggerAPIHandler.java Tue Jun 20 08:05:15 2006
@@ -27,24 +27,25 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
+
 import javax.servlet.http.HttpServletRequest;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.xmlrpc.XmlRpcException;
 import org.apache.roller.RollerException;
 import org.apache.roller.model.Roller;
 import org.apache.roller.model.RollerFactory;
 import org.apache.roller.model.UserManager;
 import org.apache.roller.model.WeblogManager;
-import org.apache.roller.pojos.WeblogTemplate;
 import org.apache.roller.pojos.UserData;
 import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WeblogTemplate;
 import org.apache.roller.pojos.WebsiteData;
 import org.apache.roller.ui.core.RollerContext;
 import org.apache.roller.ui.core.RollerRequest;
 import org.apache.roller.util.Utilities;
-
+import org.apache.xmlrpc.XmlRpcException;
 
 /**
  * Roller XML-RPC Handler for the Blogger v1 API.
@@ -395,7 +396,7 @@
                     content.indexOf("</title>"));
             content = StringUtils.replace(content, "<title>"+title+"</title>", "");
         }
-        if (Utilities.isEmpty(title)) { 
+        if (StringUtils.isEmpty(title)) { 
             title = Utilities.truncateNicely(content, 15, 15, "...");
         }
         
@@ -473,7 +474,7 @@
                         null,                   // startDate
                         new Date(),             // endDate
                         null,                   // catName
-                        null);
+                        null, 0, -1);
                 
                 Iterator iter = entries.values().iterator();
                 while (iter.hasNext()) {

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java Tue Jun 20 08:05:15 2006
@@ -20,18 +20,17 @@
 
 import java.io.ByteArrayInputStream;
 import java.sql.Timestamp;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Vector;
+
 import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.struts.util.RequestUtils;
-import org.apache.xmlrpc.XmlRpcException;
 import org.apache.roller.RollerException;
 import org.apache.roller.model.FileManager;
 import org.apache.roller.model.Roller;
@@ -45,7 +44,8 @@
 import org.apache.roller.ui.core.RollerRequest;
 import org.apache.roller.util.RollerMessages;
 import org.apache.roller.util.Utilities;
-
+import org.apache.struts.util.RequestUtils;
+import org.apache.xmlrpc.XmlRpcException;
 
 /**
  * Roller XML-RPC Handler for the MetaWeblog API.
@@ -225,11 +225,11 @@
         Hashtable postcontent = struct;
         String description = (String)postcontent.get("description");
         String title = (String)postcontent.get("title");
-        if (Utilities.isEmpty(title) && Utilities.isEmpty(description)) {
+        if (StringUtils.isEmpty(title) && StringUtils.isEmpty(description)) {
             throw new XmlRpcException(
               BLOGGERAPI_INCOMPLETE_POST, "Must specify title or description");
         }
-        if (Utilities.isEmpty(title)) { 
+        if (StringUtils.isEmpty(title)) { 
             title = Utilities.truncateNicely(description, 15, 15, "...");
         }
         
@@ -479,11 +479,11 @@
         struct.put("description", category.getPath());
         
         String catUrl = contextUrl+"/page/"+userid+"?catname="+category.getPath();
-        catUrl = Utilities.stringReplace(catUrl," ","%20");
+        catUrl = StringUtils.replace(catUrl," ","%20");
         struct.put("htmlUrl", catUrl);
         
         String rssUrl = contextUrl+"/rss/"+userid+"?catname="+category.getPath();
-        rssUrl = Utilities.stringReplace(catUrl," ","%20");
+        rssUrl = StringUtils.replace(catUrl," ","%20");
         struct.put("rssUrl",rssUrl);
         
         return struct;

Modified: incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/WeblogEntryTest.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/WeblogEntryTest.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/WeblogEntryTest.java (original)
+++ incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/WeblogEntryTest.java Tue Jun 20 08:05:15 2006
@@ -261,13 +261,13 @@
         
         // get object map
         entryMap = null;
-        entryMap = mgr.getWeblogEntryObjectMap(testWeblog, null, null, null, null);
+        entryMap = mgr.getWeblogEntryObjectMap(testWeblog, null, null, null, null, 0, -1);
         assertNotNull(entryMap);
         assertTrue(entryMap.keySet().size() > 1);
         
         // get string map
         entryMap = null;
-        entryMap = mgr.getWeblogEntryStringMap(testWeblog, null, null, null, null);
+        entryMap = mgr.getWeblogEntryStringMap(testWeblog, null, null, null, null, 0, -1);
         assertNotNull(entryMap);
         assertTrue(entryMap.keySet().size() > 1);
                 

Propchange: incubator/roller/branches/roller_3.0/tests/org/apache/roller/util/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jun 20 08:05:15 2006
@@ -0,0 +1 @@
+.LCKUtilitiesTest.java~

Modified: incubator/roller/branches/roller_3.0/tests/org/apache/roller/util/UtilitiesTest.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/tests/org/apache/roller/util/UtilitiesTest.java?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/tests/org/apache/roller/util/UtilitiesTest.java (original)
+++ incubator/roller/branches/roller_3.0/tests/org/apache/roller/util/UtilitiesTest.java Tue Jun 20 08:05:15 2006
@@ -20,11 +20,11 @@
  */
 package org.apache.roller.util;
 
-import org.apache.roller.ui.authoring.struts.actions.BookmarksActionTest;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
+import org.apache.roller.ui.rendering.model.UtilitiesPageHelper;
 
 /**
  * @author lance
@@ -96,12 +96,12 @@
     public void testAddNoFollow() {
         String test1 = "<p>this some text with a <a href=\"http://example.com\">link</a>";
         String expect1 = "<p>this some text with a <a href=\"http://example.com\" rel=\"nofollow\">link</a>";
-        String result1 = Utilities.addNofollow(test1);
+        String result1 = UtilitiesPageHelper.addNofollow(test1);
         assertEquals(expect1, result1);
 
         String test2 = "<p>this some text with a <A href=\"http://example.com\">link</a>";
         String expect2 = "<p>this some text with a <A href=\"http://example.com\" rel=\"nofollow\">link</a>";
-        String result2 = Utilities.addNofollow(test2);
+        String result2 = UtilitiesPageHelper.addNofollow(test2);
         assertEquals(expect2, result2);
 
     }

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties Tue Jun 20 08:05:15 2006
@@ -40,6 +40,7 @@
 # properties in this file are accessed like this ...
 #    RollerConfig.getProperty("propname");
 
+#---------------------------------
 # User management settings
 
 # True to enable group blogging. False to prevent users from creating more 
@@ -47,6 +48,15 @@
 groupblogging.enabled=true
 
 #---------------------------------
+# Front-page blog settings
+
+# Handle of weblog that is to serve as the main page of the site
+frontpage.weblog.handle=main
+
+# True if front page weblog feeds should be site-wide
+frontpage.weblog.aggregatedFeeds=true
+
+#---------------------------------
 # Property expansion settings
 
 # Values of the properties in this list get system property expansion 
@@ -67,14 +77,15 @@
 
 # Enables indexing of weblog entries and comments and enables search servlet
 search.enabled=true
+
 # Directory in which search index is to be created (delete this directory to
 # force Roller to recreate the entire search index)
 search.index.dir=${user.home}/roller_data/search-index
+
 # Whether or not to include comments in the search index.  If this
 # is false, comments are not included in the index.
 search.index.comments=true
 
-
 #----------------------------------
 # Rendering system settings.
 
@@ -84,6 +95,21 @@
 # The set of user defined renderer factories.  This is added to the list above.
 rendering.userRendererFactories=
 
+# Set of page models to be created for weblog rendering
+rendering.weblogPageModels=\
+org.apache.roller.ui.rendering.model.WeblogPageModel
+
+# Set of page models to be created for site-wide rendering
+rendering.sitePageModels=\
+org.apache.roller.ui.rendering.model.SitePageModel
+
+# Deprecated Roller 2.X page model configuration
+# Comment out this property to completely disable Roller 2.X page models
+velocity.pagemodel.classname=org.apache.roller.ui.rendering.velocity.deprecated.OldWeblogPageModel
+
+# Velocity settings
+velocity.properties=/WEB-INF/velocity.properties
+velocity.toolbox.file=/WEB-INF/toolbox.xml
 
 #----------------------------------
 # Cache settings.
@@ -193,27 +219,17 @@
 #org.apache.roller.ui.core.tasks.RefreshEntriesTask
 
 #----------------------------------
-# Velocity settings
-
-velocity.properties=/WEB-INF/velocity.properties
-velocity.toolbox.file=/WEB-INF/toolbox.xml
-
-# Page model implementation. You can plugin your own but it must 
-# must implement org.apache.roller.ui.rendering.velocity.PageModel
-velocity.pagemodel.classname=org.apache.roller.ui.rendering.velocity.deprecated.OldWeblogPageModel
-
-#----------------------------------
 # Persistence settings
 
 persistence.roller.classname=org.apache.roller.business.hibernate.HibernateRollerImpl
 persistence.filemanager.classname=org.apache.roller.business.FileManagerImpl
 
-# authenticator settings (experimental)
-authenticator.classname=org.apache.roller.ui.core.DefaultAuthenticator
-
 #----------------------------------
 # comment, referrer and trackback settings
 
+# comment authenticator settings (experimental)
+authenticator.classname=org.apache.roller.ui.core.DefaultAuthenticator
+
 comment.authenticator.classname=org.apache.roller.ui.rendering.util.MathCommentAuthenticator
 comment.notification.separateOwnerMessage=false
 comment.notification.hideCommenterAddresses=false
@@ -392,7 +408,7 @@
 webservices.adminprotocol.enabled=false
 
 #----------------------------------
-# legacy settings (thing that should be deprecated
+# legacy settings (things that should be deprecated)
 
 # settings for old #showNewseeds macro (not related to Planet stuff)
 aggregator.enabled=false

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/velocity.properties
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/velocity.properties?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/velocity.properties (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/velocity.properties Tue Jun 20 08:05:15 2006
@@ -52,7 +52,7 @@
 runtime.log.logsystem.log4j.category=org.apache.velocity
 
 # Override the default global library, set to blank to load no default
-velocimacro.library = deprecated/roller.vm,deprecated/bookmark.vm,deprecated/comments.vm,deprecated/navbar.vm,deprecated/newsfeed.vm,deprecated/referer.vm,deprecated/atommacros.vm,deprecated/rssmacros.vm,deprecated/user.vm,deprecated/weblog.vm,deprecated/website.vm
+velocimacro.library = weblog.vm,site.vm,deprecated/roller.vm,deprecated/bookmark.vm,deprecated/comments.vm,deprecated/navbar.vm,deprecated/newsfeed.vm,deprecated/referer.vm,deprecated/atommacros.vm,deprecated/rssmacros.vm,deprecated/user.vm,deprecated/weblog.vm,deprecated/website.vm
 
 # Change to false for deployment environments.
 # Caching for the 'class' & 'webapp' ResourceLoaders must be false for this to work

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/site.vm
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/site.vm?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/site.vm (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/site.vm Tue Jun 20 08:05:15 2006
@@ -1,6 +1,15 @@
 
-# macros for use with SitePageModel
+#** macros for use with SitePageModel
 
+   Contents
+      #showEntry($entry)
+      #showEnriesPager($entries $maxResults)
+      #showWeblogProfile($weblog)
+      #showWeblogDirectory()
+      #showUserProfile($user)
+      #showUserDirectory()
+      #showCommentsPager($comments $maxResults)
+*#
 ##-----------------------------------------------------------------------------
 #macro( showEntry $entry )
 <div class="entry">

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/weblog.vm
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/weblog.vm?rev=415691&r1=415690&r2=415691&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/weblog.vm (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/velocity/weblog.vm Tue Jun 20 08:05:15 2006
@@ -1,2 +1,483 @@
 
-# macros for use with WeblogPageModel
+#** macros for use with WeblogPageModel
+
+   Contents
+      #showWeblogEntryDayPager()
+      #showEntryText()
+      #showCommentForm()
+      #showTrackbackAutodiscoveryRDF()
+      #showAutodiscoveryLinks()
+      #showSearchForm()
+      #showSearchAgainForm()
+      #showSearchSummary()
+      #showSearchPager()
+      #showBookmarkList()
+      #showPageLinksList()
+      #showCategoryLinksList()
+      #showAuthorMenu()
+      #includePage()
+*#
+
+##-----------------------------------------------------------------------------
+#**
+ * Shows weblog entries from specified category using specified page as a "day 
+ * template" for the display of each day. The maxEntries argument is ignored
+ * because now the number of entries to display is controlled by the 
+ * entryDisplayCount property on the Preferences:Settings page.
+ * <p>
+ * This macro allows Roller to support five different types of blog displays:
+ * <p>
+ * Current day page<br />
+ *     /page/&lt;handle&gt;/<br>
+ * On the current day page, Roller will show the most recent N blog  
+ * entries (not just those for the day).
+ * At the end of the page, a previous link points to day page of entries  
+ * before the ones shown (and the link is displayed as the day's date).  
+ * This works exactly as before.
+ * <p>
+ * Day page<br>
+ *     /page/&lt;handle&gt;/YYYYMMDD<br>
+ * <p>On a day page, Roller will show all of the entries for a specific  
+ * day. At the end of the page, a next/previous link allows navigation  
+ * to next and previous day of entries (and the links are displayed as  
+ * the day's dates). Before, day pages always showed N entries (where  
+ * usually N=15), but now they'll show only a day's worth (e.g. 1-3  
+ * entries).
+ * <p>
+ * Month page<br>
+ *     /page/&lt;handle&gt;/YYYYMM<br>
+ * <p>On a month page, Roller will show the most recent N blog entries in  
+ * the month. At the end of the page, a previous link points to day page  
+ * of entries before the ones shown. This is new; we didn't have month  
+ * pages before.
+ * <p>
+ * Entry page<br>
+ *     /page/&lt;handle&gt;?entry=&lt;anchor&gt;<br>
+ * <p>On an entry page, one entry is shown. The next/prev links link to the  
+ * next and previous entries (and the links are displayed as the entry  
+ * titles, nicely truncated). This one also works exactly as before.
+ * <p>
+ * Search page<br>
+ *     /page/<handle>?q=<search terms><br>
+ * <p>If there are search results, then this macro will show them using the 
+ * current weblog's day template.
+ * <br>
+ *
+ * @param pageName   Page name of page to serve as day template.
+ * @param maxEntries (ignored)
+ * @param category   Only display weblog entries from this category.
+ *#
+#macro( showWeblogEntryDayPager $weblog $pageName $maxEntries $category)
+    #set($maxEntries = $website.entryDisplayCount)
+    #set($dayTemplateId = $pageModel.getPageIdByName($pageName))
+    #if(!$dayTemplateId ) ## if no page name, try Preview space
+        #set($dayTemplateId = $pageName)
+    #end
+    #if ($pageModel.weblogEntry)
+        <div class="top-next-prev">#showNextPreviousControl()</div>
+        #set($day = $entry.pubTime)
+        #set($entries = [$pageModel.weblogEntry])
+        #parse($dayTemplateId )
+        #if($trackbacksEnabled && $website.allowComments && $entry.commentsStillAllowed)
+           <div class="trackbackUrl">
+           $text.get("macro.weblog.trackback") #showTrackbackURL($entry)
+           </div>
+        #end
+        <div class="bottom-next-prev">#showNextPreviousControl()</div>
+        #showEntryLinkbacks($entry)
+        #showComments($entry)
+        #if($commentsEnabled && $website.allowComments && $entry.commentsStillAllowed)
+            #showCommentForm($entry)
+        #else
+            $text.get("comments.disabled")
+        #end
+    #else
+        #if($searchResults)
+            #set($map = $searchResults.results )
+            #showSearchAgainForm()
+            #showSearchSummary()
+            #foreach($day in $searchResults.results.keySet())
+                #set($entries = $searchResults.results.get($day))
+                #parse($dayTemplateId)
+            #end
+            #showSearchPager()
+        #else
+            #set($map = $pageModel.getRecentWeblogEntries($maxEntries, $category))
+            #if($map.size() == 0)
+               $text.get("macro.weblog.noEntriesForDate")
+            #else               
+               #foreach($day in $map.keySet())
+                   #set($entries = $map.get($day))
+                   #parse($dayTemplateId)
+               #end
+            #end
+            <div class="bottom-next-prev">#showNextPreviousControl()</div>
+        #end
+    #end
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Use this to show entry summary or text as appropriate on your blog pages.
+ * On single-entry pages, text is prefered. Everywhere else, summary is 
+ * preferred. Also, applies all plugins configured by entry.
+ *#
+#macro( showEntryText $entry )
+   #if( $entryPage )
+      #parse($entryPage.id)
+   #else
+      #if( $pageModel.weblogEntry) 
+          ## on single-entry pages, we prefer text
+          #if( $utilities.isNotEmpty($entry.text) )
+              #set( $sourceText = $entry.text )
+          #else 
+              #set( $sourceText = $entry.summary )
+          #end
+      #else
+          ## on multi-entry pages, we prefer summary
+          #if( $utilities.isNotEmpty($entry.summary) )
+              #set( $sourceText = $entry.summary )
+              #if( $utilities.isNotEmpty($entry.text) )
+                 #set( $readMore = "<a class='readmore' href='$entry.permaLink'> ...</a>" )
+                 #set( $sourceText = "$sourceText$readMore")
+              #end
+          #else 
+              #set( $sourceText = $entry.text )
+          #end
+      #end
+      #if( $entry.plugins )
+         #set( $displayText = $pageHelper.renderPlugins($entry, $sourceText) )
+      #else
+         #set( $displayText = $sourceText )
+      #end
+      $utilities.textToCDATA($displayText)
+   #end
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Display comment form for a weblog entry.
+ * @param entry WeblogEntry object for which form is to be shown.
+ *#
+#macro( showCommentForm $entry )
+    <div class="comments-form">
+    <div class="comments-head">$text.get("macro.weblog.postcommentHeader")</div><br/>
+
+    #showStatusMessage()
+
+    <form method="post" action="$ctxPath/comment" focus="name"
+        name="form" onsubmit="fixURL(this); return validateComments(this)">
+        
+        #if($requestParameters.popup)
+        <input type="hidden" name="popup" value="true" />
+        #end
+
+        <!-- is this a post or a preview -->
+        <input type="hidden" name="method" value="post" />
+        <input type="hidden" name="entryid" value="$entry.id" />
+
+        <table cellspacing="0" cellpadding="1" border="0" width="95%">
+        <tr><th>$text.get( "macro.weblog.name" )</th>
+            <td><input type="text" name="name" value="$commentForm.name" size="50" maxlength="255" /></td>
+        </tr>
+
+        <tr><th>$text.get( "macro.weblog.email" )</th>
+            <td><input type="text" name="email" value="$commentForm.email" size="50" maxlength="255" /></td>
+        </tr>
+
+        <tr><th>$text.get( "macro.weblog.url" )</th>
+            <td><input type="text" name="url" value="$commentForm.url" size="50" maxlength="255" /></td>
+        </tr>
+        #if ($pageModel.emailComments)
+        <tr>
+            <td></td>
+            <td>
+                <input type="checkbox" id="notify" name="notify" />
+                <label for="notify">$text.get( "macro.weblog.notifyMeOfComments" )</label>
+            </td>
+        </tr>
+        #end
+        <tr>
+            <td></td>
+            <td>
+                <input type="checkbox" id="rememberInfo" name="rememberInfo" />
+                <label for="rememberInfo">$text.get( "macro.weblog.rememberinfo" )</label>
+            </td>
+        </tr>
+        </table>
+        <br/>
+
+        <table>
+        <tr><th style="text-align: left">$text.get( "macro.weblog.yourcomment" )</th></tr>
+        <tr>
+            <td>
+            <textarea name="content" cols="50" rows="10">$commentForm.content</textarea><br />
+            <span class="comments-syntax-indicator">
+            $text.get( "macro.weblog.htmlsyntax" )
+            #if( $escapeHtml )
+                <span class="disabled">$text.get( "macro.weblog.htmldisabled" )</span>
+            #else
+                <span class="enabled">$text.get( "macro.weblog.htmlenabled" )</span>
+            #end
+            </span>
+            </td>
+        </tr>
+        </table>
+        
+        <script type="text/javascript" src="$ctxPath/theme/scripts/clientSideInclude.js"></script>
+        <div id="commentAuthenticator"></div>
+ 
+        <table cellspacing="0" cellpadding="1" border="0" width="95%">
+        <tr>
+            <td align="left" nowrap="nowrap">
+               <input type="button" name="post" value="&nbsp;$text.get( "macro.weblog.preview" )&nbsp;"
+                  onClick="this.form.method.value='preview';this.form.submit()" />
+               <input type="submit" name="post" value="&nbsp;$text.get( "macro.weblog.post" )&nbsp;" />
+            </td>
+            <td align="right">
+               <!-- <input type="button" value="&nbsp;$text.get( "macro.weblog.clear" )&nbsp;" /> -->
+            </td>
+        </tr>
+        </table>
+
+    </form>
+
+    <script type="text/javascript" src="$ctxPath/theme/scripts/roller.js"></script>
+    <script type="text/javascript">
+    clientSideInclude('commentAuthenticator', '$ctxPath/CommentAuthenticatorServlet');
+
+    var author = getCookie("commentAuthor");
+    var email = getCookie("commentEmail");
+    var url = getCookie("commentUrl");
+    // check each field - IE will render "null"
+    if (author) {
+        document.form.name.value = author;
+    }
+    if (email) {
+        document.form.email.value = email;
+    }
+    if (url) {
+        document.form.url.value = url;
+    }
+
+    if (author || email || url) {
+        document.form.rememberInfo.checked = true;
+    }
+
+    function fixURL(theForm) {
+        if (theForm.url.value != "" &&
+            theForm.url.value.indexOf("http://") == -1) { //prepend http://
+            theForm.url.value = "http://"+theForm.url.value;
+        }
+        saveUserInformation(theForm);
+    }
+
+    function saveUserInformation(theForm) {
+        if (theForm.rememberInfo.checked) {
+            rememberUser(theForm);
+        } else {
+            forgetUser(theForm);
+        }
+    }
+
+    function validateComments(theForm) {
+        if (theForm.content.value == "") {
+            alert("$text.get( "macro.weblog.commentwarning" )");
+            theForm.content.focus();
+            return false;
+        }
+    }
+    </script>
+    </div>
+#end
+
+
+##-----------------------------------------------------------------------------
+#**
+ * Display a trackback auto-discovery comment for a WeblogEntry.
+ **#
+#macro( showTrackbackAutodiscovery $entry )
+<!--
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
+         xmlns:dc="http://purl.org/dc/elements/1.1/">
+<rdf:Description
+    rdf:about="$entry.permaLink"
+    trackback:ping="#showTrackbackURL($entry)"
+    dc:title="$entry.title"
+    dc:identifier="$entry.permaLink"
+    dc:subject="$entry.category.name"
+    dc:description="$entry.title"
+    dc:creator="$entry.creator.userName"
+    dc:date="$entry.pubTime" />
+</rdf:RDF>
+-->
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Show autodiscovery links for feeds and publishing end-points.
+ *#
+#macro( showAutodiscoveryLinks $weblog )
+    <link rel="alternate" type="application/rss+xml"
+        title="RSS" href="$absBaseURL/rss/${website.handle}" />
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Display search form for searching a weblog.  This is only a form, no div
+ * or anything around it.
+ *#
+#macro( showSearchForm )
+    <form id="searchForm" method="get" action="${ctxPath}/search/${website.handle}"
+        style="margin: 0; padding: 0" onsubmit="return validateSearch(this)">
+        <p>
+          <input type="text" id="q" name="q" size="20"
+              maxlength="255" value="#if($term)$term#end" />
+          #set( $cats = $pageModel.getWeblogCategories("nil") )
+          <select name="c">
+          <option value="">- In Category -</option>
+          #foreach( $cat in $cats )
+              <option #if($cat.name == $req.getParameter('c'))selected="selected"#end>$cat.name</option>
+          #end
+          </select>
+          <input type="submit" value="$text.get( "macro.weblog.searchbutton" )" />
+        </p>
+    </form>
+    <script type="text/javascript">
+        function validateSearch(form) {
+            if (form.q.value == "") {
+                alert("$text.get( "macro.weblog.searchalert" )");
+                form.q.focus();
+                return false;
+            }
+            return true;
+        }
+    </script>
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Display search form for searching a weblog.  This is only a form, no div
+ * or anything around it.
+ *#
+#macro( showSearchForm )
+    <form id="searchForm" method="get" action="${ctxPath}/search/${website.handle}"
+        style="margin: 0; padding: 0" onsubmit="return validateSearch(this)">
+        <p>
+          <input type="text" id="q" name="q" size="20"
+              maxlength="255" value="#if($term)$term#end" />
+          #set( $cats = $pageModel.getWeblogCategories("nil") )
+          <select name="c">
+          <option value="">- In Category -</option>
+          #foreach( $cat in $cats )
+              <option #if($cat.name == $req.getParameter('c'))selected="selected"#end>$cat.name</option>
+          #end
+          </select>
+          <input type="submit" value="$text.get( "macro.weblog.searchbutton" )" />
+        </p>
+    </form>
+    <script type="text/javascript">
+        function validateSearch(form) {
+            if (form.q.value == "") {
+                alert("$text.get( "macro.weblog.searchalert" )");
+                form.q.focus();
+                return false;
+            }
+            return true;
+        }
+    </script>
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Display search again form
+ *#
+#macro( showSearchAgainForm )
+    <div id="searchAgain">
+        $text.get( "macro.weblog.searchdictionary", [$searchResults.term, $searchResults.term, $searchResults.term] )
+
+        $text.get( "macro.weblog.searchhits", [$searchResults.hits])
+
+        <form method="get" action="${ctxPath}/search/${website.handle}"
+            style="margin: 5px">
+            <input type="text" id="q" name="q" size="31"
+                maxlength="255" value="$searchResults.term"
+                style="padding-left: 1px" /><br />
+            #set( $cats = $pageModel.getWeblogCategories("nil") )
+            <select name="c">
+            <option value="">- Restrict By Category -</option>
+            #foreach( $cat in $cats )
+              <option #if($cat.name == $req.getParameter('c'))selected="selected"#end>$cat.name</option>
+            #end
+            </select>
+            <input type="submit" value="$text.get( "macro.weblog.searchagain" )" />
+        </form>
+
+        $text.get( "macro.weblog.searchgoogle", [$searchResults.term, $absBaseURL, $ctxPath, ${website.handle}] )
+    </div>
+    <!-- searchhi script hangs firefox, commenting it out for now -->
+    <!-- script type="text/javascript" src="$ctxPath/theme/scripts/searchhi.js"></script -->
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Displays header like "1 - 10 of 20 found.".
+**#
+#macro( showSearchSummary )
+    #set( $min = $searchResults.offset + 1 )
+    #set( $max = $searchResults.offset + $searchResults.limit )
+    #if( $max > $searchResults.hits )#set( $max = $searchResults.hits )#end
+    <h3>
+        $min - $max of $searchResults.hits found.
+    </h3>
+#end
+
+##-----------------------------------------------------------------------------
+#**
+ * Display list of search result pages (for pagination).
+**#
+#macro( showSearchPager )
+    <h3 style="text-align:center;">
+    #set( $numPages = $searchResults.hits / $searchResults.limit )
+    #set( $remainder = $searchResults.hits % $searchResults.limit )
+    #if( $remainder > 0 )#set( $numPages = $numPages + 1 )#end
+    #if( $numPages > 1 )
+        #foreach( $pageNum in [1..$numPages] )
+            #set( $i = $pageNum - 1 )
+            #set( $start = $searchResults.limit * $i )
+            <a href="?q=${utilities.encode($searchResults.term)}&${USERNAME_KEY}=$!{username}&n=${searchResults.limit}&o=${start}"
+               >$pageNum</a>#if( $pageNum != $numPages) | #end
+        #end
+    #end
+    </h3>
+#end
+
+##-----------------------------------------------------------------------------
+
+#macro( showBookmarkList $weblog )
+#end
+
+##-----------------------------------------------------------------------------
+
+#macro( showPageLinksList $weblog )
+#end
+
+##-----------------------------------------------------------------------------
+
+#macro( showCategoryLinksList $weblog )
+#end
+
+##-----------------------------------------------------------------------------
+
+#macro( showAuthorMenu $weblog )
+#end
+
+##-----------------------------------------------------------------------------
+
+#macro( includePage $pageName )
+#end
+
+
+
+