Package com.firefly.template

Source Code of com.firefly.template.ObjectNavigator

package com.firefly.template;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import com.firefly.template.exception.ExpressionError;
import com.firefly.template.support.ObjectMetaInfoCache;
import com.firefly.utils.ReflectUtils;
import com.firefly.utils.StringUtils;

public class ObjectNavigator {
  private ClassCache cache;

  private ObjectNavigator() {
    this.cache = new ObjectMetaInfoCache();
  }

  private static class Holder {
    private static ObjectNavigator instance = new ObjectNavigator();
  }

  public static ObjectNavigator getInstance() {
    return Holder.instance;
  }

  public Object find(Model model, String el) {
    Object current = null;
    String[] elements = StringUtils.split(el, '.');
    if ((elements != null) && (elements.length > 0)) {
      current = getObject(model, elements[0]);
      if (current == null)
        return null;

      for (int i = 1; i < elements.length; i++) {
        current = getObject(current, elements[i]);
      }
    }
    return current;
  }

  private Object getObject(Object current, String el) {
    boolean root = current instanceof Model;
    String element = el.trim();
    int listOrMapPrefixIndex = element.indexOf('[');
    if (listOrMapPrefixIndex > 0) { // map or list or array
      int listOrMapSuffixIndex = element.indexOf(']',
          listOrMapPrefixIndex);
      if (listOrMapSuffixIndex != element.length() - 1)
        throw new ExpressionError("list or map expression error: "
            + element);

      String keyEl = element.substring(listOrMapPrefixIndex + 1,
          listOrMapSuffixIndex);
      String p = element.substring(0, listOrMapPrefixIndex);
      Object obj = root ? ((Model) current).get(p)
          : getObjectProperty(current, p);

      if (isMapKey(keyEl)) { // map
        if ((obj instanceof Map))
          return ((Map<?, ?>) obj).get(keyEl.substring(1,
              keyEl.length() - 1));
      } else { // list or array
        int index = Integer.parseInt(keyEl);
        if ((obj instanceof List))
          return ((List<?>) obj).get(index);
        if (obj.getClass().isArray())
          return Array.get(obj, index);
      }
    } else if (listOrMapPrefixIndex < 0) { // object
      return root ? ((Model) current).get(element)
          : getObjectProperty(current, element);
    } else {
      throw new ExpressionError("expression error: " + element);
    }
    return null;
  }

  private boolean isMapKey(String el) {
    char head = el.charAt(0);
    char tail = el.charAt(el.length() - 1);
    return ((head == '\'') && (tail == '\''))
        || ((head == '"') && (tail == '"'));
  }

  private Object getObjectProperty(Object current, String propertyName) {
    Class<?> clazz = current.getClass();
    Method method = cache.get(clazz, propertyName);
    if (method == null) {
      Config.LOG.debug("no cache: " + clazz.getName() + "|"
          + propertyName);
      method = ReflectUtils.getGetterMethod(clazz, propertyName);
      cache.put(clazz, propertyName, method);
    }

    Object ret = null;
    try {
      ret = method.invoke(current);
    } catch (IllegalArgumentException e) {
      Config.LOG.error("getObjectProperty error", e);
    } catch (IllegalAccessException e) {
      Config.LOG.error("getObjectProperty error", e);
    } catch (InvocationTargetException e) {
      Config.LOG.error("getObjectProperty error", e);
    }
    return ret;
  }

}
TOP

Related Classes of com.firefly.template.ObjectNavigator

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.