001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.freemarker;
016    
017    import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
018    import com.liferay.portal.kernel.freemarker.FreeMarkerEngine;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.Validator;
023    import com.liferay.portal.util.PropsValues;
024    
025    import freemarker.cache.ClassTemplateLoader;
026    import freemarker.cache.MultiTemplateLoader;
027    import freemarker.cache.StringTemplateLoader;
028    import freemarker.cache.TemplateLoader;
029    
030    import freemarker.template.Configuration;
031    import freemarker.template.DefaultObjectWrapper;
032    import freemarker.template.Template;
033    
034    import java.io.IOException;
035    import java.io.Writer;
036    
037    /**
038     * @author Mika Koivisto
039     */
040    public class FreeMarkerEngineImpl implements FreeMarkerEngine {
041    
042            public FreeMarkerContext getWrappedRestrictedToolsContext() {
043                    return new FreeMarkerContextImpl(
044                            _restrictedToolsContext.getWrappedContext());
045            }
046    
047            public FreeMarkerContext getWrappedStandardToolsContext() {
048                    return new FreeMarkerContextImpl(
049                            _standardToolsContext.getWrappedContext());
050            }
051    
052            public void init() throws Exception {
053                    LiferayTemplateLoader liferayTemplateLoader =
054                            new LiferayTemplateLoader();
055    
056                    liferayTemplateLoader.setTemplateLoaders(
057                            PropsValues.FREEMARKER_ENGINE_TEMPLATE_LOADERS);
058    
059                    _stringTemplateLoader = new StringTemplateLoader();
060    
061                    MultiTemplateLoader multiTemplateLoader =
062                            new MultiTemplateLoader(
063                                    new TemplateLoader[] {
064                                            new ClassTemplateLoader(getClass(), StringPool.SLASH),
065                                            _stringTemplateLoader, liferayTemplateLoader
066                                    });
067    
068                    _configuration = new Configuration();
069    
070                    _configuration.setDefaultEncoding(StringPool.UTF8);
071                    _configuration.setLocalizedLookup(
072                            PropsValues.FREEMARKER_ENGINE_LOCALIZED_LOOKUP);
073                    _configuration.setObjectWrapper(new DefaultObjectWrapper());
074                    _configuration.setSetting(
075                            "auto_import", PropsValues.FREEMARKER_ENGINE_MACRO_LIBRARY);
076                    _configuration.setSetting(
077                            "cache_storage", PropsValues.FREEMARKER_ENGINE_CACHE_STORAGE);
078                    _configuration.setSetting(
079                            "template_exception_handler",
080                            PropsValues.FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER);
081                    _configuration.setTemplateLoader(multiTemplateLoader);
082                    _configuration.setTemplateUpdateDelay(
083                            PropsValues.FREEMARKER_ENGINE_MODIFICATION_CHECK_INTERVAL);
084    
085                    _restrictedToolsContext = new FreeMarkerContextImpl();
086    
087                    FreeMarkerVariables.insertHelperUtilities(
088                            _restrictedToolsContext,
089                            PropsValues.JOURNAL_TEMPLATE_FREEMARKER_RESTRICTED_VARIABLES);
090    
091                    _standardToolsContext = new FreeMarkerContextImpl();
092    
093                    FreeMarkerVariables.insertHelperUtilities(_standardToolsContext, null);
094            }
095    
096            public boolean mergeTemplate(
097                            String freeMarkerTemplateId, FreeMarkerContext freeMarkerContext,
098                            Writer writer)
099                    throws Exception {
100    
101                    return mergeTemplate(
102                            freeMarkerTemplateId, null, freeMarkerContext, writer);
103            }
104    
105            public boolean mergeTemplate(
106                            String freeMarkerTemplateId, String freemarkerTemplateContent,
107                            FreeMarkerContext freeMarkerContext, Writer writer)
108                    throws Exception {
109    
110                    if ((Validator.isNotNull(freeMarkerTemplateId)) &&
111                            (Validator.isNotNull(freemarkerTemplateContent)) &&
112                            (!PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED ||
113                             !resourceExists(freeMarkerTemplateId))) {
114    
115                            _stringTemplateLoader.putTemplate(
116                                    freeMarkerTemplateId, freemarkerTemplateContent);
117    
118                            if (_log.isDebugEnabled()) {
119                                    _log.debug(
120                                            "Added " + freeMarkerTemplateId +
121                                                    " to the FreeMarker template repository");
122                            }
123                    }
124    
125                    FreeMarkerContextImpl freeMarkerContextImpl =
126                            (FreeMarkerContextImpl)freeMarkerContext;
127    
128                    Template template = _configuration.getTemplate(
129                            freeMarkerTemplateId, StringPool.UTF8);
130    
131                    template.process(freeMarkerContextImpl.getWrappedContext(), writer);
132    
133                    return true;
134            }
135    
136            public boolean resourceExists(String resource) {
137                    try {
138                            Template template = _configuration.getTemplate(resource);
139    
140                            if (template != null) {
141                                    return true;
142                            }
143                            else {
144                                    return false;
145                            }
146                    }
147                    catch (IOException ioe) {
148                            if (_log.isWarnEnabled()) {
149                                    _log.warn(ioe, ioe);
150                            }
151    
152                            return false;
153                    }
154            }
155    
156            private static Log _log = LogFactoryUtil.getLog(FreeMarkerEngineImpl.class);
157    
158            private Configuration _configuration;
159            private FreeMarkerContextImpl _restrictedToolsContext;
160            private FreeMarkerContextImpl _standardToolsContext;
161            private StringTemplateLoader _stringTemplateLoader;
162    
163    }