Package org.apache.roller.business

Source Code of org.apache.roller.business.ThemeManagerImpl

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

package org.apache.roller.business;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
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.apache.roller.RollerException;
import org.apache.roller.business.ThemeNotFoundException;
import org.apache.roller.config.RollerConfig;
import org.apache.roller.business.FileIOException;
import org.apache.roller.business.FileManager;
import org.apache.roller.business.FilePathException;
import org.apache.roller.business.RollerFactory;
import org.apache.roller.business.ThemeManager;
import org.apache.roller.business.UserManager;
import org.apache.roller.pojos.Theme;
import org.apache.roller.pojos.ThemeTemplate;
import org.apache.roller.pojos.WeblogTemplate;
import org.apache.roller.pojos.WebsiteData;


/**
* Base implementation of a ThemeManager.
*
* This particular implementation reads theme data off the filesystem
* and assumes that those themes are not changable at runtime.
*/
public class ThemeManagerImpl implements ThemeManager {
   
    private static Log log = LogFactory.getLog(ThemeManagerImpl.class);
   
    // directory where themes are kept
    private String themeDir = null;
   
    // the Map contains ... (theme name, Theme)
    private Map themes = null;
   
   
    protected ThemeManagerImpl() {
       
        log.debug("Initializing ThemeManagerImpl");
       
        // get theme directory from config and verify it
        this.themeDir = RollerConfig.getProperty("themes.dir");
        if(themeDir == null || themeDir.trim().length() < 1) {
            throw new RuntimeException("couldn't get themes directory from config");
        } else {
            // chop off trailing slash if it exists
            if(themeDir.endsWith("/")) {
                themeDir = themeDir.substring(0, themeDir.length()-1);
            }
           
            // make sure it exists and is readable
            File themeDirFile = new File(themeDir);
            if(!themeDirFile.exists() ||
                    !themeDirFile.isDirectory() ||
                    !themeDirFile.canRead()) {
                throw new RuntimeException("couldn't access theme dir ["+themeDir+"]");
            }
           
            // rather than be lazy we are going to load all themes from
            // the disk preemptively during initialization and cache them
            this.themes = loadAllThemesFromDisk();
           
            log.info("Loaded "+this.themes.size()+" themes from disk.");
        }
    }
   
   
    /**
     * @see org.apache.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.apache.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.apache.roller.model.ThemeManager#importTheme(website, theme)
     */
    public void importTheme(WebsiteData website, Theme theme)
        throws RollerException {
       
        log.debug("Importing theme "+theme.getName()+" to weblog "+website.getName());
       
        try {
            UserManager userMgr = RollerFactory.getRoller().getUserManager();
           
            Collection templates = theme.getTemplates();
            Iterator iter = templates.iterator();
            ThemeTemplate theme_template = null;
            while ( iter.hasNext() ) {
                theme_template = (ThemeTemplate) iter.next();
               
                WeblogTemplate template = null;
               
                if(theme_template.getName().equals(WeblogTemplate.DEFAULT_PAGE)) {
                    // this is the main Weblog template
                    try {
                        template = userMgr.getPage(website.getDefaultPageId());
                    } catch(Exception e) {
                        // user may not have a default page yet
                    }
                } else {
                    // any other template
                    template = userMgr.getPageByName(website, theme_template.getName());
                }
               
               
                if (template != null) {
                    // User already has page by that name, so overwrite it.
                    template.setContents(theme_template.getContents());
                    template.setLink(theme_template.getLink());
                   
                } else {
                    // User does not have page by that name, so create new page.
                    template = new WeblogTemplate(
                            null,                               // id
                            website,                            // website
                            theme_template.getName(),           // name
                            theme_template.getDescription(),    // description
                            theme_template.getLink(),           // link
                            theme_template.getContents(),       // contents
                            new Date(),                         // last mod
                            theme_template.getTemplateLanguage(), // temp lang
                            theme_template.isHidden(),          // hidden
                            theme_template.isNavbar(),          // navbar
                            theme_template.getDecoratorName()   // decorator
                            );
                    userMgr.savePage( template );
                }
            }
           
            // now update this website's theme to custom
            website.setEditorTheme(Theme.CUSTOM);
           
            // if this is the first time someone is customizing a theme then
            // we need to set a default page
            if(website.getDefaultPageId() == null ||
                    website.getDefaultPageId().trim().equals("") ||
                    website.getDefaultPageId().equals("dummy")) {
                // we have to go back to the db to figure out the id
                WeblogTemplate template = userMgr.getPageByName(website, "Weblog");
                if(template != null) {
                    log.debug("Setting default page to "+template.getId());
                    website.setDefaultPageId(template.getId());
                }
            }
           
            // we also want to set the weblogdayid
            WeblogTemplate dayTemplate = userMgr.getPageByName(website, "_day");
            if(dayTemplate != null) {
                log.debug("Setting default day page to "+dayTemplate.getId());
                website.setWeblogDayPageId(dayTemplate.getId());
            }
           
            // save our updated website
            userMgr.saveWebsite(website);
           
            // now lets import all the theme resources
            FileManager fileMgr = RollerFactory.getRoller().getFileManager();
           
            List resources = theme.getResources();
            Iterator iterat = resources.iterator();
            File resourceFile = null;
            while ( iterat.hasNext() ) {
                resourceFile = (File) iterat.next();
               
                String path = resourceFile.getAbsolutePath().substring(
                        this.themeDir.length()+theme.getName().length()+1);
               
                // make sure path isn't prefixed with a /
                if(path.startsWith("/")) {
                    path = path.substring(1);
                }
               
                log.debug("Importing resource "+resourceFile.getAbsolutePath()+" to "+path);
               
                try {
                    if(resourceFile.isDirectory()) {
                        fileMgr.createDirectory(website, path);
                    } else {
                        fileMgr.saveFile(website, path, "text/plain",
                                resourceFile.length(), new FileInputStream(resourceFile));
                    }
                } catch (Exception ex) {
                    log.info(ex);
                }
            }
           
        } catch (Exception e) {
            log.error("ERROR in action",e);
            throw new RollerException( e );
        }
    }
   
   
    /**
     * 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();
       
        String themespath = RollerConfig.getProperty("themes.dir");
        if(themespath.endsWith(File.separator)) {
            themespath.substring(0, themespath.length() - 1);
        }
       
        // 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);
       
        if(themenames == null)
            themenames = new String[0];
       
        // now go through each theme and read all it's templates
        Theme theme = null;
        for(int i=0; i < themenames.length; i++) {
            try {
                theme = this.loadThemeFromDisk(themenames[i],
                            themespath + File.separator + themenames[i]);           
                themes.put(theme.getName(), theme);
            } catch (Throwable unexpected) {
                // shouldn't happen, so let's learn why it did
                log.error("Problem reading theme " + themenames[i], unexpected);
            }
        }
       
        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) {
       
        log.info("Loading theme "+theme_name)
       
        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);           
            File template_file = new File(themepath + File.separator + templates[i]);
           
            // Continue reading theme even if problem encountered with one file
            String msg = "read theme template file ["+template_file+"]";
            if(!template_file.exists() && !template_file.canRead()) {
                log.error("Couldn't " + msg);
                continue;
            }
            char[] chars = null;
            int length;
            try {
//                FileReader reader = new FileReader(template_file);
                chars = new char[(int) template_file.length()];
              FileInputStream stream = new FileInputStream(template_file);
              InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
                length = reader.read(chars);           
            } catch (Exception noprob) {
                log.error("Exception while attempting to " + msg);
                if (log.isDebugEnabled()) log.debug(noprob);
                continue;
            }
           
            // Strip "_" from name to form link
            boolean navbar = true;
            String template_link = template_name;
            if (template_name.startsWith("_") && template_name.length() > 1) {
                navbar = false;
                template_link = template_link.substring(1);
                log.debug("--- " + template_link);
            }
           
            String decorator = "_decorator";
            if("_decorator".equals(template_name)) {
                decorator = null;
            }
           
            // construct ThemeTemplate representing this file
            // a few restrictions for now:
            //   - we only allow "velocity" for the template language
            //   - decorator is always "_decorator" or null
            //   - all theme templates are considered not hidden
            theme_template = new ThemeTemplate(
                    theme,
                    theme_name+":"+template_name,
                    template_name,
                    template_name,
                    new String(chars, 0, length),
                    template_link,
                    new Date(template_file.lastModified()),
                    "velocity",
                    false,
                    navbar,
                    decorator);

            // add it to the theme
            theme.setTemplate(template_name, theme_template);
        }
       
        // use the last mod date of the theme dir
        theme.setLastModified(new Date(themedir.lastModified()));
       
        // load up resources as well
        loadThemeResources(theme, themedir, themedir.getAbsolutePath());
       
        return theme;
    }
   
   
    /**
     * Convenience method for loading a theme's resource files.
     * This method works recursively to load from subdirectories.
     */
    private void loadThemeResources(Theme theme, File workPath, String basePath) {
       
        // now go through all static resources for this theme
        FilenameFilter resourceFilter = new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return !name.endsWith(".vm");
            }
        };
        File[] resources = workPath.listFiles(resourceFilter);
       
        // go through each resource file and add it to the theme
        String resourcePath = null;
        File resourceFile = null;
        for (int i=0; i < resources.length; i++) {
            resourceFile = resources[i];
            resourcePath = resourceFile.getAbsolutePath().substring(basePath.length()+1);
           
            log.debug("handling resource ["+resourcePath+"]");
           
            // Continue reading theme even if problem encountered with one file
            if(!resourceFile.exists() || !resourceFile.canRead()) {
                log.warn("Couldn't read theme resource file ["+resourcePath+"]");
                continue;
            }
           
            // if its a directory, recurse
            if(resourceFile.isDirectory()) {
                log.debug("resource is a directory, recursing");
                loadThemeResources(theme, resourceFile, basePath);
            }
           
            // otherwise just add the File to the theme
            theme.setResource(resourcePath, resourceFile);
        }
    }
   
}
TOP

Related Classes of org.apache.roller.business.ThemeManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.