Package juzu.impl.template.spi.juzu.dialect.gtmpl

Source Code of juzu.impl.template.spi.juzu.dialect.gtmpl.GroovyTemplateStub

/*
* Copyright 2013 eXo Platform SAS
*
* 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 juzu.impl.template.spi.juzu.dialect.gtmpl;

import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.Script;
import juzu.impl.template.spi.TemplateStub;
import juzu.template.TemplateExecutionException;
import juzu.template.TemplateRenderContext;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.runtime.InvokerHelper;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;

/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
public class GroovyTemplateStub extends TemplateStub {

  /** . */
  private Class<?> scriptClass;

  /** . */
  private HashMap<Integer, Foo> locationTable;

  public GroovyTemplateStub(ClassLoader loader, String templateId) {
    super(loader, templateId);

    //
    this.scriptClass = null;
    this.locationTable = null;
  }

  @Override
  public void doInit(ClassLoader loader) {

    // The class fqn
    String fqn = id + "_";

    // Load from class loader first
    try {
      scriptClass = loader.loadClass(fqn);
    }
    catch (ClassNotFoundException ignore) {
    }
    catch (NoClassDefFoundError ignore) {
    }

    // Compile class
    if (scriptClass == null) {
      CompilerConfiguration config = new CompilerConfiguration();
      String script = getScript(loader, fqn);
      GroovyCodeSource gcs = new GroovyCodeSource(new ByteArrayInputStream(script.getBytes()), "myscript", "/groovy/shell");
      GroovyClassLoader gcl = new GroovyClassLoader(loader, config);
      try {
        scriptClass = gcl.parseClass(gcs, false);
      }
      catch (Exception e) {
        throw new UnsupportedOperationException("handle me gracefully", e);
      }
    }

    // Load constants
    try {
      String simpleName;
      String prefix;
      int pos = id.lastIndexOf('.');
      if (pos != -1) {
        prefix = id.substring(0, pos + 1);
        simpleName = id.substring(pos + 1);
      } else {
        prefix = "";
        simpleName = id;
      }
      String constantsName = prefix + "C" + simpleName;
      Class<?> constants = scriptClass.getClassLoader().loadClass(constantsName);
      locationTable = (HashMap<Integer, Foo>)constants.getField("TABLE").get(null);
    }
    catch (Exception e) {
      throw new UnsupportedOperationException("Handle me gracefully", e);
    }
  }

  public String getScript(ClassLoader loader, String fqn) {
    try {
      String path = fqn.replace('.', '/') + ".groovy";
      URL url = loader.getResource(path);
      if (url != null) {
        byte[] buffer = new byte[256];
        InputStream in = url.openStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int l = in.read(buffer);l != -1;l = in.read(buffer)) {
          baos.write(buffer, 0, l);
        }
        return baos.toString();
      }
      else {
        // Should log that
      }
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

  public String getClassName() {
    return scriptClass != null ? scriptClass.getName() : null;
  }

  @Override
  public void doRender(TemplateRenderContext renderContext) throws TemplateExecutionException, IOException {
    Binding binding = new BindingImpl(renderContext);

    //
    Script script = InvokerHelper.createScript(scriptClass, binding);

    //
    try {
      script.run();
    }
    catch (Exception e) {
      if (e instanceof IOException) {
        throw (IOException)e;
      }
      else {
        throw buildRuntimeException(e);
      }
    }
    catch (Throwable e) {
      if (e instanceof Error) {
        throw ((Error)e);
      }
      throw buildRuntimeException(e);
    }
  }

  private TemplateExecutionException buildRuntimeException(Throwable t) {
    StackTraceElement[] trace = t.getStackTrace();

    //
    Foo firstItem = null;

    // Try to find the groovy script lines
    for (int i = 0;i < trace.length;i++) {
      StackTraceElement element = trace[i];
      if (element.getClassName().equals(scriptClass.getName())) {
        int lineNumber = element.getLineNumber();
        Foo item = locationTable.get(lineNumber);
        int templateLineNumber;
        if (item != null) {
          templateLineNumber = item.getPosition().getLine();
          if (firstItem == null) {
            firstItem = item;
          }
        }
        else {
          templateLineNumber = -1;
        }
        element = new StackTraceElement(
          element.getClassName(),
          element.getMethodName(),
          element.getFileName(),
          templateLineNumber);
        trace[i] = element;
      }
    }

    //
    t.setStackTrace(trace);

    //
    if (firstItem != null) {
      return new TemplateExecutionException(id, firstItem.getPosition(), firstItem.getValue(), t);
    }
    else {
      return new TemplateExecutionException(id, null, null, t);
    }
  }
}
TOP

Related Classes of juzu.impl.template.spi.juzu.dialect.gtmpl.GroovyTemplateStub

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.