org.yawlfoundation.yawl.util.YPredicateParser.java Source code

Java tutorial

Introduction

Here is the source code for org.yawlfoundation.yawl.util.YPredicateParser.java

Source

/*
 * Copyright (c) 2004-2012 The YAWL Foundation. All rights reserved.
 * The YAWL Foundation is a collaboration of individuals and
 * organisations who are committed to improving workflow technology.
 *
 * This file is part of YAWL. YAWL 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.
 *
 * YAWL 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 YAWL. If not, see <http://www.gnu.org/licenses/>.
 */

package org.yawlfoundation.yawl.util;

import org.jdom2.Document;
import org.jdom2.Element;

import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Set;

/**
 * Parses strings, replacing substrings within of the form ${expression} with the
 * result of the expression evaluation
 *
 * Author: Michael Adams
 * Date: 02/04/2010
 *
 * Known subclasses: logging.YLogPredicateDecompositionParser,
 *                   logging.YLogPredicateParameterParser,
 *                   logging.YLogPredicateWorkItemParser,
 *                   resourcing.util.LogPredicateParser,
 *                   resourcing.jsf.dynform.DynTextParser
 *
 * Subclasses should override the 'valueOf' method to handle their own pre-parsing.
 */

public class YPredicateParser {

    public YPredicateParser() {
    }

    /**
     * Parses a string, replacing substrings within of the form ${expression} with the
     * result of the expression evaluation
     * @param s the string to parse
     * @return s, with any embedded expressions replaced with their evaluations
     */
    public String parse(String s) {
        if ((s == null) || (!s.contains("${")))
            return s; // short circuit 

        // split on the points immediately before an instance of "${" or immediately
        // after an instance of "}", preserving all chars.
        String[] phrases = s.split("(?=\\$\\{)|(?<=\\})");

        for (int i = 0; i < phrases.length; i++) {
            String phrase = phrases[i];
            if (isDelimited(phrase)) {
                phrases[i] = valueOf(phrase);
            }
        }
        return join(phrases);
    }

    /**
     * Evaluates an expression and returns the result. Subclasses should override this
     * class to do their own expression evaluations before calling this version for
     * any general expression evaluations.
     * @param s the string representing the expression, of the form ${expression}
     * @return the result of the expression evaluation, or the unchanged string if the
     * expression is unrecognised
     */
    protected String valueOf(String s) {
        if (s.equalsIgnoreCase("${now}")) {
            s = dateTimeString(System.currentTimeMillis());
        } else if (s.equalsIgnoreCase("${date}")) {
            s = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis());
        } else if (s.equalsIgnoreCase("${time}")) {
            s = new SimpleDateFormat("HH:mm:ss.SSS").format(System.currentTimeMillis());
        }
        return s;
    }

    /**
     * Converts a time value to a full date & time string
     * @param time the time value
     * @return a string representing the date & time value
     */
    protected String dateTimeString(long time) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(time);
    }

    /**
     * Extracts a key from the delimited expression passed, then seeks the value
     * corresponding to that key from the map passed
     * @param map a map of String pairs
     * @param s a string representing an expression, of the form ${expression:key},
     * containing the key
     * @return the corresponding key value, or null if the map is null or the map
     * does not contain the key
     */
    protected String getAttributeValue(Map<String, String> map, String s) {
        if (map == null)
            return null;
        String key = extractKey(stripDelimiters(s));
        return map.get(key);
    }

    /**
     * Transforms a Set of Strings into a string of comma separated values
     * @param names the Set of Strings to transform
     * @return a string containing each of the Strings in the Set, spearated by a
     * comma, or "Nil" if there are no Strings in the Set
     */
    protected String namesToCSV(Set<String> names) {
        if (names == null)
            return "Nil";
        String csv = "";
        for (String name : names) {
            csv += name + ", ";
        }
        return csv;
    }

    /**
     * Evaluates an XQuery embedded within a delimited expression 
     * @param s the delimited expression, either of the form ${query} or ${expression:query}
     * @param data XML'd data that may be referenced by the expression. May be null if
     * the expression doesn't reference any data
     * @return the result of the evaluation, or "__evaluation_error__" if there's a
     * problem evaluating the expression
     */
    protected String evaluateQuery(String s, Element data) {
        String expression = stripDelimiters(s);
        if (expression.startsWith("expression:")) {
            expression = extractKey(expression);
        }
        return evaluateXQuery(expression, data);
    }

    /*******************************************************************************/

    /**
     * Checks if the string passed is a delimited expression of the form ${expression}
     * @param s the string to check
     * @return true if it has the correct form, false if otherwise
     */
    private boolean isDelimited(String s) {
        return s.startsWith("${") && s.endsWith("}");
    }

    /**
     * Transforms the String array passed into a single String
     * @param phrases the String array to join
     * @return the joined Strings
     */
    private String join(String[] phrases) {
        StringBuilder joined = new StringBuilder();
        for (String phrase : phrases) {
            joined.append(phrase);
        }
        return joined.toString();
    }

    /**
     * Evaluates an XQuery
     * @param s the query expression
     * @param data XML'd data that may be referenced by the expression. May be null if
     * the expression doesn't reference any data
     * @return the result of the evaluation, or "__evaluation_error__" if there's a
     * problem evaluating the expression
     */
    protected String evaluateXQuery(String s, Element data) {
        return evaluateXQuery(s, new Document(data.clone()));

    }

    protected String evaluateXQuery(String s, Document dataDoc) {
        try {
            return SaxonUtil.evaluateQuery(s, dataDoc);
        } catch (Exception e) {
            return "__evaluation_error__";
        }
    }

    /**
     * removes the surrounding ${...} from a String
     * @param s the delimited String
     * @return the inner contents of the String with the delimiters removed
     */
    protected String stripDelimiters(String s) {
        return s.substring(2, s.length() - 1);
    }

    /**
     * Extracts the key part of an expression of the form "expression:key"
     * @param s the String containing the key
     * @return the kay part of the String
     */
    private String extractKey(String s) {
        return s.substring(s.lastIndexOf(":") + 1);
    }

}