/*
* Copyright (C) 2000 - 2010 TagServlet Ltd
*
* This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
*
* OpenBD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Free Software Foundation,version 3.
*
* OpenBD 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenBD. If not, see http://www.gnu.org/licenses/
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with any of the JARS listed in the README.txt (or a modified version of
* (that library), containing parts covered by the terms of that JAR, the
* licensors of this Program grant you additional permission to convey the
* resulting work.
* README.txt @ http://www.openbluedragon.org/license/README.txt
*
* http://www.openbluedragon.org/
*/
package com.naryx.tagfusion.cfm.tag;
import java.io.Serializable;
import com.naryx.tagfusion.cfm.engine.cfQueryInterface;
import com.naryx.tagfusion.cfm.engine.cfQueryResultData;
import com.naryx.tagfusion.cfm.engine.cfSession;
import com.naryx.tagfusion.cfm.engine.cfTableData;
import com.naryx.tagfusion.cfm.engine.cfmBadFileException;
import com.naryx.tagfusion.cfm.engine.cfmRunTimeException;
import com.naryx.tagfusion.cfm.parser.runTime;
/**
* This class works in conjunction with the cfCOL class.
* Both classes share an instance of cftableData.
*
* Two differences between this class and CF.
*
* o It will not render the column headers if there are no results from the query.
* o If the table is set to be non-HTML, no HTML tags will be rendered.
*/
public class cfTABLE extends cfTag implements Serializable {
static final long serialVersionUID = 1;
public static final String DATA_BIN_KEY = "CFTABLEDATA";
// --[ Load cycle
/**
* The CFTABLE must have an end tag
*
* @returns string
*/
public String getEndMarker() {
return "</CFTABLE>";
}
protected void defaultParameters( String _tag ) throws cfmBadFileException {
defaultAttribute( "COLSPACING", 2 );
defaultAttribute( "HEADERLINES", 2 );
defaultAttribute( "STARTROW", 0 );
defaultAttribute( "MAXROWS", -1 );
parseTagHeader( _tag );
if ( !containsAttribute( "QUERY" ) )
throw newBadFileException( "Missing ATTRIBUTE",
"You need to provide a QUERY attribute" );
}
// ---------------------------------------------------------------------------------------------------------
// --[ Run cycle
public cfTagReturnType render( cfSession _Session ) throws cfmRunTimeException {
boolean processingCfOutput = _Session.setProcessingCfOutput( true );
boolean whitespace = _Session.setSuppressWhiteSpace( false );
cfTableData tableData = new cfTableData();
_Session.setDataBin( DATA_BIN_KEY, tableData );
tableData.colSpacing = getDynamic( _Session, "COLSPACING" ).getInt();
tableData.headerLines = getDynamic( _Session, "HEADERLINES" ).getInt();
if ( containsAttribute( "HTMLTABLE" ) )
tableData.HTML = true;
if ( containsAttribute( "COLHEADERS" ) )
tableData.colHeaders = true;
if ( tableData.HTML ) {
_Session.write( "<TABLE " );
if ( containsAttribute( "BORDER" ) )
_Session.write( " BORDER " );
_Session.write( ">" );
} else
_Session.write( "<PRE>" + "\n" );
// ---------------------------------------------------------------------------------------------------------
// --[ Deal with the query
cfQueryInterface queryData = (cfQueryInterface) runTime.runExpression( _Session, getDynamic( _Session, "QUERY" ).getString() );
if ( queryData != null ) {
queryData.reset();
int startRow = getDynamic( _Session, "STARTROW" ).getInt();
int maxRows = getDynamic( _Session, "MAXROWS" ).getInt();
int rowCount = 0;
_Session.pushQuery( (cfQueryResultData) queryData );
// --[ If there's no ResultSet from the QUERY, print the headers anyway
int numOfRows = 0;
// --[ For every row
// ---------------------------------------------------------------
while (queryData.nextRow()) {
rowCount++;
// --------[ Send the data out for the COLHEADERS
if ( tableData.colHeaders ) {
renderColumnsOnly( _Session );
}
if ( tableData.HTML && tableData.colHeaders )
_Session.write( "</TR>" );
else if ( tableData.colHeaders ) {
for (int x = 0; x < tableData.headerLines; x++)
_Session.write( "\n" );
}
// --[ Ok we've done the HEADERS, move on and set colHeaders to false;
tableData.colHeaders = false;
// --[ Get ourselves up to the start
if ( rowCount < startRow )
continue;
numOfRows++;
if ( tableData.HTML )
_Session.write( "<TR>" );
// --[ Send the data out
renderColumnsOnly( _Session );
if ( tableData.HTML )
_Session.write( "</TR>" );
else
_Session.write( "\n" );
// --[ Determine if the maximum rows have been reached
if ( maxRows != -1 && numOfRows == maxRows )
break;
}
// --[ -------------------------------------------------------------------------------
queryData.finishQuery();
_Session.popQuery();
_Session.deleteDataBin( DATA_BIN_KEY );
if ( tableData.HTML )
_Session.write( "</TABLE>" );
else
_Session.write( "\r\n</PRE>" );
}
_Session.setProcessingCfOutput( processingCfOutput );
_Session.setProcessingCfOutput( whitespace );
return cfTagReturnType.NORMAL;
}
private void renderColumnsOnly( cfSession _Session ) throws cfmRunTimeException {
for (int i = 0; i < childTagList.length; i++) {
cfTag childTag = childTagList[i];
if ( childTag instanceof cfCOL )
childTag.render( _Session );
else
throw newRunTimeException( "An invalid tag was found" );
}
}
}