Package com.catify.processengine.core.services

Source Code of com.catify.processengine.core.services.ExpressionService

package com.catify.processengine.core.services;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import akka.actor.ActorRef;

import com.catify.processengine.core.data.dataobjects.DataObjectSPI;
import com.catify.processengine.core.data.dataobjects.DataObjectService;

/**
*
*
* @author claus straube
*
*/
public class ExpressionService {

  public static final JexlEngine JEXL = new JexlEngine();
  public static final Logger LOG = LoggerFactory.getLogger(ExpressionService.class);
 
  /**
   * Creates a new JEXL engine instance.
   *
   * @return a new {@link JexlEngine}
   */
  public static JexlEngine createJexlEngine() {
    return new JexlEngine();
  }
 
  /**
   * Evaluates, what data objects are used inside a
   * JEXL expression. So we have only to load the objects
   * that are really used.
   *
   * @param expression as {@link String} (foo.a > bar.b)
   * @param dataObjectIds as {@link String} in a {@link Set}
   * @return all data object ids that are available in the process and use inside the expression as {@link Set}.
   */
  public static Set<String> evaluateUsedObjects(String expression, Set<String> dataObjectIds) {
    Set<String> result = new HashSet<String>();
   
    for (String id : dataObjectIds) {
      if(expression.contains(id)) {
        result.add(id);
      }
    }
   
    return result;
  }
 
  /**
   * Evaluates all data objects (object ids) used inside a
   * list of different expressions. If an object foo occurs
   * in multible expressions, its exactly one object id for
   * foo inside the result set.
   *
   * @param expressions
   * @param dataObjectIds
   * @return
   */
  public static Set<String> evaluateAllUsedObjects(List<String> expressions, Set<String> dataObjectIds) {
    Set<String> result = new HashSet<String>();
   
    for (String expression : expressions) {
      Set<String> oids = evaluateUsedObjects(expression, dataObjectIds);
      result.addAll(oids);
    }
   
    return result;
  }
 
  /**
   * Converts a JEXL {@link String} into a JEXL {@link Expression}. Take a look on the
   * <a href="http://commons.apache.org/jexl/reference/syntax.html">Apache Commons JEXL page</a>
   * to get more information.
   *
   * @param expression as {@link String} (foo.a > bar.b)
   * @param jexlEngine a external jexlEngine instance
   * @return expression as {@link Expression}
   */
  public static Expression createJexlExpression(String expression, JexlEngine jexlEngine) {
    return jexlEngine.createExpression(expression);
  }
 
  /**
   * Converts a JEXL {@link String} into a JEXL {@link Expression}. Take a look on the
   * <a href="http://commons.apache.org/jexl/reference/syntax.html">Apache Commons JEXL page</a>
   * to get more information.
   *
   * @param expression as {@link String} (foo.a > bar.b)
   * @return expression as {@link Expression}
   */
  public static Expression createJexlExpression(String expression) {
    // there can be null values - e.g. within default sequences
    Expression result = null;
    if(expression != null) {
      LOG.debug(String.format("Creating JEXL expression from '%s'.", expression));
      result = JEXL.createExpression(expression);
    }
    return result;
  }
 
  /**
   * Converts a {@link Set} of JEXL {@link String}s into a {@link Set} of
   * JEXL {@link Expression}s. Take a look on the
   * <a href="http://commons.apache.org/jexl/reference/syntax.html">Apache Commons JEXL page</a>
   * to get more information.
   *
   * @param expressions the {@link String} expressions in a {@link Set}
   * @param jexlEngine a external jexlEngine instance
   * @return the {@link Expression} in a {@link Set}
   */
  public static Set<Expression> createJexlExpressions(Set<String> expressions, JexlEngine jexlEngine) {
    Set<Expression> result = new HashSet<Expression>();
   
    for (String expression : expressions) {
      result.add(createJexlExpression(expression, jexlEngine));
    }
   
    return result;
  }
 
  /**
   * Converts a {@link Set} of JEXL {@link String}s into a {@link Set} of
   * JEXL {@link Expression}s. Take a look on the
   * <a href="http://commons.apache.org/jexl/reference/syntax.html">Apache Commons JEXL page</a>
   * to get more information.
   *
   * @param expressions the {@link String} expressions in a {@link Set}
   * @return the {@link Expression} in a {@link Set}
   */
  public static Set<Expression> createJexlExpressions(Set<String> expressions) {
    Set<Expression> result = new HashSet<Expression>();
   
    for (String expression : expressions) {
      result.add(createJexlExpression(expression));
    }
   
    return result;
  }
 
  /**
   * Converts a {@link Map} of JEXL {@link String}s into a {@link Map} of
   * JEXL {@link Expression}s. Take a look on the
   * <a href="http://commons.apache.org/jexl/reference/syntax.html">Apache Commons JEXL page</a>
   * to get more information.
   *
   * @param expressions
   * @return
   */
  public static Map<ActorRef,Expression> createJexlExpressions(Map<ActorRef,String> expressions) {
    Map<ActorRef,Expression> result = new TreeMap<ActorRef, Expression>();
   
    Iterator<ActorRef> it = expressions.keySet().iterator();
    while (it.hasNext()) {
      ActorRef actorRef = it.next();
      if(expressions != null) {
        result.put(actorRef, createJexlExpression(expressions.get(actorRef)));
      } else {
        System.out.println("###################### expressions NULL!!!");
      }
    }
   
    return result;
  }
 
  /**
   * Evaluates a given JEXL {@link Expression} with the given
   * objects (loaded over the {@link DataObjectSPI}).
   *
   * @param expression a JEXL {@link Expression}
   * @param dataObjectIds all needed data objects ids (see {@link ExpressionService.evaluateUsedObjects})
   * @param dataObjectHandler the connector to the data
   * @param uniqueProcessId the process id
   * @param instanceId the instance id
   * @return the result of the JEXL evaluation
   */
  public static Object evaluate(Expression expression,
      Set<String> dataObjectIds,
      DataObjectService dataObjectHandler,
      String uniqueProcessId,
      String instanceId) {
   
    JexlContext jc = fillContext(dataObjectIds, dataObjectHandler, uniqueProcessId, instanceId);
   
    // evaluate the expression
    Object result = expression.evaluate(jc);
       
    return result;
  }
 
  public static JexlContext fillContext(Set<String> dataObjectIds,
      DataObjectService dataObjectHandler,
      String uniqueProcessId,
      String instanceId) {
    // create context
    JexlContext jc = new MapContext();
       
    // fill context
    for (String id : dataObjectIds) {
      jc.set(id, dataObjectHandler.loadObject(uniqueProcessId, instanceId, id));
    }
   
    return jc;
  }
 
  /**
   * Evaluates a given JEXL {@link Expression} with the given
   * objects (loaded over the {@link DataObjectSPI}).
   *
   * @param expression a JEXL {@link Expression}
   * @param dataObjectIds all needed data objects ids (see {@link ExpressionService.evaluateUsedObjects})
   * @param dataObjectHandler the connector to the data
   * @param uniqueProcessId the process id
   * @param instanceId the instance id
   * @return the result of the JEXL evaluation (must be boolean - otherwise an {@link IllegalArgumentException} will be thrown
   */
  public static boolean evaluateToBoolean(Expression expression,
      Set<String> dataObjectIds,
      DataObjectService dataObjectHandler,
      String uniqueProcessId,
      String instanceId) {
   
    JexlContext context = fillContext(dataObjectIds, dataObjectHandler, uniqueProcessId, instanceId);
    return evaluateToBoolean(expression, context);
  }
 
  /**
   * Evaluates a given JEXL {@link Expression} with the given
   * {@link JexlContext}.
   *
   * @param expression a JEXL expression.
   * @param context the filled JEXL context.
   * @return
   */
  public static boolean evaluateToBoolean(Expression expression, JexlContext context) {
    if(expression != null) {
      Object result = expression.evaluate(context);
      LOG.debug(String.format("Evaluated expression '%s' to result '%s'.", expression.getExpression(), result));
     
      if(result instanceof Boolean) {
        return (Boolean) result;
      } else {
        throw new IllegalArgumentException(String.format("Your JEXL expression '%s' has not a boolean result.", expression.getExpression()));
      }
    }
    return false;
  }
 
 
}
TOP

Related Classes of com.catify.processengine.core.services.ExpressionService

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.