All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hasor.dataql.runtime.inset.ROU Maven / Gradle / Ivy

/*
 * Copyright 2008-2009 the original author or authors.
 *
 * 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 net.hasor.dataql.runtime.inset;
import net.hasor.dataql.InvokerProcessException;
import net.hasor.dataql.ProcessException;
import net.hasor.dataql.result.ObjectModel;
import net.hasor.dataql.runtime.InsetProcess;
import net.hasor.dataql.runtime.InstSequence;
import net.hasor.dataql.runtime.ProcessContet;
import net.hasor.dataql.runtime.mem.FindData;
import net.hasor.dataql.runtime.mem.MemStack;
import net.hasor.dataql.runtime.mem.StackStruts;
import net.hasor.utils.BeanUtils;
import net.hasor.utils.StringUtils;

import java.lang.reflect.Method;
import java.util.Map;
/**
 * ROU,寻值
 * --
 *  寻值机制:ROU会先尝试在当前结果中寻找值,如果找不到则到上一层数据节点进行查找,直到根节点(默认:自下而上)。
 *
 * @author 赵永春([email protected])
 * @version : 2017-07-19
 */
class ROU implements InsetProcess {
    /*路由类型*/
    private static enum RouType {
        Type_1, // @ (Default)  在 '数据' 上路由
        Type_2, // #
        Type_3, // $            在 '结果' 上路由
        Type_4, // %
        Type_5, // &
    }
    @Override
    public int getOpcode() {
        return ROU;
    }
    //
    @Override
    public void doWork(InstSequence sequence, MemStack memStack, StackStruts local, ProcessContet context) throws ProcessException {
        String rouPath = sequence.currentInst().getString(0);
        if (StringUtils.isBlank(rouPath)) {
            memStack.push(null);
            return;
        }
        // 确定路由类型  @、#、$、%、&
        rouPath = rouPath.trim();
        RouType rouType = RouType.Type_1;
        String routeExpression = rouPath;
        switch (rouPath.charAt(0)) {
        case '@':   //
            rouPath = rouPath.substring(1);
            rouType = RouType.Type_1;
            break;
        case '#':   //
            rouPath = rouPath.substring(1);
            rouType = RouType.Type_2;
            break;
        case '$':   //
            rouPath = rouPath.substring(1);
            rouType = RouType.Type_3;
            break;
        case '%':   //
            rouPath = rouPath.substring(1);
            rouType = RouType.Type_4;
            break;
        case '&':   //
            rouPath = rouPath.substring(1);
            rouType = RouType.Type_5;
            break;
        }
        // .拆大括号
        if (rouPath.startsWith("{") && rouPath.endsWith("}")) {
            rouPath = rouPath.substring(1, rouPath.length() - 1);
        }
        // .数据路由(一般出现在 ASX...ASE 之间使用)
        if (rouType == RouType.Type_1) {
            memStack.push(this.routeByStack(rouPath, local, 0));
            return;
        }
        if (rouType == RouType.Type_3) {
            memStack.push(this.routeByStack(rouPath, memStack, 0));
            return;
        }
        //
        throw new InvokerProcessException(getOpcode(), "does not support routing expressions -> " + routeExpression);
    }
    //
    protected Object routeByStack(String routePath, FindData local, int startDepth) throws InvokerProcessException {
        if (startDepth > local.getLayerDepth()) {
            return null;
        }
        Object useData = local.dataOfDepth(startDepth);
        if (useData == null) {
            return null;
        }
        //
        String[] routeSplit = routePath.split("\\.");
        for (String nodeName : routeSplit) {
            if (useData == null) {
                return this.routeByStack(routePath, local, startDepth + 1);
            }
            try {
                useData = readProperty(useData, nodeName);
            } catch (Exception e) {
                throw new InvokerProcessException(getOpcode(), e.getMessage(), e);
            }
        }
        //
        //        Object data = local.dataOfHead();
        //        SelfData self = memStack.findSelf();
        //        memStack.findSelf();
        return useData;
    }
    public static Object readProperty(Object object, String fieldName) throws Exception {
        if (object == null) {
            return null;
        }
        if (object instanceof Map) {
            return ((Map) object).get(fieldName);
        }
        if (object instanceof ObjectModel) {
            return ((ObjectModel) object).getOriResult(fieldName);
        }
        //
        Method[] allMethod = object.getClass().getMethods();
        for (Method m : allMethod) {
            Class[] parameterTypes = m.getParameterTypes();
            if ("get".equalsIgnoreCase(m.getName()) && parameterTypes.length == 1 && parameterTypes[0] == String.class) {
                return m.invoke(object, fieldName);
            }
        }
        return BeanUtils.readPropertyOrField(object, fieldName);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy