/* * Copyright 2009-2012 by KNURT Systeme (http://www.knurt.de) * * Licensed under the Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://creativecommons.org/licenses/by-nc-sa/3.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. */ package de.knurt.fam.template.velocity; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.jdom.Element; import de.knurt.fam.connector.FamConnector; import de.knurt.fam.connector.FamSystemMeta; import de.knurt.fam.core.aspects.logging.FamLog; import de.knurt.fam.core.view.text.FamDateFormat; import de.knurt.fam.core.view.text.FamText; import de.knurt.fam.template.model.TemplateModelFactory; import de.knurt.fam.template.model.TemplateResource; import de.knurt.fam.template.parser.ContentFactory; import de.knurt.fam.template.util.TemplateConfig; /** * produce contents * * @author Daniel Oltmanns * @since 1.21 (09/28/2010) */ public class VelocityFileContentFactory implements ContentFactory { /** one and only instance of TemplateConfig */ private volatile static VelocityFileContentFactory me; /** construct TemplateConfig */ private VelocityFileContentFactory() { String templateDirectory = FamConnector.templateDirectory(); Properties props = new Properties(); props.setProperty(Velocity.INPUT_ENCODING, "UTF-8"); props.setProperty("resource.loader", "file"); props.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader"); props.setProperty("file.resource.loader.path", templateDirectory); props.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute"); props.setProperty("runtime.log.logsystem.log4j.logger", "velocity"); props.setProperty("userdirective", "com.googlecode.htmlcompressor.velocity.HtmlCompressorDirective"); try { Velocity.init(props); } catch (Exception e) { for (StackTraceElement ste : e.getStackTrace()) { FamLog.info(ste.getClassName() + " - " + ste.getFileName() + " - " + ste.getLineNumber() + " - " + ste.getMethodName(), 234234234l); } FamLog.exception(e, 201104201301l); } } /** * return the one and only instance of TemplateConfig * * @return the one and only instance of TemplateConfig */ public static VelocityFileContentFactory getInstance() { if (me == null) { // ↖ no instance so far synchronized (VelocityFileContentFactory.class) { if (me == null) { // ↖ still no instance so far // ↓ the one and only me me = new VelocityFileContentFactory(); } } } return me; } /** * short for {@link #getInstance()} * * @return the one and only instance of TemplateConfig */ public static VelocityFileContentFactory me() { return getInstance(); } private VelocityContext getVelocityContext(TemplateResource templateResource) { VelocityContext result = new VelocityContext(); Properties config = FamConnector.getGlobalProperties(); config.put("version", FamSystemMeta.CURRENT_VERSION); config.put("deploydate", FamSystemMeta.getDateDeployed()); config.put("preview", FamSystemMeta.isPreview()); if (templateResource.isRequestForContent()) { Element configXml = TemplateConfig.me().getContentProperties().getCustomConfig(); if (configXml != null) { Properties configXmlProps = new Properties(); configXmlProps.put("xml", configXml); try { configXmlProps.put("page", TemplateConfig.me().getContentProperties().getCustomConfigPage(templateResource.getName())); } catch (Exception e) { FamLog.exception(templateResource.getName(), e, 201011041432l); } try { configXmlProps.put("model", new TemplateModelFactory(templateResource).getProperties()); } catch (Exception e) { FamLog.exception(templateResource.getName(), e, 201011041433l); } configXmlProps.put("resource", templateResource); config.putAll(configXmlProps); } try { config.put("user", templateResource.getAuthUser() == null ? false : templateResource.getAuthUser()); } catch (Exception e) { FamLog.exception(templateResource.getName(), e, 201011041434l); } Properties lang = new Properties(); Element langXml = TemplateConfig.me().getContentProperties().getCustomLanguage(); if (langXml != null) { Properties langXmlProps = new Properties(); langXmlProps.put("xml", langXml); try { langXmlProps.put("page", TemplateConfig.me().getContentProperties().getCustomLanguagePage(templateResource.getName())); } catch (Exception e) { FamLog.exception(templateResource.getName(), e, 201011041435l); } try { lang.putAll(langXmlProps); } catch (Exception e) { FamLog.exception(templateResource.getName(), e, 201011041436l); } } result.put("lang", lang); result.put("visibility", templateResource.getVisibility().toString().toLowerCase()); } result.put("config", config); result.put("util", TemplateConfig.me().getUtilities()); result.put("resource_name", templateResource.getName()); // some statics result.put("FamDateFormat", FamDateFormat.class); result.put("Math", Math.class); result.put("FamText", FamText.class); return result; } public String getTemplateFile(TemplateResource templateResource) { String result = ""; boolean found = false; if (templateResource.getSuffix().equals("html")) { result = templateResource.getTemplateFile(); // answer relative to found = result != null && !result.isEmpty(); } else if (templateResource.getSuffix().equals("js") || templateResource.getSuffix().equals("css")) { String candidate = templateResource.getSuffix().equals("js") ? "scripts" : "styles"; candidate += File.separator + templateResource.getName() + "." + templateResource.getSuffix(); found = new File(FamConnector.templateDirectory() + candidate).exists(); if (found) { result = candidate; } } if (!found) { Properties p = new Properties(); try { p.load(new FileInputStream(String.format("%smapping.properties", FamConnector.templateDirectory()))); result = p.getProperty(String.format("%s.%s", templateResource.getSuffix(), templateResource.getName())); } catch (IOException e) { FamLog.logException(this.getClass(), e, "could not get " + String.format("%smapping.properties", FamConnector.templateDirectory()), 201010071656l); } } return result; } @Override public String getContent(TemplateResource templateResource) { String result = null; VelocityContext context = null; Template template = null; Writer writer = null; try { context = this.getVelocityContext(templateResource); template = Velocity.getTemplate(this.getTemplateFile(templateResource)); writer = new StringWriter(); template.merge(context, writer); result = writer.toString(); } catch (ResourceNotFoundException e) { FamLog.logException(this.getClass(), e, "no resource found", 201010071653l); } catch (ParseErrorException e) { FamLog.logException(this.getClass(), e, "could not parse it", 201010071655l); } catch (Exception e) { FamLog.logException(this.getClass(), e, "unknown: " + templateResource + " | " + context + " | " + template + " | " + (templateResource != null ? templateResource.getTemplateFile() + " | " + this.getTemplateFile(templateResource) : "") + " | " + FamConnector.templateDirectory(), 201010071654l); } return result; } }