Package org.opoo.press.impl

Source Code of org.opoo.press.impl.RendererImpl

/*
* Copyright 2013 Alex Lin.
*
* 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.
*/
package org.opoo.press.impl;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opoo.press.Renderer;
import org.opoo.press.Site;
import org.opoo.press.SiteConfig;
import org.opoo.press.source.SourceEntry;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
* @author Alex Lin
*
*/
public class RendererImpl implements Renderer {
  private static final Logger log = LoggerFactory.getLogger(RendererImpl.class);
 
  private Configuration configuration;
  private Site site;
  private File templateDir;
  private File workingTemplateDir;
  private long start = System.currentTimeMillis();
 
  /**
   * @param site
   * @param templateLoaders
   */
  @SuppressWarnings("unchecked")
  public RendererImpl(Site site, List<TemplateLoader> templateLoaders) {
    super();
    this.site = site;
    templateDir = site.getTemplates();
    log.debug("Template directory: " + templateDir.getAbsolutePath());
   
    //Working directory
    workingTemplateDir = new File( site.getWorking(), "templates");
    if(!workingTemplateDir.exists()){
      workingTemplateDir.mkdirs();
    }
    log.debug("Working template directory: " + workingTemplateDir.getAbsolutePath());
   
    //configuration
    configuration = new Configuration();
    configuration.setObjectWrapper(new DefaultObjectWrapper());
    configuration.setTemplateLoader(buildTemplateLoader(templateLoaders));
   
    Locale locale = site.getLocale();
    if(locale != null){
      configuration.setLocale(site.getLocale());
    }
   
    //Add import i18n messages template.
    configuration.addAutoImport("i18n", "i18n/messages.ftl");
   
    SiteConfig config = site.getConfig();
    List<String> autoIncludeTemplates = (List<String>) config.get("auto_include_templates");
    if(autoIncludeTemplates != null && !autoIncludeTemplates.isEmpty()){
      for(String template: autoIncludeTemplates){
        configuration.addAutoInclude(template);
        log.info("Add auto include: " + template);
      }
    }
   
    Map<String,String> autoImportTemplates = (Map<String, String>) config.get("auto_import_templates");
    if(autoImportTemplates != null && !autoImportTemplates.isEmpty()){
      for(Map.Entry<String, String> en: autoImportTemplates.entrySet()){
        configuration.addAutoImport(en.getKey(), en.getValue());
        log.info("Add auto import: " + en.getKey() + " -> " + en.getValue());
      }
    }
  }
 
  private TemplateLoader buildTemplateLoader(List<TemplateLoader> loaders){
    try {
      FileTemplateLoader loader1 = new FileTemplateLoader(workingTemplateDir);
      FileTemplateLoader loader2 = new FileTemplateLoader(templateDir);
      ClassTemplateLoader loader3 = new ClassTemplateLoader(RendererImpl.class, "/org/opoo/press/templates");
       
      if(loaders == null){
        loaders = new ArrayList<TemplateLoader>();
      }
      if(loaders != null){
        loaders.add(0, loader3);
        loaders.add(0, loader2);
        loaders.add(0, loader1);
      }
      TemplateLoader[] loaders2 = loaders.toArray(new TemplateLoader[loaders.size()]);
      //TemplateLoader loader = new MultiTemplateLoader(new TemplateLoader[]{loader1, loader2});
      TemplateLoader loader = new MultiTemplateLoader(loaders2);
      return loader;
    } catch (IOException e) {
      throw new IllegalArgumentException(e);
    }
  }
 
  public Site getSite() {
    return site;
  }

//  private String buildTemplate(String layout, String content){
//    return buildTemplateContent(layout, content, false).toString();
//  }

  @Override
  public String render(String templateName, Map<String, Object> rootMap) {
    StringWriter out = new StringWriter();
    render(templateName, rootMap, out);
    IOUtils.closeQuietly(out);
    return out.toString();
  }
 
  @Override
  public void render(String templateName, Map<String, Object> rootMap, Writer out){
    Template template = null;
    try {
      template = configuration.getTemplate(templateName, "UTF-8");
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
   
    process(template, rootMap, out);
  }
 
  private void process(Template template, Map<String,Object> rootMap, Writer out){
    //if(log.isDebugEnabled()){
      //log.debug("Template " + template);
    //}
       
    try {
      template.process(rootMap, out);
      out.flush();
    } catch (TemplateException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
 
  public String prepareWorkingTemplate(String layout, boolean isValidLayout,
      String content, boolean isContentRenderRequired, SourceEntry entry) {
    log.debug("Prepare template for " + entry.getFile());

    String name = isContentRenderRequired ? buildTemplateName(layout, entry) : getLayoutWorkingTemplate(layout);
    File targetTemplateFile = new File(this.workingTemplateDir, name);
   
    if(targetTemplateFile.exists() && targetTemplateFile.lastModified() >= entry.getLastModified()){
      log.debug("Working template exists and newer than source file: " + targetTemplateFile);
    }else{
      StringBuffer templateContent = buildTemplateContent(layout, isValidLayout,
          content, isContentRenderRequired);
      try {
        FileUtils.write(targetTemplateFile, templateContent, "UTF-8");
        //targetTemplateFile.setLastModified(sourceEntry.getLastModified());
        if(log.isDebugEnabled()){
          log.debug("Create working template: " + targetTemplateFile);
        }
      } catch (IOException e) {
        throw new RuntimeException("Write working template error: " + targetTemplateFile, e);
      }
    }
   
    return name;
  }
 
//  private String buildPlainTextTemplateName(String layout){
//    return "_" + layout + ".content.ftl";
//  }
 
  private String buildTemplateName(String layout, SourceEntry entry){
    String name = entry.getPath() + "/" + entry.getName() + "." + layout + ".ftl";
//    return StringUtils.replace(name, "/", "__");
    return name;
  }

  private StringBuffer buildTemplateContent(String layout, boolean isValidLayout,
      String content, boolean isContentRenderRequired){
    StringBuffer template = new StringBuffer();
    //appendPluginMarcos(template);
   
    if(isValidLayout){
      template.append("<#include \"/_" + layout + ".ftl\">");
      template.append("<@" + layout + "Layout>");
    }
   
    if(isContentRenderRequired){
      template.append(content);
    }else{
      template.append("${content}");
    }
   
    if(isValidLayout){
      template.append("</@" + layout + "Layout>");
    }
   
    return template;
  }

  @Override
  public String renderContent(String templateContent,  Map<String, Object> rootMap) {
    StringWriter out = new StringWriter();
    renderContent(templateContent, rootMap, out);
    IOUtils.closeQuietly(out);
    return out.toString();
  }
 
  @Override
  public void renderContent(String templateContent, Map<String, Object> rootMap, Writer out){
    Template template = null;
    try {
      template = new Template("CT" + (start++), new StringReader(templateContent), configuration, "UTF-8");
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    process(template, rootMap, out);
  }

  @Override
  public boolean isRenderRequired(String content) {
    if(StringUtils.contains(content, "<#")){
      return true;
    }
    if(StringUtils.contains(content, "${")){
      return true;
    }
    return false;
  }

  @Override
  public boolean isValidLayout(String layout) {
    if(layout == null){
      return false;
    }
    if("nil".equalsIgnoreCase(layout)){
      return false;
    }
    if("null".equalsIgnoreCase(layout)){
      return false;
    }
    if("none".equalsIgnoreCase(layout)){
      return false;
    }
//    return (layout != null) && !"nil".equals(layout);
    return true;
  }

  /* (non-Javadoc)
   * @see org.opoo.press.Renderer#prepareLayoutWorkingTemplates()
   */
  @Override
  public void prepareLayoutWorkingTemplates() {
    log.debug("Prepare layout working templates...");
   
    File templates = site.getTemplates();
    File[] layoutFiles = templates.listFiles(new FilenameFilter(){
      public boolean accept(File file, String name) {
        return name.startsWith("_") && name.endsWith(".ftl");
      }
    });
   
    for(File layoutFile: layoutFiles){
      String layout = FilenameUtils.getBaseName(layoutFile.getName()).substring(1);
      String name = getLayoutWorkingTemplate(layout);
     
      File targetTemplateFile = new File(this.workingTemplateDir, name);
      if(targetTemplateFile.exists() && targetTemplateFile.lastModified() >= layoutFile.lastModified()){
        log.debug("Layout template exists and newer than source file: " + targetTemplateFile);
      }else{
        StringBuffer templateContent = buildTemplateContent(layout, true, null, false);
        try {
          FileUtils.write(targetTemplateFile, templateContent, "UTF-8");
          //targetTemplateFile.setLastModified(sourceEntry.getLastModified());
          if(log.isDebugEnabled()){
            log.debug("Create layout template: " + targetTemplateFile);
          }
        } catch (IOException e) {
          throw new RuntimeException("Write layout template error: " + targetTemplateFile, e);
        }
      }
    }
  }
 
  public String getLayoutWorkingTemplate(String layout){
    return "_" + layout + ".content.ftl";
  }
}
TOP

Related Classes of org.opoo.press.impl.RendererImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.