⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rulebuilder.java

📁 drools 一个开放源码的规则引擎
💻 JAVA
字号:
package org.drools.spring.factory;

/*
 * Copyright 2005 (C) The Werken Company. All Rights Reserved.
 *
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright statements and
 * notices. Redistributions must also contain a copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name "drools" must not be used to endorse or promote products derived
 * from this Software without prior written permission of The Werken Company.
 * For written permission, please contact bob@werken.com.
 *
 * 4. Products derived from this Software may not be called "drools" nor may
 * "drools" appear in their names without prior written permission of The Werken
 * Company. "drools" is a registered trademark of The Werken Company.
 *
 * 5. Due credit should be given to The Werken Company.
 * (http://drools.werken.com/).
 *
 * THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE WERKEN COMPANY OR ITS CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */



import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.drools.DroolsException;
import org.drools.rule.Rule;
import org.drools.spring.metadata.ArgumentMetadata;
import org.drools.spring.metadata.ArgumentMetadataSource;
import org.drools.spring.metadata.MethodMetadata;
import org.drools.spring.metadata.MethodMetadataSource;
import org.drools.spring.pojorule.Argument;
import org.drools.spring.pojorule.PojoCondition;
import org.drools.spring.pojorule.PojoConsequence;
import org.drools.spring.pojorule.RuleReflectMethod;

public class RuleBuilder {

    public static final class InvalidReturnTypeException extends DroolsException {
        InvalidReturnTypeException(String message) {
            super(message);
        }
    }

    public static final class InvalidParameterException extends DroolsException {
        InvalidParameterException(String message) {
            super(message);
        }
    }
    
    public static final class InvalidPojoConditionException extends DroolsException {
        InvalidPojoConditionException(String msg, Throwable rootCause) {
            super(msg, rootCause);
        }

        InvalidPojoConditionException(String message) {
            super(message);
        }
    }

    // ---- ---- ----

    private MethodMetadataSource methodMetadataSource;
    private ArgumentMetadataSource argumentMetadataSource;

    public void setMethodMetadataSource(MethodMetadataSource methodMetadataSource) {
        this.methodMetadataSource = methodMetadataSource;
    }

    public void setArgumentMetadataSource(ArgumentMetadataSource argumentMetadataSource) {
        this.argumentMetadataSource = argumentMetadataSource;
    }

    // ---- ---- ----

    private static Log log = LogFactory.getLog(RuleBuilder.class);

    public Rule buildRule(Rule rule, Object pojo) throws DroolsException {
        List conditionRuleReflectMethods = new ArrayList();

        Method[] pojoMethods = pojo.getClass().getMethods();
        for (int i = 0; i < pojoMethods.length; i++) {
            Method pojoMethod = pojoMethods[i];
            MethodMetadata methodMetadata = methodMetadataSource.getMethodMetadata(pojoMethod);
            if (methodMetadata == null) {
                if (log.isDebugEnabled()) {
                    log.debug("No metadata for method " + pojoMethod.toString());
                }
                continue;
            }

            ArgumentMetadata[] argumentsMetadata = getArgumentMetadata(pojoMethod);
            Argument[] arguments = getArguments(rule, argumentsMetadata);

            if (methodMetadata.getMethodType() == MethodMetadata.METHOD_CONDITION) {
                assertReturnType(pojoMethod, boolean.class);
                rule.addCondition(
                        new PojoCondition(new RuleReflectMethod(rule, pojo, pojoMethod, arguments)));
                log.info("Condition method added to rule: " + pojoMethod.toString());

            } else if (methodMetadata.getMethodType() == MethodMetadata.METHOD_CONSEQUENCE) {
                conditionRuleReflectMethods.add(
                        new RuleReflectMethod(rule, pojo, pojoMethod, arguments));
                log.info("Consequence method added to rule: " + pojoMethod.toString());
            } else if (methodMetadata.getMethodType() == MethodMetadata.OBJECT_CONDITION) {
                if (arguments.length != 0) {
                    throw new InvalidPojoConditionException("Rule pojo condition must not have arguments"
                                                            + ": method = " + pojoMethod + ", arguments = " + arguments);
                }
                try {
                    buildObjectConditions(rule, pojoMethod.invoke(pojo, new Object[0]));
                } catch (Exception e) {
                    throw new InvalidPojoConditionException("Unable to execute pojo condition"
                                                            + ": method = " + pojoMethod, e);
                }
            }
        }

        if (!conditionRuleReflectMethods.isEmpty()) {
            addConsequence(rule, conditionRuleReflectMethods);
        }

        rule.checkValidity();
        return rule;
    }

    private void buildObjectConditions(Rule rule, Object pojo) throws DroolsException {
        Method[] pojoMethods = pojo.getClass().getMethods();
        for (int i = 0; i < pojoMethods.length; i++) {
            Method pojoMethod = pojoMethods[i];
            MethodMetadata methodMetadata = methodMetadataSource.getMethodMetadata(pojoMethod);
            if (methodMetadata == null) {
                continue;
            }
    
            ArgumentMetadata[] argumentsMetadata = getArgumentMetadata(pojoMethod);
            Argument[] arguments = getArguments(rule, argumentsMetadata);
    
            if (methodMetadata.getMethodType() == MethodMetadata.METHOD_CONDITION) {
                assertReturnType(pojoMethod, boolean.class);
                rule.addCondition(new PojoCondition(new RuleReflectMethod(rule, pojo, pojoMethod, arguments)));
    
            }
        }
    }

    private ArgumentMetadata[] getArgumentMetadata(Method pojoMethod) throws InvalidParameterException {
        Class[] parameterTypes = pojoMethod.getParameterTypes();
        ArgumentMetadata[] metadata = new ArgumentMetadata[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            metadata[i] = argumentMetadataSource.getArgumentMetadata(pojoMethod, parameterTypes[i], i);
            if (metadata[i] == null) {
                throw new InvalidParameterException("Cannot determine parameter metdata"
                        + ": method=" + pojoMethod.getName()
                        + ", parameterType[" + i + "]=" + parameterTypes[i]);
            }
        }
        return metadata;
    }

    private Argument[] getArguments(Rule rule, ArgumentMetadata[] argumentsMetadata) throws DroolsException {
        Argument[] arguments = new Argument[argumentsMetadata.length];
        for (int i = 0; i < argumentsMetadata.length; i++) {
            arguments[i] = argumentsMetadata[i].createArgument(rule);
        }
        return arguments;
    }

    private static void assertReturnType(Method method, Class returnClass)
            throws InvalidReturnTypeException {
        if (method.getReturnType() != returnClass) {
            throw new InvalidReturnTypeException("Rule method returns the wrong class"
                    + ": method = " + method + ", expected return class = " + returnClass
                    + ", actual return class = " + method.getReturnType());
        }
    }

    private void addConsequence(Rule rule, List conditionRuleReflectMethodsCollector) {
        RuleReflectMethod[] conditionRuleReflectMethodArray = (RuleReflectMethod[]) conditionRuleReflectMethodsCollector.toArray(
                new RuleReflectMethod[conditionRuleReflectMethodsCollector.size()]);
        PojoConsequence consequence = new PojoConsequence(conditionRuleReflectMethodArray);
        rule.setConsequence(consequence);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -