You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by ag...@apache.org on 2005/07/06 01:32:00 UTC
svn commit: r209350 - in /incubator/roller/trunk/src/org/roller: ./
business/ model/ pojos/ presentation/velocity/
presentation/velocity/wrappers/
Author: agilliland
Date: Tue Jul 5 16:31:59 2005
New Revision: 209350
URL: http://svn.apache.org/viewcvs?rev=209350&view=rev
Log:
New classes for Theme Management.
Added:
incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java
incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java
incubator/roller/trunk/src/org/roller/model/Template.java
incubator/roller/trunk/src/org/roller/model/ThemeManager.java
incubator/roller/trunk/src/org/roller/pojos/Theme.java
incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java
incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java
incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/
incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java
Added: incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java (added)
+++ incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,33 @@
+/*
+ * ThemeNotFoundException.java
+ *
+ * Created on June 28, 2005, 12:48 PM
+ */
+
+package org.roller;
+
+
+/**
+ * Thrown when the ThemeManager has a problem finding a named theme.
+ *
+ * @author Allen Gilliland
+ */
+public class ThemeNotFoundException extends RollerException {
+
+ public ThemeNotFoundException(String s,Throwable t) {
+ super(s, t);
+ }
+
+ public ThemeNotFoundException(Throwable t) {
+ super(t);
+ }
+
+ public ThemeNotFoundException(String s) {
+ super(s);
+ }
+
+ public ThemeNotFoundException() {
+ super();
+ }
+
+}
Added: incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java (added)
+++ incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,272 @@
+/*
+ * ThemeManagerImpl.java
+ *
+ * Created on June 27, 2005, 1:33 PM
+ */
+
+package org.roller.business;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.RollerException;
+import org.roller.ThemeNotFoundException;
+import org.roller.config.RollerConfig;
+import org.roller.model.ThemeManager;
+import org.roller.pojos.Theme;
+import org.roller.pojos.ThemeTemplate;
+
+
+/**
+ * Base implementation of a ThemeManager.
+ *
+ * This particular implementation reads theme data off the filesystem
+ * and assumes that those themes are not changable at runtime.
+ *
+ * @author Allen Gilliland
+ */
+public class ThemeManagerImpl implements ThemeManager {
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ThemeManagerImpl.class);
+
+ private Map themes;
+
+
+ protected ThemeManagerImpl() {
+
+ // rather than be lazy we are going to load all themes from
+ // the disk preemptively during initialization and cache them
+ mLogger.debug("Initializing ThemeManagerImpl");
+ mLogger.info("Loading all themes from disk ... ");
+ this.themes = this.loadAllThemesFromDisk();
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getTheme(java.lang.String)
+ */
+ public Theme getTheme(String name)
+ throws ThemeNotFoundException, RollerException {
+
+ Theme theme = (Theme) this.themes.get(name);
+ if(theme == null)
+ throw new ThemeNotFoundException("Couldn't find theme ["+name+"]");
+
+ return theme;
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getThemeById(java.lang.String)
+ */
+ public Theme getThemeById(String id)
+ throws ThemeNotFoundException, RollerException {
+
+ // In this implementation where themes come from the filesystem we
+ // know that the name and id for a theme are the same
+ return this.getTheme(id);
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getThemesList()
+ */
+ public List getThemesList() {
+
+ List themes = new ArrayList(this.themes.keySet());
+
+ // sort 'em ... the natural sorting order for Strings is alphabetical
+ Collections.sort(themes);
+
+ return themes;
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getEnabledThemesList()
+ */
+ public List getEnabledThemesList() {
+
+ Collection all_themes = this.themes.values();
+
+ // make a new list of only the enabled themes
+ List enabled_themes = new ArrayList();
+ Iterator it = all_themes.iterator();
+ Theme theme = null;
+ while(it.hasNext()) {
+ theme = (Theme) it.next();
+ if(theme.isEnabled())
+ enabled_themes.add(theme.getName());
+ }
+
+ // sort 'em ... the natural sorting order for Strings is alphabetical
+ Collections.sort(enabled_themes);
+
+ return enabled_themes;
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getTemplate(String, String)
+ */
+ public ThemeTemplate getTemplate(String theme_name, String template_name)
+ throws ThemeNotFoundException, RollerException {
+
+ // basically we just try and lookup the theme first, then template
+ Theme theme = this.getTheme(theme_name);
+
+ return theme.getTemplate(template_name);
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getTemplateById(java.lang.String)
+ */
+ public ThemeTemplate getTemplateById(String id)
+ throws ThemeNotFoundException, RollerException {
+
+ if(id == null)
+ throw new ThemeNotFoundException("Theme id was null");
+
+ // in our case we expect a template id to be <theme>:<template>
+ // so extract each piece and do the lookup
+ String[] split = id.split(":", 2);
+ if(split.length != 2)
+ throw new ThemeNotFoundException("Invalid theme id ["+id+"]");
+
+ return this.getTemplate(split[0], split[1]);
+ }
+
+
+ /**
+ * @see org.roller.model.ThemeManager#getTemplateByLink(java.lang.String)
+ */
+ public ThemeTemplate getTemplateByLink(String theme_name, String template_link)
+ throws ThemeNotFoundException, RollerException {
+
+ // basically we just try and lookup the theme first, then template
+ Theme theme = this.getTheme(theme_name);
+
+ return theme.getTemplateByLink(template_link);
+ }
+
+
+ /**
+ * This is a convenience method which loads all the theme data from
+ * themes stored on the filesystem in the roller webapp /themes/ directory.
+ */
+ private Map loadAllThemesFromDisk() {
+
+ Map themes = new HashMap();
+
+ // NOTE: we need to figure out how to get the roller context path
+ String themespath = RollerConfig.getProperty("context.realpath");
+ if(themespath.endsWith(File.separator))
+ themespath += "themes";
+ else
+ themespath += File.separator + "themes";
+
+ // first, get a list of the themes available
+ File themesdir = new File(themespath);
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ File file =
+ new File(dir.getAbsolutePath() + File.separator + name);
+ return file.isDirectory();
+ }
+ };
+ String[] themenames = themesdir.list(filter);
+
+ // now go through each theme and read all it's templates
+ Theme theme = null;
+ for(int i=0; i < themenames.length; i++) {
+ theme = this.loadThemeFromDisk(themenames[i],
+ themespath + File.separator + themenames[i]);
+
+ themes.put(theme.getName(), theme);
+ }
+
+ return themes;
+ }
+
+
+ /**
+ * Another convenience method which knows how to load a single theme
+ * off the filesystem and return a Theme object
+ */
+ private Theme loadThemeFromDisk(String theme_name, String themepath) {
+
+ mLogger.debug("Loading theme "+theme_name+" from "+themepath);
+
+ Theme theme = new Theme();
+ theme.setName(theme_name);
+ theme.setAuthor("Roller");
+ theme.setLastEditor("Roller");
+ theme.setEnabled(true);
+
+ // start by getting a list of the .vm files for this theme
+ File themedir = new File(themepath);
+ FilenameFilter filter = new FilenameFilter()
+ {
+ public boolean accept(File dir, String name)
+ {
+ return name.endsWith(".vm");
+ }
+ };
+ String[] templates = themedir.list(filter);
+
+ // go through each .vm file and read in its contents to a ThemeTemplate
+ String template_name = null;
+ ThemeTemplate theme_template = null;
+ for (int i=0; i < templates.length; i++) {
+ // strip off the .vm part
+ template_name = templates[i].substring(0, templates[i].length() - 3);
+
+ try {
+ File template_file = new File(themepath + File.separator + templates[i]);
+
+ if(!template_file.exists() && !template_file.canRead()) {
+ mLogger.warn("Couldn't read theme template file ["+template_file.getPath()+"]");
+ continue;
+ }
+
+ FileReader reader = new FileReader(template_file);
+ char[] chars = new char[(int) template_file.length()];
+ reader.read(chars);
+
+ // construct ThemeTemplate representing this file
+ theme_template = new ThemeTemplate(
+ theme_name+":"+template_name,
+ template_name,
+ template_name,
+ new String(chars),
+ template_name,
+ new Date(template_file.lastModified()));
+
+ // add it to the theme
+ theme.setTemplate(template_name, theme_template);
+
+ } catch (Exception e) {
+ // warn?
+ }
+ }
+
+ // use the last mod date of the last template file
+ // as the last mod date of the theme
+ theme.setLastModified(theme_template.getLastModified());
+
+ return theme;
+ }
+
+}
Added: incubator/roller/trunk/src/org/roller/model/Template.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/model/Template.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/model/Template.java (added)
+++ incubator/roller/trunk/src/org/roller/model/Template.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,37 @@
+/*
+ * Template.java
+ *
+ * Created on June 27, 2005, 11:59 AM
+ */
+
+package org.roller.model;
+
+import java.util.Date;
+
+
+/**
+ * The Template interface represents the abstract concept of a single unit
+ * of templated or non-rendered content. For Roller we mainly think of
+ * templates as Velocity templates which are meant to be fed into the
+ * Velocity rendering engine.
+ *
+ * @author Allen Gilliland
+ */
+public interface Template {
+
+ public String getId();
+ public String getName();
+ public String getDescription();
+ public String getContents();
+ public String getLink();
+ public Date getLastModified();
+
+ /*
+ public void setId(String id);
+ public void setName(String name);
+ public void setDescription(String desc);
+ public void setContents(String contents);
+ public void setLink(String link);
+ public void setLastModified(Date date);
+ */
+}
Added: incubator/roller/trunk/src/org/roller/model/ThemeManager.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/model/ThemeManager.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/model/ThemeManager.java (added)
+++ incubator/roller/trunk/src/org/roller/model/ThemeManager.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,99 @@
+/*
+ * ThemeManager.java
+ *
+ * Created on June 27, 2005, 12:49 PM
+ */
+
+package org.roller.model;
+
+import java.util.List;
+import org.roller.RollerException;
+import org.roller.ThemeNotFoundException;
+import org.roller.pojos.Theme;
+import org.roller.pojos.ThemeTemplate;
+
+
+/**
+ * Manager interface for accessing Theme related objects.
+ *
+ * @author Allen Gilliland
+ */
+public interface ThemeManager {
+
+ /**
+ * Get the Theme object with the given name.
+ *
+ * @throws ThemeNotFoundException If the named theme cannot be found.
+ * @throws RollerException If there is some kind of fatal backend error.
+ **/
+ public Theme getTheme(String name)
+ throws ThemeNotFoundException, RollerException;
+
+
+ /**
+ * Get the Theme object with the given theme id.
+ *
+ * @throws ThemeNotFoundException If the named theme cannot be found.
+ * @throws RollerException If there is some kind of fatal backend error.
+ */
+ public Theme getThemeById(String theme_id)
+ throws ThemeNotFoundException, RollerException;
+
+
+ /**
+ * Get a list of all available themes.
+ * This list is ordered alphabetically by default.
+ *
+ * NOTE: this only returns a list of theme names, not actual Theme objects.
+ **/
+ public List getThemesList();
+
+
+ /**
+ * Get a list of all theme names that are currently enabled.
+ * This list is ordered alphabetically by default.
+ *
+ * NOTE: this only returns a list of theme names, not actual Theme objects.
+ */
+ public List getEnabledThemesList();
+
+
+ /**
+ * Get the template from a given theme.
+ *
+ * @throws ThemeNotFoundException If the named theme cannot be found.
+ * @throws RollerException If there is some kind of fatal backend error.
+ */
+ public ThemeTemplate getTemplate(String theme_name, String template_name)
+ throws ThemeNotFoundException, RollerException;
+
+
+ /**
+ * Get the template from a given theme using the template id.
+ *
+ * Theme templates use a special id value when they come off the filesystem.
+ * When a theme is read off the filesystem it's templates are given an id
+ * like ... <theme name>:<template name>
+ *
+ * @throws ThemeNotFoundException If the named theme cannot be found.
+ * @throws RollerException If there is some kind of fatal backend error.
+ */
+ public ThemeTemplate getTemplateById(String template_id)
+ throws ThemeNotFoundException, RollerException;
+
+
+ /**
+ * Get the template from a given theme using the template link value.
+ *
+ * Note that for themes we enforce the rule that
+ * Theme.name == Theme.link
+ *
+ * So doing a lookup by link is the same as doing a lookup by name.
+ *
+ * @throws ThemeNotFoundException If the named theme cannot be found.
+ * @throws RollerException If there is some kind of fatal backend error.
+ */
+ public ThemeTemplate getTemplateByLink(String theme_name, String template_link)
+ throws ThemeNotFoundException, RollerException;
+
+}
Added: incubator/roller/trunk/src/org/roller/pojos/Theme.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/Theme.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/Theme.java (added)
+++ incubator/roller/trunk/src/org/roller/pojos/Theme.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,173 @@
+/*
+ * Theme.java
+ *
+ * Created on June 27, 2005, 12:55 PM
+ */
+
+package org.roller.pojos;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * The Theme object encapsulates all elements of a single weblog theme. It
+ * is used mostly to contain all the templates for a theme, but does contain
+ * other theme related attributes such as name, last modifed date, etc.
+ *
+ * @author Allen Gilliland
+ */
+public class Theme implements Serializable {
+
+ // this is the name that will be used to identify a user customized theme
+ public static final String CUSTOM = "custom";
+
+ private String id;
+ private String name;
+ private String description;
+ private String author;
+ private String lastEditor; // user id value of last editor
+ private Date lastModified;
+ private boolean enabled;
+
+ // we keep templates in a Map for faster lookups by name
+ // the Map contains ... (template name, ThemeTemplate)
+ private Map templates;
+
+
+ public Theme() {
+ this.id = null;
+ this.name = null;
+ this.description = null;
+ this.author = null;
+ this.lastEditor = null;
+ this.lastModified = null;
+ this.enabled = false;
+ this.templates = new HashMap();
+ }
+
+
+ /**
+ * Get the collection of all templates associated with this Theme.
+ */
+ public Collection getTemplates() {
+ return this.templates.values();
+ }
+
+
+ /**
+ * Lookup the specified template by name.
+ * Returns null if the template cannot be found.
+ */
+ public ThemeTemplate getTemplate(String name) {
+ return (ThemeTemplate) this.templates.get(name);
+ }
+
+
+ /**
+ * Lookup the specified template by link.
+ * Returns null if the template cannot be found.
+ *
+ * NOTE: for themes we enforce the rule that
+ * Theme.link == Theme.name
+ *
+ * So this lookup is basically the same as lookup by name.
+ */
+ public ThemeTemplate getTemplateByLink(String link) {
+ return (ThemeTemplate) this.templates.get(link);
+ }
+
+
+ /**
+ * Set the value for a given template name.
+ */
+ public void setTemplate(String name, ThemeTemplate template) {
+ this.templates.put(name, template);
+ }
+
+
+ /**
+ * Check if this Theme contains the named template.
+ * Returns true if the template exists, false otherwise.
+ */
+ public boolean hasTemplate(String name) {
+ return this.templates.containsKey(name);
+ }
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public String getLastEditor() {
+ return lastEditor;
+ }
+
+ public void setLastEditor(String lastEditor) {
+ this.lastEditor = lastEditor;
+ }
+
+ public Date getLastModified() {
+ return lastModified;
+ }
+
+ public void setLastModified(Date lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(name);
+ sb.append("\n");
+
+ Iterator it = this.templates.values().iterator();
+ while(it.hasNext()) {
+ sb.append(it.next());
+ sb.append("\n");
+ }
+
+ return sb.toString();
+
+ }
+
+}
Added: incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java (added)
+++ incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,97 @@
+/*
+ * ThemeTemplate.java
+ *
+ * Created on June 27, 2005, 12:14 PM
+ */
+
+package org.roller.pojos;
+
+import java.io.Serializable;
+import java.util.Date;
+import org.roller.model.Template;
+
+
+/**
+ * A Theme based implementation of a Template. A ThemeTemplate represents a
+ * template which is part of a shared Theme.
+ *
+ * @author Allen Gilliland
+ */
+public class ThemeTemplate implements Template, Serializable {
+
+ private String id;
+ private String name;
+ private String description;
+ private String contents;
+ private String link;
+ private Date lastModified;
+
+
+ public ThemeTemplate() {}
+
+ public ThemeTemplate(String id, String name,
+ String desc, String contents, String link, Date date) {
+
+ this.id = id;
+ this.name = name;
+ this.description = desc;
+ this.contents = contents;
+ this.link = link;
+ this.lastModified = date;
+ }
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getContents() {
+ return contents;
+ }
+
+ public void setContents(String contents) {
+ this.contents = contents;
+ }
+
+ public Date getLastModified() {
+ return lastModified;
+ }
+
+ public void setLastModified(Date lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public void setLink(String link) {
+ this.link = link;
+ }
+
+ public String toString() {
+ return (id + "," + name + "," + description + "," + link + "," +
+ lastModified + "\n\n" + contents + "\n");
+ }
+
+}
Added: incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,130 @@
+/*
+ * ThemeResourceLoader.java
+ *
+ * Created on June 28, 2005, 12:25 PM
+ */
+
+package org.roller.presentation.velocity;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import org.apache.commons.collections.ExtendedProperties;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.resource.Resource;
+import org.apache.velocity.runtime.resource.loader.ResourceLoader;
+import org.roller.RollerException;
+import org.roller.ThemeNotFoundException;
+import org.roller.model.RollerFactory;
+import org.roller.model.ThemeManager;
+import org.roller.pojos.Theme;
+import org.roller.pojos.ThemeTemplate;
+
+
+/**
+ * The ThemeResourceLoader is a Velocity template loader which loads
+ * templates from shared themes.
+ *
+ * @author Allen Gilliland
+ */
+public class ThemeResourceLoader extends ResourceLoader {
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ThemeResourceLoader.class);
+
+
+ public void init(ExtendedProperties configuration) {
+ mLogger.debug(configuration);
+ }
+
+
+ public InputStream getResourceStream( String name )
+ throws ResourceNotFoundException {
+
+ mLogger.debug("Looking up resource named ... "+name);
+
+ if (name == null || name.length() < 1) {
+ throw new ResourceNotFoundException("Need to specify a template name!");
+ }
+
+ try {
+ // parse the name ... theme templates name are <theme>:<template>
+ String[] split = name.split(":", 2);
+ if(split.length < 2)
+ throw new ResourceNotFoundException("Invalid ThemeRL key "+name);
+
+ // lookup the template from the proper theme
+ ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
+ Theme theme = themeMgr.getTheme(split[0]);
+ ThemeTemplate template = theme.getTemplate(split[1]);
+
+ if(template == null)
+ throw new ResourceNotFoundException("Template ["+split[1]+
+ "] doesn't seem to be part of theme ["+split[0]+"]");
+
+ mLogger.debug("Resource found!");
+
+ // return the input stream
+ return new ByteArrayInputStream(template.getContents().getBytes("UTF-8"));
+
+ } catch (UnsupportedEncodingException uex) {
+ // We expect UTF-8 in all JRE installation.
+ // This rethrows as a Runtime exception after logging.
+ mLogger.error(uex);
+ throw new RuntimeException(uex);
+
+ } catch (ThemeNotFoundException tnfe) {
+ String msg = "ThemeResourceLoader Error: " + tnfe.getMessage();
+ mLogger.error(msg, tnfe);
+ throw new ResourceNotFoundException(msg);
+
+ } catch (RollerException re) {
+ String msg = "RollerResourceLoader Error: " + re.getMessage();
+ mLogger.error( msg, re );
+ throw new ResourceNotFoundException(msg);
+ }
+ }
+
+
+ public boolean isSourceModified(Resource resource) {
+ return (resource.getLastModified() != this.getLastModified(resource));
+ }
+
+
+ public long getLastModified(Resource resource) {
+ long last_mod = 0;
+ String name = resource.getName();
+
+ mLogger.debug("Checking last modified time for resource named ... "+name);
+
+ if (name == null || name.length() < 1)
+ return last_mod;
+
+ try {
+ // parse the name ... theme templates name are <theme>:<template>
+ String[] split = name.split(":", 2);
+ if(split.length < 2)
+ return last_mod;
+
+ // lookup the template from the proper theme
+ ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
+ Theme theme = themeMgr.getTheme(split[0]);
+ ThemeTemplate template = theme.getTemplate(split[1]);
+
+ if(template == null)
+ return last_mod;
+
+ last_mod = template.getLastModified().getTime();
+
+ } catch (ThemeNotFoundException tnfe) {
+ // ignore
+ } catch (RollerException re) {
+ // we don't like to see this happen, but oh well
+ }
+
+ return last_mod;
+ }
+
+}
Added: incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java?rev=209350&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java (added)
+++ incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java Tue Jul 5 16:31:59 2005
@@ -0,0 +1,52 @@
+/*
+ * TemplateWrapper.java
+ *
+ * Created on July 2, 2005, 4:02 PM
+ */
+
+package org.roller.presentation.velocity.wrappers;
+
+import java.util.Date;
+import org.roller.model.Template;
+
+
+/**
+ * Wrapper class for org.roller.model.Template objects.
+ *
+ * @author Allen Gilliland
+ */
+public class TemplateWrapper {
+
+ private Template template = null;
+
+
+ public TemplateWrapper(Template template) {
+ this.template = template;
+ }
+
+
+ public String getId() {
+ return this.template.getId();
+ }
+
+ public String getName() {
+ return this.template.getName();
+ }
+
+ public String getDescription() {
+ return this.template.getDescription();
+ }
+
+ public String getContents() {
+ return this.template.getContents();
+ }
+
+ public Date getLastModified() {
+ return this.template.getLastModified();
+ }
+
+ public String getLink() {
+ return this.template.getLink();
+ }
+
+}
New theme management code
Posted by Allen Gilliland <Al...@Sun.COM>.
This isn't exactly complete yet, but I think it's far enough along that
it's worth putting in the repository and letting other people play with
it. No database changes, so it should be easy to play with. A few
things to keep in mind ...
- New registering users are forced to select a shared theme during
registration
- Themes are "shared" and the templates are not editable by users
- Templates are only copied down when you "customize" a theme
- Simply changing your theme does not affect your page templates at all
- The preview servlet works the exact same way as the page servlet,
except that it accepts a "?theme=<theme>" param which can control what
theme the page is rendered with
- You can toggle on/off custom themes from the admin settings page.
try it out. let me know what you think and if you find any bugs.
-- Allen
agilliland@apache.org wrote:
>Author: agilliland
>Date: Tue Jul 5 16:31:59 2005
>New Revision: 209350
>
>URL: http://svn.apache.org/viewcvs?rev=209350&view=rev
>Log:
>New classes for Theme Management.
>
>
>Added:
> incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java
> incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java
> incubator/roller/trunk/src/org/roller/model/Template.java
> incubator/roller/trunk/src/org/roller/model/ThemeManager.java
> incubator/roller/trunk/src/org/roller/pojos/Theme.java
> incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java
> incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java
> incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/
> incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java
>
>Added: incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java (added)
>+++ incubator/roller/trunk/src/org/roller/ThemeNotFoundException.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,33 @@
>+/*
>+ * ThemeNotFoundException.java
>+ *
>+ * Created on June 28, 2005, 12:48 PM
>+ */
>+
>+package org.roller;
>+
>+
>+/**
>+ * Thrown when the ThemeManager has a problem finding a named theme.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class ThemeNotFoundException extends RollerException {
>+
>+ public ThemeNotFoundException(String s,Throwable t) {
>+ super(s, t);
>+ }
>+
>+ public ThemeNotFoundException(Throwable t) {
>+ super(t);
>+ }
>+
>+ public ThemeNotFoundException(String s) {
>+ super(s);
>+ }
>+
>+ public ThemeNotFoundException() {
>+ super();
>+ }
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java (added)
>+++ incubator/roller/trunk/src/org/roller/business/ThemeManagerImpl.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,272 @@
>+/*
>+ * ThemeManagerImpl.java
>+ *
>+ * Created on June 27, 2005, 1:33 PM
>+ */
>+
>+package org.roller.business;
>+
>+import java.io.File;
>+import java.io.FileReader;
>+import java.io.FilenameFilter;
>+import java.util.ArrayList;
>+import java.util.Collection;
>+import java.util.Collections;
>+import java.util.Date;
>+import java.util.HashMap;
>+import java.util.Iterator;
>+import java.util.List;
>+import java.util.Map;
>+import org.apache.commons.logging.Log;
>+import org.apache.commons.logging.LogFactory;
>+import org.roller.RollerException;
>+import org.roller.ThemeNotFoundException;
>+import org.roller.config.RollerConfig;
>+import org.roller.model.ThemeManager;
>+import org.roller.pojos.Theme;
>+import org.roller.pojos.ThemeTemplate;
>+
>+
>+/**
>+ * Base implementation of a ThemeManager.
>+ *
>+ * This particular implementation reads theme data off the filesystem
>+ * and assumes that those themes are not changable at runtime.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class ThemeManagerImpl implements ThemeManager {
>+
>+ private static Log mLogger =
>+ LogFactory.getFactory().getInstance(ThemeManagerImpl.class);
>+
>+ private Map themes;
>+
>+
>+ protected ThemeManagerImpl() {
>+
>+ // rather than be lazy we are going to load all themes from
>+ // the disk preemptively during initialization and cache them
>+ mLogger.debug("Initializing ThemeManagerImpl");
>+ mLogger.info("Loading all themes from disk ... ");
>+ this.themes = this.loadAllThemesFromDisk();
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getTheme(java.lang.String)
>+ */
>+ public Theme getTheme(String name)
>+ throws ThemeNotFoundException, RollerException {
>+
>+ Theme theme = (Theme) this.themes.get(name);
>+ if(theme == null)
>+ throw new ThemeNotFoundException("Couldn't find theme ["+name+"]");
>+
>+ return theme;
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getThemeById(java.lang.String)
>+ */
>+ public Theme getThemeById(String id)
>+ throws ThemeNotFoundException, RollerException {
>+
>+ // In this implementation where themes come from the filesystem we
>+ // know that the name and id for a theme are the same
>+ return this.getTheme(id);
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getThemesList()
>+ */
>+ public List getThemesList() {
>+
>+ List themes = new ArrayList(this.themes.keySet());
>+
>+ // sort 'em ... the natural sorting order for Strings is alphabetical
>+ Collections.sort(themes);
>+
>+ return themes;
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getEnabledThemesList()
>+ */
>+ public List getEnabledThemesList() {
>+
>+ Collection all_themes = this.themes.values();
>+
>+ // make a new list of only the enabled themes
>+ List enabled_themes = new ArrayList();
>+ Iterator it = all_themes.iterator();
>+ Theme theme = null;
>+ while(it.hasNext()) {
>+ theme = (Theme) it.next();
>+ if(theme.isEnabled())
>+ enabled_themes.add(theme.getName());
>+ }
>+
>+ // sort 'em ... the natural sorting order for Strings is alphabetical
>+ Collections.sort(enabled_themes);
>+
>+ return enabled_themes;
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getTemplate(String, String)
>+ */
>+ public ThemeTemplate getTemplate(String theme_name, String template_name)
>+ throws ThemeNotFoundException, RollerException {
>+
>+ // basically we just try and lookup the theme first, then template
>+ Theme theme = this.getTheme(theme_name);
>+
>+ return theme.getTemplate(template_name);
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getTemplateById(java.lang.String)
>+ */
>+ public ThemeTemplate getTemplateById(String id)
>+ throws ThemeNotFoundException, RollerException {
>+
>+ if(id == null)
>+ throw new ThemeNotFoundException("Theme id was null");
>+
>+ // in our case we expect a template id to be <theme>:<template>
>+ // so extract each piece and do the lookup
>+ String[] split = id.split(":", 2);
>+ if(split.length != 2)
>+ throw new ThemeNotFoundException("Invalid theme id ["+id+"]");
>+
>+ return this.getTemplate(split[0], split[1]);
>+ }
>+
>+
>+ /**
>+ * @see org.roller.model.ThemeManager#getTemplateByLink(java.lang.String)
>+ */
>+ public ThemeTemplate getTemplateByLink(String theme_name, String template_link)
>+ throws ThemeNotFoundException, RollerException {
>+
>+ // basically we just try and lookup the theme first, then template
>+ Theme theme = this.getTheme(theme_name);
>+
>+ return theme.getTemplateByLink(template_link);
>+ }
>+
>+
>+ /**
>+ * This is a convenience method which loads all the theme data from
>+ * themes stored on the filesystem in the roller webapp /themes/ directory.
>+ */
>+ private Map loadAllThemesFromDisk() {
>+
>+ Map themes = new HashMap();
>+
>+ // NOTE: we need to figure out how to get the roller context path
>+ String themespath = RollerConfig.getProperty("context.realpath");
>+ if(themespath.endsWith(File.separator))
>+ themespath += "themes";
>+ else
>+ themespath += File.separator + "themes";
>+
>+ // first, get a list of the themes available
>+ File themesdir = new File(themespath);
>+ FilenameFilter filter = new FilenameFilter() {
>+ public boolean accept(File dir, String name) {
>+ File file =
>+ new File(dir.getAbsolutePath() + File.separator + name);
>+ return file.isDirectory();
>+ }
>+ };
>+ String[] themenames = themesdir.list(filter);
>+
>+ // now go through each theme and read all it's templates
>+ Theme theme = null;
>+ for(int i=0; i < themenames.length; i++) {
>+ theme = this.loadThemeFromDisk(themenames[i],
>+ themespath + File.separator + themenames[i]);
>+
>+ themes.put(theme.getName(), theme);
>+ }
>+
>+ return themes;
>+ }
>+
>+
>+ /**
>+ * Another convenience method which knows how to load a single theme
>+ * off the filesystem and return a Theme object
>+ */
>+ private Theme loadThemeFromDisk(String theme_name, String themepath) {
>+
>+ mLogger.debug("Loading theme "+theme_name+" from "+themepath);
>+
>+ Theme theme = new Theme();
>+ theme.setName(theme_name);
>+ theme.setAuthor("Roller");
>+ theme.setLastEditor("Roller");
>+ theme.setEnabled(true);
>+
>+ // start by getting a list of the .vm files for this theme
>+ File themedir = new File(themepath);
>+ FilenameFilter filter = new FilenameFilter()
>+ {
>+ public boolean accept(File dir, String name)
>+ {
>+ return name.endsWith(".vm");
>+ }
>+ };
>+ String[] templates = themedir.list(filter);
>+
>+ // go through each .vm file and read in its contents to a ThemeTemplate
>+ String template_name = null;
>+ ThemeTemplate theme_template = null;
>+ for (int i=0; i < templates.length; i++) {
>+ // strip off the .vm part
>+ template_name = templates[i].substring(0, templates[i].length() - 3);
>+
>+ try {
>+ File template_file = new File(themepath + File.separator + templates[i]);
>+
>+ if(!template_file.exists() && !template_file.canRead()) {
>+ mLogger.warn("Couldn't read theme template file ["+template_file.getPath()+"]");
>+ continue;
>+ }
>+
>+ FileReader reader = new FileReader(template_file);
>+ char[] chars = new char[(int) template_file.length()];
>+ reader.read(chars);
>+
>+ // construct ThemeTemplate representing this file
>+ theme_template = new ThemeTemplate(
>+ theme_name+":"+template_name,
>+ template_name,
>+ template_name,
>+ new String(chars),
>+ template_name,
>+ new Date(template_file.lastModified()));
>+
>+ // add it to the theme
>+ theme.setTemplate(template_name, theme_template);
>+
>+ } catch (Exception e) {
>+ // warn?
>+ }
>+ }
>+
>+ // use the last mod date of the last template file
>+ // as the last mod date of the theme
>+ theme.setLastModified(theme_template.getLastModified());
>+
>+ return theme;
>+ }
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/model/Template.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/model/Template.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/model/Template.java (added)
>+++ incubator/roller/trunk/src/org/roller/model/Template.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,37 @@
>+/*
>+ * Template.java
>+ *
>+ * Created on June 27, 2005, 11:59 AM
>+ */
>+
>+package org.roller.model;
>+
>+import java.util.Date;
>+
>+
>+/**
>+ * The Template interface represents the abstract concept of a single unit
>+ * of templated or non-rendered content. For Roller we mainly think of
>+ * templates as Velocity templates which are meant to be fed into the
>+ * Velocity rendering engine.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public interface Template {
>+
>+ public String getId();
>+ public String getName();
>+ public String getDescription();
>+ public String getContents();
>+ public String getLink();
>+ public Date getLastModified();
>+
>+ /*
>+ public void setId(String id);
>+ public void setName(String name);
>+ public void setDescription(String desc);
>+ public void setContents(String contents);
>+ public void setLink(String link);
>+ public void setLastModified(Date date);
>+ */
>+}
>
>Added: incubator/roller/trunk/src/org/roller/model/ThemeManager.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/model/ThemeManager.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/model/ThemeManager.java (added)
>+++ incubator/roller/trunk/src/org/roller/model/ThemeManager.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,99 @@
>+/*
>+ * ThemeManager.java
>+ *
>+ * Created on June 27, 2005, 12:49 PM
>+ */
>+
>+package org.roller.model;
>+
>+import java.util.List;
>+import org.roller.RollerException;
>+import org.roller.ThemeNotFoundException;
>+import org.roller.pojos.Theme;
>+import org.roller.pojos.ThemeTemplate;
>+
>+
>+/**
>+ * Manager interface for accessing Theme related objects.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public interface ThemeManager {
>+
>+ /**
>+ * Get the Theme object with the given name.
>+ *
>+ * @throws ThemeNotFoundException If the named theme cannot be found.
>+ * @throws RollerException If there is some kind of fatal backend error.
>+ **/
>+ public Theme getTheme(String name)
>+ throws ThemeNotFoundException, RollerException;
>+
>+
>+ /**
>+ * Get the Theme object with the given theme id.
>+ *
>+ * @throws ThemeNotFoundException If the named theme cannot be found.
>+ * @throws RollerException If there is some kind of fatal backend error.
>+ */
>+ public Theme getThemeById(String theme_id)
>+ throws ThemeNotFoundException, RollerException;
>+
>+
>+ /**
>+ * Get a list of all available themes.
>+ * This list is ordered alphabetically by default.
>+ *
>+ * NOTE: this only returns a list of theme names, not actual Theme objects.
>+ **/
>+ public List getThemesList();
>+
>+
>+ /**
>+ * Get a list of all theme names that are currently enabled.
>+ * This list is ordered alphabetically by default.
>+ *
>+ * NOTE: this only returns a list of theme names, not actual Theme objects.
>+ */
>+ public List getEnabledThemesList();
>+
>+
>+ /**
>+ * Get the template from a given theme.
>+ *
>+ * @throws ThemeNotFoundException If the named theme cannot be found.
>+ * @throws RollerException If there is some kind of fatal backend error.
>+ */
>+ public ThemeTemplate getTemplate(String theme_name, String template_name)
>+ throws ThemeNotFoundException, RollerException;
>+
>+
>+ /**
>+ * Get the template from a given theme using the template id.
>+ *
>+ * Theme templates use a special id value when they come off the filesystem.
>+ * When a theme is read off the filesystem it's templates are given an id
>+ * like ... <theme name>:<template name>
>+ *
>+ * @throws ThemeNotFoundException If the named theme cannot be found.
>+ * @throws RollerException If there is some kind of fatal backend error.
>+ */
>+ public ThemeTemplate getTemplateById(String template_id)
>+ throws ThemeNotFoundException, RollerException;
>+
>+
>+ /**
>+ * Get the template from a given theme using the template link value.
>+ *
>+ * Note that for themes we enforce the rule that
>+ * Theme.name == Theme.link
>+ *
>+ * So doing a lookup by link is the same as doing a lookup by name.
>+ *
>+ * @throws ThemeNotFoundException If the named theme cannot be found.
>+ * @throws RollerException If there is some kind of fatal backend error.
>+ */
>+ public ThemeTemplate getTemplateByLink(String theme_name, String template_link)
>+ throws ThemeNotFoundException, RollerException;
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/pojos/Theme.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/Theme.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/pojos/Theme.java (added)
>+++ incubator/roller/trunk/src/org/roller/pojos/Theme.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,173 @@
>+/*
>+ * Theme.java
>+ *
>+ * Created on June 27, 2005, 12:55 PM
>+ */
>+
>+package org.roller.pojos;
>+
>+import java.io.Serializable;
>+import java.util.Collection;
>+import java.util.Date;
>+import java.util.HashMap;
>+import java.util.Iterator;
>+import java.util.Map;
>+
>+
>+/**
>+ * The Theme object encapsulates all elements of a single weblog theme. It
>+ * is used mostly to contain all the templates for a theme, but does contain
>+ * other theme related attributes such as name, last modifed date, etc.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class Theme implements Serializable {
>+
>+ // this is the name that will be used to identify a user customized theme
>+ public static final String CUSTOM = "custom";
>+
>+ private String id;
>+ private String name;
>+ private String description;
>+ private String author;
>+ private String lastEditor; // user id value of last editor
>+ private Date lastModified;
>+ private boolean enabled;
>+
>+ // we keep templates in a Map for faster lookups by name
>+ // the Map contains ... (template name, ThemeTemplate)
>+ private Map templates;
>+
>+
>+ public Theme() {
>+ this.id = null;
>+ this.name = null;
>+ this.description = null;
>+ this.author = null;
>+ this.lastEditor = null;
>+ this.lastModified = null;
>+ this.enabled = false;
>+ this.templates = new HashMap();
>+ }
>+
>+
>+ /**
>+ * Get the collection of all templates associated with this Theme.
>+ */
>+ public Collection getTemplates() {
>+ return this.templates.values();
>+ }
>+
>+
>+ /**
>+ * Lookup the specified template by name.
>+ * Returns null if the template cannot be found.
>+ */
>+ public ThemeTemplate getTemplate(String name) {
>+ return (ThemeTemplate) this.templates.get(name);
>+ }
>+
>+
>+ /**
>+ * Lookup the specified template by link.
>+ * Returns null if the template cannot be found.
>+ *
>+ * NOTE: for themes we enforce the rule that
>+ * Theme.link == Theme.name
>+ *
>+ * So this lookup is basically the same as lookup by name.
>+ */
>+ public ThemeTemplate getTemplateByLink(String link) {
>+ return (ThemeTemplate) this.templates.get(link);
>+ }
>+
>+
>+ /**
>+ * Set the value for a given template name.
>+ */
>+ public void setTemplate(String name, ThemeTemplate template) {
>+ this.templates.put(name, template);
>+ }
>+
>+
>+ /**
>+ * Check if this Theme contains the named template.
>+ * Returns true if the template exists, false otherwise.
>+ */
>+ public boolean hasTemplate(String name) {
>+ return this.templates.containsKey(name);
>+ }
>+
>+
>+ public String getId() {
>+ return id;
>+ }
>+
>+ public void setId(String id) {
>+ this.id = id;
>+ }
>+
>+ public String getName() {
>+ return name;
>+ }
>+
>+ public void setName(String name) {
>+ this.name = name;
>+ }
>+
>+ public String getDescription() {
>+ return description;
>+ }
>+
>+ public void setDescription(String description) {
>+ this.description = description;
>+ }
>+
>+ public String getAuthor() {
>+ return author;
>+ }
>+
>+ public void setAuthor(String author) {
>+ this.author = author;
>+ }
>+
>+ public String getLastEditor() {
>+ return lastEditor;
>+ }
>+
>+ public void setLastEditor(String lastEditor) {
>+ this.lastEditor = lastEditor;
>+ }
>+
>+ public Date getLastModified() {
>+ return lastModified;
>+ }
>+
>+ public void setLastModified(Date lastModified) {
>+ this.lastModified = lastModified;
>+ }
>+
>+ public boolean isEnabled() {
>+ return enabled;
>+ }
>+
>+ public void setEnabled(boolean enabled) {
>+ this.enabled = enabled;
>+ }
>+
>+ public String toString() {
>+ StringBuffer sb = new StringBuffer();
>+ sb.append(name);
>+ sb.append("\n");
>+
>+ Iterator it = this.templates.values().iterator();
>+ while(it.hasNext()) {
>+ sb.append(it.next());
>+ sb.append("\n");
>+ }
>+
>+ return sb.toString();
>+
>+ }
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java (added)
>+++ incubator/roller/trunk/src/org/roller/pojos/ThemeTemplate.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,97 @@
>+/*
>+ * ThemeTemplate.java
>+ *
>+ * Created on June 27, 2005, 12:14 PM
>+ */
>+
>+package org.roller.pojos;
>+
>+import java.io.Serializable;
>+import java.util.Date;
>+import org.roller.model.Template;
>+
>+
>+/**
>+ * A Theme based implementation of a Template. A ThemeTemplate represents a
>+ * template which is part of a shared Theme.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class ThemeTemplate implements Template, Serializable {
>+
>+ private String id;
>+ private String name;
>+ private String description;
>+ private String contents;
>+ private String link;
>+ private Date lastModified;
>+
>+
>+ public ThemeTemplate() {}
>+
>+ public ThemeTemplate(String id, String name,
>+ String desc, String contents, String link, Date date) {
>+
>+ this.id = id;
>+ this.name = name;
>+ this.description = desc;
>+ this.contents = contents;
>+ this.link = link;
>+ this.lastModified = date;
>+ }
>+
>+
>+ public String getId() {
>+ return id;
>+ }
>+
>+ public void setId(String id) {
>+ this.id = id;
>+ }
>+
>+ public String getName() {
>+ return name;
>+ }
>+
>+ public void setName(String name) {
>+ this.name = name;
>+ }
>+
>+ public String getDescription() {
>+ return description;
>+ }
>+
>+ public void setDescription(String description) {
>+ this.description = description;
>+ }
>+
>+ public String getContents() {
>+ return contents;
>+ }
>+
>+ public void setContents(String contents) {
>+ this.contents = contents;
>+ }
>+
>+ public Date getLastModified() {
>+ return lastModified;
>+ }
>+
>+ public void setLastModified(Date lastModified) {
>+ this.lastModified = lastModified;
>+ }
>+
>+ public String getLink() {
>+ return link;
>+ }
>+
>+ public void setLink(String link) {
>+ this.link = link;
>+ }
>+
>+ public String toString() {
>+ return (id + "," + name + "," + description + "," + link + "," +
>+ lastModified + "\n\n" + contents + "\n");
>+ }
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java (added)
>+++ incubator/roller/trunk/src/org/roller/presentation/velocity/ThemeResourceLoader.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,130 @@
>+/*
>+ * ThemeResourceLoader.java
>+ *
>+ * Created on June 28, 2005, 12:25 PM
>+ */
>+
>+package org.roller.presentation.velocity;
>+
>+import java.io.ByteArrayInputStream;
>+import java.io.InputStream;
>+import java.io.UnsupportedEncodingException;
>+import org.apache.commons.collections.ExtendedProperties;
>+import org.apache.commons.logging.Log;
>+import org.apache.commons.logging.LogFactory;
>+import org.apache.velocity.exception.ResourceNotFoundException;
>+import org.apache.velocity.runtime.resource.Resource;
>+import org.apache.velocity.runtime.resource.loader.ResourceLoader;
>+import org.roller.RollerException;
>+import org.roller.ThemeNotFoundException;
>+import org.roller.model.RollerFactory;
>+import org.roller.model.ThemeManager;
>+import org.roller.pojos.Theme;
>+import org.roller.pojos.ThemeTemplate;
>+
>+
>+/**
>+ * The ThemeResourceLoader is a Velocity template loader which loads
>+ * templates from shared themes.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class ThemeResourceLoader extends ResourceLoader {
>+
>+ private static Log mLogger =
>+ LogFactory.getFactory().getInstance(ThemeResourceLoader.class);
>+
>+
>+ public void init(ExtendedProperties configuration) {
>+ mLogger.debug(configuration);
>+ }
>+
>+
>+ public InputStream getResourceStream( String name )
>+ throws ResourceNotFoundException {
>+
>+ mLogger.debug("Looking up resource named ... "+name);
>+
>+ if (name == null || name.length() < 1) {
>+ throw new ResourceNotFoundException("Need to specify a template name!");
>+ }
>+
>+ try {
>+ // parse the name ... theme templates name are <theme>:<template>
>+ String[] split = name.split(":", 2);
>+ if(split.length < 2)
>+ throw new ResourceNotFoundException("Invalid ThemeRL key "+name);
>+
>+ // lookup the template from the proper theme
>+ ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
>+ Theme theme = themeMgr.getTheme(split[0]);
>+ ThemeTemplate template = theme.getTemplate(split[1]);
>+
>+ if(template == null)
>+ throw new ResourceNotFoundException("Template ["+split[1]+
>+ "] doesn't seem to be part of theme ["+split[0]+"]");
>+
>+ mLogger.debug("Resource found!");
>+
>+ // return the input stream
>+ return new ByteArrayInputStream(template.getContents().getBytes("UTF-8"));
>+
>+ } catch (UnsupportedEncodingException uex) {
>+ // We expect UTF-8 in all JRE installation.
>+ // This rethrows as a Runtime exception after logging.
>+ mLogger.error(uex);
>+ throw new RuntimeException(uex);
>+
>+ } catch (ThemeNotFoundException tnfe) {
>+ String msg = "ThemeResourceLoader Error: " + tnfe.getMessage();
>+ mLogger.error(msg, tnfe);
>+ throw new ResourceNotFoundException(msg);
>+
>+ } catch (RollerException re) {
>+ String msg = "RollerResourceLoader Error: " + re.getMessage();
>+ mLogger.error( msg, re );
>+ throw new ResourceNotFoundException(msg);
>+ }
>+ }
>+
>+
>+ public boolean isSourceModified(Resource resource) {
>+ return (resource.getLastModified() != this.getLastModified(resource));
>+ }
>+
>+
>+ public long getLastModified(Resource resource) {
>+ long last_mod = 0;
>+ String name = resource.getName();
>+
>+ mLogger.debug("Checking last modified time for resource named ... "+name);
>+
>+ if (name == null || name.length() < 1)
>+ return last_mod;
>+
>+ try {
>+ // parse the name ... theme templates name are <theme>:<template>
>+ String[] split = name.split(":", 2);
>+ if(split.length < 2)
>+ return last_mod;
>+
>+ // lookup the template from the proper theme
>+ ThemeManager themeMgr = RollerFactory.getRoller().getThemeManager();
>+ Theme theme = themeMgr.getTheme(split[0]);
>+ ThemeTemplate template = theme.getTemplate(split[1]);
>+
>+ if(template == null)
>+ return last_mod;
>+
>+ last_mod = template.getLastModified().getTime();
>+
>+ } catch (ThemeNotFoundException tnfe) {
>+ // ignore
>+ } catch (RollerException re) {
>+ // we don't like to see this happen, but oh well
>+ }
>+
>+ return last_mod;
>+ }
>+
>+}
>
>Added: incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java
>URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java?rev=209350&view=auto
>==============================================================================
>--- incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java (added)
>+++ incubator/roller/trunk/src/org/roller/presentation/velocity/wrappers/TemplateWrapper.java Tue Jul 5 16:31:59 2005
>@@ -0,0 +1,52 @@
>+/*
>+ * TemplateWrapper.java
>+ *
>+ * Created on July 2, 2005, 4:02 PM
>+ */
>+
>+package org.roller.presentation.velocity.wrappers;
>+
>+import java.util.Date;
>+import org.roller.model.Template;
>+
>+
>+/**
>+ * Wrapper class for org.roller.model.Template objects.
>+ *
>+ * @author Allen Gilliland
>+ */
>+public class TemplateWrapper {
>+
>+ private Template template = null;
>+
>+
>+ public TemplateWrapper(Template template) {
>+ this.template = template;
>+ }
>+
>+
>+ public String getId() {
>+ return this.template.getId();
>+ }
>+
>+ public String getName() {
>+ return this.template.getName();
>+ }
>+
>+ public String getDescription() {
>+ return this.template.getDescription();
>+ }
>+
>+ public String getContents() {
>+ return this.template.getContents();
>+ }
>+
>+ public Date getLastModified() {
>+ return this.template.getLastModified();
>+ }
>+
>+ public String getLink() {
>+ return this.template.getLink();
>+ }
>+
>+}
>
>
>
>