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

org.tentackle.wurblet.WurbletParameterParser Maven / Gradle / Ivy

There is a newer version: 21.16.1.0
Show newest version
/*
 * Tentackle - http://www.tentackle.org
 *
 * This library 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 library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.tentackle.wurblet;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.tentackle.common.BasicStringHelper;
import org.wurbelizer.wurbel.WurbelException;

/**
 * Parses the wurblet parameters.
 * 

* The list of args from the wurblet container consist of: *

    *
  • wurblet options (starting with --)
  • *
  • a logical expression of parameters used for the WHERE clause
  • *
  • optional extra parameters, e.g. for columns to be updated
  • *
  • optional sorting parameters
  • *
  • optional joins
  • *
* * The expression evaluation is terminated either by the end of the argument list or a group * separator or the first sorting key.
* A sorting key is described by a + (for ascending) or - (for descending) immediately (i.e. without spaces) followd by an attribute.
* All other parameters outside the expression are considered as extra parameters. Expressions end implicitly at the * first sorting key or join or explicitly by a pipe-character |.
* Joins are relation names prepended by an asterisk. *

* An expression consists of operands (which may be parameters or nested expressions) connected * via logical operators. There are 3 kinds of operators: *

    *
  1. AND
  2. *
  3. OR
  4. *
  5. NOT
  6. *
* The default operator, if missing, is AND.
* Some examples: *
 * fee fie
 * (foe or foo) and (voice or plugh)
 * ((fee or fie) and foe) or foo
 * 
* A complete wurblet example: *
 * @wurblet selectUpTo PdoSelectList --remote processed:=:null or processed:>= +id *address
 * 
* * @author harald */ public class WurbletParameterParser { /** list of wurblet args starting with -- (-- cut off). */ private final List optionArgs; /** the parsed expression. */ private final WurbletParameterExpression expression; /** the list of all parameters in the expression. */ private final List expressionParameters; /** sorting parameters. */ private final List sortingParameters; /** extra parameters after group separator. */ private final List extraParameters; /** method parameters. */ private List methodParameters; /** all parameters. */ private List allParameters; /** the join names. */ private final List joinNames; /** * Creates a parser. * * @param args the wurblet arguments * @throws org.wurbelizer.wurbel.WurbelException if parsing failed */ public WurbletParameterParser(List args) throws WurbelException { optionArgs = new ArrayList<>(); expression = new WurbletParameterExpression(null); expressionParameters = new ArrayList<>(); sortingParameters = new ArrayList<>(); joinNames = new ArrayList<>(); extraParameters = new ArrayList<>(); parse(args); } /** * Gets the options. * * @return the options */ public List getOptionArgs() { return optionArgs; } /** * Gets the where expression. * * @return the expression */ public WurbletParameterExpression getExpression() { return expression; } /** * Gets all parameters part of the expression. * * @return the expression parameters */ public List getExpressionParameters() { return expressionParameters; } /** * Gets the sorting parameters. * * @return the sorting parameters */ public List getSortingParameters() { return sortingParameters; } /** * Gets the extra parameters.
* Those are not part of the expression and not sorting parameters. * * @return the extra parameters */ public List getExtraParameters() { return extraParameters; } /** * Gets all parameters. * * @return all parameters */ public List getAllParameters() { if (allParameters == null) { allParameters = new ArrayList<>(expressionParameters.size() + extraParameters.size() + sortingParameters.size()); allParameters.addAll(expressionParameters); allParameters.addAll(extraParameters); allParameters.addAll(sortingParameters); } return allParameters; } /** * Gets the method parameters. * * @return all parameters */ public List getMethodParameters() { if (methodParameters == null) { methodParameters = new ArrayList<>(extraParameters.size() + expressionParameters.size()); methodParameters.addAll(extraParameters); methodParameters.addAll(expressionParameters); } return methodParameters; } /** * Gets the relation names of the joins. * * @return the join names */ public List getJoinNames() { return joinNames; } /** * Parses the source. * * @param args the argumenys * @throws WurbelException if parsing failed */ private void parse(List args) throws WurbelException { int expressionLevel = 0; // no expression started yet LinkedList operators = new LinkedList<>(); // stacked operators WurbletParameterOperator operator = null; // last operator WurbletParameterExpression expr = expression; // current expression boolean expressionFinished = false; // true if expression evaluation finished for (String arg : args) { if (arg != null) { if (arg.startsWith("--")) { optionArgs.add(arg.substring(2)); } else if (arg.length() > 1 && arg.startsWith("*")) { joinNames.add(arg.substring(1)); expressionFinished = true; } else { if (expressionFinished) { WurbletParameter par = new WurbletParameter(arg); if (par.isSortKey()) { sortingParameters.add(par); } else { extraParameters.add(par); } } else { for (String subArg : splitArg(arg)) { switch (subArg) { case "(": expr = new WurbletParameterExpression(expr); operators.push(operator); operator = null; expressionLevel++; continue; case ")": expressionLevel--; if (expressionLevel < 0) { throw new WurbelException("unbalanced braces: more closed than opened"); } WurbletParameterExpression parent = expr.getParent(); operator = operators.pop(); if (parent != null) { parent.addOperand(operator, expr); operator = null; } expr = parent; continue; case "|": if (expressionLevel == 0) { expressionFinished = true; continue; } throw new WurbelException("key group separator not allowed in nested expressions"); } WurbletParameterOperator oper = WurbletParameterOperator.toInternal(subArg); if (oper != null) { if (operator != null) { if (oper == WurbletParameterOperator.NOT) { if (operator == WurbletParameterOperator.AND) { operator = WurbletParameterOperator.ANDNOT; continue; } else if (operator == WurbletParameterOperator.OR) { operator = WurbletParameterOperator.ORNOT; continue; } } throw new WurbelException(operator + " cannot be followed by " + oper); } operator = oper; } else { WurbletParameter operand = new WurbletParameter(subArg); if (operand.isSortKey()) { if (expressionLevel == 0) { sortingParameters.add(operand); expressionFinished = true; } else { throw new WurbelException("sorting key " + operand + " not allowed in nested expressions"); } } else { expr.addOperand(operator, operand); operator = null; expressionParameters.add(operand); } } } } } } } if (expressionLevel > 0) { throw new WurbelException("unbalanced braces: more opened than closed"); } } /** * Separates the arg according to the braces or group separator it contains. *

* Braces may be quoted with a backslash. * The backslash itself is a double backslash. * * @param arg the arg * @return the braces */ private List splitArg(String arg) { List strs = new ArrayList<>(); StringBuilder buf = new StringBuilder(); boolean quoted = false; char c = 0; char cl; for (int i=0; i < arg.length(); i++) { cl = c; c = arg.charAt(i); if (quoted) { buf.append(c); quoted = false; } else { if (c == '\\') { quoted = true; } else { if ((c == '(' && (i >= arg.length() - 1 || arg.charAt(i+1) != ')')) || (c == ')' && cl != '(') || c == '|') { String str = buf.toString().trim(); if (!BasicStringHelper.isAllWhitespace(str)) { strs.add(str); } buf.setLength(0); buf.append(c); strs.add(buf.toString()); buf.setLength(0); } else { buf.append(c); } } } } String str = buf.toString().trim(); if (!BasicStringHelper.isAllWhitespace(str)) { strs.add(str); } return strs; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy