Hello,

Remembered a while back someone asked if it was possible to reload a theme 
rather than restarting the container for development purposes. 

Rather than upgrading my laptop I decided to see if it was possible. 
Roller needs a few mods, but seems to work, also does not seem to be much 
of an overhead either.


Add a method to theme manager

        /**
         * This is a development only method which reloads theme data from 
themes
         * stored on the filesystem in the webapp /themes/ directory.
         * 
         * @param reloadTheme
         *            the reload theme
         * 
         * @return true, if theme was reloaded from disk
         */
        public boolean reLoadThemeFromDisk(String reloadTheme);


also impl:

        /**
         * @see ThemeManager#reLoadThemeFromDisk(String)
         */
        public boolean reLoadThemeFromDisk(String reloadTheme) {

                boolean reloaded = false;

                try {

                        Theme theme = new SharedThemeFromDir(this.themeDir 
+ File.separator
                                        + reloadTheme);

                        if (theme != null) {

                                Theme loadedTheme = (Theme) 
themes.get(theme.getId());

                                if (loadedTheme != null
                                                && theme.getLastModified()
 .after(loadedTheme.getLastModified())) {
                                        themes.remove(theme.getId());
                                        themes.put(theme.getId(), theme);
                                        reloaded = true;
                                }

                        }

                } catch (Throwable unexpected) {
                        log.error("Problem reloading theme " + 
reloadTheme, unexpected);
                }

                return reloaded;

        }

Modify SharedThemeFromDir to update the last modified in SharedTheme:  see 
**** Set Last Modified *****

        /**
         * Load all the elements of this theme from disk and cache them.
         */
        private void loadThemeFromDisk() throws 
ThemeInitializationException {

                log.debug("Parsing theme descriptor for " + 
this.themeDir);

                ThemeMetadata themeMetadata = null;
                try {
                        // lookup theme descriptor and parse it
                        ThemeMetadataParser parser = new 
ThemeMetadataParser();
                        InputStream is = new FileInputStream(this.themeDir 
+ File.separator
                                        + "theme.xml");
                        themeMetadata = parser.unmarshall(is);
                } catch (Exception ex) {
                        throw new ThemeInitializationException(
                                        "Unable to parse theme descriptor 
for theme "
                                                        + this.themeDir, 
ex);
                }

                log.debug("Loading Theme " + themeMetadata.getName());

                // use parsed theme descriptor to load Theme data
                setId(themeMetadata.getId());
                setName(themeMetadata.getName());
                setDescription(themeMetadata.getName());
                setAuthor(themeMetadata.getAuthor());
                                 **** Set Last Modified *****
                // setLastModified(new Date());
                setEnabled(true);

                // load resource representing preview image
                File previewFile = new File(this.themeDir + File.separator
                                + themeMetadata.getPreviewImage());
                if (!previewFile.exists() || !previewFile.canRead()) {
                        log.warn("Couldn't read theme [" + this.getName()
                                        + "] preview image file ["
                                        + themeMetadata.getPreviewImage() 
+ "]");
                } else {
                        this.previewImage = new 
SharedThemeResourceFromDir(themeMetadata
                                        .getPreviewImage(), previewFile);
                }

                // load stylesheet if possible
                if (themeMetadata.getStylesheet() != null) {

                        ThemeMetadataTemplate stylesheetTmpl = 
themeMetadata
                                        .getStylesheet();

                        // construct File object from path
                        File templateFile = new File(this.themeDir + 
File.separator
                                        + 
stylesheetTmpl.getContentsFile());

                        // read stylesheet contents
                        String contents = loadTemplateFile(templateFile);
                        if (contents == null) {
                                // if we don't have any contents then skip 
this one
                                log.error("Couldn't load stylesheet theme 
[" + this.getName()
                                                + "] template file [" + 
templateFile + "]");
                        } else {

                                // construct ThemeTemplate representing 
this file
                                SharedThemeTemplate theme_template = new 
SharedThemeTemplate(
                                                this, 
themeMetadata.getId() + ":"
                                                                + 
stylesheetTmpl.getName(),
 WebsiteTemplate.ACTION_CUSTOM,
                                                stylesheetTmpl.getName(), 
stylesheetTmpl
 .getDescription(), contents, stylesheetTmpl
 .getLink(), new Date(templateFile
 .lastModified()), stylesheetTmpl
 .getTemplateLanguage(), false, false);

                                // store it
                                this.stylesheet = theme_template;

                                // add it to templates list
                                addTemplate(theme_template);
                        }

                        // **** Set Last Modified *****
                        setLastModified(new 
Date(templateFile.lastModified()));
                }

                // go through static resources and add them to the theme
                String resourcePath = null;
                Iterator resourcesIter = 
themeMetadata.getResources().iterator();
                while (resourcesIter.hasNext()) {
                        resourcePath = (String) resourcesIter.next();

                        // construct ThemeResource object from resource
                        File resourceFile = new File(this.themeDir + 
File.separator
                                        + resourcePath);

                        // Continue reading theme even if problem 
encountered with one file
                        if (!resourceFile.exists() || 
!resourceFile.canRead()) {
                                log.warn("Couldn't read  theme [" + 
this.getName()
                                                + "] resource file [" + 
resourcePath + "]");
                                continue;
                        }

                        // add it to the theme
                        setResource(resourcePath, new 
SharedThemeResourceFromDir(
                                        resourcePath, resourceFile));
 
                        // **** Set Last Modified *****
                        Date lstModified = new 
Date(resourceFile.lastModified());
                        if (getLastModified() == null
                                        || 
lstModified.after(getLastModified())) {
                                setLastModified(lstModified);
                        }
                }

                // go through templates and read in contents to a 
ThemeTemplate
                ThemeTemplate theme_template = null;
                ThemeMetadataTemplate templateMetadata = null;
                Iterator templatesIter = 
themeMetadata.getTemplates().iterator();
                while (templatesIter.hasNext()) {
                        templateMetadata = (ThemeMetadataTemplate) 
templatesIter.next();

                        // construct File object from path
                        File templateFile = new File(this.themeDir + 
File.separator
                                        + 
templateMetadata.getContentsFile());

                        String contents = loadTemplateFile(templateFile);
                        if (contents == null) {
                                // if we don't have any contents then skip 
this one
                                throw new 
ThemeInitializationException("Couldn't load theme ["
                                                + this.getName() + "] 
template file [" + templateFile
                                                + "]");
                        }

                        // construct ThemeTemplate representing this file
                        theme_template = new SharedThemeTemplate(this, 
themeMetadata
                                        .getId()
                                        + ":" + 
templateMetadata.getName(), templateMetadata
                                        .getAction(), 
templateMetadata.getName(), templateMetadata
                                        .getDescription(), contents, 
templateMetadata.getLink(),
                                        new 
Date(templateFile.lastModified()), templateMetadata
 .getTemplateLanguage(),
                                        templateMetadata.isHidden(), 
templateMetadata.isNavbar());

                        // add it to the theme
                        addTemplate(theme_template);

                        //  **** Set Last Modified *****
                        Date lstModified = new 
Date(templateFile.lastModified());
                        if (getLastModified() == null
                                        || 
lstModified.after(getLastModified())) {
                                setLastModified(lstModified);
                        }
                }
        }


Then in PageServlet reload the theme and then clear the caches

// generate cache key
        String cacheKey = null;
        if (isSiteWide) {
            cacheKey = siteWideCache.generateKey(pageRequest);
        } else {
            cacheKey = weblogPageCache.generateKey(pageRequest);
        }

// **** Development only. Reload if theme has been modified  ***
                if 
(WebloggerConfig.getBooleanProperty("site.themeReloadMode")) {
                        try {

                                ThemeManager manager = null;
                                manager = 
WebloggerFactory.getWeblogger().getThemeManager();

                                boolean reloaded = 
manager.reLoadThemeFromDisk(website.getEditorTheme());

                                if (reloaded) {

                                        if (isSiteWide) {
                                                siteWideCache.clear();
                                        } else {
                                                websitePageCache.clear();
                                        }
                                }

                        } catch (Exception e1) {
                                // ignored
                        }

                }

 // cached content checking
        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) && 
request.getAttribute("skipCache") == null) {


Cheers Greg




Share our environment commitment - conserve resources and contribute to the 
reduction of CO2 emissions by not printing the email unless absolutely 
necessary to do so. 

Any opinions expressed are those of the author, not Ricoh UK Ltd. This 
communication does not constitute either offer or acceptance of any 
contractually binding agreement. Such offer or acceptance must be communicated 
in writing. It is the responsibility of the recipient to ensure this email and 
attachments are free from computer viruses before use and the sender accepts no 
responsibility or liability for any such computer viruses. 

Ricoh UK Ltd. may monitor the content of emails sent and received via its 
network for the purpose of ensuring compliance with its policies and 
procedures. This communication contains information, which may be confidential 
or privileged. The information is intended solely for the use of the individual 
or entity named above. If you are not the intended recipient, be aware that any 
disclosure, copying, distribution or use of the contents of this information is 
prohibited. If you have received this communication in error, please notify the 
sender immediately by return email with a copy to  [email protected] . 
Please contact us on +44 (0) 208 261 4000 if you need assistance. 

Registered in England No: 473236 
VAT No: GB524161280  

Reply via email to