182 lines
5.3 KiB
Java
182 lines
5.3 KiB
Java
/**
|
||
* Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
|
||
*
|
||
* 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 com.jfinal.template.expr.ast;
|
||
|
||
import java.util.HashMap;
|
||
import java.util.Iterator;
|
||
import java.util.LinkedList;
|
||
import com.jfinal.kit.SyncWriteMap;
|
||
import com.jfinal.template.expr.ast.FieldGetters.*;
|
||
|
||
/**
|
||
* FieldKit
|
||
*/
|
||
public class FieldKit {
|
||
|
||
private static FieldGetter[] getters = init();
|
||
|
||
private static final HashMap<Object, FieldGetter> fieldGetterCache = new SyncWriteMap<Object, FieldGetter>(1024, 0.25F);
|
||
|
||
/**
|
||
* 初始化官方默认 FieldGetter
|
||
*
|
||
* 注意:
|
||
* 默认不启用 IsMethodFieldGetter,用户可以通过下面的代码启用:
|
||
* Engine.addLastFieldGetter(new FieldGetters.IsMethodFieldGetter());
|
||
*
|
||
* 也可以通过直接调用 target.isXxx() 方法来达到与 target.xxx 表达式相同的目的
|
||
*/
|
||
private static FieldGetter[] init() {
|
||
LinkedList<FieldGetter> ret = new LinkedList<FieldGetter>();
|
||
|
||
ret.addLast(new GetterMethodFieldGetter(null));
|
||
ret.addLast(new RealFieldGetter(null));
|
||
// ret.addLast(new ModelFieldGetter());
|
||
// ret.addLast(new RecordFieldGetter());
|
||
ret.addLast(new MapFieldGetter());
|
||
|
||
// 挪到第二的位置,addSharedObject(..., modelObj) 用法可以获取到 model 中的 public 属性
|
||
// ret.addLast(new RealFieldGetter(null));
|
||
ret.addLast(new ArrayLengthGetter());
|
||
// ret.addLast(new IsMethodFieldGetter());
|
||
|
||
return ret.toArray(new FieldGetter[ret.size()]);
|
||
}
|
||
|
||
public static FieldGetter getFieldGetter(Object key, Class<?> targetClass, String fieldName) {
|
||
FieldGetter fieldGetter = fieldGetterCache.get(key);
|
||
if (fieldGetter == null) {
|
||
fieldGetter = doGetFieldGetter(targetClass, fieldName); // 已确保不会返回 null
|
||
fieldGetterCache.putIfAbsent(key, fieldGetter);
|
||
}
|
||
return fieldGetter;
|
||
}
|
||
|
||
private static FieldGetter doGetFieldGetter(Class<?> targetClass, String fieldName) {
|
||
FieldGetter ret;
|
||
for (FieldGetter fieldGetter : getters) {
|
||
ret = fieldGetter.takeOver(targetClass, fieldName);
|
||
if (ret != null) {
|
||
return ret;
|
||
}
|
||
}
|
||
return NullFieldGetter.me;
|
||
}
|
||
|
||
public static void addFieldGetter(int index, FieldGetter fieldGetter) {
|
||
addFieldGetter(fieldGetter, index, true);
|
||
}
|
||
|
||
public static void addFieldGetterToLast(FieldGetter fieldGetter) {
|
||
addFieldGetter(fieldGetter, null, true);
|
||
}
|
||
|
||
public static void addFieldGetterToFirst(FieldGetter fieldGetter) {
|
||
addFieldGetter(fieldGetter, null, false);
|
||
}
|
||
|
||
// 当 Integer index 不为 null 时,boolean addLast 为无效参数
|
||
private static synchronized void addFieldGetter(FieldGetter fieldGetter, Integer index, boolean addLast) {
|
||
checkParameter(fieldGetter);
|
||
|
||
LinkedList<FieldGetter> ret = getCurrentFieldGetters();
|
||
if (index != null) {
|
||
ret.add(index, fieldGetter);
|
||
} else {
|
||
if (addLast) {
|
||
ret.addLast(fieldGetter);
|
||
} else {
|
||
ret.addFirst(fieldGetter);
|
||
}
|
||
}
|
||
getters = ret.toArray(new FieldGetter[ret.size()]);
|
||
}
|
||
|
||
private static LinkedList<FieldGetter> getCurrentFieldGetters() {
|
||
LinkedList<FieldGetter> ret = new LinkedList<FieldGetter>();
|
||
for (FieldGetter fieldGetter : getters) {
|
||
ret.add(fieldGetter);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
private static void checkParameter(FieldGetter fieldGetter) {
|
||
if (fieldGetter == null) {
|
||
throw new IllegalArgumentException("The parameter fieldGetter can not be null");
|
||
}
|
||
for (FieldGetter fg : getters) {
|
||
if (fg.getClass() == fieldGetter.getClass()) {
|
||
throw new RuntimeException("FieldGetter already exists : " + fieldGetter.getClass().getName());
|
||
}
|
||
}
|
||
}
|
||
|
||
public static synchronized void removeFieldGetter(Class<? extends FieldGetter> fieldGetterClass) {
|
||
LinkedList<FieldGetter> ret = getCurrentFieldGetters();
|
||
|
||
for (Iterator<FieldGetter> it = ret.iterator(); it.hasNext();) {
|
||
if (it.next().getClass() == fieldGetterClass) {
|
||
it.remove();
|
||
}
|
||
}
|
||
|
||
getters = ret.toArray(new FieldGetter[ret.size()]);
|
||
}
|
||
|
||
public static void clearCache() {
|
||
fieldGetterCache.clear();
|
||
}
|
||
|
||
/**
|
||
* 设置极速模式
|
||
*
|
||
* 极速模式将生成代理对象来消除 java.lang.reflect.Method.invoke(...) 调用,
|
||
* 性能提升 12.9%
|
||
*/
|
||
public static synchronized void setFastMode(boolean fastMode) {
|
||
if (fastMode) {
|
||
if ( !contains(FastFieldGetter.class) ) {
|
||
addFieldGetterToFirst(new FastFieldGetter());
|
||
}
|
||
} else {
|
||
if (contains(FastFieldGetter.class)) {
|
||
removeFieldGetter(FastFieldGetter.class);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 判断是否包含某个 FieldGetter
|
||
*/
|
||
public static boolean contains(Class<? extends FieldGetter> fieldGetterClass) {
|
||
for (FieldGetter fg : getters) {
|
||
if (fg.getClass() == fieldGetterClass) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|