org.randombits.confluence.metadata.expression.TableFunctionParser Maven / Gradle / Ivy
/*
* Copyright (c) 2007, CustomWare Asia Pacific
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of "CustomWare Asia Pacific" nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.randombits.confluence.metadata.expression;
import org.randombits.math.eval.*;
import org.randombits.storage.Storage;
/**
* This parser allows summing of a single column in a Scaffold table from within
* an eval-data macro. In a mathematical expression, it should be used like so:
*
*
* sumtable("Table Name", "Field Name")
*
*
*
* To use summations with a Parser p
, just say p.add(new SumTableParser(ctx))
.
*/
public class TableFunctionParser implements ParserExtension {
private static final long serialVersionUID = -2199701223790450626L;
public enum Type {
AVERAGE("avgtable"),
SUM("sumtable");
public final String name;
Type( String name ) {
this.name = name;
}
}
private static final String AVG_NAME = "avgtable";
/**
* Use this type to have the parser average the table fields.
*/
public static final int AVG_TYPE = 2;
private static final String SUM_NAME = "sumtable";
/**
* Use this type to have the parser sum the table fields.
*/
public static final int SUM_TYPE = 1;
/*
* A name is required by the MathObject interface, which ParserExtension
* extends. The name is what is used to indicate a summation in an
* expression. The name should not be changed after the SummationParser is
* added to a Parser.
*/
private String name;
private Storage fields;
private Type type;
private String rowCountField;
/**
* Constructs a new "sumtable" function parser. Allows summing of single
* table columns in an expression.
*
* @param type
* The type of the table function.
*/
public TableFunctionParser( Storage fields, Type type, String rowCountField ) {
this.fields = fields;
this.type = type;
this.rowCountField = rowCountField;
this.name = type.name;
}
/**
* Set the name, which will be used in place of "sumtable" in expressions.
* This should not be done after the SummationParser has been added to a
* Parser. The default name is "sumtable".
*/
public void setName( String name ) {
this.name = name;
}
/**
* Get the name of the function.
*/
public String getName() {
return name;
}
/**
* When the name of this ParserExtension is encountered by a parser with
* which the extension is registered, the parser calls this routine to
* findObject the summation subexpression. The subexpression has the form
* ">variable<,>lower-limit<,>upper-limit<,>expression<".
* This method is not meant to be called directly
*/
public void doParse( Parser parser, ParserContext context ) {
int tok = context.next();
String open = context.tokenString;
if ( tok == ParserContext.OPCHARS
&& ( open.equals( "(" )
|| ( context.options & Parser.BRACKETS ) != 0 && open.equals( "[" )
|| ( context.options & Parser.BRACES ) != 0 && open.equals( "{" ) ) ) {
String close = open.equals( "(" ) ? ")" : ( open.equals( "[" ) ? "]" : "}" );
String tableName = parseQuotedString( context, "table name" );
// ctx.addMessage("table name: \"" + tableName + "\"");
tok = context.next();
if ( tok != ParserContext.OPCHARS || !context.tokenString.equals( "," ) )
throw new ParseException( "Expected a comma after the table name, \"" + tableName + "\".", context );
String fieldName = parseQuotedString( context, "field name" );
// ctx.addMessage("field name: \"" + fieldName + "\"");
tok = context.next();
if ( tok != ParserContext.OPCHARS || !context.tokenString.equals( close ) )
throw new ParseException( "Expected a \"" + close + "\" at the end of the parameter list for "
+ name + ".", context );
addCommand( tableName, fieldName, context );
} else
throw new ParseException( "Parentheses required around parameters of " + name + ".", context );
} // end doParse()
private void addCommand( String tableName, String fieldName, ParserContext context ) {
ExpressionCommand cmd;
switch ( type ) {
case AVERAGE:
cmd = new AvgTableCommand( tableName, fieldName, rowCountField, fields );
break;
case SUM:
cmd = new SumTableCommand( tableName, fieldName, rowCountField, fields, context.prog );
break;
default:
throw new ParseException( "Unsupported table function type: " + type, context );
}
context.prog.addCommandObject( cmd );
}
private String parseQuotedString( ParserContext context, String paramName ) {
int tok;
tok = context.next(); // Must be an identifier.
if ( tok != ParserContext.OPCHARS || !context.tokenString.equals( "\"" ) )
throw new ParseException( "Expected an opening quote (\") before the " + paramName + ".", context );
// Dodgy hack to get the table name...
int closePos = context.data.indexOf( "\"", context.pos );
if ( closePos == -1 )
throw new ParseException( "Expected a closing quote (\") after the " + paramName + ".", context );
String strValue = context.data.substring( context.pos, closePos );
context.pos = closePos + 1;
return strValue;
}
} // end SumParserExtension