Package org.jboss.internal.soa.esb.services.rules

Source Code of org.jboss.internal.soa.esb.services.rules.DroolsRuleBaseHelper

/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.internal.soa.esb.services.rules;

import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.RULE_EVENT_PROCESSING_TYPE;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue.CLOUD;
import static org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue.STREAM;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.drools.ChangeSet;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.RuntimeDroolsException;
import org.drools.agent.KnowledgeAgent;
import org.drools.agent.KnowledgeAgentConfiguration;
import org.drools.agent.KnowledgeAgentFactory;
import org.drools.builder.DecisionTableConfiguration;
import org.drools.builder.DecisionTableInputType;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderConfiguration;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.builder.conf.ClassLoaderCacheOption;
import org.drools.compiler.DroolsParserException;
import org.drools.conf.EventProcessingOption;
import org.drools.conf.MaxThreadsOption;
import org.drools.conf.MultithreadEvaluationOption;
import org.drools.io.ResourceFactory;
import org.jboss.internal.soa.esb.services.rules.util.RulesClassLoader;
import org.jboss.internal.soa.esb.util.StreamUtils;
import org.jboss.soa.esb.services.rules.RuleInfo;
import org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue;
import org.jboss.soa.esb.util.ClassUtil;

/**
* A helper class, it returns rulebases based on various methods of creating them.
* <p/>
*
* @author jdelong@redhat.com
* @author <a href="mailto:dbevenius@redhat.com">Daniel Bevenius</a>
*
*/
public class DroolsRuleBaseHelper {

  private static Logger logger = Logger.getLogger(DroolsRuleBaseHelper.class);
 
  private DroolsRuleBaseHelper()  {}
 
  /**
   * Factory method that returns an instance of this class.
   * </p>
   * The current implementation returns a new instance of this
   * class for every call.
   *
   * @return {@link DroolsRuleBaseHelper}
   */
  public static DroolsRuleBaseHelper getInstance()
  {
    return new DroolsRuleBaseHelper();
  }

  /**
   * Creates a rulebase using rules and dsl from files
   * <p/>
   *
   * @param ruleFile -
   *       file name which contains the Drools rules. Can be a file on the local
   *      filesystem, a file on the classpath or an URL. Must not be null.
   * @param dsl -
   *      file containing the Drools Domain Specific Language (dsl)
   * @throws RuleServiceException
   * @throws DroolsParserException -
   *       if an exception occurs during Drools package building 
   * @throws IOException -
   *       if an IOException occurs during Drools package building 
   * @throws RuleServiceException -
   *       if the ruleFile cannot be located or if it was not possible to
   *       add the package to the RuleBase.
   */
  public KnowledgeBase createRuleBaseFromRuleFiles(
      final RuleInfo ruleInfo ) throws RuleServiceException, RuntimeDroolsException
  {
    final String drl = ruleInfo.getRuleSource();
    final String dsl = ruleInfo.getDslSource();
   
    assertNotNull( drl, "ruleFile" );
    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    KnowledgeBase ruleBase;
    InputStream dslInputStream = null;
    InputStream drlInputStream = null;
    try
    {
      if (dsl == null)
      {
        drlInputStream = getRulesInputStream(drl);
        builder.add(ResourceFactory.newInputStreamResource(drlInputStream), ResourceType.DRL);
        ruleBase = getNewRuleBaseWithPackage(builder, ruleInfo);
      }
      else
      {
        dslInputStream = getRulesInputStream(dsl);
        builder.add(ResourceFactory.newInputStreamResource(dslInputStream), ResourceType.DSL);
        drlInputStream = getRulesInputStream(drl);
        builder.add(ResourceFactory.newInputStreamResource(drlInputStream), ResourceType.DSLR);
        ruleBase = getNewRuleBaseWithPackage(builder, ruleInfo);
      }
    }
    finally
    {
      safeClose(drlInputStream);
      safeClose(dslInputStream);
    }
    return ruleBase;
  }

  /**
   * Reads the rules and dsl from files and returning as a string
   *
   * @param ruleFile -
   *       file name which contains the Drools rules. Can be a file on the local
   *      filesystem, a file on the classpath or an URL. Must not be null.
   * @param dsl -
   *      file containing the Drools Domain Specific Language (dsl)
   * @return String -
   *       String representation of the rules
   * @throws IOException -
   *       if an IOException occurs during Drools package building 
   * @throws RuleServiceException -
   *       if the ruleFile cannot be located or if it was not possible to
   *       add the package to the RuleBase.
   * @throws RuleServiceException
   */
  public String getRulesAsString(
      final String ruleFile,
      final String dsl) throws RuleServiceException
  {
    assertNotNull( ruleFile, "rulefile" );
   
    final String rules = getFileContents( ruleFile );
    return dsl == null ? rules : rules + getFileContents( dsl );
  }
 
  /**
   * Reading the rules from a decision table.
   * <p/>
   * @param decisionTable -
   *       file name which contains the Drools decision table. Can be a file on the local
   *      filesystem, a file on the classpath or an URL. Must not be null.
   * @throws RuleServiceException
   * @throws DroolsParserException -
   *      
   * @throws IOException -
   *      
   * @throws RuleServiceException -
   */
  public KnowledgeBase createRuleBaseFromDecisionTable(
      final RuleInfo ruleInfo ) throws RuleServiceException
  {
    final String decisionTable = ruleInfo.getRuleSource();
   
    assertNotNull( decisionTable, "decisionTable" );
    DecisionTableConfiguration dtc = KnowledgeBuilderFactory.newDecisionTableConfiguration();
    String decisionTable_tlc = decisionTable.trim().toLowerCase();
    if (decisionTable_tlc.endsWith(".xls"))
    {
      dtc.setInputType(DecisionTableInputType.XLS);
    }
    else if (decisionTable_tlc.endsWith(".csv"))
    {
      dtc.setInputType(DecisionTableInputType.CSV);
    }
    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    InputStream dtInputStream = null;
    KnowledgeBase ruleBase;
    try
    {
      dtInputStream = getRulesInputStream(decisionTable);
      builder.add(ResourceFactory.newInputStreamResource(dtInputStream), ResourceType.DTABLE, dtc);
      ruleBase = getNewRuleBaseWithPackage(builder, ruleInfo);
    }
    finally
    {
      safeClose(dtInputStream);
    }
    return ruleBase;
  }

  /**
   * This shows how rules are loaded up from a deployed package.
   */
  public KnowledgeAgent createRuleAgent(final RuleInfo ruleInfo) throws RuleServiceException
  {
    final DroolsRuleAgentHelper drah = new DroolsRuleAgentHelper(ruleInfo);
    final Properties properties = drah.getProperties();
    final ClassLoader classLoader = drah.getClassLoader();
    final String name = drah.getName();
    final ChangeSet changeSet = drah.getChangeSet();
    final KnowledgeBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(properties, classLoader);
    final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig);
    final KnowledgeAgentConfiguration kagentConfig = KnowledgeAgentFactory.newKnowledgeAgentConfiguration(properties);
    final KnowledgeBuilderConfiguration kbuilderConfig = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(properties, classLoader);
    final KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent(name, kbase, kagentConfig, kbuilderConfig);
    kagent.setSystemEventListener(new LogAgentEventListener(name));
    kagent.applyChangeSet(changeSet);
    return kagent;
  }
 
  private String getFileContents( final String fileName ) throws RuleServiceException
  {
    InputStream inputStream = getRulesInputStream( fileName );
    try
    {
        return StreamUtils.readStreamString( inputStream, "UTF-8" );
    }
    catch ( final UnsupportedEncodingException e)
    {
      throw new RuleServiceException("Could not read from file [" + fileName + "].", e);
    }
    finally
    {
      safeClose( inputStream );
    }
  }
 
  //  private instance methods

  private InputStream getRulesInputStream(final String rulesFile) throws RuleServiceException
  {
    InputStream resourceAsStream = ClassUtil.getResourceAsStream( "/" + rulesFile, getClass() );
    if ( resourceAsStream == null )
        throw new RuleServiceException("Could not locate file [" + rulesFile + "], neither as a file on the local filesystem, on the classpath nor as a URL.");
    else
      return resourceAsStream;
  }
 
  private KnowledgeBase getNewRuleBaseWithPackage( final KnowledgeBuilder builder, final RuleInfo ruleInfo ) throws RuleServiceException, RuleServiceBuilderException
  {
    final KnowledgeBuilderErrors errors = builder.getErrors();
    if ((errors != null) && (errors.size() > 0))
    {
      throw new RuleServiceException("Generation raised the following errors: " + errors) ;
    }
   
    // If we don't use this config, then all rules' LHS object conditions will not match on .esb redeploys!
    // (since objects are only equal if their ClassLoaders are also equal - and they're not on redeploys..)
    final Properties properties = new Properties();
    properties.setProperty(ClassLoaderCacheOption.PROPERTY_NAME, Boolean.FALSE.toString());
    final ClassLoader classLoader = new RulesClassLoader(ruleInfo.getRuleSource());
    KnowledgeBaseConfiguration kbaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(properties, classLoader);
   
    // CEP
    StringValue eventProcessingType = RULE_EVENT_PROCESSING_TYPE.getStringValue(ruleInfo.getEventProcessingType());
    if (STREAM.equals(eventProcessingType))
    {
      kbaseConfig.setOption(EventProcessingOption.STREAM);
    }
    else if (CLOUD.equals(eventProcessingType))
    {
      kbaseConfig.setOption(EventProcessingOption.CLOUD);
    }
    Boolean multithreadEvaluation = ruleInfo.getMultithreadEvaluation();
    if (multithreadEvaluation != null) {
      MultithreadEvaluationOption meo = multithreadEvaluation.booleanValue() ? MultithreadEvaluationOption.YES : MultithreadEvaluationOption.NO;
      kbaseConfig.setOption(meo);
      // only pertinent if multithreadEvaluation == true
      Integer maxThreads = ruleInfo.getMaxThreads();
      if (maxThreads != null) {
        kbaseConfig.setOption(MaxThreadsOption.get(maxThreads.intValue()));
      }
    }
   
    KnowledgeBase ruleBase = KnowledgeBaseFactory.newKnowledgeBase(kbaseConfig);
    try
    {
      ruleBase.addKnowledgePackages(builder.getKnowledgePackages());
    }
    catch (final Exception ex)
    //   need to catch Exception as RuleBase.addPackage throws it
    {
      throw new RuleServiceException(ex.getMessage(), ex);
    }
   
    if ( builder.hasErrors() )
    {
      throw new RuleServiceBuilderException( "PackageBuilder generated errors: ", builder.getErrors() );
    }
   
    return ruleBase;
  }
 
  //  private static methods
 
  private static void safeClose( final InputStream is )
  {
    try
    {
      if (is != null)
      {
        is.close();
      }
    }
    catch (final IOException e)
    {
      logger.warn("Caught an IOException while trying to close as inputstream.", e );
    }
  }

  private static void assertNotNull( final String argumentValue, final String argumentName )
  {
    if( argumentValue == null )
      throw new NullPointerException("[" + argumentName + "] argument must not be null");
  }
 
}
TOP

Related Classes of org.jboss.internal.soa.esb.services.rules.DroolsRuleBaseHelper

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.