Package org.zkoss.zest.sys.impl

Source Code of org.zkoss.zest.sys.impl.ParserImpl

/* ParserImpl.java

  Purpose:
   
  Description:
   
  History:
    Mon Mar  7 13:04:27 TST 2011, Created by tomyeh

Copyright (C) 2011 Potix Corporation. All Rights Reserved.

*/
package org.zkoss.zest.sys.impl;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;
import java.net.URL;

import org.zkoss.lang.Classes;
import org.zkoss.util.resource.Locator;
import org.zkoss.util.logging.Log;
import org.zkoss.idom.Document;
import org.zkoss.idom.Element;
import org.zkoss.idom.Item;
import org.zkoss.idom.input.SAXBuilder;
import org.zkoss.idom.util.IDOMs;
import org.zkoss.xel.VariableResolver;
import org.zkoss.xel.taglib.Taglibs;
import org.zkoss.xel.taglib.Taglib;
import org.zkoss.xel.util.MethodFunction;

import org.zkoss.zest.sys.*;
import org.zkoss.zest.ZestException;

/**
* The default implementation of the parser of the configuration file
* (/WEB-INF/zest.xml).
* @author tomyeh
*/
public class ParserImpl implements Parser {
  private static final Log log = Log.lookup(ParserImpl.class);

  public ParserImpl() {
  }

  @Override
  public Configuration parse(URL url, Locator loc) throws Exception {
    try {
      return parse(new SAXBuilder(true, false, true).build(url).getRootElement(), loc);
    } catch (Throwable ex) {
      log.realCauseBriefly("Failed to parse "+url, ex);
      if (ex instanceof Error) throw (Error)ex;
      throw (Exception)ex;
    }
  }
  /** Parses the specified root element.
   */
  public Configuration parse(Element root, Locator loc) throws Exception {
    final List<ActionDefinition> defs = new LinkedList<ActionDefinition>();
    final List<Taglib> taglibs = new LinkedList<Taglib>();
    final List<Object[]> xelmtds = new LinkedList<Object[]>();
    final List<VariableResolver> resolvers = new LinkedList<VariableResolver>();
    String[] exts = null;
    ErrorHandler errh = null;
    for (Iterator it = root.getElements().iterator(); it.hasNext();) {
      final Element el = (Element)it.next();
      final String elnm = el.getName();
      if ("action".equals(elnm)) {
        defs.add(parseAction(el));
      } else if ("error-handler-class".equals(elnm)) {
        final String clsnm = el.getText(true);
        noELnorEmpty(elnm, clsnm, el);
        errh = (ErrorHandler)Classes.newInstanceByThread(clsnm);
      } else if ("extensions".equals(elnm)) {
        final String s = el.getText(true);
        noEL(elnm, s, el);
        exts = parseExtensions(s);
      } else if ("taglib".equals(elnm)) {
        final String uri = IDOMs.getRequiredAttributeValue(el, "uri");
        noELnorEmpty("uri", uri, el);
        final String prefix = IDOMs.getRequiredAttributeValue(el, "prefix");
        noELnorEmpty("prefix", prefix, el);
        taglibs.add(new Taglib(prefix, uri));
      } else if ("variable-resolver".equals(elnm)) {
        final String clsnm = IDOMs.getRequiredAttributeValue(el, "class");
        noELnorEmpty("class", clsnm, el);
        resolvers.add(0, (VariableResolver)Classes.newInstanceByThread(clsnm)); //FILO
      } else if ("xel-method".equals(elnm)) {
        parseXelMethod(xelmtds, el);
      }
    }
    return new ConfigurationImpl(
      defs.toArray(new ActionDefinition[defs.size()]),
      exts != null ? exts: new String[] {""}, errh,
      ChainedResolver.getVariableResolver(resolvers),
      !taglibs.isEmpty() || !xelmtds.isEmpty() ?
        Taglibs.getFunctionMapper(taglibs, null, xelmtds, loc): null);
  }
  //parse action
  private static ActionDefinition parseAction(Element el)
  throws Exception {
    final Map<String, ViewInfoProxy> results = new HashMap<String, ViewInfoProxy>();
    for (Iterator it = el.getElements("result").iterator(); it.hasNext();) {
      final Element e = (Element)it.next();
      results.put(e.getAttributeValue("name"),
        new ViewInfoProxy(e.getAttributeValue("type"), e.getText(true)));
    }
    final String path = IDOMs.getRequiredAttributeValue(el, "path");
    noELnorEmpty("path", path, el);
    return new ActionDefinitionImpl(path,
      IDOMs.getRequiredAttributeValue(el, "class"),
      el.getAttributeValue("method"), results);
  }
  /** Parse the XEL method. */
  private static void parseXelMethod(List<Object[]> xelmtds, Element el)
  throws Exception {
    final String prefix = IDOMs.getRequiredAttributeValue(el, "prefix");
    noELnorEmpty("prefix", prefix, el);
    final String nm = IDOMs.getRequiredAttributeValue(el, "name");
    noELnorEmpty("name", nm, el);
    final String clsnm = IDOMs.getRequiredAttributeValue(el, "class");
    noELnorEmpty("class", clsnm, el);
    final String sig = IDOMs.getRequiredAttributeValue(el, "signature");
    noELnorEmpty("signature", sig, el);

    final Method mtd;
    try {
      final Class cls = Classes.forNameByThread(clsnm);
      mtd = Classes.getMethodBySignature(cls, sig, null);
    } catch (ClassNotFoundException ex) {
      throw new ZestException("Class not found: "+clsnm+", "+el.getLocator());
    } catch (Exception ex) {
      throw new ZestException("Method not found: "+sig+" in "+clsnm+", "+el.getLocator());
    }
    if ((mtd.getModifiers() & Modifier.STATIC) == 0)
      throw new ZestException("Not a static method: "+mtd+", "+el.getLocator());
    xelmtds.add(new Object[] {prefix, nm, new MethodFunction(mtd)});
  }
  //parse extensions
  private static String[] parseExtensions(String extensions) {
    if (extensions == null || extensions.length() == 0)
      return null;
    final String[] exts = extensions.split(",");
    for (int j = 0; j < exts.length; ++j) {
      exts[j] = exts[j].trim();
      if (exts[j].length() > 0 && exts[j].charAt(0) != '.')
        exts[j] = '.' + exts[j];
    }
    return exts;
  }
  /** Whether a string is null or empty. */
  private static boolean isEmpty(String s) {
    return s == null || s.length() == 0;
  }
  private static void noELnorEmpty(String nm, String val, Item item)
  throws ZestException {
    if (isEmpty(val))
      throw new ZestException(nm + " cannot be empty, "+item.getLocator());
    noEL(nm, val, item);
  }
  private static void noEL(String nm, String val, Item item)
  throws ZestException {
    if (val != null && val.indexOf("${") >= 0)
      throw new ZestException(nm+" does not support EL expressions, "+item.getLocator());
  }
}
/*package*/ class ChainedResolver implements VariableResolver {
  private VariableResolver[] _resolvers;
 
  /*package*/ static
  VariableResolver getVariableResolver(List<VariableResolver> resolvers) {
    int sz;
    if (resolvers == null || (sz = resolvers.size()) == 0)
      return null;
    return new ChainedResolver(resolvers.toArray(new VariableResolver[sz]));
  }
  private ChainedResolver(VariableResolver[] resolvers) {
    _resolvers = resolvers;
  }
  @Override
  public Object resolveVariable(String name) {
    for (int j = 0; j < _resolvers.length; ++j) {
      final Object o = _resolvers[j].resolveVariable(name);
      if (o != null)
        return o;
    }
    return null;
  }
}
TOP

Related Classes of org.zkoss.zest.sys.impl.ParserImpl

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.