Package org.drools.spring.factory

Source Code of org.drools.spring.factory.RuleBuilder$InvalidReturnTypeException

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);
    }
}

TOP

Related Classes of org.drools.spring.factory.RuleBuilder$InvalidReturnTypeException

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.