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 [27/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/pojos/WeblogEntryData.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/WeblogEntryData.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/WeblogEntryData.java (added)
+++ incubator/roller/trunk/src/org/roller/pojos/WeblogEntryData.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,1012 @@
+
+package org.roller.pojos;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.WeblogManager;
+import org.roller.util.DateUtil;
+import org.roller.util.Utilities;
+
+import sun.security.krb5.internal.i;
+
+
+/**
+ * Represents a Weblog Entry.
+ * 
+ * @author David M Johnson
+ *
+ * @ejb:bean name="WeblogEntryData"
+ * @struts.form include-all="true"
+ * @hibernate.class table="weblogentry"
+ * hibernate.jcs-cache usage="read-write"
+ */
+public class WeblogEntryData extends org.roller.pojos.PersistentObject
+    implements java.io.Serializable
+{
+    private static Log mLogger = LogFactory.getFactory()
+                                           .getInstance(WeblogEntryData.class);
+                                           
+    static final long serialVersionUID = 2341505386843044125L;
+    
+    protected String id=null;
+    protected org.roller.pojos.WeblogCategoryData category=null;
+    protected String title=null;
+    protected String link=null;
+    protected String text=null;
+    protected String anchor=null;
+    protected Timestamp pubTime=null;
+    protected Timestamp updateTime=null;
+    protected Boolean publishEntry=null;
+    protected WebsiteData mWebsite=null;
+    protected String mPlugins;
+    protected Boolean allowComments = Boolean.TRUE;
+    protected Integer commentDays = new Integer(7);
+    protected Boolean rightToLeft = Boolean.FALSE;
+    protected Boolean pinnedToMain = Boolean.FALSE;
+    
+    private Map attMap = new HashMap();
+    private Set attSet = new TreeSet();
+    
+    //----------------------------------------------------------- Construction
+
+    public WeblogEntryData()
+    {
+    }
+
+    public WeblogEntryData(
+       java.lang.String id, 
+       org.roller.pojos.WeblogCategoryData category, 
+       WebsiteData website, 
+       java.lang.String title, 
+       java.lang.String link,
+       java.lang.String text, 
+       java.lang.String anchor, 
+       java.sql.Timestamp pubTime, 
+       java.sql.Timestamp updateTime, 
+       java.lang.Boolean publishEntry)
+    {
+        this.id = id;
+        this.category = category;
+        this.mWebsite = website;
+        this.title = title;
+        this.link = link;
+        this.text = text;
+        this.anchor = anchor;
+        this.pubTime = pubTime;
+        this.updateTime = updateTime;
+        this.publishEntry = publishEntry;
+    }
+
+    public WeblogEntryData(WeblogEntryData otherData)
+    {
+        setData(otherData);
+    }
+
+    //---------------------------------------------------------- Initializaion
+
+    /**
+     * Setter is needed in RollerImpl.storePersistentObject()
+     */
+    public void setData(org.roller.pojos.PersistentObject otherData)
+    {
+        WeblogEntryData other = (WeblogEntryData)otherData;
+        this.id = other.id;
+        this.category = other.category;
+        this.mWebsite = other.mWebsite;
+        this.title = other.title;
+        this.link = other.link;
+        this.text = other.text;
+        this.anchor = other.anchor;
+        this.pubTime = other.pubTime;
+        this.updateTime = other.updateTime;
+        this.publishEntry = other.publishEntry;
+        this.mPlugins = other.mPlugins;
+        this.allowComments = other.allowComments;
+        this.commentDays = other.commentDays;
+        this.rightToLeft = other.rightToLeft;
+        this.pinnedToMain = other.pinnedToMain;
+    }
+
+    //------------------------------------------------------ Simple properties
+    
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.id column="id" type="string"
+     *  generator-class="uuid.hex" unsaved-value="null"
+     */
+    public java.lang.String getId()
+    {
+        return this.id;
+    }
+
+    /** @ejb:persistent-field */
+    public void setId(java.lang.String id)
+    {
+        this.id = id;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.many-to-one column="categoryid" cascade="none" not-null="true"
+     */
+    public org.roller.pojos.WeblogCategoryData getCategory()
+    {
+        return this.category;
+    }
+
+    /** @ejb:persistent-field */
+    public void setCategory(org.roller.pojos.WeblogCategoryData category)
+    {
+        this.category = category;
+    }
+
+    /**
+     * Set weblog category via weblog category ID.
+     * @param id Weblog category ID.
+     */
+    public void setCategoryId(String id) throws RollerException
+    {
+        WeblogManager wmgr = RollerFactory.getRoller().getWeblogManager();
+        setCategory(wmgr.retrieveWeblogCategory(id));
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.many-to-one column="websiteid" cascade="none" not-null="true"
+     */
+    public WebsiteData getWebsite()
+    {
+        return this.mWebsite;
+    }
+
+    /** @ejb:persistent-field */
+    public void setWebsite(WebsiteData website)
+    {
+        this.mWebsite = website;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.property column="title" non-null="true" unique="false"
+     */
+    public java.lang.String getTitle()
+    {
+        return this.title;
+    }
+
+    /** @ejb:persistent-field */
+    public void setTitle(java.lang.String title)
+    {
+        this.title = title;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.property column="text" non-null="true" unique="false"
+     */
+    public java.lang.String getText()
+    {
+        return this.text;
+    }
+
+    /** @ejb:persistent-field */
+    public void setText(java.lang.String text)
+    {
+        this.text = text;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.property column="anchor" non-null="true" unique="false"
+     */
+    public java.lang.String getAnchor()
+    {
+        return this.anchor;
+    }
+
+    /** @ejb:persistent-field */
+    public void setAnchor(java.lang.String anchor)
+    {
+        this.anchor = anchor;
+    }
+
+    //-------------------------------------------------------------------------
+    /** 
+     * Map attributes as set because XDoclet 1.2b4 map support is broken. 
+     * @ejb:persistent-field
+     * @hibernate.set lazy="true" order-by="name" inverse="true" cascade="all" 
+     * @hibernate.collection-key column="entryid" type="String"
+     * @hibernate.collection-one-to-many class="org.roller.pojos.EntryAttributeData"
+     */
+    public Set getEntryAttributes()    
+    {
+        return attSet;
+    }
+    /** @ejb:persistent-field */
+    public void setEntryAttributes(Set attSet)
+    {
+        this.attSet = attSet;
+        
+        // copy set to map
+        if (attSet != null)
+        {
+            this.attSet = attSet;
+            this.attMap = new HashMap();
+            Iterator iter = this.attSet.iterator();
+            while (iter.hasNext()) 
+            {
+                EntryAttributeData att = (EntryAttributeData)iter.next();
+                attMap.put(att.getName(), att);
+            }
+        }
+        else 
+        {
+            this.attSet = new TreeSet();
+            this.attMap = new HashMap();
+        }
+    }
+    /** Would be named getEntryAttribute, but that would set off XDoclet */
+    public String findEntryAttribute(String name)
+    {
+        EntryAttributeData att = ((EntryAttributeData)attMap.get(name));
+        return (att != null) ? att.getValue() : null;
+    }
+    public void putEntryAttribute(String name, String value) throws Exception
+    {
+        EntryAttributeData att = (EntryAttributeData)attMap.get(name);
+        if (att == null) 
+        {
+            att = new EntryAttributeData();
+            att.setEntry(this);
+            att.setName(name);
+            att.setValue(value);
+            attMap.put(name, att);    
+            attSet.add(att);
+        }
+        else 
+        {
+            att.setValue(value);
+        }
+    }
+    public void removeEntryAttribute(String name) throws RollerException
+    {
+        EntryAttributeData att = (EntryAttributeData)attMap.get(name);
+        if (att != null) 
+        {
+            attMap.remove(att);
+            attSet.remove(att);
+            att.remove();
+        }
+    }
+    //-------------------------------------------------------------------------
+    
+    /**  
+     * <p>Publish time is the time that an entry is to be (or was) made available
+     * for viewing by newsfeed readers and visitors to the Roller site.</p> 
+     * 
+     * <p>Roller stores time using the timezone of the server itself. When
+     * times are displayed  in a user's weblog they must be translated 
+     * to the user's timezone.</p>
+     *
+     * <p>NOTE: Times are stored using the SQL TIMESTAMP datatype, which on 
+     * MySQL has only a one-second resolution.</p>
+     *
+     * @ejb:persistent-field 
+     * @hibernate.property column="pubtime" non-null="true" unique="false"
+     */
+    public java.sql.Timestamp getPubTime()
+    {
+        return this.pubTime;
+    }
+
+    /** @ejb:persistent-field */
+    public void setPubTime(java.sql.Timestamp pubTime)
+    {
+        this.pubTime = pubTime;
+    }
+
+    /** 
+     * <p>Update time is the last time that an weblog entry was saved in the 
+     * Roller weblog editor or via web services API (XML-RPC or Atom).</p> 
+     *
+     * <p>Roller stores time using the timezone of the server itself. When
+     * times are displayed  in a user's weblog they must be translated 
+     * to the user's timezone.</p>
+     *
+     * <p>NOTE: Times are stored using the SQL TIMESTAMP datatype, which on 
+     * MySQL has only a one-second resolution.</p>
+     *
+     * @ejb:persistent-field 
+     * @hibernate.property column="updatetime" non-null="true" unique="false"
+     */
+    public java.sql.Timestamp getUpdateTime()
+    {
+        return this.updateTime;
+    }
+
+    /** @ejb:persistent-field */
+    public void setUpdateTime(java.sql.Timestamp updateTime)
+    {
+        this.updateTime = updateTime;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     * @hibernate.property column="publishentry" non-null="true" unique="false"
+     */
+    public java.lang.Boolean getPublishEntry()
+    {
+        return this.publishEntry;
+    }
+
+    /** @ejb:persistent-field */
+    public void setPublishEntry(java.lang.Boolean publishEntry)
+    {
+        this.publishEntry = publishEntry;
+    }
+
+    /**
+     * Some weblog entries are about one specific link.
+     * @return Returns the link.
+     *
+     * @ejb:persistent-field 
+     * @hibernate.property column="link" non-null="false" unique="false"
+     */
+    public java.lang.String getLink()
+    {
+        return link;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @param link The link to set.
+     */
+    public void setLink(java.lang.String link)
+    {
+        this.link = link;
+    }
+
+    /**
+     * Comma-delimited list of this entry's Plugins.
+     * @ejb:persistent-field
+     * @hibernate.property column="plugins" non-null="false" unique="false"
+     */
+    public java.lang.String getPlugins()
+    {
+        return mPlugins;
+    }
+
+    /** @ejb:persistent-field */
+    public void setPlugins(java.lang.String string)
+    {
+        mPlugins = string;
+    }
+
+    
+	/**
+	 * True if comments are allowed on this weblog entry.
+     * @ejb:persistent-field 
+     * @hibernate.property column="allowcomments" non-null="true" unique="false"
+	 */
+	public Boolean getAllowComments() {
+		return allowComments;
+	}
+	/**
+	 * True if comments are allowed on this weblog entry.
+     * @ejb:persistent-field 
+	 */
+	public void setAllowComments(Boolean allowComments) {
+		this.allowComments = allowComments;
+	}
+	
+	/**
+	 * Number of days after pubTime that comments should be allowed, or 0 for no limit.
+     * @ejb:persistent-field 
+     * @hibernate.property column="commentdays" non-null="true" unique="false"
+	 */
+	public Integer getCommentDays() {
+		return commentDays;
+	}
+	/**
+	 * Number of days after pubTime that comments should be allowed, or 0 for no limit.
+     * @ejb:persistent-field 
+	 */
+	public void setCommentDays(Integer commentDays) {
+		this.commentDays = commentDays;
+	}
+	
+	/**
+	 * True if this entry should be rendered right to left.
+     * @ejb:persistent-field 
+     * @hibernate.property column="righttoleft" non-null="true" unique="false"
+	 */
+	public Boolean getRightToLeft() {
+		return rightToLeft;
+	}
+	/**
+	 * True if this entry should be rendered right to left.
+     * @ejb:persistent-field 
+	 */
+	public void setRightToLeft(Boolean rightToLeft) {
+		this.rightToLeft = rightToLeft;
+	}
+
+    /**
+     * True if story should be pinned to the top of the Roller site main blog.
+     * @return Returns the pinned.
+     * 
+     * @ejb:persistent-field 
+     * @hibernate.property column="pinnedtomain" non-null="true" unique="false"
+     */
+    public Boolean getPinnedToMain()
+    {
+        return pinnedToMain;
+    }
+    /**
+     * True if story should be pinned to the top of the Roller site main blog.
+     * @param pinnedToMain The pinned to set.
+     * 
+     * @ejb:persistent-field 
+     */
+    public void setPinnedToMain(Boolean pinnedToMain)
+    {
+        this.pinnedToMain = pinnedToMain;
+    }
+
+    //------------------------------------------------------------------------
+
+    /**
+     * Save the entry and queue applicable web log update pings if the entry is published.
+     * @see org.roller.pojos.PersistentObject#save()
+     */
+    public void save() throws RollerException
+    {
+        // If no anchor then create one
+        if (getAnchor()==null || getAnchor().trim().equals(""))
+        {
+            setAnchor(createAnchor());
+        }
+        if (getPublishEntry() != null && getPublishEntry().booleanValue()) {
+            // Queue applicable pings for this update.
+            RollerFactory.getRoller().getAutopingManager().queueApplicableAutoPings(this);
+        }
+        super.save();
+    }
+    
+    //------------------------------------------------------------------------
+    
+    /** 
+     * True if comments are still allowed on this entry considering the 
+     * allowComments and commentDays fields. 
+     */
+    public boolean getCommentsStillAllowed() 
+    {
+    		boolean ret = false;
+    		if (getAllowComments() == null || getAllowComments().booleanValue()) 
+    		{
+    			if (getCommentDays() == null || getCommentDays().intValue() == 0)
+    			{
+    				ret = true;
+    			}
+    			else 
+    			{
+    				Calendar expireCal = Calendar.getInstance(getWebsite().getLocaleInstance());
+    				expireCal.setTime(getPubTime());
+    				expireCal.add(Calendar.DATE, getCommentDays().intValue());
+    				Date expireDay = expireCal.getTime();
+    				Date today = new Date();
+    				if (today.before(expireDay))
+    				{
+    					ret = true;
+    				}
+    			}
+    		}
+    		return ret;
+    }
+    public void setCommentsStillAllowed(boolean ignored) {
+        // no-op
+    }
+
+    
+    //------------------------------------------------------------------------
+    
+    /** 
+     * Format the publish time of this weblog entry using the specified pattern.
+     * See java.text.SimpleDateFormat for more information on this format.
+     * @see java.text.SimpleDateFormat
+     * @return Publish time formatted according to pattern.
+     */
+    public String formatPubTime(String pattern)
+    {
+        try
+        {
+            SimpleDateFormat format = new SimpleDateFormat(pattern, 
+                    this.getWebsite().getLocaleInstance());
+
+            return format.format(getPubTime());
+        }
+        catch (RuntimeException e)
+        {
+            mLogger.error("Unexpected exception", e);
+        }
+
+        return "ERROR: formatting date";
+    }
+
+    //------------------------------------------------------------------------
+    
+    /** 
+     * Format the update time of this weblog entry using the specified pattern.
+     * See java.text.SimpleDateFormat for more information on this format.
+     * @see java.text.SimpleDateFormat
+     * @return Update time formatted according to pattern.
+     */
+    public String formatUpdateTime(String pattern)
+    {
+        try
+        {
+            SimpleDateFormat format = new SimpleDateFormat(pattern);
+
+            return format.format(getUpdateTime());
+        }
+        catch (RuntimeException e)
+        {
+            mLogger.error("Unexpected exception", e);
+        }
+
+        return "ERROR: formatting date";
+    }
+
+    //------------------------------------------------------------------------
+    
+    public List getComments()
+    {
+        return getComments(true);
+    }
+    
+    public List getComments(boolean ignoreSpam)
+    {
+        List list = new ArrayList();
+        try
+        {
+            return RollerFactory.getRoller().getWeblogManager().getComments(getId(), ignoreSpam);
+        }
+        catch (RollerException alreadyLogged) {}
+        return list;
+    }
+
+    //------------------------------------------------------------------------
+    
+    public List getReferers()
+    {
+        List referers = null;
+        try {
+            referers = RollerFactory.getRoller().getRefererManager().getReferersToEntry(getId());
+        } catch (RollerException e) {
+            mLogger.error("Unexpected exception", e);
+        }
+        return referers;
+    }
+
+    //------------------------------------------------------------------------
+    
+    /**
+     * @param entry
+     * @param url
+     * @param title
+     * @param excerpt
+     * @param blogName
+     */
+    public void addTrackback(
+        String url, String title, String excerpt, String blogName) 
+        throws RollerException
+    {
+        String modTitle = blogName + ": "  + title;
+        if (modTitle.length() >= 250)
+        {
+            modTitle = modTitle.substring(0, 257);
+            modTitle += "...";
+        }
+        
+        // Track trackbacks as comments
+        CommentData comment = new CommentData();
+        comment.setContent("[Trackback] "+excerpt);
+        comment.setName(blogName);
+        comment.setUrl(url);
+        comment.setWeblogEntry(this);
+        comment.setNotify(Boolean.FALSE);
+        comment.setPostTime(new Timestamp(new Date().getTime()));
+        comment.save();
+         
+        // Alternative: treat trackbacks as referers
+        //RefererData ref = new RefererData();
+        //ref.setWebsite(getWebsite());
+        //ref.setWeblogEntry(this);
+        //ref.setRequestUrl("(trackback)");
+        //ref.setRefererUrl(url);
+        //ref.setTitle(modTitle);
+        //ref.setExcerpt(excerpt);
+        //ref.setVisible(Boolean.TRUE);
+        //ref.setDayHits(new Integer(0));
+        //ref.setTotalHits(new Integer(0));
+        //ref.setDuplicate(Boolean.FALSE);        
+        //ref.setDateString(formatPubTime("yyyyMMdd"));        
+        //mRoller.getRefererManager().storeReferer(ref);
+    }
+    
+    /**
+     * Convenience method for getPermalink(category)
+     * where no category is necessary.
+     * @return
+     */
+    public String getPermaLink()
+    {
+        String lAnchor = this.getAnchor();
+        
+        try
+        {
+            lAnchor = URLEncoder.encode(anchor, "UTF-8");
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            // go with the "no encoding" version
+        }
+        
+        WebsiteData website = this.getWebsite();
+        String plink = "/page/" + website.getUser().getUserName() + 
+                "?anchor=" + lAnchor;
+        
+        return plink;
+    }
+    
+    /**
+     * Get the "relative" URL to this entry.  Proper use of this will 
+     * require prepending the baseURL (either the full root 
+     * [http://server.com/context] or at least the context
+     * [/context]) in order to generate a functional link.
+     * @param category The category name to insert into the permalink.
+     * @return String
+     */
+    public String getPermaLink(String categoryPath)
+    {
+        // i don't really understand the purpose of this method since
+        // WeblogEntryData.getPermaLink() is only meant to point to this entry
+        
+        return this.getPermaLink();
+    }
+        
+    public String getCommentsLink()
+    {
+        String dayString = DateUtil.format8chars(this.getPubTime());
+        String lAnchor = this.getAnchor();
+        try
+        {
+            lAnchor = URLEncoder.encode(anchor, "UTF-8");
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            // go with the "no encoding" version
+        }        
+        String clink = "/page/" + this.getWebsite().getUser().getUserName() + "?anchor=" + lAnchor;
+        return clink;
+    }
+    /** to please XDoclet */
+    public void setCommentsLink(String ignored) {}
+    
+    /**
+     * Return the Title of this post, or the first 255 characters of the
+     * entry's text.
+     * 
+     * @return String
+     */
+    public String getDisplayTitle()
+    {
+        if ( getTitle()==null || getTitle().trim().equals("") )
+        {
+            return StringUtils.left(Utilities.removeHTML(text),255);
+        }
+        return Utilities.removeHTML(getTitle());
+    }
+    
+    //------------------------------------------------------------------------
+    
+    public String toString()
+    {
+        StringBuffer str = new StringBuffer("{");
+
+        str.append("id=" + id + " " + 
+                   "category=" + category + " " + 
+                   "title=" + title + " " + 
+                    "text=" + text + " " + 
+                    "anchor=" + anchor + " " + 
+                    "pubTime=" + pubTime + " " + 
+                    "updateTime=" + updateTime + " " + 
+                    "publishEntry=" + publishEntry + " " + 
+                    "plugins=" + mPlugins);
+        str.append('}');
+
+        return (str.toString());
+    }
+
+    //------------------------------------------------------------------------
+    
+    public boolean equals(Object pOther)
+    {
+        if (pOther instanceof WeblogEntryData)
+        {
+            WeblogEntryData lTest = (WeblogEntryData) pOther;
+            boolean lEquals = true;
+
+            if (this.id == null)
+            {
+                lEquals = lEquals && (lTest.id == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.id.equals(lTest.id);
+            }
+
+            if (this.category == null)
+            {
+                lEquals = lEquals && (lTest.category == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.category.equals(lTest.category);
+            }
+
+            if (this.mWebsite == null)
+            {
+                lEquals = lEquals && (lTest.mWebsite == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.mWebsite.equals(lTest.mWebsite);
+            }
+
+            if (this.title == null)
+            {
+                lEquals = lEquals && (lTest.title == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.title.equals(lTest.title);
+            }
+
+            if (this.text == null)
+            {
+                lEquals = lEquals && (lTest.text == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.text.equals(lTest.text);
+            }
+
+            if (this.anchor == null)
+            {
+                lEquals = lEquals && (lTest.anchor == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.anchor.equals(lTest.anchor);
+            }
+
+            if (this.pubTime == null)
+            {
+                lEquals = lEquals && (lTest.pubTime == null);
+            }
+            else
+            {
+                lEquals = lEquals && this.pubTime.equals(lTest.pubTime);
+            }
+
+            if (this.updateTime == null)
+            {
+                lEquals = lEquals && (lTest.updateTime == null);
+            }
+            else
+            {
+                lEquals = lEquals && 
+                          this.updateTime.equals(lTest.updateTime);
+            }
+
+            if (this.publishEntry == null)
+            {
+                lEquals = lEquals && (lTest.publishEntry == null);
+            }
+            else
+            {
+                lEquals = lEquals && 
+                          this.publishEntry.equals(lTest.publishEntry);
+            }
+
+            if (this.mPlugins == null)
+            {
+                lEquals = lEquals && (lTest.mPlugins == null);
+            }
+            else
+            {
+                lEquals = lEquals && 
+                          this.mPlugins.equals(lTest.mPlugins);
+            }
+
+
+            return lEquals;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    //------------------------------------------------------------------------
+    
+    public int hashCode()
+    {
+        int result = 17;
+        result = (37 * result) + 
+                 ((this.id != null) ? this.id.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.category != null) ? this.category.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.mWebsite != null) ? this.mWebsite.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.title != null) ? this.title.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.text != null) ? this.text.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.anchor != null) ? this.anchor.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.pubTime != null) ? this.pubTime.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.updateTime != null) ? this.updateTime.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.publishEntry != null) ? this.publishEntry.hashCode() : 0);
+        result = (37 * result) + 
+                 ((this.mPlugins != null) ? this.mPlugins.hashCode() : 0);
+
+        return result;
+    }
+    
+    /** Return RSS 09x style description (escaped HTML version of entry text) */
+    public String getRss09xDescription()
+    {
+        return getRss09xDescription(-1);
+    }
+    
+    /** Return RSS 09x style description (escaped HTML version of entry text) */
+    public String getRss09xDescription(int maxLength)
+    {
+        String ret = Utilities.escapeHTML(text);
+        if (maxLength != -1 && ret.length() > maxLength) 
+        {  
+            ret = ret.substring(0,maxLength-3)+"..."; 
+        }
+        return ret;     
+    }
+
+    /** Create anchor for weblog entry, based on title or text */
+    protected String createAnchor() throws RollerException
+    {
+        return RollerFactory.getRoller().getWeblogManager().createAnchor(this);
+    }
+
+    /** Create anchor for weblog entry, based on title or text */
+    public String createAnchorBase()
+    {
+        // Use title or text for base anchor
+        String base = getTitle();
+        if (base == null || base.trim().equals(""))
+        {
+            base = getText();
+        }
+        if (base != null && !base.trim().equals(""))
+        {
+            base = Utilities.replaceNonAlphanumeric(base, ' ');
+
+            // Use only the first 4 words
+            StringTokenizer toker = new StringTokenizer(base);
+            String tmp = null;
+            int count = 0;
+            while (toker.hasMoreTokens() && count < 5)
+            {
+                String s = toker.nextToken();
+                s = s.toLowerCase();
+                tmp = (tmp == null) ? s : tmp + "_" + s;
+                count++;
+            }
+            base = tmp;
+        }
+        // No title or text, so instead we will use the items date
+        // in YYYYMMDD format as the base anchor
+        else
+        {
+            base = DateUtil.format8chars(getPubTime());
+        }
+
+        return base;
+    }
+
+    /**
+     * A no-op.
+     * TODO: fix formbean generation so this is not needed. 
+     * @param string
+     */
+    public void setPermaLink(String string)
+    {
+    }
+
+    /**
+     * A no-op.
+     * TODO: fix formbean generation so this is not needed. 
+     * @param string
+     */
+    public void setDisplayTitle(String string)
+    {
+    }
+
+    /**
+     * A no-op.
+     * TODO: fix formbean generation so this is not needed. 
+     * @param string
+     */
+    public void setRss09xDescription(String string)
+    {
+    }
+    
+    /** 
+     * @see org.roller.pojos.PersistentObject#remove()
+     */
+    public void remove() throws RollerException
+    {
+        RollerFactory.getRoller().getWeblogManager().removeWeblogEntryContents(this);
+        super.remove();
+    }
+    
+    /**
+     * Convenience method to transform mPlugins to a List
+     * @return
+     */
+    public List getPluginsList()
+    {
+        if (mPlugins != null)
+        {
+            return Arrays.asList( StringUtils.split(mPlugins, ",") );
+        }
+        return new ArrayList();
+    }
+
+    public boolean canSave() throws RollerException
+    {
+        Roller roller = RollerFactory.getRoller();
+        if (roller.getUser().equals(UserData.SYSTEM_USER)) 
+        {
+            return true;
+        }
+        if (roller.getUser().equals(getWebsite().getUser()))
+        {
+            return true;
+        }
+        return false;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/pojos/WebsiteData.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/WebsiteData.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/WebsiteData.java (added)
+++ incubator/roller/trunk/src/org/roller/pojos/WebsiteData.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,598 @@
+package org.roller.pojos;
+
+import org.apache.commons.lang.StringUtils;
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.util.PojoUtil;
+
+import java.util.Locale;
+import java.util.TimeZone;
+/**
+ * A user's website is a weweblog, newsfeed channels and bookmarks.
+ * @author David M Johnson
+ *
+ * @ejb:bean name="WebsiteData"
+ * @struts.form include-all="true"
+ * @hibernate.class table="website"
+ * hibernate.jcs-cache usage="read-write"
+ */
+public class WebsiteData extends org.roller.pojos.PersistentObject
+    implements java.io.Serializable
+{
+    static final long serialVersionUID = 206437645033737127L;
+    protected java.lang.String id;
+    protected java.lang.String name;
+    protected java.lang.String description;
+    protected java.lang.String defaultPageId;
+    protected java.lang.String weblogDayPageId;
+    protected java.lang.Boolean enableBloggerApi;
+    protected WeblogCategoryData bloggerCategory;
+    protected WeblogCategoryData defaultCategory;
+    protected java.lang.String editorPage;
+    protected java.lang.String ignoreWords;
+    protected java.lang.Boolean allowComments;
+    protected java.lang.Boolean emailComments;
+    protected java.lang.String emailFromAddress;
+    protected java.lang.String editorTheme;
+    protected java.lang.String locale;
+    protected java.lang.String timezone;
+    protected java.lang.String mDefaultPlugins;
+    protected java.lang.Boolean isEnabled;
+
+    protected UserData mUser = null;
+
+    public WebsiteData()
+    {
+    }
+
+    public WebsiteData(final java.lang.String id, 
+                       final java.lang.String name,
+                       final java.lang.String description,
+                       final UserData user,
+                       final java.lang.String defaultPageId,
+                       final java.lang.String weblogDayPageId,
+                       final java.lang.Boolean enableBloggerApi,
+                       final WeblogCategoryData bloggerCategory,
+                       final WeblogCategoryData defaultCategory,
+                       final java.lang.String editorPage,
+                       final java.lang.String ignoreWords,
+                       final java.lang.Boolean allowComments,
+                       final java.lang.Boolean emailComments,
+                       final java.lang.String emailFromAddress,
+                       final java.lang.Boolean isEnabled)
+    {
+        this.id = id;
+        this.name = name;
+        this.description = description;
+        this.mUser = user;
+        this.defaultPageId = defaultPageId;
+        this.weblogDayPageId = weblogDayPageId;
+        this.enableBloggerApi = enableBloggerApi;
+        this.bloggerCategory = bloggerCategory;
+        this.defaultCategory = defaultCategory;
+        this.editorPage = editorPage;
+        this.ignoreWords = ignoreWords;
+        this.allowComments = allowComments;
+        this.emailComments = emailComments;
+        this.emailFromAddress = emailFromAddress;
+        this.isEnabled = isEnabled;
+    }
+
+    public WebsiteData(WebsiteData otherData)
+    {
+        this.setData(otherData);
+    }
+
+    /**
+     * Id of the Website.
+     * @ejb:persistent-field
+     * @hibernate.id column="id" type="string"
+     *  generator-class="uuid.hex" unsaved-value="null"
+     */
+    public java.lang.String getId()
+    {
+        return this.id;
+    }
+
+    /** @ejb:persistent-field */
+    public void setId(java.lang.String id)
+    {
+        this.id = id;
+    }
+
+    /**
+     * Name of the Website.
+     * @ejb:persistent-field
+     * @hibernate.property column="name" non-null="true" unique="false"
+     */
+    public java.lang.String getName()
+    {
+        return this.name;
+    }
+
+    /** @ejb:persistent-field */
+    public void setName(java.lang.String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Description
+     * @ejb:persistent-field
+     * @hibernate.property column="description" non-null="true" unique="false"
+     */
+    public java.lang.String getDescription()
+    {
+        return this.description;
+    }
+
+    /** @ejb:persistent-field */
+    public void setDescription(java.lang.String description)
+    {
+        this.description = description;
+    }
+
+    /**
+     * Id of owner.
+     * @ejb:persistent-field
+     * @hibernate.many-to-one column="userid" cascade="none" not-null="true"
+     */
+    public org.roller.pojos.UserData getUser()
+    {
+        return mUser;
+    }
+
+    /** @ejb:persistent-field */
+    public void setUser( org.roller.pojos.UserData ud )
+    {
+        mUser = ud;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="defaultpageid" non-null="true" unique="false"
+     */
+    public java.lang.String getDefaultPageId()
+    {
+        return this.defaultPageId;
+    }
+
+    /**
+     * @ejb:persistent-field
+     */
+    public void setDefaultPageId(java.lang.String defaultPageId)
+    {
+        this.defaultPageId = defaultPageId;
+    }
+
+    /**
+     * @deprecated
+     * @ejb:persistent-field
+     * @hibernate.property column="weblogdayid" non-null="true" unique="false"
+     */
+    public java.lang.String getWeblogDayPageId()
+    {
+        return this.weblogDayPageId;
+    }
+
+    /**
+     * @deprecated
+     * @ejb:persistent-field
+     */
+    public void setWeblogDayPageId(java.lang.String weblogDayPageId)
+    {
+        this.weblogDayPageId = weblogDayPageId;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="enablebloggerapi" non-null="true" unique="false"
+     */
+    public java.lang.Boolean getEnableBloggerApi()
+    {
+        return this.enableBloggerApi;
+    }
+
+    /** @ejb:persistent-field */
+    public void setEnableBloggerApi(java.lang.Boolean enableBloggerApi)
+    {
+        this.enableBloggerApi = enableBloggerApi;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * 
+     * @hibernate.many-to-one column="bloggercatid" non-null="false"
+     */
+    public WeblogCategoryData getBloggerCategory()
+    {
+        return bloggerCategory;
+    }
+
+    /** @ejb:persistent-field */
+    public void setBloggerCategory(WeblogCategoryData bloggerCategory)
+    {
+        this.bloggerCategory = bloggerCategory;
+    }
+
+    /**
+     * By default,the default category for a weblog is the root and all macros
+     * work with the top level categories that are immediately under the root.
+     * Setting a different default category allows you to partition your weblog.
+     * 
+     * @ejb:persistent-field
+     * 
+     * @hibernate.many-to-one column="defaultcatid" non-null="false"
+     */
+    public WeblogCategoryData getDefaultCategory() 
+    {
+        return defaultCategory;
+    }
+
+    /** @ejb:persistent-field */
+    public void setDefaultCategory(WeblogCategoryData defaultCategory)
+    {
+        this.defaultCategory = defaultCategory;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="editorpage" non-null="true" unique="false"
+     */
+    public java.lang.String getEditorPage()
+    {
+        return this.editorPage;
+    }
+
+    /** @ejb:persistent-field */
+    public void setEditorPage(java.lang.String editorPage)
+    {
+        this.editorPage = editorPage;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="ignorewords" non-null="true" unique="false"
+     */
+    public java.lang.String getIgnoreWords()
+    {
+        return this.ignoreWords;
+    }
+
+    /** @ejb:persistent-field */
+    public void setIgnoreWords(java.lang.String ignoreWords)
+    {
+        this.ignoreWords = ignoreWords;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="allowcomments" non-null="true" unique="false"
+     */
+    public java.lang.Boolean getAllowComments()
+    {
+        return this.allowComments;
+    }
+
+    /** @ejb:persistent-field */
+    public void setAllowComments(java.lang.Boolean allowComments)
+    {
+        this.allowComments = allowComments;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="emailcomments" non-null="true" unique="false"
+     */
+    public java.lang.Boolean getEmailComments()
+    {
+        return this.emailComments;
+    }
+
+    /** @ejb:persistent-field */
+    public void setEmailComments(java.lang.Boolean emailComments)
+    {
+        this.emailComments = emailComments;
+    }
+    
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="emailfromaddress" non-null="true" unique="false"
+     */
+    public java.lang.String getEmailFromAddress()
+    {
+        return this.emailFromAddress;
+    }
+
+    /** @ejb:persistent-field */
+    public void setEmailFromAddress(java.lang.String emailFromAddress)
+    {
+        this.emailFromAddress = emailFromAddress;
+    }
+    
+    /**
+     * EditorTheme of the Website.
+     * @ejb:persistent-field
+     * @hibernate.property column="editortheme" non-null="true" unique="false"
+     */
+    public java.lang.String getEditorTheme()
+    {
+        return this.editorTheme;
+    }
+
+    /** @ejb:persistent-field */
+    public void setEditorTheme(java.lang.String editorTheme)
+    {
+        this.editorTheme = editorTheme;
+    }
+
+    /**
+     * Locale of the Website.
+     * @ejb:persistent-field
+     * @hibernate.property column="locale" non-null="true" unique="false"
+     */
+    public java.lang.String getLocale()
+    {
+        return this.locale;
+    }
+
+    /** @ejb:persistent-field */
+    public void setLocale(java.lang.String locale)
+    {
+        this.locale = locale;
+    }
+
+    /**
+     * Timezone of the Website.
+     * @ejb:persistent-field
+     * @hibernate.property column="timezone" non-null="true" unique="false"
+     */
+    public java.lang.String getTimezone()
+    {
+        return this.timezone;
+    }
+
+    /** @ejb:persistent-field */
+    public void setTimezone(java.lang.String timezone)
+    {
+        this.timezone = timezone;
+    }
+
+    /**
+     * Comma-delimited list of user's default Plugins.
+     * @ejb:persistent-field
+     * @hibernate.property column="defaultplugins" non-null="false" unique="false"
+     */
+    public java.lang.String getDefaultPlugins()
+    {
+        return mDefaultPlugins;
+    }
+
+    /** @ejb:persistent-field */
+    public void setDefaultPlugins(java.lang.String string)
+    {
+        mDefaultPlugins = string;
+    }
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="isenabled" non-null="true" unique="false"
+     */
+    public java.lang.Boolean getIsEnabled()
+    {
+        return this.isEnabled;
+    }
+    
+    /** @ejb:persistent-field */ 
+    public void setIsEnabled(java.lang.Boolean isEnabled)
+    {
+        this.isEnabled = isEnabled;
+    }
+
+    public String toString()
+    {
+        StringBuffer str = new StringBuffer("{");
+
+        str.append("id=" + id + " " + "name=" + name + " " + "description=" +
+                   description + " " +
+                   "defaultPageId=" + defaultPageId + " " +
+                   "weblogDayPageId=" + weblogDayPageId + " " +
+                   "enableBloggerApi=" + enableBloggerApi + " " +
+                   "bloggerCategory=" + bloggerCategory + " " +
+                   "defaultCategory=" + defaultCategory + " " +
+                   "editorPage=" + editorPage + " " +
+                   "ignoreWords=" + ignoreWords + " " +
+                   "allowComments=" + allowComments + " " +
+                   "emailComments=" + emailComments + " " + 
+                   "emailFromAddress=" + emailFromAddress + " " +
+                   "editorTheme=" + editorTheme + " " +
+                   "locale=" + locale + " " +
+                   "timezone=" + timezone + " " +
+                   "defaultPlugins=" + mDefaultPlugins);
+        str.append('}');
+
+        return (str.toString());
+    }
+
+    public boolean equals(Object pOther)
+    {
+        if (pOther instanceof WebsiteData)
+        {
+            WebsiteData lTest = (WebsiteData) pOther;
+            boolean lEquals = true;
+
+            lEquals = PojoUtil.equals(lEquals, this.id, lTest.id);
+
+            lEquals = PojoUtil.equals(lEquals, this.name, lTest.name);
+
+            lEquals = PojoUtil.equals(lEquals, this.description, lTest.description);
+
+            lEquals = PojoUtil.equals(lEquals, this.mUser, lTest.mUser);
+
+            lEquals = PojoUtil.equals(lEquals, this.defaultPageId, lTest.defaultPageId);
+
+            lEquals = PojoUtil.equals(lEquals, this.weblogDayPageId, lTest.weblogDayPageId);
+
+            lEquals = PojoUtil.equals(lEquals, this.enableBloggerApi, lTest.enableBloggerApi);
+
+            lEquals = PojoUtil.equals(lEquals, this.bloggerCategory.getId(), lTest.bloggerCategory.getId());
+
+            lEquals = PojoUtil.equals(lEquals, this.defaultCategory.getId(), lTest.defaultCategory.getId());
+
+            lEquals = PojoUtil.equals(lEquals, this.editorPage, lTest.editorPage);
+
+            lEquals = PojoUtil.equals(lEquals, this.ignoreWords, lTest.ignoreWords);
+
+            lEquals = PojoUtil.equals(lEquals, this.allowComments, lTest.allowComments);
+            
+            lEquals = PojoUtil.equals(lEquals, this.emailComments, lTest.emailComments);
+            
+            lEquals = PojoUtil.equals(lEquals, this.emailFromAddress, lTest.emailFromAddress);
+
+            lEquals = PojoUtil.equals(lEquals, this.editorTheme, lTest.editorTheme);
+
+            lEquals = PojoUtil.equals(lEquals, this.locale, lTest.locale);
+
+            lEquals = PojoUtil.equals(lEquals, this.timezone, lTest.timezone);
+
+            lEquals = PojoUtil.equals(lEquals, this.mDefaultPlugins, lTest.mDefaultPlugins);
+            
+            return lEquals;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    public int hashCode()
+    {
+        int result = 17;
+        result = PojoUtil.addHashCode(result, this.id);
+        result = PojoUtil.addHashCode(result, this.name);
+        result = PojoUtil.addHashCode(result, this.description);
+        result = PojoUtil.addHashCode(result, this.mUser);
+        result = PojoUtil.addHashCode(result, this.defaultPageId);
+        result = PojoUtil.addHashCode(result, this.weblogDayPageId);
+        result = PojoUtil.addHashCode(result, this.enableBloggerApi);
+        //result = PojoUtil.addHashCode(result, this.bloggerCategory);
+        //result = PojoUtil.addHashCode(result, this.defaultCategory);
+        result = PojoUtil.addHashCode(result, this.editorPage);
+        result = PojoUtil.addHashCode(result, this.ignoreWords);
+        result = PojoUtil.addHashCode(result, this.allowComments);
+        result = PojoUtil.addHashCode(result, this.emailComments);
+        result = PojoUtil.addHashCode(result, this.emailFromAddress);
+        result = PojoUtil.addHashCode(result, this.editorTheme);
+        result = PojoUtil.addHashCode(result, this.locale);
+        result = PojoUtil.addHashCode(result, this.timezone);
+        result = PojoUtil.addHashCode(result, this.mDefaultPlugins);
+
+        return result;
+    }
+
+    /**
+     * Setter is needed in RollerImpl.storePersistentObject()
+     */
+    public void setData(org.roller.pojos.PersistentObject otherData)
+    {
+        WebsiteData other = (WebsiteData)otherData;
+
+        this.id = other.id;
+        this.name = other.name;
+        this.description = other.description;
+        this.mUser = other.mUser;
+        this.defaultPageId = other.defaultPageId;
+        this.weblogDayPageId = other.weblogDayPageId;
+        this.enableBloggerApi = other.enableBloggerApi;
+        this.bloggerCategory = other.bloggerCategory;
+        this.defaultCategory = other.defaultCategory;
+        this.editorPage = other.editorPage;
+        this.ignoreWords = other.ignoreWords;
+        this.allowComments = other.allowComments;
+        this.emailComments = other.emailComments;
+        this.emailFromAddress = other.emailFromAddress;
+        this.editorTheme = other.editorTheme;
+        this.locale = other.locale;
+        this.timezone = other.timezone;
+        this.mDefaultPlugins = other.mDefaultPlugins;
+        this.isEnabled = other.isEnabled;
+    }
+    
+    /**
+     * Parse locale value and instantiate a Locale object,
+     * otherwise return default Locale.
+     * @return Locale
+     */
+    public Locale getLocaleInstance()
+    {
+        if (locale != null)
+        {
+            String[] localeStr = StringUtils.split(locale,"_");
+            if (localeStr.length == 1)
+            {
+                if (localeStr[0] == null) localeStr[0] = "";
+                return new Locale(localeStr[0]);
+            }
+            else if (localeStr.length == 2)
+            {
+                if (localeStr[0] == null) localeStr[0] = "";
+                if (localeStr[1] == null) localeStr[1] = "";
+                return new Locale(localeStr[0], localeStr[1]);
+            }
+            else if (localeStr.length == 3)
+            {
+                if (localeStr[0] == null) localeStr[0] = "";
+                if (localeStr[1] == null) localeStr[1] = "";
+                if (localeStr[2] == null) localeStr[2] = "";
+                return new Locale(localeStr[0], localeStr[1], localeStr[2]);
+            } 
+        } 
+        return Locale.getDefault();
+    }
+    
+    /**
+     * Return TimeZone instance for value of timezone,
+     * otherwise return system default instance.
+     * @return TimeZone
+     */
+    public TimeZone getTimeZoneInstance()
+    {
+    	if (timezone == null) 
+        {
+            if (TimeZone.getDefault() != null) 
+            {
+                this.setTimezone( TimeZone.getDefault().getID() );
+            }
+            else
+            {
+                this.setTimezone("America/New_York");
+            }
+        }
+        return TimeZone.getTimeZone(timezone);
+    }
+    
+    /** 
+     * @see org.roller.pojos.PersistentObject#remove()
+     */
+    public void remove() throws RollerException
+    {
+        RollerFactory.getRoller().getUserManager().removeWebsiteContents(this);        
+        super.remove();
+    }
+
+    public boolean canSave() throws RollerException
+    {
+        Roller roller = RollerFactory.getRoller();
+        if (roller.getUser().equals(UserData.SYSTEM_USER)) 
+        {
+            return true;
+        }
+        if (roller.getUser().equals(getUser()))
+        {
+            return true;
+        }
+        return false;
+    }
+
+}
\ No newline at end of file

Added: incubator/roller/trunk/src/org/roller/pojos/WebsiteDisplayData.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/WebsiteDisplayData.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/WebsiteDisplayData.java (added)
+++ incubator/roller/trunk/src/org/roller/pojos/WebsiteDisplayData.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,118 @@
+/*
+ * Created on Apr 15, 2003
+ */
+package org.roller.pojos;
+
+
+/**
+ * For most popular website display on Roller main page.
+ * The id property is the website's name.
+ * 
+ * @author David M Johnson
+ *
+ * @ejb:bean name="WebsiteDisplayData"
+ * @struts.form include-all="true" 
+ */
+public class WebsiteDisplayData extends PersistentObject
+{    
+    static final long serialVersionUID = 5264701383470813687L;
+    
+    private String mId;
+    private String mUserName = null;
+    private String mWebsiteName = null;
+    private Integer mHits = new Integer(0);    
+
+    /**
+     * 
+     */
+    public WebsiteDisplayData()
+    {
+        super();
+    }
+
+    /**
+     * 
+     */
+    public WebsiteDisplayData(String id, String userName, String websiteName, Integer hits)
+    {
+        super();
+        mId = id;
+        mUserName = userName;
+        mWebsiteName = websiteName;
+        mHits = hits;
+    }
+
+    /** 
+     * No-op.
+     * @see org.roller.pojos.PersistentObject#setData(org.roller.pojos.PersistentObject)
+     */
+    public void setData(PersistentObject vo)
+    {
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     */
+    public String getId()
+    {
+        return mId;
+    }
+
+    /** 
+     * @see org.roller.pojos.PersistentObject#setId(java.lang.String)
+     */
+    public void setId(String id)
+    {
+        mId = id;
+    }
+
+
+    /** 
+     * @ejb:persistent-field 
+     */
+    public String getUserName()
+    {
+        return mUserName;
+    }
+
+    /**
+     * @param string
+     */
+    public void setUserName(String string)
+    {
+        mUserName = string;
+    }
+
+    /** 
+     * @ejb:persistent-field 
+     */
+    public Integer getHits()
+    {
+        return mHits;
+    }
+
+    /**
+     * @param integer
+     */
+    public void setHits(Integer integer)
+    {
+        mHits = integer;
+    }
+
+
+    /**
+     * @return Returns the title.
+     */
+    public String getWebsiteName()
+    {
+        return mWebsiteName;
+    }
+    
+    /**
+     * @param title The title to set.
+     */
+    public void setWebsiteName(String name)
+    {
+        mWebsiteName = name;
+    }
+}

Added: incubator/roller/trunk/src/org/roller/pojos/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/package.html?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/package.html (added)
+++ incubator/roller/trunk/src/org/roller/pojos/package.html Wed Jun  8 20:18:46 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Persistent objects and supporting classes. Source for XDoclet generation of Hibernate mappings,
+Struts form beans, and Struts validation configuration file.<br>
+</body>
+</html>

Added: incubator/roller/trunk/src/org/roller/presentation/AccessDeniedException.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/AccessDeniedException.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/AccessDeniedException.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/AccessDeniedException.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,28 @@
+
+package org.roller.presentation;
+
+import javax.servlet.jsp.JspException;
+
+/** 
+ * Indicates user is not authorized to access a resource.
+ */ 
+public class AccessDeniedException extends JspException 
+{
+	public AccessDeniedException(String s,Throwable t)
+	{
+		super(s,t);
+	}
+	public AccessDeniedException(Throwable t)
+	{
+		super(t);
+	}
+	public AccessDeniedException(String s)
+	{
+		super(s);
+	}
+	public AccessDeniedException()
+	{
+		super();
+	}
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/ArchiveParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/ArchiveParser.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/ArchiveParser.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/ArchiveParser.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,428 @@
+/*
+ * Created on Apr 2, 2004
+ */
+package org.roller.presentation;
+
+
+/**
+ * TODO: revisit this class once Atom 1.0 support comes to Rome
+ * @author lance.lavandowska
+ */
+public class ArchiveParser
+{
+//    protected static final Log mLogger = 
+//        LogFactory.getFactory().getInstance(ArchiveParser.class);
+//    
+//    private Roller roller;
+//    private WebsiteData website;
+//    private File archiveFile;
+//
+//    private Timestamp current;
+//
+//    private WeblogCategoryData defaultCategory;
+//
+//    private WeblogCategoryData rootCategory;
+//
+//    private IndexManager indexMgr;
+// 
+//
+//    /**
+//     * @param rreq
+//     * @param f
+//     */
+//    public ArchiveParser(Roller roller, WebsiteData website, File f) throws RollerException
+//    {
+//        this.roller = roller;
+//        this.website = website;
+//        archiveFile = f;
+//        
+//        current = new Timestamp( System.currentTimeMillis());
+//        defaultCategory = website.getDefaultCategory();
+//        rootCategory = roller.getWeblogManager().getRootWeblogCategory(website);
+//        indexMgr = roller.getIndexManager();
+//    }
+//
+//    public String parse() throws RollerException
+//    {        
+//        StringBuffer buf = new StringBuffer();
+//        
+//        // parse file and convert to WeblogEntryDatas
+//        Feed atomFeed = getAtomFeed();
+//        if (atomFeed != null)
+//        {    
+//            importAtom(buf, atomFeed);
+//        }
+//        else
+//        {    
+//            // not an Atom feed, try RSS
+//            ChannelIF channel = getInformaChannel();
+//            
+//            if (channel != null && channel.getItems()!= null)
+//            {
+//                importRSS(buf, channel);
+//            }
+//        }
+//        
+//        return buf.toString();
+//    }
+//
+//    /**
+//     * @return
+//     * @throws FileNotFoundException
+//     * @throws IOException
+//     */
+//    private Feed getAtomFeed()
+//    {
+//        Feed feed = null;
+//        BufferedInputStream bis = null;
+//        try
+//        {
+//            FileInputStream fis = new FileInputStream(archiveFile);
+//            bis = new BufferedInputStream(fis);
+//            // we need AtomFeedReader for Roller-specific elements
+//            AtomFeedReader reader = new AtomFeedReader(bis);
+//            // current 'version' of Atom4J parses on init, next version won't
+//            if (reader.getFeed() == null) 
+//            {
+//                reader.parse(); 
+//            }
+//            feed = reader.getFeed();
+//        }
+//        catch (FileNotFoundException e)
+//        {
+//            mLogger.debug("You told me to read a non-existant file.", e);
+//        }
+//        catch (IOException e)
+//        {
+//            mLogger.debug("Digester throws IOException for no reason I can tell.", e);
+//        }
+//        finally
+//        {
+//            try
+//            {
+//                if (bis != null) bis.close();
+//            }
+//            catch (IOException e1)
+//            {
+//                mLogger.error("Unable to close stream to " + archiveFile);
+//            }
+//        }
+//        return feed;
+//    }
+//
+//    /**
+//     * @param channel
+//     * @return
+//     */
+//    private ChannelIF getInformaChannel()
+//    {
+//        ChannelIF channel = null;
+//        BufferedInputStream bis = null;
+//        try
+//        {
+//            FileInputStream fis = new FileInputStream(archiveFile);
+//            bis = new BufferedInputStream(fis);
+//            channel = RSSParser.parse(new ChannelBuilder(), bis);
+//        }
+//        catch (FileNotFoundException e)
+//        {
+//            e.printStackTrace();
+//        }
+//        catch (IOException e)
+//        {
+//            e.printStackTrace();
+//        }
+//        catch (ParseException e)
+//        {
+//            e.printStackTrace();
+//        }
+//        finally
+//        {
+//            try
+//            {
+//                if (bis != null) bis.close();
+//            }
+//            catch (IOException e1)
+//            {
+//                mLogger.error("Unable to close stream to " + archiveFile);
+//            }
+//        }
+//        return channel;
+//    }
+//
+//    /**
+//     * 
+//     */
+//    private void importAtom(StringBuffer buf, Feed atomFeed) throws RollerException
+//    {
+//        AtomEntry atomEntry;
+//        WeblogEntryData entry = null;
+//        HashMap entryMap = new HashMap(); // map of Roller entries
+//        WeblogCategoryData category;
+//        HashMap categoryMap = new HashMap();
+//        categoryMap.put("defaultCategory", defaultCategory);
+//        Collection entries = atomFeed.getEntries();
+//        if (entries != null)
+//        {
+//            Iterator it = entries.iterator();
+//            while (it.hasNext())
+//            {
+//                entry = null; //reset
+//
+//                // create new Entry from AtomEntry
+//                atomEntry = (AtomEntry)it.next();
+//
+//                // test to see if this Entry is a Comment (it's
+//                // parent should already exist).
+//                /* Added by Roller's AtomEntry */
+//                if (atomEntry.getAnnotation() != null)
+//                {
+//                    createComment(atomEntry, entryMap);
+//                    continue;
+//                }
+//
+//                if (atomEntry.getId() != null)
+//                {
+//                    entry = roller.getWeblogManager().retrieveWeblogEntry(atomEntry.getId());
+//                }
+//                if (entry == null)
+//                {
+//                    category = null;
+//                    /* Atom doesn't currently have a Category definition.
+//                     Added by Roller's AtomEntry */
+//                    // return WeblogCategoryData for getCategories
+//                    if (atomEntry.getCategories() != null)
+//                    {
+//                        Iterator cIt = atomEntry.getCategories().iterator();
+//                        if (cIt.hasNext())
+//                        {
+//                            String catPath = (String)cIt.next();
+//                            category = locateCategory(catPath, categoryMap);
+//                        }
+//                    }
+//                    if (category == null) category = defaultCategory;
+//
+//                    entry = entryFromAtom(buf, atomEntry, entryMap, category);
+//
+//                    indexEntry(entry);
+//                }
+//                else
+//                {
+//                    entryMap.put(entry.getId(), entry);
+//                    buf.append("An Entry already exists for id: " + atomEntry.getId() + ".<br />");
+//                }
+//            }
+//        }
+//    }
+//
+//    /**
+//     * Convert an AtomEntry to a WeblogEntryData.
+//     * @param buf
+//     * @param atomEntry
+//     * @param entryMap
+//     * @param category
+//     * @return
+//     * @throws RollerException
+//     */
+//    private WeblogEntryData entryFromAtom(StringBuffer buf, AtomEntry atomEntry, HashMap entryMap, WeblogCategoryData category) throws RollerException
+//    {        
+//        System.out.println(atomEntry);
+//        String title = atomEntry.getTitle().getText();
+//        String content = "";
+//        Date issued = new Date(current.getTime());
+//        Date modified = new Date(current.getTime());     
+//        String id = atomEntry.getId();
+//        if (atomEntry.getContent() != null) 
+//        {
+//            content = atomEntry.getContent().getText();
+//        }
+//        if (atomEntry.getIssued() != null) issued = atomEntry.getIssued();
+//        if (atomEntry.getModified()!= null) modified = atomEntry.getModified();
+//        
+//        WeblogEntryData entry = new WeblogEntryData(
+//            null, category, website, 
+//            title, (String)null, 
+//            content, (String)null, 
+//            new Timestamp(issued.getTime()),
+//            new Timestamp(modified.getTime()), 
+//            Boolean.TRUE);
+//        entry.save();
+//        // store entry in local cache for Comments' to lookup
+//        if (id == null) id = entry.getId();
+//        entryMap.put(id, entry);
+//        
+//        buf.append("\"").append(title).append("\" imported.<br />\n");
+//        return entry;
+//    }
+//
+//    /**
+//     * @param atomEntry
+//     * @param entryMap
+//     */
+//    private void createComment(AtomEntry atomEntry, HashMap entryMap) throws RollerException
+//    {
+//        // first try to get the Entry from local cache
+//        CommentData comment = roller.getWeblogManager().retrieveComment(atomEntry.getId());
+//        if (comment == null)
+//        {    
+//            String entryId = atomEntry.getAnnotation();
+//            WeblogEntryData entry = (WeblogEntryData) entryMap.get(entryId);
+//            if (entry == null)
+//            {
+//                // now try getting it from database
+//                entry = roller.getWeblogManager().retrieveWeblogEntry(entryId);
+//            }
+//            if (entry != null)
+//            {    
+//                comment = new CommentData(
+//                    null, 
+//                    entry, 
+//                    atomEntry.getAuthor().getName(), 
+//                    atomEntry.getAuthor().getEmail(), 
+//                    atomEntry.getAuthor().getUrl(), 
+//                    atomEntry.getContent().getText(), 
+//                    new Timestamp(atomEntry.getIssued().getTime()), 
+//                    Boolean.FALSE, Boolean.FALSE);
+//                comment.save();
+//            }
+//            else
+//            {
+//                mLogger.warn("Unable to find parent WeblogEntry for id: " + entryId +
+//                             ".\n\tComment not created: " + atomEntry.getTitle().getText());
+//            }
+//        }
+//        else
+//        {
+//            mLogger.info("A Comment already exists for id: " + atomEntry.getId());
+//        }
+//    }
+//
+//    /**
+//     * @param rreq
+//     * @param buf
+//     * @param channel
+//     * @throws RollerException
+//     */
+//    private void importRSS(StringBuffer buf, ChannelIF channel) throws RollerException
+//    {       
+//        ItemIF item;
+//        WeblogEntryData entry = null;
+//        WeblogCategoryData category;
+//        HashMap categoryMap = new HashMap();
+//        categoryMap.put("defaultCategory", defaultCategory);
+//        Iterator it = channel.getItems().iterator();
+//        while (it.hasNext())
+//        {
+//            entry = null; //reset
+//            item = (ItemIF)it.next();
+//            
+//            if (item.getGuid() != null && !item.getGuid().isPermaLink())
+//            {
+//                entry = roller.getWeblogManager().retrieveWeblogEntry(item.getGuid().getLocation());
+//            }
+//            
+//            if (entry == null)
+//            {    
+//                category = null;
+//                // return WeblogCategoryData for getCategories
+//                if (item.getCategories() != null)
+//                {
+//                    Iterator cIt = item.getCategories().iterator();
+//                    if (cIt.hasNext()) 
+//                    {
+//                        // see if we've already created a category for this String
+//                        CategoryIF catIF = (CategoryIF)cIt.next();
+//                        category = locateCategory(catIF.getTitle(), categoryMap);
+//                    }
+//                }
+//                if (category == null) category = defaultCategory;
+//                
+//                entry = entryFromRSS(buf, item, category);
+//                
+//                indexEntry(entry);
+//            }
+//            else
+//            {
+//                buf.append("An Entry already exists for id: " + entry.getId() + ".<br />");
+//            }
+//        }
+//    }
+//
+//    /**
+//     * @param entry
+//     */
+//    private void indexEntry(WeblogEntryData entry) throws RollerException
+//    {
+//        // index the new Entry
+//        indexMgr.addEntryIndexOperation(entry);
+//    }
+//
+//    /**
+//     * Convert an RSS Item to a WeblogEntryData.
+//     * @param buf
+//     * @param item
+//     * @param category
+//     * @return
+//     * @throws RollerException
+//     */
+//    private WeblogEntryData entryFromRSS(StringBuffer buf, ItemIF item, WeblogCategoryData category) throws RollerException
+//    {
+//        WeblogEntryData entry;
+//        // make sure there is an item date
+//        if (item.getDate() == null)
+//        {
+//            item.setDate(new Date(current.getTime()));
+//        }
+//        
+//        entry = new WeblogEntryData(
+//            (String)null, category, website, 
+//            item.getTitle(), (String)null, 
+//            item.getDescription(), (String)null, 
+//            new Timestamp(item.getDate().getTime()),
+//            new Timestamp(item.getDate().getTime()), 
+//            Boolean.TRUE);
+//        entry.save();
+//        buf.append("\"").append(item.getTitle()).append("\" imported.<br />\n");
+//        return entry;
+//    }
+//
+//    /**
+//     * Iterate over Item's Categories, if any, using the first one.  
+//     * Try to match against any we've already pulled.  
+//     * If none found locally, check against the database.  
+//     * If we still don't find a match, create one and store it locally.
+//     * If there are no Item Categories, use defaultCategory
+//     * 
+//     * @param mapping
+//     * @param actionForm
+//     * @param request
+//     * @param response
+//     * @return
+//     * @throws IOException
+//     * @throws ServletException
+//     */
+//    private WeblogCategoryData locateCategory(
+//                                  String catName, HashMap categoryMap) 
+//    throws RollerException
+//    {
+//        WeblogCategoryData category = (WeblogCategoryData)categoryMap.get(catName);
+//        if (category == null) // not in local map
+//        {
+//            // look for it in database, by path
+//            category = roller.getWeblogManager()
+//                .getWeblogCategoryByPath(website, category, catName);
+//                        
+//            if (category == null) // not in database
+//            {    
+//                // create a new one
+//                category = new WeblogCategoryData(null, 
+//                    website, rootCategory, 
+//                    catName, catName, null);
+//                category.save();
+//            }
+//            categoryMap.put(catName, category);
+//        }
+//        
+//        return category;
+//    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/Authenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/Authenticator.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/Authenticator.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/Authenticator.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,15 @@
+
+package org.roller.presentation;
+
+import javax.servlet.http.HttpServletRequest;
+
+/** Interface used by Roller to check user authentication and role */
+public interface Authenticator
+{
+/** Return the name of the request's authenticated user, or null if none */
+public String getAuthenticatedUserName( HttpServletRequest req );
+
+/** Return true if authenticated user is in the specified role */
+public boolean isAuthenticatedUserInRole( HttpServletRequest req, String role);
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/BasePageModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/BasePageModel.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/BasePageModel.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/BasePageModel.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,96 @@
+/*
+ * Created on Mar 10, 2004
+ */
+package org.roller.presentation;
+
+import org.apache.struts.action.ActionMapping;
+import org.roller.RollerException;
+import org.roller.pojos.UserData;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Re-usable base for page models.
+ * @author David M Johnson
+ */
+public class BasePageModel
+{
+    private HttpServletRequest request = null;
+    private HttpServletResponse response = null;
+    private ActionMapping mapping = null;
+    
+    public BasePageModel(
+            HttpServletRequest request,
+            HttpServletResponse response,
+            ActionMapping mapping)
+    {
+        this.request = request;
+        this.response = response;
+        this.mapping = mapping;
+    }
+
+    public String getBaseURL()
+    {
+		return request.getContextPath();
+	}
+
+    public String getShortDateFormat()
+    {
+        DateFormat sdf = DateFormat.getDateInstance(
+                DateFormat.SHORT, request.getLocale());
+        if (sdf instanceof SimpleDateFormat)
+        {
+            return ((SimpleDateFormat)sdf).toLocalizedPattern();
+        }
+        return "yyyy/MM/dd";
+    }
+
+    public String getMediumDateFormat()
+    {
+        DateFormat sdf = DateFormat.getDateInstance(
+                DateFormat.MEDIUM, request.getLocale());
+        if (sdf instanceof SimpleDateFormat)
+        {
+            return ((SimpleDateFormat)sdf).toLocalizedPattern();
+        }
+        return "MMM dd, yyyy";
+    }
+
+    public UserData getUser()
+    {
+        return RollerRequest.getRollerRequest(request).getUser();
+    }
+    
+    /**
+     * @return Returns the mapping.
+     */
+    public ActionMapping getMapping() 
+    {
+        return mapping;
+    }
+    
+    /**
+     * @return Returns the request.
+     */
+    public HttpServletRequest getRequest() 
+    {
+        return request;
+    }
+    
+    /**
+     * @return Returns the response.
+     */
+    public HttpServletResponse getResponse() 
+    {
+        return response;
+    }
+    
+    public boolean getIsAdmin() throws RollerException
+    {
+        return RollerRequest.getRollerRequest(request).isAdminUser(); 
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/BlacklistUpdateTask.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/BlacklistUpdateTask.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/BlacklistUpdateTask.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/BlacklistUpdateTask.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,32 @@
+/*
+ * Created on Mar 10, 2004
+ */
+package org.roller.presentation;
+
+import java.util.TimerTask;
+
+import org.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.ScheduledTask;
+import org.roller.util.Blacklist;
+
+/**
+ * @author lance.lavandowska
+ */
+public class BlacklistUpdateTask extends TimerTask implements ScheduledTask
+{
+    public void run() 
+    {
+        // try reading new def from URL
+        Blacklist.checkForUpdate();
+    }
+    public void init(Roller roller, String realPath) throws RollerException
+    {
+        // load Blacklist from file
+        String uploadDir = RollerFactory.getRoller().getFileManager().getUploadDir();
+        Blacklist.getBlacklist(null, uploadDir);
+        // now have it check for an update
+        Blacklist.checkForUpdate();
+    }
+}

Added: incubator/roller/trunk/src/org/roller/presentation/DefaultAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/DefaultAuthenticator.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/DefaultAuthenticator.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/DefaultAuthenticator.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,30 @@
+
+package org.roller.presentation;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/** Class used by Roller to check user authentication and role */
+public class DefaultAuthenticator implements Authenticator
+{
+    /** Return the name of the request's authenticated user, or null if none */
+    public String getAuthenticatedUserName( HttpServletRequest req )
+    {
+        String ret = null;
+        Principal prince = req.getUserPrincipal(); 
+        if ( prince != null )
+        {
+            ret = prince.getName();
+        }
+        return ret;
+    }
+
+    /** Return true if authenticated user is in the specified role */
+    public boolean isAuthenticatedUserInRole(HttpServletRequest req,String role)
+    {
+        return req.isUserInRole( role );
+    }
+}
+

Added: incubator/roller/trunk/src/org/roller/presentation/LanguageUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/LanguageUtil.java?rev=189695&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/LanguageUtil.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/LanguageUtil.java Wed Jun  8 20:18:46 2005
@@ -0,0 +1,268 @@
+/*
+ * Filename: LanguageUtil.java
+ * 
+ * Created on 04-May-04
+ */
+package org.roller.presentation;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.Globals;
+import org.roller.pojos.WebsiteData;
+
+/**
+ * This class provides utility methods to deal with 
+ * multiple languages and other i18n stuff. 
+ * 
+ * @author <a href="mailto:molen@mail.com">Jaap van der Molen</a>
+ * @version $Revision: 1.8 $
+ */
+public class LanguageUtil
+{
+	private static Log mLogger = 
+	   LogFactory.getFactory().getInstance(LanguageUtil.class);
+
+	/**
+	 * reference to supported languages
+	 */
+	public static final String SUPPORTED_LANGUAGES =
+		"org.roller.presentation.supported.languages";
+
+	/**
+	 * Extracts langauges from the ServletContext. If
+	 * not present, returns null.
+	 * 
+	 * @param ctx
+	 * @return
+	 */
+	public static Locale[] getSupportedLanguages(ServletContext ctx)
+	{
+		return (Locale[]) ctx.getAttribute(SUPPORTED_LANGUAGES);
+	}
+
+	/**
+	 * Tests if a language is supported by roller as configured
+	 * in the LanguageServlet init paramater.
+	 * 
+	 * @param lang
+	 * @param ctx
+	 * @return
+	 */
+	public static boolean isSupported(String lang, ServletContext ctx)
+	{
+		return isSupported(createLocale(lang), ctx);
+	}
+		
+	/**
+	 * Tests if a language is supported by roller as configured
+	 * in the LanguageServlet init paramater.
+	 * 
+	 * If no supported languages are available, false is returned.
+	 * 
+	 * @param locale
+	 * @param ctx
+	 * @return
+	 */
+	public static boolean isSupported(Locale locale, ServletContext ctx)
+	{
+		mLogger.debug("isSupported( locale = "+locale+" )");
+		boolean isSupported = false;
+		Locale[] supportedLanguages = getSupportedLanguages(ctx);
+
+		if (supportedLanguages == null)
+		{
+			return false;
+		}
+		
+		for (int i=0; i<supportedLanguages.length; i++) 
+		{
+			Locale l = (Locale) supportedLanguages[i];
+			if (l.equals(locale)) {
+				isSupported = true;
+				break;
+			} else {
+				Locale langOnly = new Locale(locale.getLanguage());
+				if (l.equals(langOnly)) {
+					isSupported = true;
+					break;
+				}
+			}
+		}
+
+		return isSupported;
+	}
+
+	/**
+	 * This method returns the Locale in which the current viewer wants
+	 * to view the website. This 'View Locale' is derived as follows:
+	 * <ul>
+	 * <li>look for existing Locale in Session</li>
+	 * <li>if not available, get Locale from request</li>
+	 * <li>if not available, use {@link org.roller.presentation.LanguageUtil.getDefaultLocale()} 
+	 * (= Locale from <code>WebsiteData</code>)</li>
+	 * <li>if a Locale is available in the request, verify it against the locales that 
+	 * are supported by Roller; if it is not supported replace it with the default Locale</li>
+	 * 
+	 * The reason why I don't want to resort to the standard default mechanism of the
+	 * Java ResourceBundles, is that this only works for the messages and not for
+	 * other things like the dates and calendars (standard Java classes supports all locales). 
+	 * I think it looks silly to have the dates and calendars appear in French (e.g.) while 
+	 * the messages appear in English.
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static Locale getViewLocale(HttpServletRequest request)
+	{
+		mLogger.debug("getViewLocale()");
+		Locale viewLocale = null;
+
+		// if user is logged in and the user looking at his own website, take website-locale
+		if (isWebsiteOfPrincipal(request)) 
+        {
+			viewLocale = getDefaultLocale(request);
+			mLogger.debug("websiteLocale = "+viewLocale);
+		} 
+        else if (request.getSession(false) != null) 
+        {
+			// check session for existing Locale
+			viewLocale = (Locale) request.getSession().getAttribute(Globals.LOCALE_KEY);
+			mLogger.debug("sessionLocale = "+viewLocale);
+		}
+
+		// if not found, look in many places
+		if (viewLocale == null)
+		{
+			// get from request
+			viewLocale = request.getLocale();
+			mLogger.debug("requestLocale = "+viewLocale);
+
+			//still not there? take default
+			if (viewLocale == null)
+			{
+				viewLocale = getDefaultLocale(request);
+				mLogger.debug("defaultLocale = "+viewLocale);
+			}
+		}
+		
+		/*
+		 * If viewLocale is not supported, switch back to default.
+		 * 
+		 * Note: I do this here under the assumption
+		 * that the Locale in the Session is always supported. So,
+		 * no checks on the Session Locale.
+		 */
+        ServletContext ctx = RollerContext.getServletContext();
+		if (!LanguageUtil.isSupported(viewLocale, ctx))
+		{
+			viewLocale = Locale.getDefault();
+		}
+		mLogger.debug("return Locale = "+viewLocale);
+		
+		// add to session (for Velocity text tool)
+		request.getSession().setAttribute(Globals.LOCALE_KEY, viewLocale);
+		return viewLocale;
+	}
+	
+	/**
+	 * Returns the default website locale using <code>WebsiteData.getLocaleInstance()</code> and
+	 * returns <code>null</code> if the WebsiteData object is <code>null</code>.
+	 * 
+	 * Note: This <code>null</code> situation occurs if a User logs in, but his or her website has
+	 * been disabled. The website data is not loaded in that case.
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static Locale getDefaultLocale(HttpServletRequest request) {
+		mLogger.debug("getDefaultLocale()");
+		RollerRequest rreq = RollerRequest.getRollerRequest(request);
+		WebsiteData website = rreq.getWebsite();
+		if (website==null) {
+			return null;
+		} else {
+			return website.getLocaleInstance();
+		}
+	}
+	
+	/**
+	 * Verifies if the user is logged in and if so, if the website he
+	 * is currently viewing, is the user's website. In that case, true is returned.
+	 * Otherwise false.
+	 * 
+	 * The reason for this additional check is that I only want to enforce the
+	 * user's own locale if he at his own website. If I didn't, a logged-in user would be forced to 
+	 * view other sites in their default locale. That could lead to confusing situations.
+	 * 
+	 * TODO: Maybe what I am saying is: shouldn't we store the user's locale as the user's locale,
+	 * instead of as the website's locale?
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static boolean isWebsiteOfPrincipal(HttpServletRequest request) {
+		boolean result = false;
+		RollerRequest rreq = RollerRequest.getRollerRequest(request);
+		if (rreq != null) {            
+            WebsiteData website = rreq.getWebsite();
+            Principal principal = request.getUserPrincipal(); 
+            if (website != null && principal != null) {
+                return website.getUser().getUserName().equals(principal.getName());
+            }
+        }
+        return result;
+	}
+	
+	/**
+	 * Helper method to convert a language string to a <code>Locale</code> object.
+	 * Example language stringds are 'en' or 'en_US'.
+	 * 
+	 * @param lang
+	 * @return
+	 */
+	public static Locale createLocale(String lang) {
+		mLogger.debug("createLocale( lang = "+lang+" )");
+		Locale l = null;
+		if (lang.indexOf("_")>0) {
+			String tmpLang = lang.substring(0, lang.indexOf("_"));
+			String tmpCoun = lang.substring(lang.indexOf("_")+1, lang.length());
+			l = new Locale(tmpLang, tmpCoun); 
+		} else
+		{
+			l = new Locale(lang);
+		}
+		return l;
+	}
+
+	/**
+	 * Helper method to extract a collection of <code>Locale</code> from the
+	 * supported languages config string for the LanguageServlet.
+	 *  
+	 * @param supportedLanguages
+	 * @return
+	 */
+	public static Locale[] extractLanguages(String supportedLanguages) {
+		mLogger.debug("extractLanguages( lang = "+supportedLanguages+" )");
+		
+		Vector langs = new Vector();
+		StringTokenizer st = new StringTokenizer(supportedLanguages, ",");
+		while (st.hasMoreTokens())
+		{
+			Locale l = LanguageUtil.createLocale(st.nextToken());
+			langs.add(l);
+		}
+		mLogger.debug("supported languages: "+langs);
+		
+		return (Locale[]) langs.toArray(new Locale[langs.size()]);
+	}
+
+}