package org.openswing.swing.export.java;
import java.lang.reflect.*;
import java.sql.Date;
import java.text.*;
import java.util.*;
import org.openswing.swing.message.receive.java.*;
import org.openswing.swing.message.send.java.*;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: This class is used to export grid data in CSV format (with ";" or "," separator).</p>
* CSV is a delimited data format that has fields/columns separated by the comma character and records/rows separated by newlines.
* Fields that contain a special character ( comma, newline, or double quote ), must be enclosed in double quotes.
* However, if a line contains a single entry which is the empty string, it may be enclosed in double quotes.
* If a field's value contains a double quote character it is escaped by placing another double quote character next to it.
* The CSV file format does not require a specific character encoding, byte order, or line terminator format.
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class ExportToCSV {
public ExportToCSV() {
}
/**
* @param opt export options
* @return CSV document, as byte array
*/
public byte[] getDocument(ExportOptions opt) throws Throwable {
StringBuffer sb = new StringBuffer("");
Object obj = null;
for(int i=0;i<opt.getComponentsExportOptions().size();i++) {
obj = opt.getComponentsExportOptions().get(i);
processComponent(sb,opt,obj);
}
byte[] doc = sb.toString().getBytes();
return doc;
}
private void processComponent(StringBuffer sb,ExportOptions exportOptions,Object obj) throws Throwable {
if (obj!=null) {
GridExportCallbacks callbacks = null;
if (obj instanceof GridExportOptions) {
callbacks = (GridExportCallbacks)((GridExportOptions)obj).getCallbacks();
if (callbacks!=null)
processComponent(sb,exportOptions,callbacks.getHeaderComponent());
prepareGrid(sb,exportOptions,(GridExportOptions)obj);
if (callbacks!=null)
processComponent(sb,exportOptions,callbacks.getFooterComponent());
}
else if (obj instanceof ComponentExportOptions)
prepareGenericComponent(sb,exportOptions,(ComponentExportOptions)obj);
else
return;
sb.append("\n");
}
}
private void prepareGenericComponent(StringBuffer sb,ExportOptions exportOptions,ComponentExportOptions opt) throws Throwable {
Object[] row = null;
Object obj = null;
SimpleDateFormat sdatf = new SimpleDateFormat(exportOptions.getDateTimeFormat());
String sep = exportOptions.getExportType().endsWith(ExportOptions.CSV_FORMAT1) ? "," : ";";
if (opt.getCellsContent()!=null)
for(int i=0;i<opt.getCellsContent().length;i++) {
row = opt.getCellsContent()[i];
for(int j=0;j<row.length;j++) {
obj = row[j];
if (obj!=null) {
if (obj instanceof Boolean) {
sb.append ((Boolean)obj);
}
else if (obj.getClass().equals(boolean.class)) {
sb.append ((Boolean)obj);
}
else if (obj instanceof Date ||
obj instanceof java.util.Date ||
obj instanceof java.sql.Timestamp) {
sb.append( sdatf.format((java.util.Date)obj) );
}
else {
sb.append( encodeText(obj.toString(),sep) );
}
}
if (j<row.length-1)
sb.append(sep);
}
sb.append("\n");
}
}
private void prepareGrid(StringBuffer sb,ExportOptions exportOptions,GridExportOptions opt) throws Throwable {
// prepare vo getters methods...
String methodName = null;
String attributeName = null;
Hashtable gettersMethods = new Hashtable();
Method[] voMethods = opt.getValueObjectType().getMethods();
for(int i=0;i<voMethods.length;i++) {
methodName = voMethods[i].getName();
if (methodName.startsWith("get")) {
attributeName = methodName.substring(3,4).toLowerCase()+methodName.substring(4);
if (opt.getExportAttrColumns().contains(attributeName))
gettersMethods.put(attributeName,voMethods[i]);
}
}
Response response = null;
int start = 0;
int rownum = 0;
Object value = null;
Object vo = null;
int type;
String sep = exportOptions.getExportType().endsWith(ExportOptions.CSV_FORMAT1) ? "," : ";";
if (opt.getTitle()!=null && !opt.getTitle().equals(""))
sb.append(opt.getTitle()).append("\n\n");
String[] filters = opt.getFilteringConditions();
if (filters!=null) {
for(int i=0;i<filters.length;i++)
sb.append(filters[i]).append("\n");
sb.append("\n");
}
SimpleDateFormat sdf = new SimpleDateFormat(exportOptions.getDateFormat());
SimpleDateFormat sdatf = new SimpleDateFormat(exportOptions.getDateTimeFormat());
SimpleDateFormat stf = new SimpleDateFormat(exportOptions.getTimeFormat());
for(int j=0;j<opt.getTopRows().size();j++) {
// create a row for each top rows...
vo = opt.getTopRows().get(j);
appendRow(
exportOptions,
sb,
vo,
opt,
gettersMethods,
sdf,
sdatf,
stf,
sep,
j,
0
);
}
do {
response=opt.getGridDataLocator().loadData(
GridParams.NEXT_BLOCK_ACTION,
start,
opt.getFilteredColumns(),
opt.getCurrentSortedColumns(),
opt.getCurrentSortedVersusColumns(),
opt.getValueObjectType(),
opt.getOtherGridParams()
);
if (response.isError())
throw new Exception(response.getErrorMessage());
for(int j=0;j<((VOListResponse)response).getRows().size();j++) {
// create a row
vo = ((VOListResponse)response).getRows().get(j);
appendRow(
exportOptions,
sb,
vo,
opt,
gettersMethods,
sdf,
sdatf,
stf,
sep,
rownum,
1
);
rownum++;
}
start = start+((VOListResponse)response).getRows().size();
if ( !((VOListResponse)response).isMoreRows() )
break;
}
while (rownum<opt.getMaxRows());
for(int j=0;j<opt.getBottomRows().size();j++) {
// create a row for each bottom rows...
vo = opt.getBottomRows().get(j);
appendRow(
exportOptions,
sb,
vo,
opt,
gettersMethods,
sdf,
sdatf,
stf,
sep,
j,
2
);
}
}
/**
* Append current row to result StringBuffer.
* @return current row to append
*/
private void appendRow(
ExportOptions exportOptions,
StringBuffer sb,
Object vo,
GridExportOptions opt,
Hashtable gettersMethods,
SimpleDateFormat sdf,
SimpleDateFormat sdatf,
SimpleDateFormat stf,
String sep,
int rownum,
int tableType
) throws Throwable {
int type;
String aName = null;
Method getter = null;
Class clazz = null;
Object obj = null;
for(int i=0;i<opt.getExportColumns().size();i++) {
// value = ((Method)gettersMethods.get(opt.getExportAttrColumns().get(i))).invoke(vo,new Object[0]);
clazz = vo.getClass();
obj = vo;
aName = opt.getExportAttrColumns().get(i).toString();
// check if the specified attribute is a composed attribute and there exist inner v.o. to instantiate...
while(aName.indexOf(".")!=-1) {
try {
getter = clazz.getMethod(
"get" +
aName.substring(0, 1).
toUpperCase() +
aName.substring(1,aName.indexOf(".")),
new Class[0]
);
}
catch (NoSuchMethodException ex2) {
getter = clazz.getMethod("is"+aName.substring(0,1).toUpperCase()+aName.substring(1,aName.indexOf(".")),new Class[0]);
}
aName = aName.substring(aName.indexOf(".")+1);
clazz = getter.getReturnType();
obj = getter.invoke(obj,new Object[0]);
if (obj==null)
break;
}
try {
getter = clazz.getMethod(
"get" +
aName.substring(0, 1).
toUpperCase() +
aName.substring(1),
new Class[0]
);
}
catch (NoSuchMethodException ex2) {
getter = clazz.getMethod("is"+aName.substring(0,1).toUpperCase()+aName.substring(1),new Class[0]);
}
if (obj!=null)
obj = getter.invoke(obj,new Object[0]);
if (obj!=null) {
if (obj instanceof Boolean) {
sb.append ((Boolean)obj);
}
else if (obj.getClass().equals(boolean.class)) {
sb.append ((Boolean)obj);
}
else if (obj instanceof Date ||
obj instanceof java.util.Date ||
obj instanceof java.sql.Timestamp) {
type = ((Integer)opt.getColumnsType().get(opt.getExportAttrColumns().get(i))).intValue();
if (type==opt.TYPE_DATE)
sb.append( sdf.format((java.util.Date)obj) );
else if (type==opt.TYPE_DATE_TIME)
sb.append( sdatf.format((java.util.Date)obj) );
else if (type==opt.TYPE_TIME)
sb.append( stf.format((java.util.Date)obj) );
}
else {
sb.append( encodeText(obj.toString(),sep) );
}
}
if (i<opt.getExportColumns().size()-1)
sb.append(sep);
}
sb.append("\n");
if (opt.getCallbacks()!=null) {
if (tableType==0) {
processComponent(
sb,
exportOptions,
opt.getCallbacks().getComponentPerRowInHeader(
(ValueObject)vo,
rownum
)
);
}
else if (tableType==1) {
ComponentExportOptions compOpts = opt.getCallbacks().getComponentPerRow(
(ValueObject)vo,
rownum
);
if (compOpts!=null) {
processComponent(
sb,
exportOptions,
compOpts
);
}
}
else if (tableType==2) {
processComponent(
sb,
exportOptions,
opt.getCallbacks().getComponentPerRowInFooter(
(ValueObject)vo,
rownum
)
);
}
}
}
/**
* Fields that contain a special character ( comma, newline, or double quote ), must be enclosed in double quotes.
* However, if a line contains a single entry which is the empty string, it may be enclosed in double quotes.
* If a field's value contains a double quote character it is escaped by placing another double quote character next to it.
* The CSV file format does not require a specific character encoding, byte order, or line terminator format.
* @param text text to encode with rules defined above.
* @return encoded text
*/
private String encodeText(String text,String sep) {
if (text.indexOf("\"")!=-1) {
StringBuffer sb = new StringBuffer("");
for(int i=0;i<text.length();i++) {
sb.append(text.charAt(i));
if (text.charAt(i)=='\"')
sb.append("\"");
}
text = sb.toString();
}
if (text.indexOf(sep)!=-1 || text.indexOf("\n")!=-1 || text.indexOf("\"")!=-1)
text = "\""+text+"\"";
return text;
}
// public static void main(String[] argv) {
// ExportToCSV a = new ExportToCSV();
// System.out.println( a.endodeText("ac, abs, moon",",") );
// System.out.println( a.endodeText("aVenture \"Extended Edition\"",",") );
// System.out.println( a.endodeText("MUST SELL!\nair, moon roof, loaded",",") );
// }
}