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/05/02 00:23:34 UTC

svn commit: r398712 [12/32] - in /incubator/roller/trunk/src/org/apache: ./ roller/ roller/business/ roller/business/hibernate/ roller/business/referrers/ roller/business/runnable/ roller/business/search/ roller/business/search/operations/ roller/busin...

Added: incubator/roller/trunk/src/org/apache/roller/pojos/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/pojos/package.html?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/pojos/package.html (added)
+++ incubator/roller/trunk/src/org/apache/roller/pojos/package.html Mon May  1 15:23:02 2006
@@ -0,0 +1,41 @@
+<!--
+  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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title></title>
+</head>
+<body>
+Persistent objects stored/retrieved by business layer.
+
+<p>At this level we avoid dependance on specific persistence engines 
+(e.g. Hibernate). We do this by using an interface named 
+{@link org.roller.business.PersistenceStrategy PersistenceStrategy} 
+to store, retrieve and remove 
+{@link org.roller.pojos.PersistentObject PersistentObjects}.</p>
+
+<img src="../business/roller-persistence.png" 
+    alt="diagram of Roller persistent object and strategy" />
+
+<p>The diagram below shows the objects in the Roller data model and the
+relationships between them.</p>
+
+<img src="roller-datamodel.png" alt="diagram of Roller data model" />
+
+</body>
+</html>

Added: incubator/roller/trunk/src/org/apache/roller/pojos/roller-datamodel.png
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/pojos/roller-datamodel.png?rev=398712&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/roller/trunk/src/org/apache/roller/pojos/roller-datamodel.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/roller/trunk/src/org/apache/roller/presentation/ArchiveParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/ArchiveParser.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/ArchiveParser.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/ArchiveParser.java Mon May  1 15:23:02 2006
@@ -0,0 +1,445 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Apr 2, 2004
+ */
+package org.apache.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/apache/roller/presentation/Authenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/Authenticator.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/Authenticator.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/Authenticator.java Mon May  1 15:23:02 2006
@@ -0,0 +1,32 @@
+/*
+* 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.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/apache/roller/presentation/BasePageModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/BasePageModel.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/BasePageModel.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/BasePageModel.java Mon May  1 15:23:02 2006
@@ -0,0 +1,148 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Mar 10, 2004
+ */
+package org.apache.roller.presentation;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.ActionMapping;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.util.StrutsUtil;
+
+/**
+ * Re-usable base for page models.
+ * @author David M Johnson
+ */
+public class BasePageModel
+{
+    protected static ResourceBundle bundle = 
+        ResourceBundle.getBundle("ApplicationResources");  
+    
+    protected String titleKey = null;
+    protected HttpServletRequest request = null;
+    protected HttpServletResponse response = null;
+    protected ActionMapping mapping = null;
+    protected WebsiteData website = null;
+    
+    public BasePageModel(
+            String titleKey,
+            HttpServletRequest request,
+            HttpServletResponse response,
+            ActionMapping mapping)
+    {
+        this.request = request;
+        this.response = response;
+        this.mapping = mapping;
+        this.titleKey = titleKey;
+        request.setAttribute("locales", StrutsUtil.getLocaleBeans());        
+        request.setAttribute("timeZones", StrutsUtil.getTimeZoneBeans());        
+        RollerRequest rreq = RollerRequest.getRollerRequest(request);
+        website = rreq.getWebsite();
+    }
+
+    public WebsiteData getWebsite() 
+    {
+        return website;
+    }
+    
+    public void setWebsite(WebsiteData website) 
+    {
+        this.website = website;
+    }
+    
+    public String getTitle() 
+    {
+        return bundle.getString(titleKey);
+    }
+    
+    public String getBaseURL()
+    {
+        RollerContext rctx = RollerContext.getRollerContext();
+		return rctx.getAbsoluteContextUrl(request);
+	}
+
+    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";
+    }
+
+    /**
+     * @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 RollerSession getRollerSession()
+    {
+        return RollerSession.getRollerSession(request);
+    }
+
+    public List getLocales()
+    {
+        return StrutsUtil.getLocaleBeans();
+    }
+
+    public List getTimeZones()
+    {
+        return StrutsUtil.getTimeZoneBeans();
+    }
+
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/BlacklistUpdateTask.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/BlacklistUpdateTask.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/BlacklistUpdateTask.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/BlacklistUpdateTask.java Mon May  1 15:23:02 2006
@@ -0,0 +1,80 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Mar 10, 2004
+ */
+package org.apache.roller.presentation;
+
+import java.util.TimerTask;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.RollerException;
+import org.apache.roller.model.Roller;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.ScheduledTask;
+import org.apache.roller.util.Blacklist;
+
+/**
+ * Update MT Blacklist if needed.
+ *
+ * @author Allen Gilliland
+ */
+public class BlacklistUpdateTask extends TimerTask implements ScheduledTask {
+    
+    private static Log mLogger = LogFactory.getLog(BlacklistUpdateTask.class);
+    
+    
+    /**
+     * Task init.
+     */
+    public void init(Roller roller, String realPath) throws RollerException {
+        mLogger.debug("initing");
+    }
+    
+    
+    /**
+     * Excecute the task.
+     */
+    public void run() {
+        
+        mLogger.info("task started");
+
+        Blacklist.checkForUpdate();
+        
+        mLogger.info("task completed");
+    }
+    
+    
+    /**
+     * Main method so that this task may be run from outside the webapp.
+     */
+    public static void main(String[] args) throws Exception {
+        try {            
+            // NOTE: if this task is run externally from the Roller webapp then
+            // all it will really be doing is downloading the MT blacklist file
+            BlacklistUpdateTask task = new BlacklistUpdateTask();
+            task.init(null, null);
+            task.run();
+            System.exit(0);
+        } catch (RollerException ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        }
+    }
+    
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/DefaultAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/DefaultAuthenticator.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/DefaultAuthenticator.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/DefaultAuthenticator.java Mon May  1 15:23:02 2006
@@ -0,0 +1,47 @@
+/*
+* 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.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/apache/roller/presentation/InvalidRequestException.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/InvalidRequestException.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/InvalidRequestException.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/InvalidRequestException.java Mon May  1 15:23:02 2006
@@ -0,0 +1,42 @@
+/*
+* 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.
+*/
+/*
+ * InvalidRequestException.java
+ *
+ * Created on December 12, 2005, 9:49 AM
+ */
+
+package org.apache.roller.presentation;
+
+/**
+ * An InvalidRequestException is thrown by the ParsedRequest class or any of
+ * its subclasses when the request being parsed is invalid in any way.
+ *
+ * @author Allen Gilliland
+ */
+public class InvalidRequestException extends Exception {
+    
+    public InvalidRequestException(String msg) {
+        super(msg);
+    }
+    
+    public InvalidRequestException(String msg, Exception e) {
+        super(msg, e);
+    }
+    
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/LanguageUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/LanguageUtil.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/LanguageUtil.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/LanguageUtil.java Mon May  1 15:23:02 2006
@@ -0,0 +1,289 @@
+/*
+* 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.
+*/
+/*
+ * Filename: LanguageUtil.java
+ * 
+ * Created on 04-May-04
+ */
+package org.apache.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.apache.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.apache.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.apache.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 user's don;t have locales, websites do and a user
+        // can belong to multiple websites, each with a different locale.
+        // So this check no longer makes sense.
+		//if (isWebsiteOfPrincipal(request)) 
+        //{
+			//viewLocale = getDefaultLocale(request);
+			//mLogger.debug("websiteLocale = "+viewLocale);
+		//} 
+        
+        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()]);
+	}
+
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/MainPageAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/MainPageAction.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/MainPageAction.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/MainPageAction.java Mon May  1 15:23:02 2006
@@ -0,0 +1,146 @@
+/*
+* 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.presentation;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.roller.RollerException;
+import org.apache.roller.config.RollerRuntimeConfig;
+import org.apache.roller.model.Roller;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.WeblogManager;
+import org.apache.roller.pojos.WeblogEntryData;
+
+
+/**
+ * Main page action for Roller.
+ * @struts.action name="main" path="/main" scope="request"
+ * @struts.action-forward name="main.page" path=".main"
+ */
+public class MainPageAction extends Action {
+    
+    private static Log mLogger =
+            LogFactory.getFactory().getInstance(MainPageAction.class);
+    
+    /**
+     * Loads model and forwards to main.page.
+     */
+    public ActionForward execute(
+            ActionMapping mapping, ActionForm form,
+            HttpServletRequest req, HttpServletResponse res)
+            throws Exception {
+        RollerContext rctx = RollerContext.getRollerContext();
+        
+        req.setAttribute("version",rctx.getRollerVersion());
+        req.setAttribute("buildTime",rctx.getRollerBuildTime());
+        req.setAttribute("baseURL", rctx.getContextUrl(req));
+        
+        MainPageData model = new MainPageData(req, res, mapping);
+        req.setAttribute("model", model);
+        req.setAttribute("data", model);
+        
+        // Determines if register new sers
+        boolean allowNewUsers =
+                RollerRuntimeConfig.getBooleanProperty("users.registration.enabled");
+        
+        java.security.Principal prince = req.getUserPrincipal();
+        if (prince != null) {
+            req.setAttribute("loggedIn",Boolean.TRUE);
+            req.setAttribute("userName",prince.getName());
+        } else if (allowNewUsers) {
+            req.setAttribute("allowNewUsers",Boolean.TRUE);
+        }
+        req.setAttribute("leftPage","/theme/status.jsp");
+        
+        return mapping.findForward("main.page");
+    }
+        
+    /**
+     * Page model.
+     */
+    public static class MainPageData extends BasePageModel {
+        private HttpServletRequest mRequest = null;
+        
+        public MainPageData(
+                HttpServletRequest req,
+                HttpServletResponse res,
+                ActionMapping mapping) {
+            super("dummyTitleKey", req, res, mapping);
+            mRequest = req;
+        }
+        
+        /**
+         * Get list of most popular websites in terms of day hits.
+         * @param num Number of entries to return (takes effect on next cache refresh)
+         */
+        public List getPopularWebsites(int num) throws RollerException {
+            List list = null;
+            mLogger.debug("Refreshing popular websites list");
+            Roller roller = RollerFactory.getRoller();
+            list = roller.getRefererManager().getDaysPopularWebsites(num);
+            return list;
+        }
+        
+        /**
+         * Get list of recent weblog entries.
+         * @param num Number of entries to return (takes effect on next cache refresh)
+         */
+        public List getRecentWeblogEntries(int num) throws RollerException {
+            List list = null;
+            try {
+                mLogger.debug("Refreshing recent entries list");
+                Roller roller = RollerFactory.getRoller();
+                list = roller.getWeblogManager().getWeblogEntries(
+                        null,                   // userName
+                        null,                   // startDate
+                        new Date(),             // endDate
+                        null,                   // catName
+                        WeblogEntryData.PUBLISHED, // status
+                        null,                   // sortby (null for pubTime)
+                        new Integer(num));      // maxEntries
+            } catch (Exception e) {
+                mLogger.error(e);
+            }
+            return list;
+        }
+        
+        /**
+         * Get list of recent weblog pinned entries
+         * @param num Number of entries to return (takes effect on next cache refresh)
+         */
+        public List getWeblogEntriesPinnedToMain(int num) throws RollerException {
+            List list = null;
+            mLogger.debug("Refreshing pinned entries list");
+            Roller roller = RollerFactory.getRoller();
+            list = roller.getWeblogManager()
+                .getWeblogEntriesPinnedToMain(new Integer(num));
+            return list;
+        }
+    }
+}
+

Added: incubator/roller/trunk/src/org/apache/roller/presentation/ParsedRequest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/ParsedRequest.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/ParsedRequest.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/ParsedRequest.java Mon May  1 15:23:02 2006
@@ -0,0 +1,101 @@
+/*
+* 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.
+*/
+/*
+ * WeblogRequest.java
+ *
+ * Created on November 7, 2005, 12:29 PM
+ */
+
+package org.apache.roller.presentation;
+
+import java.util.Locale;
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * An abstract class representing any request made to Roller that has been
+ * parsed in order to extract relevant pieces of information from the url.
+ *
+ * NOTE: It is extremely important to mention that this class and all of its
+ * subclasses are meant to be extremely light weight.  Meaning they should
+ * avoid any time consuming operations at all costs, especially operations
+ * which require a trip to the db.  Those operations should be used very, very
+ * sparingly and should only be triggered when it's guaranteed that they are
+ * needed.
+ *
+ * @author Allen Gilliland
+ */
+public abstract class ParsedRequest {
+    
+    HttpServletRequest request = null;
+    
+    private String language = null;
+    private String authenticUser = null;
+    
+    
+    ParsedRequest() {}
+    
+    
+    /**
+     * Parse the given http request and extract any information we can.
+     *
+     * This abstract version of the constructor gathers info likely to be
+     * relevant to all requests to Roller.
+     */
+    public ParsedRequest(HttpServletRequest request) throws InvalidRequestException {
+        
+        // keep a reference to the original request
+        this.request = request;
+        
+        // login status
+        java.security.Principal prince = request.getUserPrincipal();
+        if(prince != null) {
+            this.authenticUser = prince.getName();
+        }
+        
+    }
+    
+    
+    public String getLanguage() {
+        if(this.language == null) {
+            // determine language
+            // this operation can possibly require a trip to the db, so we only
+            // do it when we know our user needs to know the language
+            Locale locale = LanguageUtil.getViewLocale(request);
+            this.language = locale.getLanguage();
+        }
+
+        return this.language;
+    }
+    
+    
+    public String getAuthenticUser() {
+        return this.authenticUser;
+    }
+    
+    
+    public boolean isLoggedIn() {
+        return (this.authenticUser != null);
+    }
+
+    
+    public HttpServletRequest getRequest() {
+        return this.request;
+    }
+    
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/PlanetRequest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/PlanetRequest.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/PlanetRequest.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/PlanetRequest.java Mon May  1 15:23:02 2006
@@ -0,0 +1,112 @@
+/*
+* 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.
+*/
+/*
+ * PlanetRequest.java
+ *
+ * Created on December 12, 2005, 9:47 AM
+ */
+
+package org.apache.roller.presentation;
+
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Represents a request for a Planet Roller url.
+ *
+ * currently ... /planet.do and /planetrss
+ *
+ * @author Allen Gilliland
+ */
+public class PlanetRequest extends ParsedRequest {
+    
+    private static Log mLogger = LogFactory.getLog(PlanetRequest.class);
+    
+    private String context = null;
+    private String type = null;
+    private String flavor = null;
+    private boolean excerpts = false;
+    
+    
+    /**
+     * Construct the PlanetRequest by parsing the incoming url
+     */
+    public PlanetRequest(HttpServletRequest request) throws InvalidRequestException {
+        
+        super(request);
+        
+        // parse the request object and figure out what we've got
+        mLogger.debug("parsing url "+request.getRequestURL());
+        
+        String servlet = request.getServletPath();
+        
+        // what servlet is our destination?
+        if(servlet != null) {
+            // strip off the leading slash
+            servlet = servlet.substring(1);
+            
+            if(servlet.equals("planet.do")) {
+                this.context = "planet";
+                this.type = "page";
+            } else if(servlet.equals("planetrss")) {
+                this.context = "planet";
+                this.type = "feed";
+                this.flavor = "rss";
+            } else {
+                // not a request to a feed servlet
+                throw new InvalidRequestException("not a planet request, "+request.getRequestURL());
+            }
+            
+        } else {
+            throw new InvalidRequestException("not a planet request, "+request.getRequestURL());
+        }
+        
+        
+        /* 
+         * parse request parameters
+         *
+         * the only params we currently care about are:
+         *   excerpts - specifies the feed should only include excerpts
+         *
+         */
+        if(request.getParameter("excerpts") != null) {
+            this.excerpts = Boolean.valueOf(request.getParameter("excerpts")).booleanValue();
+        }
+        
+    }
+
+    
+    public String getContext() {
+        return context;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getFlavor() {
+        return flavor;
+    }
+
+    public boolean isExcerpts() {
+        return excerpts;
+    }
+    
+}

Added: incubator/roller/trunk/src/org/apache/roller/presentation/RollerContext.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/RollerContext.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/RollerContext.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/RollerContext.java Mon May  1 15:23:02 2006
@@ -0,0 +1,520 @@
+/*
+* 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.presentation;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.TimerTask;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSessionEvent;
+import javax.sql.DataSource;
+
+import org.acegisecurity.ConfigAttributeDefinition;
+import org.acegisecurity.SecurityConfig;
+import org.acegisecurity.intercept.web.PathBasedFilterInvocationDefinitionMap;
+import org.acegisecurity.providers.ProviderManager;
+import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
+import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
+import org.acegisecurity.providers.encoding.PasswordEncoder;
+import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
+import org.acegisecurity.securechannel.ChannelProcessingFilter;
+import org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.apache.roller.RollerException;
+import org.apache.roller.business.utils.UpgradeDatabase;
+import org.apache.roller.config.PingConfig;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.config.RollerRuntimeConfig;
+import org.apache.roller.model.Roller;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.ScheduledTask;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.pings.PingQueueTask;
+import org.apache.roller.util.StringUtils;
+import org.apache.roller.util.Utilities;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+import org.apache.roller.presentation.cache.CacheManager;
+
+
+/**
+ * Responds to app init/destroy events and holds Roller instance.
+ *
+ * @web.listener
+ */
+public class RollerContext extends ContextLoaderListener implements ServletContextListener {
+    
+    private static Log mLogger = LogFactory.getLog(RollerContext.class);
+    
+    private String mVersion = null;
+    private String mBuildTime = null;
+    private String mBuildUser = null;
+    
+    public static final String ROLLER_CONTEXT = "roller.context";
+    
+    private static ServletContext mContext = null;
+    private static Authenticator mAuthenticator = null;
+    private final SynchronizedInt mSessionCount = new SynchronizedInt(0);
+    
+    
+    /**
+     * Constructor for RollerContext.
+     */
+    public RollerContext() {
+        super();
+        
+        Properties props = new Properties();
+        try {
+            props.load(getClass().getResourceAsStream("/version.properties"));
+        } catch (IOException e) {
+            mLogger.error("version.properties not found", e);
+        }
+        
+        mVersion = props.getProperty("ro.version", "UNKNOWN");
+        mBuildTime = props.getProperty("ro.buildTime", "UNKNOWN");
+        mBuildUser = props.getProperty("ro.buildUser", "UNKNOWN");
+    }
+    
+    
+    /* Returns Roller instance for specified app */
+    public static RollerContext getRollerContext() {
+        // get roller from servlet context
+        ServletContext sc = RollerContext.getServletContext();
+        return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
+    }
+    
+    
+    /** Responds to app-destroy by saving the indexManager's information */
+    public void contextDestroyed(ServletContextEvent sce) {
+        RollerFactory.getRoller().shutdown();
+        
+        // do we need a more generic mechanism for presentation layer shutdown?
+        CacheManager.shutdown();
+    }
+    
+    
+    /**
+     * Responds to context initialization event by processing context
+     * paramters for easy access by the rest of the application.
+     */
+    public void contextInitialized(ServletContextEvent sce) {
+        
+        mLogger.debug("RollerContext initializing");
+        
+        // Save context in self and self in context
+        mContext = sce.getServletContext();
+        mContext.setAttribute(ROLLER_CONTEXT, this);
+        
+        // get the *real* path to <context>/resources
+        String ctxPath = mContext.getRealPath("/");
+        if(!ctxPath.endsWith(File.separator))
+            ctxPath += File.separator + "resources";
+        else
+            ctxPath += "resources";
+        
+        // try setting the uploads path to <context>/resources
+        // NOTE: this should go away at some point
+        // we leave it here for now to allow users to keep writing
+        // uploads into their webapp context, but this is a bad idea
+        //
+        // also, the RollerConfig.setUploadsDir() method is smart
+        // enough to disregard this call unless the uploads.path
+        // is set to ${webapp.context}
+        RollerConfig.setUploadsDir(ctxPath);
+        
+        // set the roller context real path in RollerConfig
+        // NOTE: it seems that a few backend classes do actually need
+        //       to know what the real path to the roller context is,
+        //       so we set this property to give them the info they need.
+        //
+        //       this is really not a best practice and we should try to
+        //       remove these dependencies on the webapp context if possible
+        RollerConfig.setContextRealPath(mContext.getRealPath("/"));
+        
+        try {
+            // always upgrade database first
+            upgradeDatabaseIfNeeded();
+            
+            Roller roller = RollerFactory.getRoller();
+            
+            setupRollerProperties();
+            
+            // call Spring's context ContextLoaderListener to initialize
+            // all the context files specified in web.xml. This is necessary
+            // because listeners don't initialize in the order specified in
+            // 2.3 containers
+            super.contextInitialized(sce);
+            
+            initializeSecurityFeatures(mContext);
+            
+            roller.getThemeManager();
+            setupIndexManager(roller);
+            initializePingFeatures(roller);
+            setupPingQueueTask(roller);
+            setupScheduledTasks(mContext, roller);
+            
+            roller.flush();
+            roller.release();
+            
+        } catch (Throwable t) {
+            mLogger.fatal("RollerContext initialization failed", t);
+        }
+        
+        mLogger.debug("RollerContext initialization complete");
+    }
+    
+    
+    private void setupRollerProperties() throws RollerException {
+        // init property manager by creating it
+        Roller mRoller = RollerFactory.getRoller();
+        mRoller.getPropertiesManager();
+    }
+    
+    
+    /** Setup daily and hourly tasks specified in web.xml */
+    private void setupScheduledTasks(ServletContext context, Roller roller)
+            throws RollerException, InstantiationException,
+            IllegalAccessException, ClassNotFoundException {
+        
+        // setup the hourly tasks
+        String hourlyString = RollerConfig.getProperty("tasks.hourly");
+        if (hourlyString != null && hourlyString.trim().length() > 0) {
+            String[] hourlyTasks = StringUtils.stripAll(
+                    StringUtils.split(hourlyString, ",") );
+            for (int i=0; i<hourlyTasks.length; i++) {
+                mLogger.info("Setting hourly task: "+hourlyTasks[i]);
+                ScheduledTask task =
+                        (ScheduledTask)Class.forName(hourlyTasks[i]).newInstance();
+                task.init(roller, mContext.getRealPath("/"));
+                roller.getThreadManager().scheduleHourlyTimerTask((TimerTask)task);
+            }
+        }
+        
+        // setup the daily tasks
+        String dailyString = RollerConfig.getProperty("tasks.daily");
+        if (dailyString != null && dailyString.trim().length() > 0) {
+            String[] dailyTasks = StringUtils.stripAll(
+                    StringUtils.split(dailyString, ",") );
+            for (int j=0; j<dailyTasks.length; j++) {
+                mLogger.info("Setting daily task: "+dailyTasks[j]);
+                ScheduledTask task =
+                        (ScheduledTask)Class.forName(dailyTasks[j]).newInstance();
+                task.init(roller, mContext.getRealPath("/"));
+                roller.getThreadManager().scheduleDailyTimerTask((TimerTask)task);
+            }
+        }
+    }
+    
+    
+    // Initialize ping features
+    private void initializePingFeatures(Roller roller) throws RollerException {
+        
+        // Initialize common targets from the configuration
+        PingConfig.initializeCommonTargets();
+        // Remove csutom ping targets if they have been disallowed
+        if (PingConfig.getDisallowCustomTargets()) {
+            mLogger.info("Custom ping targets have been disallowed.  Removing any existing custom targets.");
+            roller.getPingTargetManager().removeAllCustomPingTargets();
+        }
+        // Remove all autoping configurations if ping usage has been disabled.
+        if (PingConfig.getDisablePingUsage()) {
+            mLogger.info("Ping usage has been disabled.  Removing any existing auto ping configurations.");
+            roller.getAutopingManager().removeAllAutoPings();
+        }
+    }
+    
+    
+    // Set up the ping queue processing task
+    private void setupPingQueueTask(Roller roller) throws RollerException {
+        
+        long intervalMins = PingConfig.getQueueProcessingIntervalMins();
+        if (intervalMins == 0) {
+            // Ping queue processing interval of 0 indicates that ping queue processing is disabled on this host.
+            // This provides a crude  way to disable running the ping queue task on some servers if there are
+            // multiple servers in a cluster sharing a db.  Exclusion should really be handled dynamically but isn't.
+            mLogger.warn("Ping queue processing interval is zero; processing from the ping queue will be disabled on this server.");
+            mLogger.warn("Please make sure that ping queue processing is configured to run on one server in the cluster.");
+            return;
+        }
+        
+        // Set up the task
+        PingQueueTask pingQueueTask = new PingQueueTask();
+        pingQueueTask.init(this, intervalMins);
+        
+        // Schedule it at the appropriate interval, delay start for one interval.
+        mLogger.info("Scheduling ping queue task to run at " + intervalMins + " minute intervals.");
+        roller.getThreadManager().scheduleFixedRateTimerTask(pingQueueTask, intervalMins, intervalMins);
+    }
+    
+    
+    protected void initializeSecurityFeatures(ServletContext context) {
+        
+        ApplicationContext ctx =
+                WebApplicationContextUtils.getRequiredWebApplicationContext(context);
+        
+        String rememberMe = RollerConfig.getProperty("rememberme.enabled");
+        boolean rememberMeEnabled = Boolean.valueOf(rememberMe).booleanValue();
+        
+        mLogger.info("Remember Me enabled: " + rememberMeEnabled);
+        
+        context.setAttribute("rememberMeEnabled", rememberMe);
+        
+        if (rememberMeEnabled) {
+            ProviderManager provider = (ProviderManager) ctx.getBean("authenticationManager");
+            provider.getProviders().add(ctx.getBean("rememberMeAuthenticationProvider"));
+        }
+        
+        String encryptPasswords = RollerConfig.getProperty("passwds.encryption.enabled");
+        boolean doEncrypt = Boolean.valueOf(encryptPasswords).booleanValue();
+        
+        if (doEncrypt) {
+            DaoAuthenticationProvider provider =
+                    (DaoAuthenticationProvider) ctx.getBean("daoAuthenticationProvider");
+            String algorithm = RollerConfig.getProperty("passwds.encryption.algorithm");
+            PasswordEncoder encoder = null;
+            if (algorithm.equalsIgnoreCase("SHA")) {
+                encoder = new ShaPasswordEncoder();
+            } else if (algorithm.equalsIgnoreCase("MD5")) {
+                encoder = new Md5PasswordEncoder();
+            } else {
+                mLogger.error("Encryption algorithm '" + algorithm +
+                        "' not supported, disabling encryption.");
+            }
+            if (encoder != null) {
+                provider.setPasswordEncoder(encoder);
+                mLogger.info("Password Encryption Algorithm set to '" + algorithm + "'");
+            }
+        }
+        
+        if (RollerConfig.getBooleanProperty("securelogin.enabled")) {
+            AuthenticationProcessingFilterEntryPoint entryPoint =
+                    (AuthenticationProcessingFilterEntryPoint)ctx.getBean("authenticationProcessingFilterEntryPoint");
+            entryPoint.setForceHttps(true);
+        }
+        /*
+        if (RollerConfig.getBooleanProperty("schemeenforcement.enabled")) {
+            
+            ChannelProcessingFilter procfilter =
+                    (ChannelProcessingFilter)ctx.getBean("channelProcessingFilter");
+            ConfigAttributeDefinition secureDef = new ConfigAttributeDefinition();
+            secureDef.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
+            ConfigAttributeDefinition insecureDef = new ConfigAttributeDefinition();
+            insecureDef.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
+            PathBasedFilterInvocationDefinitionMap defmap =
+                    (PathBasedFilterInvocationDefinitionMap)procfilter.getFilterInvocationDefinitionSource();
+            
+            // add HTTPS URL path patterns to Acegi config
+            String httpsUrlsProp = RollerConfig.getProperty("schemeenforcement.https.urls");
+            if (httpsUrlsProp != null) {
+                String[] httpsUrls = StringUtils.stripAll(StringUtils.split(httpsUrlsProp, ",") );
+                for (int i=0; i<httpsUrls.length; i++) {
+                    defmap.addSecureUrl(httpsUrls[i], secureDef);
+                }
+            }
+            // all other action URLs are non-HTTPS
+            defmap.addSecureUrl("/**<!-- need to remove this when uncommenting -->/*.do*", insecureDef);
+        }
+        */
+    }
+    
+    
+    protected void upgradeDatabaseIfNeeded() throws RollerException {
+        
+        try {
+            InitialContext ic = new InitialContext();
+            DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/rollerdb");
+            Connection con = ds.getConnection();
+            UpgradeDatabase.upgradeDatabase(con, mVersion);
+            con.close();
+        } catch (NamingException e) {
+            mLogger.warn("Unable to access DataSource", e);
+        } catch (SQLException e) {
+            mLogger.warn(e);
+        }
+    }
+    
+    
+    private void setupIndexManager(Roller roller) throws RollerException {
+        roller.getIndexManager();
+    }
+    
+    
+    public void sessionCreated(HttpSessionEvent se) {
+        mSessionCount.increment();
+        
+        mLogger.debug("sessions="+ mSessionCount
+                    + ":freemem=" + Runtime.getRuntime().freeMemory()
+                    + ":totmem=" + Runtime.getRuntime().totalMemory());
+    }
+    
+    
+    public void sessionDestroyed(HttpSessionEvent se) {
+        mSessionCount.decrement();
+        
+        mLogger.debug("sessions=" + mSessionCount
+                    + ":freemem=" + Runtime.getRuntime().freeMemory()
+                    + ":totalmem=" + Runtime.getRuntime().totalMemory());
+    }
+    
+    
+    /**
+     * Get authenticator
+     */
+    public Authenticator getAuthenticator() {
+        if (mAuthenticator == null) {
+            try {
+                Class authClass =
+                        Class.forName(RollerConfig.getProperty("authenticator.classname"));
+                mAuthenticator = (Authenticator) authClass.newInstance();
+            } catch (Exception e) {
+                // this isn't an ERROR if no authenticatorClass was specified
+                if (!(e instanceof NullPointerException)) {
+                    mLogger.error("ERROR creating authenticator, using default", e);
+                } else {
+                    mLogger.debug("No authenticator specified, using DefaultAuthenticator");
+                }
+                mAuthenticator = new DefaultAuthenticator();
+            }
+        }
+        return mAuthenticator;
+    }
+       
+    /**
+     * Returns the full url for the website of the specified username.
+     */
+    public String getContextUrl(HttpServletRequest request, WebsiteData website) {
+        String url = this.getContextUrl(request);
+        if (website != null) {
+            url = url + "/page/" + website.getHandle();
+        }
+        return url;
+    }
+    
+    
+    /** Get absolute URL of Roller context */
+    public String getContextUrl(HttpServletRequest request) {
+        String url = request.getContextPath();
+        if (url.endsWith("/")) {
+            url = url.substring(0, url.length() - 1);
+        }
+        return url;
+    }
+    
+    
+    /** Get absolute URL of Roller context */
+    public String getAbsoluteContextUrl(HttpServletRequest request) {
+        
+        String url = RollerRuntimeConfig.getProperty("site.absoluteurl");
+        
+        if (url == null || url.trim().length() == 0) {
+            try {
+                URL absURL = RequestUtils.absoluteURL(request, "/");
+                url = absURL.toString();
+            } catch (MalformedURLException e) {
+                url = "/";
+                mLogger.error("ERROR: forming absolute URL", e);
+            }
+        }
+        
+        if (url.endsWith("/")) {
+            url = url.substring(0, url.length() - 1);
+        }
+        
+        mContext.setAttribute("org.apache.roller.absoluteContextURL", url);
+        return url;
+    }
+    
+    
+    /**
+     * For use by MetaWeblog API.
+     *
+     * @return Context URL or null if not initialized yet.
+     */
+    public String getAbsoluteContextUrl() {
+        return (String) mContext.getAttribute("org.apache.roller.absoluteContextURL");
+    }
+    
+    
+    public String createEntryPermalink(
+            WeblogEntryData entry,
+            HttpServletRequest request,
+            boolean absolute) {
+        String link = null;
+        try {
+            String baseUrl = null;
+            if (absolute) {
+                baseUrl = getAbsoluteContextUrl(request);
+            } else {
+                baseUrl = getContextUrl(request);
+            }
+            link = Utilities.escapeHTML(baseUrl + entry.getPermaLink());
+        } catch (Exception e) {
+            mLogger.error("Unexpected exception", e);
+        }
+        
+        return link;
+    }
+    
+    
+    /**
+     * Get the ServletContext.
+     *
+     * @return ServletContext
+     */
+    public static ServletContext getServletContext() {
+        return mContext;
+    }
+    
+    
+    /** Roller version */
+    public String getRollerVersion() {
+        return mVersion;
+    }
+    
+    
+    /** Roller build time */
+    public String getRollerBuildTime() {
+        return mBuildTime;
+    }
+    
+    
+    /** Get username that built Roller */
+    public String getRollerBuildUser() {
+        return mBuildUser;
+    }
+
+}