/* * #%L * Wisdom-Framework * %% * Copyright (C) 2013 - 2014 Wisdom Framework * %% * Licensed 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. * #L% */ package org.wisdom.template.thymeleaf.impl; import org.apache.commons.io.FilenameUtils; import org.osgi.framework.Bundle; import org.wisdom.api.Controller; import org.wisdom.api.asset.Assets; import org.wisdom.api.http.MimeTypes; import org.wisdom.api.http.Renderable; import org.wisdom.api.router.Router; import org.wisdom.api.templates.Template; import org.wisdom.template.thymeleaf.ThymeleafTemplateCollector; import org.wisdom.template.thymeleaf.dialect.ExtendedOGNLExpressionEvaluator; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.*; /** * Template implementation for ThymeLeaf template. */ public class ThymeLeafTemplateImplementation implements Template { /** * The name of the thymeleaf template engine. */ public static final String THYME_LEAF_ENGINE_NAME = "thymeleaf"; /** * The location in which templates are looked inside bundles. */ public static final String TEMPLATES = "/templates/"; private final URL url; private final String name; private final Router router; private final Assets assets; /** * The reference on the bundle containing the template. Use the system bundle for external template. This bundle * object is used to load classes from templates. */ private final Bundle bundle; private WisdomTemplateEngine templateEngine; public ThymeLeafTemplateImplementation(WisdomTemplateEngine templateEngine, File templateFile, Router router, Assets assets, Bundle source ) throws MalformedURLException { this(templateEngine, templateFile.toURI().toURL(), router, assets, source); } public ThymeLeafTemplateImplementation(WisdomTemplateEngine templateEngine, URL templateURL, Router router, Assets assets, Bundle source) { this.templateEngine = templateEngine; this.url = templateURL; this.bundle = source; // The name of the template is its relative path against its template root // For instance in bundles, it's the relative paths from /templates/ String externalForm = templateURL.toExternalForm(); int indexOfTemplates = externalForm.indexOf(TEMPLATES); if (indexOfTemplates == -1) { name = FilenameUtils.getBaseName(templateURL.getFile()); } else { name = externalForm.substring(indexOfTemplates + TEMPLATES.length(), externalForm.length() - (ThymeleafTemplateCollector.THYMELEAF_TEMPLATE_EXTENSION.length() + 1)); } this.router = router; this.assets = assets; } public synchronized void updateEngine(WisdomTemplateEngine engine) { this.templateEngine = engine; } /** * Gets the template source url. * * @return the url of the template backend (file, jar entry...) */ public URL getURL() { return url; } /** * @return the template name, usually the template file name without the extension. */ @Override public String name() { return name; } /** * @return the template full name. For example, for a file, it will be the file name (including extension). */ @Override public String fullName() { return url.toExternalForm(); } /** * @return the name of the template engine, generally the name of the technology. */ @Override public String engine() { return THYME_LEAF_ENGINE_NAME; } /** * @return the mime type of the document produced by the template. */ @Override public String mimetype() { return MimeTypes.HTML; } /** * Renders the template. * * @param controller the controller having requested the rendering. * @param variables the parameters * @return the rendered object. */ @Override public synchronized Renderable<?> render(Controller controller, Map<String, Object> variables) { HashMap<String, Object> map = new HashMap<>(variables); if (!map.containsKey(ExtendedOGNLExpressionEvaluator.BUNDLE_VAR_KEY)) { map.put(ExtendedOGNLExpressionEvaluator.BUNDLE_VAR_KEY, bundle); } return templateEngine.process(this, controller, router, assets, map); } /** * Renders the template. Unlike {@link #render(org.wisdom.api.Controller, java.util.Map)}, * this method does not inject any user variables. * * @param controller the controller having requested the rendering. * @return the rendered object. */ @Override public Renderable<?> render(Controller controller) { return render(controller, Collections.<String, Object>emptyMap()); } /** * Computes the service properties to be exposed with the {@link org.wisdom.api.templates.Template} service. * * @return the service properties. */ public Dictionary<String, ?> getServiceProperties() { Dictionary<String, String> props = new Hashtable<>(); props.put("name", name()); props.put("fullName", fullName()); props.put("mimetype", mimetype()); props.put("engine", engine()); return props; } }