package edu.harvard.wcfia.yoshikoder.reporting; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.table.AbstractTableModel; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import edu.harvard.wcfia.yoshikoder.document.DocumentList; import edu.harvard.wcfia.yoshikoder.document.YKDocument; /** * A report on a single document with respect to a particular dictionary * @author will * */ abstract public class AbstractReport extends AbstractTableModel implements YKReport { private static Logger log = Logger.getLogger("edu.harvard.wcfia.yoshikoder.reporting.AbstractReport"); protected String title; protected String description; protected Date date; protected String dictionaryName; protected DocumentList documentList; protected Object[][] data; public AbstractReport(String reportTitle, String desc, String dictName, DocumentList dl){ super(); title = reportTitle; date = new Date(); description = desc; dictionaryName = dictName; documentList = dl; //data = initData(obj); } abstract protected Object[][] initData(); // subclasses decide what they want to show // Partial TableModel implementation abstract public String getColumnName(int column); abstract public Class getColumnClass(int colIndex); public int getColumnCount() { return data[0].length; } public int getRowCount() { return data.length; } public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } // report metadata public Date getDate() { return date; } public String getDescription() { return description; } public DocumentList getDocuments() { return documentList; } public String getDictionaryName() { return dictionaryName; } public String getTitle() { return title; } public void saveAsHtml(File f) throws IOException { Properties props = new Properties(); InputStream str = AbstractReport.class.getClassLoader().getResourceAsStream("velocity.properties"); props.load(str); Writer out = null; try { Velocity.init(props); VelocityContext context = new VelocityContext(); context.put("title", getTitle()); if (dictionaryName != null) context.put("dictionaryName", dictionaryName); else context.put("dictionaryName", "None"); context.put("date", getDate()); context.put("description", getDescription()); context.put("documentList", getDocuments()); List columnHeadings = new ArrayList(); for (int i = 0; i < getColumnCount(); i++) columnHeadings.add(getColumnName(i)); context.put("columnHeadings", columnHeadings); context.put("rowCount", new Integer(getRowCount()-1)); context.put("colCount", new Integer(getColumnCount()-1)); context.put("tableModel", this); FileOutputStream fos = new FileOutputStream(f); out = new OutputStreamWriter(fos, "UTF-8"); // *export* in UTF-8 // assume that the templates are all *stored* in UTF-8 Velocity.mergeTemplate("templates/htmlreport.vm", "UTF-8", context, out); } catch (Exception mie){ log.log(Level.WARNING, "Could not fill template", mie); throw new IOException(mie.getMessage()); } finally { try { out.close(); } catch (Exception ex){ } } } protected void setExcelValue(HSSFRow row, int column, String value){ HSSFCell cell = row.createCell((short)column); cell.setEncoding(HSSFCell.ENCODING_UTF_16); cell.setCellValue(value); } public void saveAsExcel(File f) throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFRow row; HSSFCell cell; HSSFSheet sheet = wb.createSheet(getTitle()); row = sheet.createRow((short)0); setExcelValue(row, 0, "Title:"); setExcelValue(row, 1, getTitle()); row = sheet.createRow((short)1); setExcelValue(row, 0, "Description:"); setExcelValue(row, 1, getDescription()); row = sheet.createRow((short)2); setExcelValue(row, 0, "Date:"); setExcelValue(row, 1, getDate().toString()); row = sheet.createRow((short)3); setExcelValue(row, 0, "Dictionary:"); if (getDictionaryName() == null) setExcelValue(row, 1, "None"); else setExcelValue(row, 1, getDictionaryName()); row = sheet.createRow((short)4); setExcelValue(row, 0, "Documents:"); int ii=5; DocumentList dl = getDocuments(); for (Iterator iterator = dl.iterator(); iterator.hasNext();) { YKDocument d = (YKDocument) iterator.next(); row = sheet.createRow((short)ii); setExcelValue(row, 0, d.getTitle()); ii++; } ii++; // now the table model row = sheet.createRow((short)ii); for (int c=0; c<getColumnCount(); c++){ setExcelValue(row, c, getColumnName(c)); } ii++; for (int r=0; r<getRowCount(); r++){ row = sheet.createRow((short)(ii+r)); for (int c=0; c<getColumnCount(); c++){ cell = row.createCell((short)c); Object val = getValueAt(r,c); if (val == null) continue; else if (val instanceof Integer) cell.setCellValue(((Integer)val).intValue()); else if (val instanceof Double) cell.setCellValue(((Double)val).doubleValue()); else if (val instanceof String){ cell.setEncoding(HSSFCell.ENCODING_UTF_16); cell.setCellValue((String)val); } else { cell.setCellValue(val.toString()); } } } FileOutputStream fout = new FileOutputStream(f); wb.write(fout); fout.close(); } }