All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.firefly.template.support.ObjectNavigator Maven / Gradle / Ivy
package com.firefly.template.support;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.firefly.template.Config;
import com.firefly.template.Model;
import com.firefly.template.exception.ExpressionError;
import com.firefly.utils.ReflectUtils;
import com.firefly.utils.ReflectUtils.ArrayProxy;
import com.firefly.utils.StringUtils;
public class ObjectNavigator {
private ObjectNavigator() {}
private class ArrayCollection extends AbstractCollection {
private Object obj;
private ArrayProxy arrayProxy;
private int size;
private Iterator iterator;
public ArrayCollection(Object array) {
obj = array;
try {
arrayProxy = ReflectUtils.getArrayProxy(array.getClass());
size = arrayProxy.size(array);
} catch (Throwable e) {
Config.LOG.error("get array proxy error", e);
}
iterator = new ArrayInterator();
}
private class ArrayInterator implements Iterator {
private int i = 0;
@Override
public boolean hasNext() {
return i < size;
}
@SuppressWarnings("unchecked")
@Override
public E next() {
return (E) arrayProxy.get(obj, i++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
@Override
public Iterator iterator() {
return iterator;
}
@Override
public int size() {
return size;
}
}
private static class Holder {
private static ObjectNavigator instance = new ObjectNavigator();
}
public static ObjectNavigator getInstance() {
return Holder.instance;
}
@SuppressWarnings("rawtypes")
public Collection> getCollection(Model model, String el) {
Object ret = find(model, el);
return (Collection>) (ret instanceof Collection ? ret : new ArrayCollection(ret));
}
public Integer getInteger(Model model, String el) {
Object ret = find(model, el);
return ret != null ? ((Number) ret).intValue() : 0;
}
public Float getFloat(Model model, String el) {
Object ret = find(model, el);
return ret != null ? ((Number) ret).floatValue() : 0F;
}
public Long getLong(Model model, String el) {
Object ret = find(model, el);
return ret != null ? ((Number) ret).longValue() : 0L;
}
public Double getDouble(Model model, String el) {
Object ret = find(model, el);
return ret != null ? ((Number) ret).doubleValue() : 0.0;
}
public Boolean getBoolean(Model model, String el) {
Object ret = find(model, el);
return ret != null ? (Boolean) ret : false;
}
public String getValue(Model model, String el) {
Object ret = find(model, el);
return ret != null ? String.valueOf(ret) : "";
}
@SuppressWarnings("unchecked")
public Comparable getComparable(Model model, String el) {
Object ret = find(model, el);
return (Comparable)ret;
}
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 getArrayObject(Object obj, int index) {
Object ret = null;
try {
ret = ReflectUtils.arrayGet(obj, index);
} catch (Throwable e) {
Config.LOG.error("get array value error", e);
}
return ret;
}
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);
String keyEl = element.substring(listOrMapPrefixIndex + 1, listOrMapSuffixIndex);
String p = element.substring(0, listOrMapPrefixIndex);
Object obj = root ? ((Model) current).get(p) : getObjectProperty(current, p);
if(obj == null)
return null;
Object ret = null;
if (isStringKey(keyEl)) {
if (obj instanceof Map)
ret = ((Map, ?>) obj).get(keyEl.substring(1, keyEl.length() - 1));
} else { // list or array
int index = Integer.parseInt(keyEl);
if (obj instanceof List)
ret = ((List>) obj).get(index);
else if (obj instanceof Map)
ret = ((Map, ?>) obj).get(index);
else
ret = getArrayObject(obj, index);
}
if (listOrMapSuffixIndex != element.length() - 1) {
if(element.charAt(listOrMapSuffixIndex + 1) != '[')
throw new ExpressionError("list or map expression error: " + element);
return getObject(ret, element.substring(listOrMapSuffixIndex + 1));
}
return ret;
} else if (listOrMapPrefixIndex < 0) { // object
return root ? ((Model) current).get(element) : getObjectProperty(current, element);
} else if (listOrMapPrefixIndex == 0) { // map['foo']['bar']['hello']
int listOrMapSuffixIndex = element.indexOf(']', listOrMapPrefixIndex);
String keyEl = element.substring(listOrMapPrefixIndex + 1, listOrMapSuffixIndex);
Object ret = null;
if (isStringKey(keyEl)) {
if (current instanceof Map)
ret = ((Map, ?>) current).get(keyEl.substring(1, keyEl.length() - 1));
} else { // list or array
int index = Integer.parseInt(keyEl);
if (current instanceof List)
ret = ((List>) current).get(index);
else if (current instanceof Map)
ret = ((Map, ?>) current).get(index);
else
ret = getArrayObject(current, index);
}
if (listOrMapSuffixIndex != element.length() - 1) {
if(element.charAt(listOrMapSuffixIndex + 1) != '[')
throw new ExpressionError("list or map expression error: " + element);
return getObject(ret, element.substring(listOrMapSuffixIndex + 1));
}
return ret;
} else {
throw new ExpressionError("expression error: " + element);
}
}
private boolean isStringKey(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) {
Object ret = null;
try {
ret = ReflectUtils.get(current, propertyName);
} catch (Throwable e) {
Config.LOG.error("get property error", e);
}
return ret;
}
}