/** You may copy this example and use it for any purpose, commercial or otherwise. */
import com.ricebridge.xmlman.XmlManager;
import com.ricebridge.xmlman.RecordSpec;
import com.ricebridge.xmlman.XmlManagerException;
import com.ricebridge.data.BeanSpec;
import java.util.HashMap;
import java.util.List;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.text.SimpleDateFormat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
/** This is the main class of this example. It loads the data in the
* company.xml file and creates a new HTML file called company.htm.
* This lists the employees and projects with cross-referenced links.
*
* You can specify a different file as the first command line argument,
* and if you use "stream" as the second, then the data is read in streaming mode.
*
* To compile and run this program, you will need to include xmlman.jar
* (in the lib folder of the XML Manager distribution) in your CLASSPATH.
*/
public class MakeTable {
/** This is our custom date format used in the XML data file. */
public static SimpleDateFormat sDateInputFormat = new SimpleDateFormat("yyyy-MM-dd");
/** This is the display format for dates. */
public static SimpleDateFormat sDateDisplayFormat = new SimpleDateFormat("dd/MMM/yyyy");
/** Run the program to create the HTML table of employees and projects.
* Usage: windows: java -cp .;..\..\..\lib\xmlman.jar MakeTable
* unix: java -cp .:../../../lib/xmlman.jar MakeTable reallybig.xml stream
*/
public static void main( String[] args ) {
String filepath = "company.xml"; // this is the default
boolean streaming = false;
if( 1 == args.length ) {
filepath = args[0];
}
if( 2 == args.length ) {
streaming = "stream".equals(args[1]);
}
try {
MakeTable mt = new MakeTable();
mt.make( new File(filepath), streaming );
}
catch( XmlManagerException xme ) {
System.out.println( xme.getUserMessage() );
}
catch( Exception e ) {
e.printStackTrace();
}
}
/** Make the HTML table from the XML file.
* @param pCompanyXmlFile XML file containing company data about employees and projects
* @param pStreaming if true then using StreamingMultipleBeansRecordListener
*/
public void make( File pCompanyXmlFile, boolean pStreaming ) throws Exception {
// This is the XmlManager object we'll be using.
XmlManager xmlman = new XmlManager();
// Create our own date converter for dates in the format YYYY-MM-DD.
DateConverter dc = new DateConverter( sDateInputFormat );
// This is the XPath to extract the project details.
RecordSpec rs_project
= new RecordSpec("/company/project",
new String[]{"'project'","@num","@name","deadline","employees"},
new String[]{"","Number","Name","Deadline","EmployeeNumbers"});
// The deadline field is in our custom dateformat.
HashMap project_stringconv = new HashMap();
project_stringconv.put( "Deadline", dc );
// Define a BeanSpec class describing the Project Java Bean.
BeanSpec bs_project = new BeanSpec( Project.class, project_stringconv );
// This is the XPath to extract the employee details.
RecordSpec rs_employee
= new RecordSpec("/company/employee",
new String[]{"'employee'","@num","@manager","name","hired","projects"},
new String[]{"","Number","Manager","Name","HireDate","ProjectNumbers"});
// The hiring date field is in our custom dateformat.
HashMap employee_stringconv = new HashMap();
employee_stringconv.put( "HireDate", dc );
// Define a BeanSpec class describing the Employee Java Bean.
BeanSpec bs_employee = new BeanSpec( Employee.class, employee_stringconv );
// Create a PrintWriter for the output file
FileOutputStream fos = new FileOutputStream( pCompanyXmlFile.getName().replaceFirst("\\.xml$",".htm") );
PrintWriter pw = new PrintWriter( fos );
// Decide which RecordListener to use.
MultipleBeansRecordListener mb = null;
if( pStreaming ) {
mb = new StreamingMultipleBeansRecordListener( pw );
}
else {
mb = new MultipleBeansRecordListener();
}
// Set the BeanSpecs.
mb.addBeanSpec( "project", bs_project, rs_project );
mb.addBeanSpec( "employee", bs_employee, rs_employee );
// And load the data.
xmlman.load( pCompanyXmlFile, new RecordSpec( rs_project, rs_employee ), mb );
// If we're not streaming, we still need to create the HTML table with the data we loaded.
if( !pStreaming ) {
List employees = mb.getBeans("employee");
List projects = mb.getBeans("project");
String htmltable = buildTable( projects, employees );
pw.print( htmltable );
}
pw.close();
fos.close();
}
/** Create the HTML table using a list of projects and employees.
* @param pProjects list of Project objects
* @param pEmployees list of Employee objects
*/
private String buildTable( List pProjects, List pEmployees ) throws Exception {
Collections.sort( pProjects, new Comparator() { public int compare(Object a, Object b){
return ((Project)a).getName().compareTo( ((Project)b).getName() );
}});
Collections.sort( pEmployees, new Comparator() { public int compare(Object a, Object b){
return ((Employee)a).getName().compareTo( ((Employee)b).getName() );
}});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter( baos );
outputStartProjectTable( pw );
for( Iterator pI = pProjects.iterator(); pI.hasNext(); ) {
outputProject( (Project) pI.next(), pEmployees, pw );
}
outputEndProjectTable( pw );
outputStartEmployeeTable( pw );
for( Iterator eI = pEmployees.iterator(); eI.hasNext(); ) {
outputEmployee( (Employee) eI.next(), pProjects, pw );
}
outputEndEmployeeTable( pw );
pw.close();
return baos.toString("UTF-8");
}
/** Output HTML tags for start of the project table. */
public static void outputStartProjectTable( PrintWriter pPrintWriter ) {
pPrintWriter.print("
| Project | Deadline | Employees |
\n");
}
/** Output HTML tags for end of the project table. */
public static void outputEndProjectTable( PrintWriter pPrintWriter ) {
pPrintWriter.print( "
\n" );
}
/** Output HTML tags for start of the employee table. */
public static void outputStartEmployeeTable( PrintWriter pPrintWriter ) {
pPrintWriter.print("
| Employee | Manager | Hired | Projects |
\n");
}
/** Output HTML tags for end of the employee table. */
public static void outputEndEmployeeTable( PrintWriter pPrintWriter ) {
pPrintWriter.print( "
\n" );
}
/** Output HTML tags for project details row.
* @param pProject project to output
* @param pEmployees for cross-referencing
* @param pPrintWriter PrintWriter for output
*/
public static void outputProject( Project pProject, List pEmployees, PrintWriter pPrintWriter ) {
Project p = pProject;
PrintWriter pw = pPrintWriter;
pw.print( "| "+p.getName()+" | \n" );
pw.print( ""+sDateDisplayFormat.format(p.getDeadline())+" | \n" );
pw.print( "" );
int[] emps = p.getEmployeeNumbers();
if( null == pEmployees ) {
for( int i = 0; i < emps.length; i++ ) {
pw.print( "Emp "+emps[i]+" " );
}
}
else {
for( Iterator eI = pEmployees.iterator(); eI.hasNext(); ) {
Employee e = (Employee) eI.next();
for( int i = 0; i < emps.length; i++ ) {
if( e.getNumber() == emps[i] ) {
pw.print( ""+e.getName()+" " );
break;
}
}
}
}
pw.print( " |
\n" );
}
/** Output HTML tags for employee details row.
* @param pEmployee employee to output
* @param pProjects for cross-referencing
* @param pPrintWriter PrintWriter for output
*/
public static void outputEmployee( Employee pEmployee, List pProjects, PrintWriter pPrintWriter ) {
Employee e = pEmployee;
PrintWriter pw = pPrintWriter;
pw.print( "| "+e.getName()+" | \n" );
pw.print( ""+(e.isManager()?"YES":"NO")+" | \n" );
pw.print( ""+sDateDisplayFormat.format(e.getHireDate())+" | \n" );
pw.print( "" );
int[] prjs = e.getProjectNumbers();
if( null == pProjects ) {
for( int i = 0; i < prjs.length; i++ ) {
pw.print( "Project "+prjs[i]+" " );
}
}
else {
for( Iterator pI = pProjects.iterator(); pI.hasNext(); ) {
Project p = (Project) pI.next();
for( int i = 0; i < prjs.length; i++ ) {
if( p.getNumber() == prjs[i] ) {
pw.print( ""+p.getName()+" " );
break;
}
}
}
}
pw.print( " |
\n" );
}
}