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

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

/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* 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,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*
* (C) 2005-2010
*/
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.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.drools.ChangeSet;
import org.drools.agent.RuleAgent;
import org.drools.builder.ResourceType;
import org.drools.builder.conf.ClassLoaderCacheOption;
import org.drools.conf.EventProcessingOption;
import org.drools.conf.MaxThreadsOption;
import org.drools.conf.MultithreadEvaluationOption;
import org.drools.xml.ChangeSetSemanticModule;
import org.drools.xml.SemanticModules;
import org.drools.xml.XmlChangeSetReader;
import org.jboss.internal.soa.esb.services.rules.util.RulesClassLoader;
import org.jboss.internal.soa.esb.util.StreamUtils;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.services.rules.RuleInfo;
import org.jboss.soa.esb.services.rules.RuleServicePropertiesNames.StringValue;
import org.jboss.soa.esb.util.ClassUtil;
import org.xml.sax.SAXException;

/**
* Helper class which converts old RuleAgent properties to new KnowledgeAgent properties and change-set.
*
* @author dward at jboss.org
*/
public class DroolsRuleAgentHelper
{
 
  private static final Logger logger = Logger.getLogger(DroolsRuleAgentHelper.class);
 
  // unfortunately, there is no public KnowledgeAgent.NEW_INSTANCE
  private static final String KnowledgeAgent_NEW_INSTANCE = "drools.agent.newInstance";
 
  private static final Map<String,ResourceType> resExt_to_resType = new HashMap<String,ResourceType>();
  static
  {
    resExt_to_resType.put(".drl", ResourceType.DRL);
    resExt_to_resType.put(".xdrl", ResourceType.XDRL);
    resExt_to_resType.put(".dsl", ResourceType.DSL);
    resExt_to_resType.put(".dslr", ResourceType.DSLR);
    resExt_to_resType.put(".drf", ResourceType.DRF);
    resExt_to_resType.put(".xls", ResourceType.DTABLE);
    resExt_to_resType.put(".csv", ResourceType.DTABLE);
    resExt_to_resType.put(".pkg", ResourceType.PKG);
    resExt_to_resType.put(".brl", ResourceType.BRL);
    resExt_to_resType.put(".xml", ResourceType.CHANGE_SET);
  }
 
  private static final ResourceType getResourceType(String resource)
  {
    ResourceType type = null;
    String resource_tlc = resource.trim().toLowerCase();
    for (Entry<String,ResourceType> entry : resExt_to_resType.entrySet())
    {
      if (resource_tlc.endsWith(entry.getKey()))
      {
        type = entry.getValue();
        break;
      }
    }
    return type;
  }
 
  private final Properties properties = new Properties();
  private final ClassLoader classLoader;
  private String name = null;
  private final ChangeSet changeSet;
 
  private Boolean basicAuthentication = null;
  private String username = null;
  private String password = null;
 
  public DroolsRuleAgentHelper(final RuleInfo ruleInfo) throws RuleServiceException
  {
    final String ruleAgentProperties = ruleInfo.getRuleSource();
    classLoader = new RulesClassLoader(ruleAgentProperties);
   
    String contents;
    InputStream is = null;
    try
    {
      is = ClassUtil.getResourceAsStream("/" + ruleAgentProperties, getClass());
      if (is != null)
      {
        // we'll most likely find it here as a classloader resource
        contents = StreamUtils.readStreamString(is, "UTF-8");
      }
      else
      {
        // we'll reach here if ruleAgentProperties is a File path or URL location
        contents = StreamUtils.getResourceAsString(ruleAgentProperties, "UTF-8");
      }
    }
    catch (UnsupportedEncodingException uee)
    {
      // should never happen with UTF-8
      throw new RuleServiceException(uee);
    }
    catch (ConfigurationException ce)
    {
      throw new RuleServiceException(ce);
    }
    finally
    {
      try { if (is != null) is.close(); } catch (Throwable t) {}
    }
    if (ruleAgentProperties.endsWith(".xml") && contents.indexOf("<change-set") != -1)
    {
      // change-set
      changeSet = readChangeSet(contents);
    }
    else
    {
      // properties
      Properties source_props = new Properties();
      InputStream source_is = null;
      try
      {
        source_is = new ByteArrayInputStream(contents.getBytes());
        source_props.load(source_is);
      }
      catch (IOException ioe)
      {
        throw new RuleServiceException(ioe);
      }
      finally
      {
        try { if (source_is != null) source_is.close(); } catch (Throwable t) {}
      }
     
      // name
      name = source_props.getProperty(RuleAgent.CONFIG_NAME);
     
      // newInstance
      String newInstance_value = source_props.getProperty(KnowledgeAgent_NEW_INSTANCE);
      if (newInstance_value == null)
      {
        newInstance_value = source_props.getProperty(RuleAgent.NEW_INSTANCE);
      }
      if (newInstance_value != null)
      {
        properties.setProperty(KnowledgeAgent_NEW_INSTANCE, newInstance_value);
      }
     
      // BASIC Auth
      String eba = source_props.getProperty(RuleAgent.ENABLE_BASIC_AUTHENTICATION);
      if (eba != null)
      {
        basicAuthentication = Boolean.valueOf(eba);
        if (basicAuthentication.booleanValue())
        {
          username = source_props.getProperty(RuleAgent.USER_NAME);
          password = source_props.getProperty(RuleAgent.PASSWORD);
        }
      }
     
      // CEP
        StringValue eventProcessingType = RULE_EVENT_PROCESSING_TYPE.getStringValue(ruleInfo.getEventProcessingType());
        if (STREAM.equals(eventProcessingType))
        {
          properties.setProperty(EventProcessingOption.PROPERTY_NAME, EventProcessingOption.STREAM.getMode());
        }
        else if (CLOUD.equals(eventProcessingType))
        {
          properties.setProperty(EventProcessingOption.PROPERTY_NAME, EventProcessingOption.CLOUD.getMode());
        }
        Boolean multithreadEvaluation = ruleInfo.getMultithreadEvaluation();
        if (multithreadEvaluation != null) {
          MultithreadEvaluationOption meo = multithreadEvaluation.booleanValue() ? MultithreadEvaluationOption.YES : MultithreadEvaluationOption.NO;
          properties.setProperty(MultithreadEvaluationOption.PROPERTY_NAME, meo.name());
          // only pertinent if multithreadEvaluation == true
          Integer maxThreads = ruleInfo.getMaxThreads();
          if (maxThreads != null) {
            properties.setProperty(MaxThreadsOption.PROPERTY_NAME, maxThreads.toString());
          }
        }
     
      // leftover properties
      Enumeration<?> source_prop_names = source_props.propertyNames();
      while (source_prop_names.hasMoreElements())
      {
        String source_prop_name = (String)source_prop_names.nextElement();
        String source_prop_value = source_props.getProperty(source_prop_name);
        if (source_prop_name.startsWith("drools.") && !properties.containsKey(source_prop_name))
        {
          properties.setProperty(source_prop_name, source_prop_value);
        }
        else if (source_prop_name.equals(RuleAgent.POLL_INTERVAL) || source_prop_name.equals(RuleAgent.LOCAL_URL_CACHE))
        {
          logger.warn("RuleAgent property [" + source_prop_name + "=" + source_prop_value + "] is unsupported by KnowledgeAgent in properties [" + ruleAgentProperties + "]");
        }
      }
     
      // change-set
      StringBuffer sb = new StringBuffer();
      sb.append("<change-set xmlns=\"http://drools.org/drools-5.0/change-set\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema-instance\" xs:schemaLocation=\"http://drools.org/drools-5.0/change-set drools-change-set-5.0.xsd\">");
      addResourceDirectories(list(source_props.getProperty(RuleAgent.DIRECTORY)), sb);
      addResourceFiles(list(source_props.getProperty(RuleAgent.FILES)), sb);
      addResourceURLs(list(source_props.getProperty(RuleAgent.URLS)), sb);
      sb.append("</change-set>");
      String xml = sb.toString();
      if (logger.isDebugEnabled())
      {
        try
        {
          StringWriter sw = new StringWriter();
          OutputFormat of = OutputFormat.createPrettyPrint();
          of.setSuppressDeclaration(true);
          new XMLWriter(sw, of).write(DocumentHelper.parseText(xml.replaceAll("&", "&amp;")));
          logger.debug("created ChangeSet XML [" + sw.toString().replaceAll("&amp;", "&") + "]");
        }
        catch (Exception e)
        {
          logger.warn("problem pretty-printing ChangeSet: " + e.getMessage());
          logger.debug("created ChangeSet XML [" + xml + "]");
        }
      }
      changeSet = readChangeSet(xml);
    }
    // If this isn't false, then all rules' LHS object conditions will not match on .esb redeploys!
    // (since objects are only equal if they're classloaders are also equal - and they're not on redploys)
    properties.setProperty(ClassLoaderCacheOption.PROPERTY_NAME, Boolean.FALSE.toString());
  }
 
  private ChangeSet readChangeSet(String xml) throws RuleServiceException
  {
    SemanticModules semanticModules = new SemanticModules();
    semanticModules.addSemanticModule(new ChangeSetSemanticModule());
    XmlChangeSetReader reader = new XmlChangeSetReader(semanticModules);
    reader.setClassLoader(classLoader, null);
    try
    {
      return reader.read(new StringReader(xml));
    }
    catch (SAXException se)
    {
      throw new RuleServiceException(se);
    }
    catch (IOException ioe)
    {
      throw new RuleServiceException(ioe);
    }
  }
 
  private void addResourceDirectories(List<String> prop_values, StringBuffer sb) throws RuleServiceException
  {
    for (String prop_value : prop_values)
    {
      File dir = new File(prop_value.trim());
      if (dir.isDirectory())
      {
        Set<ResourceType> res_types = new HashSet<ResourceType>();
        List<String> res_list = new ArrayList<String>();
        for (File file : dir.listFiles())
        {
          if (file.isFile())
          {
            String path = file.getAbsolutePath();
            ResourceType type = getResourceType(path);
            if (type != null)
            {
              res_types.add(type);
              res_list.add(path);
            }
            else
            {
              logger.warn("could not determine ResourceType for file: " + path);
            }
          }
        }
        int res_types_size = res_types.size();
        if (res_types_size == 1)
        {
          // homogenous
          URL url;
          try
          {
            url = dir.toURL();
          }
          catch (MalformedURLException mue)
          {
            throw new RuleServiceException(mue);
          }
          addResource(url.toString(), res_types.iterator().next(), sb);
        }
        else if (res_types_size > 1)
        {
          // heterogenous
          addResourceFiles(res_list, sb);
        }
      }
    }
  }
 
  private void addResourceFiles(List<String> prop_values, StringBuffer sb) throws RuleServiceException
  {
    for (String prop_value : prop_values)
    {
      File file = new File(prop_value.trim());
      if (file.isFile())
      {
        String path = file.getAbsolutePath();
        ResourceType type = getResourceType(path);
        if (type != null)
        {
          URL url;
          try
          {
            url = file.toURL();
          }
          catch (MalformedURLException mue)
          {
            throw new RuleServiceException(mue);
          }
          addResource(url.toString(), type, sb);
        }
        else
        {
          logger.warn("could not determine ResourceType for file: " + path);
        }
      }
    }
  }
 
  private void addResourceURLs(List<String> prop_values, StringBuffer sb) throws RuleServiceException
  {
    for (String prop_value : prop_values)
    {
      URI uri;
      try
      {
        uri = new URI(prop_value.trim());
      }
      catch (URISyntaxException use)
      {
        throw new RuleServiceException(use);
      }
      if (uri.isAbsolute())
      {
        URL url;
        try
        {
          url = uri.toURL();
        }
        catch (MalformedURLException mue)
        {
          throw new RuleServiceException(mue);
        }
        String location = url.toString();
        ResourceType type = getResourceType(location);
        if (type == null)
        {
          type = ResourceType.PKG;
        }
        addResource(location, type, sb, true);
      }
    }
  }
 
  private void addResource(String source, ResourceType type, StringBuffer sb)
  {
    addResource(source, type, sb, false);
  }
 
  private void addResource(String source, ResourceType type, StringBuffer sb, boolean isResourceURL)
  {
    String source_tlc = source.trim().toLowerCase();
    sb.append("<add><resource source=\"");
    sb.append(source);
    sb.append("\" type=\"");
    sb.append(type.getName());
    if (isResourceURL)
    {
      if (source_tlc.startsWith("http://") || source_tlc.startsWith("https://"))
      {
        if ((basicAuthentication != null) && basicAuthentication.booleanValue())
        {
          sb.append("\" basicAuthentication=\"enabled");
          if (username != null)
          {
            sb.append("\" username=\"");
            sb.append(username);
          }
          if (password != null)
          {
            sb.append("\" password=\"");
            sb.append(password);
          }
        }
      }
    }
    boolean closeResourceElement = true;
    if (ResourceType.DTABLE.equals(type))
    {
      if (source_tlc.endsWith(".xls"))
      {
        sb.append("\"><decisiontable-conf input-type=\"XLS\"/></resource>");
        closeResourceElement = false;
      }
      else if (source_tlc.endsWith(".csv"))
      {
        sb.append("\"><decisiontable-conf input-type=\"CSV\"/></resource>");
        closeResourceElement = false;
      }
    }
    if (closeResourceElement)
    {
      sb.append("\"/>");
    }
    sb.append("</add>");
  }
 
  // copied (and modified for generics) from package-protected RuleAgent.list(String):List
    private List<String> list(String property) {
        if ( property == null ) return Collections.<String>emptyList();
        char[] cs = property.toCharArray();
        boolean inquotes = false;
        List<String> items = new ArrayList<String>();
        String current = "";
        for ( int i = 0; i < cs.length; i++ ) {
            char c = cs[i];
            switch ( c ) {
                case '\"' :
                    if ( inquotes ) {
                        items.add( current );
                        current = "";
                    }
                    inquotes = !inquotes;
                    break;

                default :
                    if ( !inquotes && (c == ' ' || c == '\n' || c == '\r' || c == '\t') ) {
                        if ( !"".equals( current.trim() ) ) {
                            items.add( current );
                            current = "";
                        }
                    } else {
                        current = current + c;
                    }
                    break;
            }
        }
        if ( !"".equals( current.trim() ) ) {
            items.add( current );
        }

        return items;
    }
   
  public Properties getProperties()
  {
    return properties;
  }
    public ClassLoader getClassLoader()
    {
      return classLoader;
    }
 
  public String getName()
  {
    return name;
  }
 
  public ChangeSet getChangeSet()
  {
    return changeSet;
  }
 
}
TOP

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

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.