/*
* [ExportHolidaysToCSV.java]
*
* Summary: Export list of holidays in CSV format for use in other other calendar programs.
*
* Copyright: (c) 2008-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.8+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2011-02-16 initial version
*/
package com.mindprod.holidays;
import com.mindprod.common18.BigDate;
import com.mindprod.common18.EIO;
import com.mindprod.common18.Misc;
import com.mindprod.csv.CSVWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import static java.lang.System.*;
/**
* Export list of holidays in CSV format for use in other other calendar programs.
*
* We also export in HTML form to E:\mindprod\jgloss\include\holidays.javafrag
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2011-02-16 initial version
* @since 2011-02-16
*/
public final class ExportHolidaysToCSV
{
/**
* A delegate object that implements the HolInfo abstract class. That lets us execute code for a number of different
* holidays given only the name of the class that computes them. We dynamically load the HolInfo classes with
* Class.forName.
*/
private static ArrayList holidayDelegates;
/**
* export list of all holidays as html for this year
*
* @param desiredYear year we are interested in holidays
* @param verbose true if want long form with Authority/Rule included.
*
* @throws java.io.IOException if trouble writing file.
*/
private static void exportHolidays( final int desiredYear, final boolean verbose ) throws IOException
{
final PrintWriter pw = EIO.getPrintWriter( new File( "holidaysInYear" + desiredYear + ".csv" ), 32 * 1024, EIO.UTF8 );
final CSVWriter w = new CSVWriter( pw, 0 /* minimal quoting */, ',', '\"', '#', true /* trim */ );
w.nl( "holiday, when observed in " + desiredYear + ", first observed, first proclaimed" + ( verbose ? ", " +
"authority, rule" : "" ) );
for ( HolInfo h : holidayDelegates )
{
w.put( h.getName() );
w.put( new BigDate( h.when( desiredYear ) ).toString() );
w.put( h.getFirstYear( HolInfo.OBSERVED ) );
w.put( h.getFirstYear( HolInfo.PROCLAIMED ) );
if ( verbose )
{
// spills over multiple lines. Not all CSV readers could handle it.
w.put( h.getAuthority() );
w.put( h.getRule() );
}
w.nl();
}
out.println( w.getLineCount() + " holidays exported to holidaysInYear" + desiredYear + ".csv\nHolidays that " +
"don't occur in " + desiredYear + " are excluded." );
w.close();
}
/**
* get list of holidays from properties file: com.mindprod.holidays.Holiday.properties which lives in the jar. class
* names are case-sensitive. file looks like this:
Christmas=yes
GroundhogDay=no
...
where
* yes=include no=ignore
*
* @param desiredYear year we are interested in holidays
*/
private static void findHolidays( int desiredYear )
{
String[][] definedHolidayClassNames = null;
try
{
// look in jar, and on classpath for
// com.mindprod.holidays.Holiday.properties
final InputStream fis = ExportHolidaysToCSV.class.getResourceAsStream( "Holiday.properties" );
definedHolidayClassNames = Misc.loadProperties( fis );
// we now key=value pairs
}
catch ( IOException oops )
{
out.println( oops + " Problem accessing Holiday.properties file." );
System.exit( 1 );
}
// in pairs className=yes/no
int length = definedHolidayClassNames[ 0 ].length;
// keep all holidays in the holidayDelegate array, not just ones marked yes to get a maximal export.
holidayDelegates = new ArrayList<>( length );
for ( int i = 0; i < length; i++ )
{
try
{
final HolInfo h = ( HolInfo ) ( Class.forName( "com.mindprod.holidays." + definedHolidayClassNames[ 0
][ i ] ).newInstance() );
if ( h != null && h.when( desiredYear, false ) != BigDate.NULL_ORDINAL )
{
holidayDelegates.add( h );
}
}
catch ( Exception oops )
{
out.println( oops
+ " Bug in Holiday.properties or class file for "
+ definedHolidayClassNames[ 0 ][ i ] );
System.exit( 1 );
}
} // end for
}
/**
* Allow this Applet to run as as application as well.
*
* @param args command line year desired and optionally [verbose]
* to get extra authority and rule fields.
*
* @throws java.io.IOException if cannot load or export all the holidays.
*/
public static void main( String args[] ) throws IOException
{
int desiredYear = Misc.thisYear();
boolean verbose = false;
for ( String arg : args )
{
if ( arg.equals( "verbose" ) )
{
verbose = true;
}
else
{
desiredYear = Integer.parseInt( arg );
}
}
findHolidays( desiredYear );
Collections.sort( holidayDelegates,
new HolidaySort( desiredYear, false ) ); // sorted by when celebrated in desiredYear
exportHolidays( desiredYear, verbose );
} // end main
}