Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package Reports; import java.awt.geom.AffineTransform; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import static java.lang.System.exit; import java.util.ArrayList; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Scanner; import java.util.TreeMap; import javax.swing.JOptionPane; import org.apache.pdfbox.exceptions.COSVisitorException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import static org.apache.pdfbox.pdmodel.PDPage.PAGE_SIZE_A4; import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.util.Matrix; import Utilities.GlobalVar; import java.util.Set; import java.util.TreeSet; /** * * @author SPC Cui, * this class generates leave reports given the text files */ public class LeaveDataReader { // Status SSN Member Name Transaction // Description Cycle Seq# Input Source // Input Clerk Input Service Station Memo // Memo Text Post Date Update Number // Julian Date Error Code Error Description // Error Code 2 Error Code 3 Card Data private final int XLSX_STATUS_INDEX = 0; private final int XLSX_SSN_INDEX = 1; private final int XLSX_MEMBER_NAME_INDEX = 2; private final int XLSX_TRANS_INDEX = 3; private final int XLSX_DESCRIPTION_INDEX = 4; private final int XLSX_CYCLE_INDEX = 5; private final int XLSX_SEQ_NUM_INDEX = 6; private final int XLSX_INPUT_SOURCE_INDEX = 7; private final int XLSX_INPUT_CLERK_INDEX = 8; private final int XLSX_INPUT_SERVICE_STATION_INDEX = 9; private final int XLSX_MEMO_INDEX = 10; // 6 No Action Required; 7 Freedom private final int XLSX_MEMO_TEXT_INDEX = 11; private final int XLSX_POST_DT_INDEX = 12; private final int XLSX_UPDATE_NUM_INDEX = 13; private final int XLSX_JULIAN_DT_INDEX = 14; private final int XLSX_ERR_CODE1_INDEX = 15; private final int XLSX_ERR_CODE1_DESCRIPTION_INDEX = 16; private final int XLSX_ERR_CODE2_INDEX = 17; private final int XLSX_ERR_CODE3_INDEX = 18; private final int XLSX_CARD_DATA_INDEX = 19; private final int XLSX_CTRL_NUM_INDEX = 19; // share the same index private final int XLSX_START_DT_INDEX = 20; private final int XLSX_STOP_DT_INDEX = 21; private final int XLSX_LV_TYPE_INDEX = 22; private final int XLSX_LV_DAYS_INDEX = 23; private final String LEAVE_WHITE_SPACE = " "; //white space between columns public static final int ADD_MODIFIED_DAYS = 2; // add additional 2 days if date is modified public static final int SSN_LEN = 9; public static final int LEN_SEQ_NUM = 3; public static final int NAME_LENGTH = 5; public static final int FONT_SIZE = 10; public static final int BIG_FONT_SIZE = 32; public static final int MAX_CARD_DATA_CHAR_NUM = 55; public static final int ORIG_X = 0; //x coordinate of text origin public static final int ORIG_Y = 0; //x coordinate of text origin public static final int TRANS_X = 30; // Starting point public static final int TRANS_Y = 30; // Starting point public static final int FOOTNOTE_TRANS_X = 8 * 72; // page num point x coordinate 8 inch position public static final int FOOTNOTE_TRANS_Y = 330; // y coordinate, bottom middle of the page public static final int INVERVAL_X = 15; public static final int INTERVAL_Y = 15; // line space () public static final int BIG_FONT_UPDT_X = 1 * 72; // 2 inch from the top public static final int BIG_FONT_UPDT_Y = 1 * 72; // 2 inch from the left public static final int BIG_FONT_CYCLE_X = 1 * 72; // 2 inch from the top public static final int BIG_FONT_CYCLE_Y = 9 * 72; // 9 inch from the left public static final int MAX_NUM_TRANS_FIRST_PAGE = 15; public static final int MAX_NUM_TRANS = 35; public static final String MEMO_PARSE = " "; public static final int LEN_DESCRIPTION = 5; private static Map<String, Map<String, List<String>>> LEAVE_DATA; //private boolean IS_LANDSCAPE; private int PAGE_ROT_DEGREE; private double TEXT_ROT_RAD; //private static final String TITLE = "Stat SSN Name Trans Seq# IS PostDt Update ErrCode Card Data"; private static final String TITLE = "Status SSN Name Tran Desc Cycle Seq Src SvcSta PTDate Update LvCntr# LvStart LvStop LvType LvDays"; private Set<String> SOURCE_CONTAIN_LEAVE; public LeaveDataReader(String txtfileName, String PROCESS_YEAR, Boolean isLandScape) throws FileNotFoundException { LEAVE_DATA = new TreeMap<>(); SOURCE_CONTAIN_LEAVE = new TreeSet<>(); if (isLandScape) { PAGE_ROT_DEGREE = 90; TEXT_ROT_RAD = 3.14 / 2; } else { PAGE_ROT_DEGREE = 0; TEXT_ROT_RAD = 3.14 / 2; } // String outputFileName = "DTL.csv"; // String whiteSpace = " "; Scanner input = new Scanner(new File(txtfileName)); input.nextLine(); //Skip title // int count = 0; while (input.hasNextLine()) { String line = input.nextLine(); //line = line.replaceAll("\\s+", ","); line = line.replaceAll("\t", "@@"); line = line.replaceAll("\"", ""); // delimit in txt is "\t", remove all the " String[] info = line.split("@@"); if (info.length == XLSX_CARD_DATA_INDEX + 1) { // all data putAllDatainStorage(info, PROCESS_YEAR); } else if (info.length > XLSX_CARD_DATA_INDEX + 1) { //leave data, XLSX_LV_DAYS_INDEX + 1 putLeaveDatainStorage(info, PROCESS_YEAR); } } input.close(); } // work for raw data exported from dtl and all tabs private void putAllDatainStorage(String[] info, String PROCESS_YEAR) { String status = readStatus(info[XLSX_STATUS_INDEX]); String updateNum = readUpdateNum(info[XLSX_UPDATE_NUM_INDEX]); String trans = info[XLSX_TRANS_INDEX]; //SB03 if ((updateNum.contains("[WEB]") && status != null) && // ditch 10-10[OTH/Sys] and By Others (trans.substring(0, 2).equalsIgnoreCase("SB"))) { // if(updateNum.contains("[WEB]") && status != null){ // ditch 10-10[OTH/Sys] and By Others String ssn = fullSSNgenerator(info[XLSX_SSN_INDEX]); String name = readName(info[XLSX_MEMBER_NAME_INDEX]); String desc = descriptionGenerator(info[XLSX_DESCRIPTION_INDEX]); String seqNum = seqNumGenerator(info[XLSX_SEQ_NUM_INDEX]); String inputSource = info[XLSX_INPUT_SOURCE_INDEX]; String postDT = readPostDT(info[XLSX_POST_DT_INDEX]); String updateNumKey = updateNum.substring(0, 5); String errCode1 = errCodeGenerator(info[XLSX_ERR_CODE1_INDEX]); String errCode2 = errCodeGenerator(info[XLSX_ERR_CODE2_INDEX]); String errCode3 = errCodeGenerator(info[XLSX_ERR_CODE3_INDEX]); String errorCode = errCode1 + " " + errCode2 + " " + errCode3; String cardData = info[XLSX_CARD_DATA_INDEX]; //String cardData = readDataCard(info[XLSX_CARD_DATA_INDEX]); String lvCtrlNum = cardData.substring(GlobalVar.CTRL_NUM_START_INDEX, GlobalVar.CTRL_NUM_STOP_INDEX); String lvStartDate = cardData.substring(GlobalVar.SO_START_INDEX, GlobalVar.SO_STOP_INDEX); String lvStopDate = cardData.substring(GlobalVar.SI_START_INDEX, GlobalVar.SI_STOP_INDEX); String lvType = cardData.substring(GlobalVar.LV_TYPE_START_INDEX, GlobalVar.LV_TYPE_STOP_INDEX); String lvDays = cardData.substring(GlobalVar.LV_DAYS_START_INDEX, GlobalVar.LV_DAYS_STOP_INDEX); String ADSN = info[XLSX_INPUT_SERVICE_STATION_INDEX]; String cycle = info[XLSX_CYCLE_INDEX]; String memoText = info[XLSX_MEMO_INDEX] + MEMO_PARSE + info[XLSX_MEMO_TEXT_INDEX]; SOURCE_CONTAIN_LEAVE.add(inputSource); String outputLine = status + LEAVE_WHITE_SPACE + ssn + LEAVE_WHITE_SPACE + name + LEAVE_WHITE_SPACE + trans + LEAVE_WHITE_SPACE + desc + LEAVE_WHITE_SPACE + cycle + LEAVE_WHITE_SPACE + seqNum + LEAVE_WHITE_SPACE + inputSource + LEAVE_WHITE_SPACE + ADSN + LEAVE_WHITE_SPACE + postDT + LEAVE_WHITE_SPACE + updateNum + LEAVE_WHITE_SPACE + lvCtrlNum + LEAVE_WHITE_SPACE + lvStartDate + LEAVE_WHITE_SPACE + lvStopDate + LEAVE_WHITE_SPACE + lvType + LEAVE_WHITE_SPACE + lvDays; //System.out.println("line" + count + ": " + outputLine + "UpdateNum: " + updateNum + "Cycle: " + cycle); //updateNum = updateNum.substring(0,5); //09-16[WEB] become 09-16 if (LEAVE_DATA.containsKey(updateNumKey)) { Map<String, List<String>> thisDTdata = LEAVE_DATA.get(updateNumKey); if (thisDTdata.containsKey(inputSource)) { List<String> transactions = thisDTdata.get(inputSource); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any } else { List<String> transactions = new ArrayList<>(); setUpFirstPageTitle(transactions, postDT, updateNum, inputSource, PROCESS_YEAR, ADSN); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(inputSource, transactions); } } else if (!updateNum.equalsIgnoreCase("UpdateNumber")) { //skip the title line Map<String, List<String>> thisDTdata = new TreeMap<>(); List<String> transactions = new ArrayList<>(); setUpFirstPageTitle(transactions, postDT, updateNum, inputSource, PROCESS_YEAR, ADSN); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(inputSource, transactions); LEAVE_DATA.put(updateNumKey, thisDTdata); } } } // work for raw data exported from leave tab private void putLeaveDatainStorage(String[] info, String PROCESS_YEAR) { String status = readStatus(info[XLSX_STATUS_INDEX]); String updateNum = readUpdateNum(info[XLSX_UPDATE_NUM_INDEX]); String trans = info[XLSX_TRANS_INDEX]; //SB03 if ((updateNum.contains("[WEB]") && status != null) && // ditch 10-10[OTH/Sys] and By Others (trans.substring(0, 2).equalsIgnoreCase("SB"))) { // if(updateNum.contains("[WEB]") && status != null){ // ditch 10-10[OTH/Sys] and By Others String ssn = fullSSNgenerator(info[XLSX_SSN_INDEX]); String name = readName(info[XLSX_MEMBER_NAME_INDEX]); String desc = descriptionGenerator(info[XLSX_DESCRIPTION_INDEX]); String seqNum = seqNumGenerator(info[XLSX_SEQ_NUM_INDEX]); String inputSource = info[XLSX_INPUT_SOURCE_INDEX]; String postDT = readPostDT(info[XLSX_POST_DT_INDEX]); String updateNumKey = updateNum.substring(0, 5); String errCode1 = errCodeGenerator(info[XLSX_ERR_CODE1_INDEX]); String errCode2 = errCodeGenerator(info[XLSX_ERR_CODE2_INDEX]); String errCode3 = errCodeGenerator(info[XLSX_ERR_CODE3_INDEX]); String errorCode = errCode1 + " " + errCode2 + " " + errCode3; // String cardData = info[XLSX_CARD_DATA_INDEX]; //String cardData = readDataCard(info[XLSX_CARD_DATA_INDEX]); String lvCtrlNum = info[XLSX_CTRL_NUM_INDEX]; String lvStartDate = readDate(info, XLSX_START_DT_INDEX); String lvStopDate = readDate(info, XLSX_STOP_DT_INDEX); String lvType = readLvType(info, XLSX_LV_TYPE_INDEX); String lvDays = readLvDays(info, XLSX_LV_DAYS_INDEX); String ADSN = info[XLSX_INPUT_SERVICE_STATION_INDEX]; String cycle = info[XLSX_CYCLE_INDEX]; String memoText = info[XLSX_MEMO_INDEX] + MEMO_PARSE + info[XLSX_MEMO_TEXT_INDEX]; SOURCE_CONTAIN_LEAVE.add(inputSource); String outputLine = status + LEAVE_WHITE_SPACE + ssn + LEAVE_WHITE_SPACE + name + LEAVE_WHITE_SPACE + trans + LEAVE_WHITE_SPACE + desc + LEAVE_WHITE_SPACE + cycle + LEAVE_WHITE_SPACE + seqNum + LEAVE_WHITE_SPACE + inputSource + LEAVE_WHITE_SPACE + ADSN + LEAVE_WHITE_SPACE + postDT + LEAVE_WHITE_SPACE + updateNum + LEAVE_WHITE_SPACE + lvCtrlNum + LEAVE_WHITE_SPACE + lvStartDate + LEAVE_WHITE_SPACE + lvStopDate + LEAVE_WHITE_SPACE + lvType + LEAVE_WHITE_SPACE + lvDays; //System.out.println("line" + count + ": " + outputLine + "UpdateNum: " + updateNum + "Cycle: " + cycle); //updateNum = updateNum.substring(0,5); //09-16[WEB] become 09-16 if (LEAVE_DATA.containsKey(updateNumKey)) { Map<String, List<String>> thisDTdata = LEAVE_DATA.get(updateNumKey); if (thisDTdata.containsKey(inputSource)) { List<String> transactions = thisDTdata.get(inputSource); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any } else { List<String> transactions = new ArrayList<>(); setUpFirstPageTitle(transactions, postDT, updateNum, inputSource, PROCESS_YEAR, ADSN); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(inputSource, transactions); } } else if (!updateNum.equalsIgnoreCase("UpdateNumber")) { //skip the title line Map<String, List<String>> thisDTdata = new TreeMap<>(); List<String> transactions = new ArrayList<>(); setUpFirstPageTitle(transactions, postDT, updateNum, inputSource, PROCESS_YEAR, ADSN); transactions.add(outputLine); //addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(inputSource, transactions); LEAVE_DATA.put(updateNumKey, thisDTdata); } } } // return a set of input sources that need to generate pdf files // if the given list is empty, return all the sources that contain leave transactions public Set<String> modifiedListFinder(List<String> inputSources) { if (inputSources.isEmpty()) { return SOURCE_CONTAIN_LEAVE; // return every thing } else { Set<String> result = new TreeSet<>(); for (String inputSource : inputSources) { if (SOURCE_CONTAIN_LEAVE.contains(inputSource)) { result.add(inputSource); } } return result; } } // generate multiple pdf files public void multiPdfGenerator(String pdfFileNameBase, Set<String> inputSources) throws IOException, COSVisitorException { GlobalVar.dirMake(new File(pdfFileNameBase)); //create a folder with the same name int rowCount = 0; int pageCount = 1; System.out.println("passed in " + inputSources); PDPage page; //default size PAGE_SIZE_A4 PDPageContentStream stream; //page.setRotation(90); //counterclock wise rotate 90 degree ////left hand rule // stream.setFont(PDType1Font.COURIER, FONT_SIZE); String lastUpdate = null; String lastInputSource = null; System.out.println("LEAVE_DATA keyset:" + LEAVE_DATA.keySet()); // System.out.println("Cycles empty? " + cycles.isEmpty() + cycles.size()); // System.out.println(cycles); for (String updateDate : LEAVE_DATA.keySet()) { Map<String, List<String>> thisDTData = LEAVE_DATA.get(updateDate); lastUpdate = updateDate; System.out.println("thisDT_DATA keyset:" + thisDTData.keySet()); for (String inputSource : thisDTData.keySet()) { if (inputSources.isEmpty() || inputSources.contains(inputSource)) { PDDocument pdf = new PDDocument(); lastInputSource = inputSource; List<String> thisCycle = thisDTData.get(inputSource); pageCount = 1; // new cycle, restart page num page = new PDPage(); //page break stream = new PDPageContentStream(pdf, page, true, false); stream.beginText(); page.setRotation(PAGE_ROT_DEGREE); //stream.setFont(PDType1Font.COURIER, FONT_SIZE); addBigFontUpdateNumberAndCycle(updateDate, lastInputSource, stream); stream.setFont(PDType1Font.COURIER, FONT_SIZE); // stream.setFont(PDType1Font. int thisCycleRowCount = 0; for (String row : thisCycle) { if (thisCycleRowCount > MAX_NUM_TRANS) { //close the current page setupFootNote(stream, pageCount, lastInputSource, updateDate); pageCount++; stream.endText(); stream.close(); pdf.addPage(page); // start a new page page = new PDPage(); stream = new PDPageContentStream(pdf, page, true, false); page.setRotation(PAGE_ROT_DEGREE); stream.beginText(); stream.setFont(PDType1Font.COURIER, FONT_SIZE); thisCycleRowCount = 0; } stream.setTextRotation(TEXT_ROT_RAD, TRANS_X + thisCycleRowCount * INVERVAL_X, TRANS_Y); stream.drawString(row); thisCycleRowCount++; //System.out.println("Update:" + updateDate + " Cycle: " + cycle + " " + row); } setupFootNote(stream, pageCount, lastInputSource, lastUpdate); stream.endText(); stream.close(); pdf.addPage(page); String pdfFileName = pdfFileNameBase + "\\LEAVE UPDT " + updateDate + " " + lastInputSource + ".pdf"; pdf.save(pdfFileName); pdf.close(); } } } // pdf.save(pdfFileName); // pdf.close(); } // generate single pdf files public void singlePdfGenerator(String pdfFileNameBase, Set<String> inputSources) throws IOException, COSVisitorException { GlobalVar.dirMake(new File(pdfFileNameBase)); //create a folder with the same name int rowCount = 0; int pageCount = 1; System.out.println("passed in " + inputSources); PDDocument pdf = new PDDocument(); PDPage page; //default size PAGE_SIZE_A4 PDPageContentStream stream; //page.setRotation(90); //counterclock wise rotate 90 degree ////left hand rule // stream.setFont(PDType1Font.COURIER, FONT_SIZE); String lastUpdate = null; String lastInputSource = null; System.out.println("LEAVE_DATA keyset:" + LEAVE_DATA.keySet()); // System.out.println("Cycles empty? " + cycles.isEmpty() + cycles.size()); // System.out.println(cycles); String pdfFileName = pdfFileNameBase + "\\LEAVE UPDT"; for (String updateDate : LEAVE_DATA.keySet()) { Map<String, List<String>> thisDTData = LEAVE_DATA.get(updateDate); lastUpdate = updateDate; System.out.println("thisDT_DATA keyset:" + thisDTData.keySet()); pdfFileName = pdfFileName + " " + updateDate; for (String inputSource : thisDTData.keySet()) { if (inputSources.isEmpty() || inputSources.contains(inputSource)) { lastInputSource = inputSource; List<String> thisCycle = thisDTData.get(inputSource); pageCount = 1; // new cycle, restart page num page = new PDPage(); //page break stream = new PDPageContentStream(pdf, page, true, false); stream.beginText(); page.setRotation(PAGE_ROT_DEGREE); //stream.setFont(PDType1Font.COURIER, FONT_SIZE); addBigFontUpdateNumberAndCycle(updateDate, lastInputSource, stream); stream.setFont(PDType1Font.COURIER, FONT_SIZE); // stream.setFont(PDType1Font. int thisCycleRowCount = 0; for (String row : thisCycle) { if (thisCycleRowCount > MAX_NUM_TRANS) { //close the current page setupFootNote(stream, pageCount, lastInputSource, updateDate); pageCount++; stream.endText(); stream.close(); pdf.addPage(page); // start a new page page = new PDPage(); stream = new PDPageContentStream(pdf, page, true, false); page.setRotation(PAGE_ROT_DEGREE); stream.beginText(); stream.setFont(PDType1Font.COURIER, FONT_SIZE); thisCycleRowCount = 0; } stream.setTextRotation(TEXT_ROT_RAD, TRANS_X + thisCycleRowCount * INVERVAL_X, TRANS_Y); stream.drawString(row); thisCycleRowCount++; //System.out.println("Update:" + updateDate + " Cycle: " + cycle + " " + row); } setupFootNote(stream, pageCount, lastInputSource, lastUpdate); stream.endText(); stream.close(); pdf.addPage(page); } } } if (pdf.getNumberOfPages() > 0) { pdfFileName = pdfFileName + ".pdf"; pdf.save(pdfFileName); } pdf.close(); } // given the status, return the four letter long process status private String readStatus(String status) { if (status != null && status.length() > 4) { if (status.equalsIgnoreCase("Reject")) { return "Rej "; // four charaters } else if (status.equalsIgnoreCase("By Others")) { return null; } else { return status.substring(0, 4); } } else { return status; } } public String fullSSNgenerator(String ssn) { if (ssn != null) { while (ssn.length() < SSN_LEN) { ssn = "0" + ssn; } return ssn; } else { JOptionPane.showMessageDialog(null, "Invalid SSN! SSN is longer than 9 digits"); exit(1); return null; } } // take an integer, return LEN_SEQ_NUM character long string private String seqNumGenerator(String seqNum) { while (seqNum.length() < LEN_SEQ_NUM) { seqNum = "0" + seqNum; } return seqNum; } // take an integer, return LEN_SEQ_NUM character long string private String errCodeGenerator(String errCode) { while (errCode.length() < LEN_SEQ_NUM) { errCode = errCode + " "; } return errCode; } // get rid of 4830DAB0@0001 private String readDataCard(String data) { if (data != null && data.length() > MAX_CARD_DATA_CHAR_NUM) { // System.out.println(data.length()); // data = data.replaceAll(" +", ""); // String[] info = data.split(" "); // if (info != null && info.length > 1) String res = data.substring(0, MAX_CARD_DATA_CHAR_NUM); //System.out.println(res); return res; } else if (data != null) { return data; } else { return " "; } } private void addMemoText(List<String> transactions, String status, String memoText) { if (!status.equalsIgnoreCase("Proc")) { transactions.add(" ** " + memoText); //needs a memo text but which is missing } // if(!memoText.equals()) { // memo only contains parse // transactions.add(" ** " + memoText); // }else if(!status.equalsIgnoreCase("Proc")){ //not processed // transactions.add(" ** "); //needs a memo text but which is missing // } } private void setUpFirstPageTitle(List<String> transactions, String postDT, String updateDT, String cycle, String PROCESS_YEAR, String ADSN) { GregorianCalendar today = new GregorianCalendar(); if (PROCESS_YEAR != null) { //modified date is used processModifiedyDate(today, postDT, PROCESS_YEAR); } transactions.add("Date: " + today.getTime().toString()); transactions .add(" Information in this report is covered by the Privacy Act of 1974 "); transactions.add(" and must be protected from unauthorized access or use. "); transactions.add(" For Official Use Only. "); transactions.add(" "); transactions.add(" Leave Transactions Report"); //DTL transactions.add(" ADSN: " + ADSN); transactions.add(" Update Number: " + updateDT); transactions.add(" "); transactions.add(TITLE); } //return a modified date private void processModifiedyDate(GregorianCalendar today, String postDT, String PROCESS_YEAR) { String correctDate = postDT.trim(); //String[] dates = correctDate.split("-"); //09-16 int monthNum = Integer.parseInt(correctDate.substring(2, 4)) - 1; //zero based month // int dateNum = Integer.parseInt(dates[1]) + ADD_MODIFIED_DAYS; //print after two days int dateNum = Integer.parseInt(correctDate.substring(4, 6)) + ADD_MODIFIED_DAYS; //dateNum += (dateNum % 7 - ADD_MODIFIED_DAYS); //first week minus 1 day, second week add 0 days, third week add 1 day, ... int yearNum = Integer.parseInt(PROCESS_YEAR); Random r = new Random(); int minNum = r.nextInt(60); int secNum = r.nextInt(60); int hourNum = r.nextInt(3) + 9; // a random hour between 9 - 12 today.set(yearNum, monthNum, dateNum, hourNum, minNum, secNum); // yearnum must be 4 digits String[] date = today.getTime().toString().split(" "); if (date != null && date[0].equalsIgnoreCase("Sat")) { today.set(yearNum, monthNum, dateNum + 2, hourNum, minNum, secNum); } else if (date != null && date[0].equalsIgnoreCase("Sun")) { today.set(yearNum, monthNum, dateNum + 1, hourNum, minNum, secNum); } } private void setupFootNote(PDPageContentStream stream, int pageCount, String cycle, String updateDt) throws IOException { String pageNum = cycle + " - " + pageCount + " - " + updateDt; stream.setTextRotation(TEXT_ROT_RAD, FOOTNOTE_TRANS_X, FOOTNOTE_TRANS_Y); stream.drawString(pageNum); } private String readName(String name) { if (name != null) { while (name.length() < NAME_LENGTH) { name = name + " "; } return name; } return " "; } // take an description, return certain character long string if the description is too long private String descriptionGenerator(String desc) { desc = desc.trim(); if (desc.length() > LEN_DESCRIPTION) { return desc.substring(0, LEN_DESCRIPTION); } else { while (desc.length() < LEN_DESCRIPTION) { desc += " "; } } return desc; } private String readUpdateNum(String info) { if (info != null) { info = info.replaceAll(" ", ""); return info; } return " "; } // given the string[] line and the index, return line[index] if index is within the length of line // otherwise return " " private String readDate(String[] info, int dateIndex) { if (info != null && info.length > dateIndex) { String res = info[dateIndex]; while (res.length() < 6) { res += " "; } return res; } else { return " "; } } // given the string[] line and the index, return line[index] if index is within the length of line // otherwise return " " private String readLvType(String[] info, int typeIndex) { if (info != null && info.length > typeIndex) { String res = info[typeIndex]; if (res == null || res.length() == 0) { return " "; } else { return res; } } else { return " "; } } // given the string[] line and the index, return line[index] if index is within the length of line // otherwise return " " private String readLvDays(String[] info, int daysIndex) { if (info != null && info.length > daysIndex) { return info[daysIndex]; } else { return " "; } } private String readPostDT(String info) { if (info != null) { if (info.length() > 6) { return info.substring(2); } else { while (info.length() < 6) { info = info + " "; } return info; } } else { return " "; } } // add big font update number and cycle private void addBigFontUpdateNumberAndCycle(String updateDate, String cycle, PDPageContentStream stream) throws IOException { stream.setFont(PDType1Font.COURIER, BIG_FONT_SIZE); stream.setTextRotation(TEXT_ROT_RAD, BIG_FONT_UPDT_X, BIG_FONT_UPDT_Y); if (updateDate != null && updateDate.length() >= 5) { updateDate = updateDate.substring(0, 5); // choose the first 5 characters. 10-10 stream.drawString(updateDate); } stream.setTextRotation(TEXT_ROT_RAD, BIG_FONT_CYCLE_X, BIG_FONT_CYCLE_Y); stream.drawString(cycle); } }