001    /**
002     * Copyright (c) 2000-2013 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.security.pacl.DoPrivileged;
018    import com.liferay.portal.kernel.template.Template;
019    import com.liferay.portal.kernel.template.TemplateConstants;
020    import com.liferay.portal.kernel.template.TemplateException;
021    import com.liferay.portal.kernel.template.TemplateResource;
022    import com.liferay.portal.kernel.util.ReflectionUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.template.BaseTemplateManager;
025    import com.liferay.portal.template.RestrictedTemplate;
026    import com.liferay.portal.template.TemplateContextHelper;
027    import com.liferay.portal.util.PropsValues;
028    
029    import freemarker.cache.TemplateCache;
030    
031    import freemarker.debug.impl.DebuggerService;
032    
033    import freemarker.template.Configuration;
034    
035    import java.lang.reflect.Field;
036    
037    import java.util.Map;
038    
039    /**
040     * @author Mika Koivisto
041     * @author Tina Tina
042     */
043    @DoPrivileged
044    public class FreeMarkerManager extends BaseTemplateManager {
045    
046            @Override
047            public void destroy() {
048                    if (_configuration == null) {
049                            return;
050                    }
051    
052                    _configuration.clearEncodingMap();
053                    _configuration.clearSharedVariables();
054                    _configuration.clearTemplateCache();
055    
056                    _configuration = null;
057    
058                    _templateContextHelper.removeAllHelperUtilities();
059    
060                    _templateContextHelper = null;
061    
062                    if (isEnableDebuggerService()) {
063                            DebuggerService.shutdown();
064                    }
065            }
066    
067            @Override
068            public void destroy(ClassLoader classLoader) {
069                    _templateContextHelper.removeHelperUtilities(classLoader);
070            }
071    
072            @Override
073            public String getName() {
074                    return TemplateConstants.LANG_TYPE_FTL;
075            }
076    
077            @Override
078            public void init() throws TemplateException {
079                    if (_configuration != null) {
080                            return;
081                    }
082    
083                    _configuration = new Configuration();
084    
085                    try {
086                            Field field = ReflectionUtil.getDeclaredField(
087                                    Configuration.class, "cache");
088    
089                            TemplateCache templateCache = new LiferayTemplateCache(
090                                    _configuration);
091    
092                            field.set(_configuration, templateCache);
093                    }
094                    catch (Exception e) {
095                            throw new TemplateException(
096                                    "Unable to Initialize Freemarker manager");
097                    }
098    
099                    _configuration.setDefaultEncoding(StringPool.UTF8);
100                    _configuration.setLocalizedLookup(
101                            PropsValues.FREEMARKER_ENGINE_LOCALIZED_LOOKUP);
102                    _configuration.setNewBuiltinClassResolver(
103                            new LiferayTemplateClassResolver());
104                    _configuration.setObjectWrapper(new LiferayObjectWrapper());
105    
106                    try {
107                            _configuration.setSetting(
108                                    "auto_import", PropsValues.FREEMARKER_ENGINE_MACRO_LIBRARY);
109                            _configuration.setSetting(
110                                    "template_exception_handler",
111                                    PropsValues.FREEMARKER_ENGINE_TEMPLATE_EXCEPTION_HANDLER);
112                    }
113                    catch (Exception e) {
114                            throw new TemplateException("Unable to init freemarker manager", e);
115                    }
116    
117                    if (isEnableDebuggerService()) {
118                            DebuggerService.getBreakpoints("*");
119                    }
120            }
121    
122            public void setTemplateContextHelper(
123                    TemplateContextHelper templateContextHelper) {
124    
125                    _templateContextHelper = templateContextHelper;
126            }
127    
128            @Override
129            protected Template doGetTemplate(
130                    TemplateResource templateResource,
131                    TemplateResource errorTemplateResource, boolean restricted,
132                    Map<String, Object> helperUtilities) {
133    
134                    Template template = new FreeMarkerTemplate(
135                            templateResource, errorTemplateResource, helperUtilities,
136                            _configuration, _templateContextHelper);
137    
138                    if (restricted) {
139                            template = new RestrictedTemplate(
140                                    template, _templateContextHelper.getRestrictedVariables());
141                    }
142    
143                    return template;
144            }
145    
146            @Override
147            protected TemplateContextHelper getTemplateContextHelper() {
148                    return _templateContextHelper;
149            }
150    
151            protected boolean isEnableDebuggerService() {
152                    if ((System.getProperty("freemarker.debug.password") != null) &&
153                            (System.getProperty("freemarker.debug.port") != null)) {
154    
155                            return true;
156                    }
157    
158                    return false;
159            }
160    
161            private Configuration _configuration;
162            private TemplateContextHelper _templateContextHelper;
163    
164    }