roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r327589 [28/72] - in /incubator/roller/branches/roller_1.x: ./ 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...
Date Fri, 21 Oct 2005 21:46:28 GMT
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/ArchiveParser.java Fri Oct 21 14:27:36 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/branches/roller_1.x/src/org/roller/presentation/Authenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/Authenticator.java Fri Oct 21 14:27:36 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/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/BasePageModel.java Fri Oct 21 14:27:36 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/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/BlacklistUpdateTask.java Fri Oct 21 14:27:36 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/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/DefaultAuthenticator.java Fri Oct 21 14:27:36 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/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/LanguageUtil.java Fri Oct 21 14:27:36 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()]);
+	}
+
+}

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/LoginServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,225 @@
+package org.roller.presentation;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.presentation.util.SslUtil;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.roller.config.RollerConfig;
+
+
+
+/**
+ * Implementation of <strong>HttpServlet</strong> that is used
+ * to get a username and password and mEncrypt the password
+ * before sending to container-managed authentication.
+ *
+ * <p><a href="LoginServlet.java.html"><i>View Source</i></a></p>
+ *
+ * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
+ * @version $Revision: 1.19 $ $Date: 2005/06/07 18:30:18 $
+ *
+ * @web.servlet
+ *     display-name="Login Servlet"
+ *     load-on-startup="3"
+ *     name="login"
+ *
+ * @web.servlet-init-param
+ *     name="authURL"
+ *     value="/j_security_check"
+ *
+ * @web.servlet-mapping
+ *     url-pattern="/auth/*"
+ */
+public class LoginServlet extends HttpServlet
+{
+    static final long serialVersionUID = 8054268881470797053L;
+    
+    protected static String mAuthURL = "/j_security_check";
+    protected static String mAlgorithm = "SHA";
+    protected static Boolean mEncrypt = Boolean.FALSE;
+    
+    private boolean secureLogin = false;
+    private String loginHttpsPort = SslUtil.STD_HTTPS_PORT;
+    
+    //=========================================================================
+    // Private Member Variables
+    //=========================================================================
+    private static Log mLogger = LogFactory.getLog(LoginServlet.class);
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Validates the Init and Context parameters, configures authentication URL
+     *
+     * @throws ServletException if the init parameters are invalid or any
+     * other problems occur during initialisation
+     */
+    public void init() throws ServletException
+    {
+        // Get the container authentication URL for FORM-based Authentication
+        // J2EE spec says should be j_security_check
+        if (getInitParameter("authURL") != null) 
+        {
+        	    mAuthURL = getInitParameter("authURL");
+        }
+        
+        String secureLogin = RollerConfig.getProperty("securelogin.enabled");
+        if(secureLogin != null && "true".equalsIgnoreCase(secureLogin))
+            this.secureLogin = true;
+        
+        String secureLoginPort = RollerConfig.getProperty("securelogin.https.port");
+        if(secureLoginPort != null)
+            this.loginHttpsPort = secureLoginPort;
+        
+        mLogger.info("secure login enabled: "+this.secureLogin);
+        mLogger.info("secure login port: "+this.loginHttpsPort);
+    }
+
+    /**
+     * Route the user to the execute method
+     *
+     * @param request The HTTP request we are processing
+     * @param response The HTTP response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+               throws IOException, ServletException
+    {
+        execute(request, response);
+    }
+
+    /**
+     * Route the user to the execute method
+     *
+     * @param request The HTTP request we are processing
+     * @param response The HTTP response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void doPost(HttpServletRequest request, HttpServletResponse response)
+                throws IOException, ServletException
+    {
+        execute(request, response);
+    }
+
+    /**
+     * Process the specified HTTP request, and create the corresponding HTTP
+     * response (or forward to another web component that will create it).
+     *
+     * @param request The HTTP request we are processing
+     * @param response The HTTP response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void execute(HttpServletRequest request, 
+                        HttpServletResponse response) throws IOException, 
+                                                             ServletException
+    {
+        // if user is already authenticated, it means they probably bookmarked
+        // or typed in the URL to login.jsp directly, route them to the main
+        // menu if this is the case
+        if (request.getRemoteUser() != null) {
+            if (mLogger.isDebugEnabled()) {
+                mLogger.debug("User '" + request.getRemoteUser() +
+                          "' already logged in, routing to main");
+            }
+            response.sendRedirect(request.getContextPath() + "/main.do");
+            return;
+        }
+        
+        // Extract attributes we will need
+        String username = request.getParameter("j_username");
+        String password = request.getParameter("j_password");
+        
+        String encryptedPassword = getEncryptedPassword(request, username, password);
+
+        String req = null;
+        String contextUrl = null;
+        if (this.secureLogin)
+        {
+            // Secure login and app server may not know it, so we must build URL 
+            StringBuffer sb = new StringBuffer("");
+            sb.append("https://");
+            if (this.loginHttpsPort.equals(SslUtil.STD_HTTPS_PORT)) 
+            {
+                sb.append(request.getServerName());
+            }
+            else 
+            {
+                sb.append(request.getServerName() + ":" + this.loginHttpsPort);
+            }
+            sb.append(request.getContextPath());
+            contextUrl = sb.toString();
+        }
+        else 
+        {
+            contextUrl = request.getContextPath();
+        }
+        // TODO: is there a way we can do this without having password in the URL?
+        req = contextUrl + mAuthURL 
+            + "?j_username=" + username 
+            + "&j_password=" + encryptedPassword 
+            + "&j_uri=" + request.getParameter("j_uri");
+
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("Authenticating user '" + username + "'");
+        }
+
+        response.sendRedirect(response.encodeRedirectURL(req));
+    }
+
+    /**
+     * Encode the user's password (if necessary) before redirecting to
+     * the Container Managed Security servlet.
+     * 
+     * @param request
+     * @param username
+     * @param password
+     * @return
+     */
+    public static String getEncryptedPassword(
+                       HttpServletRequest request, String username, String password)
+    {
+        // This determines if the password should be encrypted programmatically
+        mEncrypt = new Boolean(RollerConfig.getProperty("passwds.encryption.enabled"));
+        mAlgorithm = RollerConfig.getProperty("passwds.encryption.algorithm");
+
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("Authentication URL: " + mAuthURL);
+            mLogger.debug("Programmatic encryption of password? " + mEncrypt);
+            mLogger.debug("Encryption algorithm: " + mAlgorithm);
+        }
+
+        if (request.getParameter("rememberMe") != null) {
+            request.getSession().setAttribute(RollerRequest.LOGIN_COOKIE, "true");
+        }
+        String encryptedPassword = "";
+        if (mEncrypt.booleanValue() && (request.getAttribute("encrypt") == null))
+        {
+            if (mLogger.isDebugEnabled())
+            {
+                mLogger.debug("Encrypting password for user '" + username + "'");
+            }
+            encryptedPassword = Utilities.encodePassword(password, mAlgorithm);
+        }
+        else
+        {
+            encryptedPassword = password;
+        }
+        return encryptedPassword;
+    }
+}
\ No newline at end of file

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/MainPageAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,194 @@
+package org.roller.presentation;
+
+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.roller.RollerException;
+import org.roller.model.Roller;
+import org.roller.model.WeblogManager;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.roller.config.RollerRuntimeConfig;
+
+
+/**
+ * Main page action for Roller.
+ * @struts.action name="main" path="/main" scope="request"
+ * @struts.action-forward name="main.page" path="/main.jsp"
+ */
+public class MainPageAction extends Action
+{
+    // TODO: make timeouts configurable
+    private static TimedHolder mPopularWebsites = new TimedHolder(30 * 60 * 1000);
+    private static TimedHolder mRecentEntries = new TimedHolder(120 * 60 * 1000);
+    private static TimedHolder mPinnedEntries = new TimedHolder(120 * 60 * 1000);
+    
+    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);
+		
+        req.setAttribute("version",rctx.getRollerVersion());
+        req.setAttribute("buildTime",rctx.getRollerBuildTime());
+        req.setAttribute("baseURL", rctx.getContextUrl(req));
+        req.setAttribute("data", new MainPageData(req));
+        
+        /* I am pretty sure this value isn't used on the display anymore, 
+         * but I am scared to remove it ... Allen G */
+        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");
+	}
+    
+    public static void flushMainPageCache()
+    {
+        mLogger.debug("Flushing recent and pinned entries");
+        mRecentEntries.expire();    
+        mPinnedEntries.expire();    
+    }
+    
+    /**
+     * Page model. 
+     */
+    public static class MainPageData 
+    {
+        private HttpServletRequest mRequest = null;
+        
+        public MainPageData(HttpServletRequest req) 
+        {
+            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 = (List)mPopularWebsites.getObject();
+            if (list == null)
+            {
+                mLogger.debug("Refreshing popular websites list");
+                Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();            
+                list = roller.getRefererManager().getDaysPopularWebsites(num);
+                mPopularWebsites.setObject(list);
+            }
+            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 = (List)mRecentEntries.getObject();
+            try {
+            if (list == null)
+            {
+                mLogger.debug("Refreshing recent entries list");
+                Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();			                       
+                list = roller.getWeblogManager().getWeblogEntries(
+                    null,                   // userName
+                    null,                   // startDate
+                    new Date(),             // endDate
+                    null,                   // catName
+                    WeblogManager.PUB_ONLY, // status
+                    new Integer(num));       // maxEntries
+                mRecentEntries.setObject(list);
+            }
+            } 
+            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 = (List)mPinnedEntries.getObject();
+            if (list == null)
+            {
+                mLogger.debug("Refreshing pinned entries list");
+                Roller roller = RollerRequest.getRollerRequest(mRequest).getRoller();
+                list = roller.getWeblogManager()
+                    .getWeblogEntriesPinnedToMain(new Integer(num));  
+                mPinnedEntries.setObject(list);
+            }
+            return list;
+        }
+    }
+    
+    /** Hold object and expire after timeout passes. */
+    public static class TimedHolder 
+    {
+        private Object obj = null;
+        private long updated = 0L;
+        private long timeout = 3000L;  // 3 seconds ?? -Lance
+        
+        /** Create holder with timeout */
+        public TimedHolder(long timeout)
+        {
+            this.timeout = timeout;
+        }
+        /** Set object and reset the timeout clock */
+        public synchronized void setObject(Object obj)
+        {
+            this.obj = obj;
+            this.updated = new Date().getTime();
+        }
+        /** Force object to expire */
+        public synchronized void expire()
+        {
+            this.obj = null;
+        }
+        /** Get object or null if object has expired */
+        public Object getObject()
+        {
+            long currentTime = new Date().getTime();
+            if ((currentTime - this.updated) > this.timeout)
+            {
+                return null;
+            }
+            else 
+            {
+                return this.obj;
+            }
+        }
+    }
+}
+

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/ResourceServlet.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,136 @@
+package org.roller.presentation;
+
+import java.io.*;
+import java.util.Date;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.roller.model.RollerFactory;
+
+
+/**
+ * Resources servlet.  Acts as a gateway to files uploaded by users.
+ *
+ * Since we keep uploaded resources in a location outside of the webapp
+ * context we need a way to serve them up.  This servlet assumes that 
+ * resources are stored on a filesystem in the "uploads.dir" directory.
+ *
+ * @author Allen Gilliland
+ *
+ * @web.servlet name="ResourcesServlet"
+ * @web.servlet-mapping url-pattern="/resources/*"
+ */
+public class ResourceServlet extends HttpServlet
+{   
+    private static Log mLogger =
+            LogFactory.getFactory().getInstance(ResourceServlet.class);
+    
+    private String upload_dir = null;
+    private ServletContext context = null;
+    
+    
+    /** Initializes the servlet.*/
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        
+        this.context = config.getServletContext();
+
+        try {
+            this.upload_dir = RollerFactory.getRoller().getFileManager().getUploadDir();
+            mLogger.debug("upload dir is ["+this.upload_dir+"]");
+        } catch(Exception e) { mLogger.warn(e); }
+
+    }
+    
+    /** Destroys the servlet.
+     */
+    public void destroy() {
+        
+    }
+    
+    
+    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
+     * @param request servlet request
+     * @param response servlet response
+     */
+    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+    throws ServletException, IOException {
+        
+        String context = request.getContextPath();
+        String servlet = request.getServletPath();
+        String reqURI = request.getRequestURI();
+        
+        // calculate the path of the requested resource
+        // we expect ... /<context>/<servlet>/path/to/resource
+        String reqResource = reqURI.substring(servlet.length() + context.length());
+        
+        // now we can formulate the *real* path to the resource on the filesystem
+        String resource_path = this.upload_dir + reqResource;
+        File resource = new File(resource_path);
+
+        mLogger.debug("Resource requested ["+reqURI+"]");
+        mLogger.debug("Real path is ["+resource.getAbsolutePath()+"]");
+        
+        // do a quick check to make sure the resource exits, otherwise 404
+        if(!resource.exists() || !resource.canRead()) {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+        
+        // does the client already have this file?  if so, then 304
+        Date ifModDate = new Date(request.getDateHeader("If-Modified-Since"));
+        Date lastMod = new Date(resource.lastModified());
+        if(lastMod.compareTo(ifModDate) <= 0) {
+            mLogger.debug("Resource unmodified ... sending 304");
+            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+            return;
+        }
+        
+        // looks like we'll be serving up the file ... lets set some headers
+        // set last-modified date so we can do if-modified-since checks
+        // set the content type based on whatever is in our web.xml mime defs
+        response.addDateHeader("Last-Modified", (new Date()).getTime());
+        response.setContentType(this.context.getMimeType(resource.getAbsolutePath()));
+        
+        // ok, lets serve up the file
+        byte[] buf = new byte[8192];
+        int length = 0;
+        OutputStream out = response.getOutputStream();
+        InputStream resource_file = new FileInputStream(resource);
+        while((length = resource_file.read(buf)) > 0)
+            out.write(buf, 0, length);
+        
+        // cleanup
+        out.close();
+        resource_file.close();
+    }
+    
+    
+    /** Handles the HTTP <code>GET</code> method.
+     * @param request servlet request
+     * @param response servlet response
+     */
+    protected void doGet(HttpServletRequest request, HttpServletResponse response)
+    throws ServletException, IOException {
+        processRequest(request, response);
+    }
+    
+    /** Handles the HTTP <code>POST</code> method.
+     * @param request servlet request
+     * @param response servlet response
+     */
+    protected void doPost(HttpServletRequest request, HttpServletResponse response)
+    throws ServletException, IOException {
+        processRequest(request, response);
+    }
+    
+    /** Returns a short description of the servlet.
+     */
+    public String getServletInfo() {
+        return "ResourceServlet ... serving you since 2005 ;)";
+    }
+    
+}

Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/RollerContext.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,644 @@
+package org.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.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.roller.RollerException;
+import org.roller.config.RollerConfig;
+import org.roller.model.RefererManager;
+import org.roller.model.Roller;
+import org.roller.model.RollerFactory;
+import org.roller.model.RollerSpellCheck;
+import org.roller.model.ScheduledTask;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.presentation.velocity.CommentAuthenticator;
+import org.roller.presentation.velocity.ContextLoader;
+import org.roller.presentation.velocity.DefaultCommentAuthenticator;
+import org.roller.presentation.pings.PingQueueTask;
+import org.roller.util.StringUtils;
+import org.roller.util.Utilities;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
+import org.roller.business.utils.UpgradeDatabase;
+import org.roller.config.RollerRuntimeConfig;
+import org.roller.config.PingConfig;
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ * Responds to app init/destroy events and holds Roller instance.
+ * @web.listener
+ */
+public class RollerContext implements ServletContextListener
+{
+    private static Log mLogger =
+        LogFactory.getFactory().getInstance(RollerContext.class);
+
+    private String mVersion = null;
+    private String mBuildTime = null;
+    private String mBuildUser = null;
+
+    public static final String ROLLER_KEY = "session.roller";
+    public static final String ROLLER_CONTEXT = "roller.context";
+    public static final String USER_RESOURCES = "/resources";
+    public static final String VERSION_KEY = "org.roller.version";
+    public static final String MEMDEBUG_KEY = "org.roller.memdebug";
+    public static final String INDEX_MGR_KEY = "org.roller.indexMgr";
+    public static final String HTTP_PORT = "http_port";
+    public static final String HTTPS_PORT = "https_port";
+    public static final String HTTPS_HEADER_NAME = "https_header_name";
+    public static final String HTTPS_HEADER_VALUE = "https_header_value";
+    private static final String HOURLY_TASK_KEY = "roller.hourly.tasks";
+    private static final String DAILY_TASK_KEY = "roller.daily.tasks";
+    
+    private static final String ROLLER_IMPL_KEY 
+        = "org.roller.persistence";
+    
+    private static final String ROLLER_COMMENT_AUTH_KEY 
+        = "org.roller.commentAuthenticatorClass";
+
+    private static ServletContext mContext = null;
+    private static Authenticator mAuthenticator = null;
+    private static CommentAuthenticator mCommentAuthenticator = null;
+    private final SynchronizedInt mSessionCount = new SynchronizedInt(0);
+    private boolean mMemDebug = false;
+
+    /**
+     * 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(ServletContext sc)
+    {
+        // get roller from servlet context
+        return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
+    }
+
+    //-----------------------------------------------------------------------
+    /* Returns Roller instance for specified app */
+    public static RollerContext getRollerContext(HttpServletRequest req)
+    {
+        // 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();
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Responds to context initialization event by processing context
+     * paramters for easy access by the rest of the application.
+     */
+    public void contextInitialized(ServletContextEvent sce)
+    {
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("RollerContext initializing");
+        }
+
+        // Save context in self and self in context
+        mContext = sce.getServletContext();
+        mContext.setAttribute(ROLLER_CONTEXT, this);
+
+        try
+        {
+            // 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.setContextPath(mContext.getRealPath("/"));
+            
+            // always upgrade database first
+            upgradeDatabaseIfNeeded();
+            
+            Roller roller = RollerFactory.getRoller();
+            roller.begin(UserData.SYSTEM_USER);
+            
+            setupRollerProperties();
+            roller.getThemeManager();
+            setupSpellChecker();
+            setupPagePlugins();
+            setupIndexManager(roller);
+            setupRefererManager(roller);
+            initializePingFeatures(roller);
+            setupPingQueueTask(roller);
+            setupScheduledTasks(mContext, roller);
+            
+            roller.commit();
+            roller.release();
+            
+            String flag = RollerConfig.getProperty("debug.memory.enabled");
+            if (flag != null && !flag.equalsIgnoreCase("false"))
+            {
+                mMemDebug = true;
+            }
+
+            if (mLogger.isDebugEnabled())
+            {
+                mLogger.debug("RollerContext initialization complete");
+            }
+        }
+        catch (Throwable t)
+        {
+            mLogger.fatal("RollerContext initialization failed", t);
+        }
+    }
+
+    
+    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 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);
+        }
+    }
+
+    //------------------------------------------------------------------------
+    /**
+     * Initialize the configured PagePlugins
+     * @param mContext
+     */
+    private void setupPagePlugins()
+    {
+        if (mLogger.isDebugEnabled())
+        {
+            mLogger.debug("Initialize PagePlugins");
+        }
+        ContextLoader.initializePagePlugins(mContext);
+
+    }
+
+    /**
+     * Add TurnoverReferersTask to run on a schedule.
+     */
+    private void setupRefererManager(Roller roller)
+    {
+        try
+        {
+            // Check for turnover when we first start
+            final RefererManager refManager = roller.getRefererManager();
+            refManager.checkForTurnover(false, null);
+
+            // Schedule a check every day, starting at end of today
+            //TurnoverReferersTask task = new TurnoverReferersTask();
+            //task.init(roller, mContext.getRealPath("/"));
+            //roller.getThreadManager().scheduleDailyTimerTask(task);
+        }
+        catch (RollerException e)
+        {
+            mLogger.warn("Couldn't schedule referer turnover task", e);
+        }
+    }
+
+    //------------------------------------------------------------------------
+
+    private void setupIndexManager(Roller roller) throws RollerException
+    {
+        roller.getIndexManager();        
+    }
+
+    public void sessionCreated(HttpSessionEvent se)
+    {
+        if (mMemDebug)
+        {
+            mSessionCount.increment();
+            mContext.log(
+                "Roller:SESSION_CREATED:count="
+                    + mSessionCount
+                    + ":freemem="
+                    + Runtime.getRuntime().freeMemory()
+                    + ":totmem="
+                    + Runtime.getRuntime().totalMemory());
+        }
+    }
+
+    //------------------------------------------------------------------------
+
+    public void sessionDestroyed(HttpSessionEvent se)
+    {
+        if (mMemDebug)
+        {
+            mSessionCount.decrement();
+            mContext.log(
+                "Roller:SESSION_DESTROY:count="
+                    + mSessionCount
+                    + ":freemem="
+                    + Runtime.getRuntime().freeMemory()
+                    + ":totalmem="
+                    + Runtime.getRuntime().totalMemory());
+        }
+    }
+
+    //------------------------------------------------------------------------
+
+    /**
+     * Get an instance of Roller from the RollerFactory.
+     * If one does not exist, tell Factory to create new one.
+     */
+    public static Roller getRoller(HttpServletRequest req)
+    {
+        return RollerFactory.getRoller();
+    }
+
+    //------------------------------------------------------------------------
+
+    /**
+     * 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;
+    }
+
+
+    /**
+     *  Gets the hard-drive location of the upload directory.
+     */
+    public static String getUploadDir(ServletContext app)
+    {
+        // ACK ... this really isn't the right place for this lookup!!
+        String uploaddir = null;
+        try 
+        {
+            uploaddir = RollerFactory.getRoller().getFileManager().getUploadDir();
+        } 
+        catch(Exception e) {}
+        
+        return uploaddir;
+    }
+
+
+    /**
+     * Gets the base url for the upload directory.
+     */
+    public static String getUploadPath(ServletContext app)
+    {
+        // ACK ... why do this here??
+        String uploadurl = null;
+        try {
+            uploadurl = RollerFactory.getRoller().getFileManager().getUploadUrl();
+        } catch(Exception e) {}
+        
+        return uploadurl;
+    }
+
+    /**
+     * RollerSpellCheck must be initialized with a dictionary file
+     * so that it can return valid a SpellChecker.
+     */
+    private void setupSpellChecker()
+    {
+        InputStream is = null;
+        try
+        {
+            is = mContext.getResourceAsStream("/WEB-INF/english.0");
+            RollerSpellCheck.init(is);
+        }
+        catch (Exception e)
+        {
+            mContext.log("ERROR reading dictionary file");
+        }
+        finally
+        {
+            if (is != null)
+            {
+                try
+                {
+                    is.close();
+                }
+                catch (Exception e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns the full url for the website of the specified username.
+     */
+    public String getContextUrl(HttpServletRequest request, String username)
+    {
+        String url = this.getContextUrl(request);
+        if (username != null)
+        {
+            url = url + "/page/" + username;
+        }
+        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.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.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;
+    }
+
+
+    /**
+     * Returns the mContext.
+     * @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;
+    }
+
+    //-----------------------------------------------------------------------
+
+    public static CommentAuthenticator getCommentAuthenticator() 
+    {
+        if (mCommentAuthenticator == null) 
+        {
+            String name = RollerConfig.getProperty("comment.authenticator.classname");
+            try 
+            {
+                Class clazz = Class.forName(name);
+                mCommentAuthenticator=(CommentAuthenticator)clazz.newInstance();
+            }
+            catch (Exception e)
+            {
+                mLogger.error(e);
+                mCommentAuthenticator = new DefaultCommentAuthenticator();
+            }
+        }        
+        return mCommentAuthenticator;
+    }
+}



Mime
View raw message