Package org.ajax4jsf.templatecompiler.builder

Source Code of org.ajax4jsf.templatecompiler.builder.AbstractCompilationContext

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.ajax4jsf.templatecompiler.builder;

import java.beans.PropertyDescriptor;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.ajax4jsf.builder.config.ClassVisitor;
import org.ajax4jsf.builder.config.ClassWalkingLogic;
import org.ajax4jsf.builder.model.JavaPrimitive;
import org.ajax4jsf.templatecompiler.elements.A4JRendererElementsFactory;
import org.ajax4jsf.templatecompiler.elements.ElementsFactory;
import org.ajax4jsf.templatecompiler.elements.TemplateElement;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.w3c.dom.Node;

/**
* Component Beam.
*
* @author ayukhovich@exadel.com (latest modification by $Author: alexsmirnov $)
* @version $Revision: 1.1.2.2 $ $Date: 2007/02/26 20:48:42 $
*
*/
public abstract class AbstractCompilationContext implements CompilationContext {
  private static final Log log = LogFactory.getLog(AbstractCompilationContext.class);
 
  final private static String VCPBODY = "VCPBODY";

  final private static String regexComponent = "(.*)" + VCPBODY + "(.*)"
      + VCPBODY + "(.*)";

  final private static Pattern patternComponent = Pattern.compile(
      regexComponent, Pattern.UNIX_LINES + Pattern.DOTALL);

  private final static String DEFAULT_BASE_CLASS = "org.ajax4jsf.renderkit.RendererBase";

  private String packageName;

  private String className;

  private String baseClassName;

  private ArrayList<String> declarations;

  private ArrayList<String> imports;

  private String[] EncodeBegin;

  private String[] EncodeEnd;

  private String[] EncodeChildren;

  private Map<String, Map<String, PropertyDescriptor>> resolvedProperties =
    new HashMap<String, Map<String,PropertyDescriptor>>();
 
  private HashMap<String, Class<?>> variables = new HashMap<String, Class<?>>();

  private static String[] defaultImports = new String[] {
      "java.util.Iterator", "java.util.Collection",
      "java.util.Map",
      "java.io.IOException", "javax.faces.component.UIComponent",
      "javax.faces.context.FacesContext",
      "javax.faces.context.ResponseWriter",
      "org.ajax4jsf.renderkit.ComponentsVariableResolver",
      "org.ajax4jsf.renderkit.ComponentVariables" };
 
  private TemplateElement tree;
 
  private List<ElementsFactory> elementFactories = new ArrayList<ElementsFactory>();


  /**
   * Name of UIComponent class for this template - can be used for get properties and methods by introspection.
   */
  private String componentClass;


  /**
   * Ant Task related classloader for loat UIComponent and Renderer classes for introspection.
   */
  private ClassLoader classLoader;


  public AbstractCompilationContext() {
    this.baseClassName = DEFAULT_BASE_CLASS;
    this.declarations = new ArrayList<String>();
    this.imports = new ArrayList<String>();
    this.imports.addAll(Arrays.asList(defaultImports));
    // Init default elements factory.
    this.elementFactories.add(new A4JRendererElementsFactory());
  }

  /**
   * @param loader
   * @throws CompilationException
   */
  public AbstractCompilationContext(ClassLoader loader) throws CompilationException {
    this();
    this.classLoader = loader;
    setDefaultVariables();
  }

 
  public void addElementsFactory(ElementsFactory factory) {
    elementFactories.add(0, factory);
  }
  /**
   * @param componentClass
   *            The componentClass to set.
   * @throws CompilationException
   */
  public void setComponentClass(String componentClass)
      throws CompilationException {
    this.componentClass = componentClass;
    addVariable("component", componentClass);
  }

  /**
   * set a package name
   */
  public void setPackageName(final String packageName) {
    this.packageName = packageName;
  }

  /**
   * set a class name
   */
  public void setClassName(final String className) {
    this.className = className;
  }

  /**
   *
   * @param fullClassName
   */
  public void setFullClassName(final String fullClassName) {
    int dotIndex = fullClassName.lastIndexOf(".");

    String tempPackageName = "";
    String tempClassName = fullClassName;

    if (dotIndex != -1) {
      tempPackageName = fullClassName.substring(0, dotIndex);
      tempClassName = fullClassName.substring(dotIndex + 1);
    } // if

    setPackageName(tempPackageName);
    setClassName(tempClassName);

  }

  public void setBaseclass(String baseclassName) throws CompilationException {
    this.baseClassName = baseclassName;
    addVariable("this", baseclassName);
  }

  // ------

  /**
   * @return package name
   */
  public String getPackageName() {
    return this.packageName;
  }

  /**
   * @return base class package name
   */
  public String getBaseclassPackageName() {
    String packageName = null;
    int dotIndex = this.baseClassName.lastIndexOf(".");

    if (dotIndex != -1) {
      packageName = this.baseClassName.substring(0, dotIndex);
    }

    return packageName;
  }

  /**
   * @return class name
   */
  public String getClassName() {
    return this.className;
  }

  /**
   * @return base class package name
   */
  public String getBaseclassName() {
    String className = null;

    if ((this.baseClassName != null) && (this.baseClassName.length() != 0)) {
      int dotIndex = this.baseClassName.lastIndexOf(".");

      if (dotIndex != -1) {
        className = this.baseClassName.substring(dotIndex + 1);
      } else {
        className = this.baseClassName;
      }
    }

    return className;
  }

  /**
   * @return full class name with package name
   */
  public String getFullClassName() {
    StringBuffer buf = new StringBuffer();

    if ((this.packageName != null) && (this.packageName.length() != 0)) {
      buf.append(this.packageName);
      buf.append('.');
    }

    buf.append(this.className);

    return buf.toString();
  }

  /**
   * @return base class package name
   */
  public String getFullBaseclass() {
    return this.baseClassName;
  }

  /**
   * @return
   */
  public String getComponentFileName() {
    return getFullClassName().replace('.', '/');
  }

  /**
   * @return Returns the componentClass.
   */
  public String getComponentClass() {
    String returnStr = this.componentClass;

    // if ( (componentClass != null) && ( !
    // componentClass.endsWith(".class")) ) {
    // returnStr = componentClass + ".class";
    // }

    return returnStr;
  }

  /**
   * return class loader
   */
  public ClassLoader getClassLoader() {
    return this.classLoader;
  }

  /**
   * @return string array contain declarations
   */
  public String[] getDeclarations() {
    return this.declarations.toArray(new String[0]);
  }

  /**
   * @return string array contain declarations
   */
  public String[] getImports() {
    return this.imports.toArray(new String[0]);
  }

  public void addToImport(String className) {
    this.imports.add(className);
  }

  public void addToDeclaration(String declaration) {
    this.declarations.add(declaration);
  }

  /**
   * Add variable with type String
   *
   * @param variableName
   * @throws CompilationException
   */
  public void addVariable(String variableName) throws CompilationException {
    addVariable(variableName, "java.lang.String");
  }

  public void addVariable(String variableName, Class<?> clazz) {
    this.variables.put(variableName, clazz);
  }

  public void addVariable(String variableName, String typeName)
      throws CompilationException {
    try {
      Class<?> clazz = loadClass(typeName);
      this.variables.put(variableName, clazz);
    } catch (ClassNotFoundException e) {
//      error("Error create variable "+variableName+" with type "+typeName, e);
      throw new CompilationException("Error create renderer variable "+variableName+" with type "+typeName, e);
    }
  }

  public boolean containsVariable(String variableName) {
    return this.variables.containsKey(variableName);
  }

  public Class<?> getVariableType(String variableName) {
    return this.variables.get(variableName);
  }

  public Class<?> loadClass(String className) throws ClassNotFoundException {
    Class<?> clazz = null;
    try {
        if (JavaPrimitive.isPrimitive(className)) {
          clazz = JavaPrimitive.forName(className);
        } else {
          clazz = this.classLoader.loadClass(className);
        }
    } catch (ClassNotFoundException e) {
        throw e;
    } catch (Throwable e) {
        log.error(e.getLocalizedMessage(), e);
    }

    if (null == clazz) {
      throw new ClassNotFoundException(className);
    }
    return clazz;
  }

  public void setDefaultVariables() throws CompilationException {
    addVariable("component", "javax.faces.component.UIComponent");
    addVariable("context", "javax.faces.context.FacesContext");
    addVariable("writer", "javax.faces.context.ResponseWriter");
    // addLocalVariable("component", "javax.faces.component.UIComponent" );
    addVariable("variables",
        "org.ajax4jsf.renderkit.ComponentVariables");
  }

  public Class<?> getMethodReturnedClass(Class<?> clazz, String methodName,
      Class<?>[] parametersTypes) throws NoSuchMethodException {
    Class<?> returnedType = null;
    log.debug("class : " + clazz.getName() + "\n\t method : "
        + methodName + "\n\t paramTypes : "
        + Arrays.asList(parametersTypes).toString());

    Method method = MethodUtils.getMatchingAccessibleMethod(clazz,
        methodName, parametersTypes);

    if (null != method) {
      returnedType = method.getReturnType();
      log.debug("Method found, return type : "
          + returnedType.getName());

      return returnedType;
    } else {
        throw new NoSuchMethodException(clazz  + "#" + methodName + "(" + Arrays.toString(parametersTypes) + ")");
    }

  }

  public PropertyDescriptor getPropertyDescriptor(Class<?> clazz,
      String propertyName) {
   
    Map<String, PropertyDescriptor> descriptors =
      resolvedProperties.get(clazz.getName());
   
    if (descriptors == null) {
      descriptors = resolveProperties(clazz);
      resolvedProperties.put(clazz.getName(), descriptors);
    }
   
   
    return descriptors.get(propertyName);
  }

  private Map<String, PropertyDescriptor> resolveProperties(Class<?> clazz) {
    final Map<String, PropertyDescriptor> descriptors =
      new HashMap<String, PropertyDescriptor>();
   
    new ClassWalkingLogic(clazz).walk(new ClassVisitor() {
      public void visit(Class<?> clazz) {
        PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors(clazz);
        for (PropertyDescriptor descriptor : pds) {
          descriptors.put(descriptor.getName(), descriptor);
        }
      }
    });
    return descriptors;
  }
 
  /**
   *
   */
  public String[] getEncodeBegin() {
    return this.EncodeBegin;
  }

  /**
   *
   */
  public String[] getEncodeChild() {
    return this.EncodeChildren;
  }

  /**
   *
   */
  public String[] getEncodeEnd() {
    return this.EncodeEnd;
  }

  public void setCode(String code) {

    Matcher matcher = patternComponent.matcher(code);

    String strEncodeBegin;
    String strEncodeChildren;
    String strEncodeEnd;

    if (matcher.find()) {
      strEncodeBegin = matcher.group(1);
      strEncodeChildren = matcher.group(2);
      strEncodeEnd = matcher.group(3);
    } else {
      strEncodeBegin = "";
      strEncodeChildren = "";
      strEncodeEnd = code;
    }

    if ((strEncodeBegin != null) && (strEncodeBegin.length() != 0)) {
      this.EncodeBegin = strEncodeBegin.split(";\n");
    }

    if ((strEncodeChildren != null) && (strEncodeChildren.length() != 0)) {
      this.EncodeChildren = strEncodeChildren.split(";\n");
    }

    if ((strEncodeEnd != null) && (strEncodeEnd.length() != 0)) {
      this.EncodeEnd = strEncodeEnd.split(";\n");
    }

  }

  /**
   * @return the tree
   */
  public TemplateElement getTree() {
    return this.tree;
  }

  /**
   * @param tree the tree to set
   */
  public void setTree(TemplateElement tree) {
    this.tree = tree;
  }

  /* (non-Javadoc)
   * @see org.ajax4jsf.templatecompiler.builder.CompilationContext#getProcessor(org.w3c.dom.Node)
   */
  public TemplateElement getProcessor(Node nodeElement) throws CompilationException {
    for (Iterator<ElementsFactory> iter = elementFactories.listIterator(); iter.hasNext();) {
      ElementsFactory   factory = iter.next();
      TemplateElement processor = factory.getProcessor(nodeElement, this);
      if(null != processor){
        return processor;
      }
    }
    return null;
  }
 
    /* (non-Javadoc)
     * @see org.ajax4jsf.templatecompiler.builder.CompilationContext#processTemplate(java.lang.String, org.apache.velocity.VelocityContext)
     */
    public String processTemplate(String name, VelocityContext context) throws CompilationException {
      StringWriter out = new StringWriter();
      try {
      getTemplate(name).merge(context, out);
    } catch (ResourceNotFoundException e) {
      throw new CompilationException(e.getLocalizedMessage());
    } catch (ParseErrorException e) {
      throw new CompilationException(e.getLocalizedMessage());
    } catch (Exception e) {
      throw new CompilationException(e.getLocalizedMessage());
    }
      return out.toString();
    }
   
    public Map<String, Map<String, PropertyDescriptor>> getResolvedProperties() {
    return resolvedProperties;
  }
}
TOP

Related Classes of org.ajax4jsf.templatecompiler.builder.AbstractCompilationContext

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.