All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opensymphony.xwork2.util.TextParseUtil Maven / Gradle / Ivy

There is a newer version: 6.4.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.opensymphony.xwork2.util;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.inject.Container;

import java.util.*;


/**
 * Utility class for text parsing.
 *
 * @author Jason Carreira
 * @author Rainer Hermanns
 * @author tm_jee
 */
public class TextParseUtil {

    /**
     * Converts all instances of ${...}, and %{...} in expression to the value returned
     * by a call to {@link ValueStack#findValue(java.lang.String)}. If an item cannot
     * be found on the stack (null is returned), then the entire variable ${...} is not
     * displayed, just as if the item was on the stack but returned an empty string.
     *
     * @param expression an expression that hasn't yet been translated
     * @param stack value stack
     * @return the parsed expression
     */
    public static String translateVariables(String expression, ValueStack stack) {
        return translateVariables(new char[]{'$', '%'}, expression, stack, String.class, null).toString();
    }


    /**
     * Function similarly as {@link #translateVariables(char, String, ValueStack)}
     * except for the introduction of an additional evaluator that allows
     * the parsed value to be evaluated by the evaluator. The evaluator
     * could be null, if it is it will just be skipped as if it is just calling
     * {@link #translateVariables(char, String, ValueStack)}.
     *
     * 
* * A typical use-case would be when we need to URL Encode the parsed value. To do so * we could just supply a URLEncodingEvaluator for example. * * @param expression expression string * @param stack value stack * @param evaluator The parsed Value evaluator (could be null). * @return the parsed (and possibly evaluated) variable String. */ public static String translateVariables(String expression, ValueStack stack, ParsedValueEvaluator evaluator) { return translateVariables(new char[]{'$', '%'}, expression, stack, String.class, evaluator).toString(); } /** * Converts all instances of ${...} in expression to the value returned * by a call to {@link ValueStack#findValue(java.lang.String)}. If an item cannot * be found on the stack (null is returned), then the entire variable ${...} is not * displayed, just as if the item was on the stack but returned an empty string. * * @param open open character * @param expression expression string * @param stack value stack * @return Translated variable String */ public static String translateVariables(char open, String expression, ValueStack stack) { return translateVariables(open, expression, stack, String.class, null).toString(); } /** * Converted object from variable translation. * * @param open open character * @param expression expression string * @param stack value stack * @param asType as class type * @return Converted object from variable translation. */ public static Object translateVariables(char open, String expression, ValueStack stack, Class asType) { return translateVariables(open, expression, stack, asType, null); } /** * Converted object from variable translation. * * @param open open character * @param expression expression string * @param stack value stack * @param asType as class type * @param evaluator value evaluator * @return Converted object from variable translation. */ public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) { return translateVariables(new char[]{open} , expression, stack, asType, evaluator, TextParser.DEFAULT_LOOP_COUNT); } /** * Converted object from variable translation. * * @param openChars open character array * @param expression expression string * @param stack value stack * @param asType as class type * @param evaluator value evaluator * @return Converted object from variable translation. */ public static Object translateVariables(char[] openChars, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) { return translateVariables(openChars, expression, stack, asType, evaluator, TextParser.DEFAULT_LOOP_COUNT); } /** * Converted object from variable translation. * * @param open open character * @param expression expression string * @param stack value stack * @param asType as class type * @param evaluator value evaluator * @param maxLoopCount max loop count * @return Converted object from variable translation. */ public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator, int maxLoopCount) { return translateVariables(new char[]{open}, expression, stack, asType, evaluator, maxLoopCount); } /** * Converted object from variable translation. * * @param openChars open character array * @param expression expression string * @param stack value stack * @param asType as class type * @param evaluator value evaluator * @param maxLoopCount max loop count * @return Converted object from variable translation. */ public static Object translateVariables(char[] openChars, String expression, final ValueStack stack, final Class asType, final ParsedValueEvaluator evaluator, int maxLoopCount) { ParsedValueEvaluator ognlEval = new ParsedValueEvaluator() { public Object evaluate(String parsedValue) { Object o = stack.findValue(parsedValue, asType); if (evaluator != null && o != null) { o = evaluator.evaluate(o.toString()); } return o; } }; TextParser parser = ((Container)stack.getContext().get(ActionContext.CONTAINER)).getInstance(TextParser.class); return parser.evaluate(openChars, expression, ognlEval, maxLoopCount); } /** * @see #translateVariablesCollection(char[], String, ValueStack, boolean, ParsedValueEvaluator, int) * * @param expression expression string * @param stack value stack * @param excludeEmptyElements Whether empty elements shall be excluded. * @param evaluator value evaluator * @return converted objects */ public static Collection translateVariablesCollection(String expression, ValueStack stack, boolean excludeEmptyElements, ParsedValueEvaluator evaluator) { return translateVariablesCollection(new char[]{'$', '%'}, expression, stack, excludeEmptyElements, evaluator, TextParser.DEFAULT_LOOP_COUNT); } /** * Resolves given expression on given ValueStack. If found element is a * collection each element will be converted to String. If just a single * object is found it is converted to String and wrapped in a collection. * * @param openChars open character array * @param expression expression string * @param stack value stack * @param evaluator value evaluator * @param excludeEmptyElements Whether empty elements shall be excluded. * @param maxLoopCount max loop count * @return converted objects */ public static Collection translateVariablesCollection( char[] openChars, String expression, final ValueStack stack, boolean excludeEmptyElements, final ParsedValueEvaluator evaluator, int maxLoopCount) { ParsedValueEvaluator ognlEval = new ParsedValueEvaluator() { public Object evaluate(String parsedValue) { return stack.findValue(parsedValue); // no asType !!! } }; Map context = stack.getContext(); TextParser parser = ((Container)context.get(ActionContext.CONTAINER)).getInstance(TextParser.class); Object result = parser.evaluate(openChars, expression, ognlEval, maxLoopCount); Collection resultCol; if (result instanceof Collection) { @SuppressWarnings("unchecked") Collection casted = (Collection)result; resultCol = new ArrayList<>(); XWorkConverter conv = ((Container)context.get(ActionContext.CONTAINER)).getInstance(XWorkConverter.class); for (Object element : casted) { String stringElement = (String)conv.convertValue(context, element, String.class); if (shallBeIncluded(stringElement, excludeEmptyElements)) { if (evaluator != null) { stringElement = evaluator.evaluate(stringElement).toString(); } resultCol.add(stringElement); } } } else { resultCol = new ArrayList<>(); String resultStr = translateVariables(expression, stack, evaluator); if (shallBeIncluded(resultStr, excludeEmptyElements)) { resultCol.add(resultStr); } } return resultCol; } /** * Tests if given string is not null and not empty when excluding of empty * elements is requested. * * @param str String to check. * @param excludeEmptyElements Whether empty elements shall be excluded. * @return True if given string can be included in collection. */ private static boolean shallBeIncluded(String str, boolean excludeEmptyElements) { return !excludeEmptyElements || ((str != null) && (str.length() > 0)); } /** * Returns a set from comma delimited Strings. * @param s The String to parse. * @return A set from comma delimited Strings. */ public static Set commaDelimitedStringToSet(String s) { Set set = new HashSet<>(); String[] split = s.split(","); for (String aSplit : split) { String trimmed = aSplit.trim(); if (trimmed.length() > 0) set.add(trimmed); } return set; } /** *

* A parsed value evaluator for {@link TextParseUtil}. It could be supplied by * calling {@link TextParseUtil#translateVariables(char, String, ValueStack, Class, ParsedValueEvaluator)}. *

* *

* By supplying this ParsedValueEvaluator, the parsed value * (parsed against the value stack) value will be * given to ParsedValueEvaluator to be evaluated before the * translateVariable process goes on. *

* *

* A typical use-case would be to have a custom ParseValueEvaluator * to URL Encode the parsed value. *

* * @author tm_jee */ public static interface ParsedValueEvaluator { /** * Evaluated the value parsed by Ognl value stack. * * @param parsedValue - value parsed by ognl value stack * @return return the evaluated value. */ Object evaluate(String parsedValue); } }