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; /** * * @author SPC Cui, * this class generates rejects given the text files */ public class RejectDataReader { // 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 String REJECT_WHITE_SPACE = " "; //white space better 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 = " "; private static Map<String, Map<String, List<String>>> REJECT_DATA; //private boolean IS_LANDSCAPE; private int PAGE_ROT_DEGREE; private double TEXT_ROT_RAD; //Status SSN Name Tran Desc Cycle Seq Source SvcSta PostDate Update private static final String TITLE = "Stat SSN Name Trans Seq# IS PostDt Update ErrCode Card Data"; public RejectDataReader(String txtfileName, String PROCESS_YEAR, Boolean isLandScape) throws FileNotFoundException { REJECT_DATA = new TreeMap<>(); 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) { String status = readStatus(info[XLSX_STATUS_INDEX]); String ssn = fullSSNgenerator(info[XLSX_SSN_INDEX]); String name = readName(info[XLSX_MEMBER_NAME_INDEX]); String trans = info[XLSX_TRANS_INDEX]; //SB03 String seqNum = seqNumGenerator(info[XLSX_SEQ_NUM_INDEX]); String inputSource = info[XLSX_INPUT_SOURCE_INDEX]; String postDT = readPostDT(info[XLSX_POST_DT_INDEX]); String updateNum = readUpdateNum(info[XLSX_UPDATE_NUM_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 = readDataCard(info[XLSX_CARD_DATA_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]; if ((updateNum.contains("[WEB]") && status != null) || // ditch 10-10[OTH/Sys] and By Others (updateNum.contains("[OTH/Sys]") && status != null && status.equalsIgnoreCase("Mgmt")) || trans.equalsIgnoreCase("C903")) { //for debt management String outputLine = status + REJECT_WHITE_SPACE + ssn + REJECT_WHITE_SPACE + name + REJECT_WHITE_SPACE + trans + REJECT_WHITE_SPACE + seqNum + REJECT_WHITE_SPACE + inputSource + REJECT_WHITE_SPACE + postDT + REJECT_WHITE_SPACE + updateNum + REJECT_WHITE_SPACE + errorCode + REJECT_WHITE_SPACE + cardData; //System.out.println("line" + count + ": " + outputLine + "UpdateNum: " + updateNum + "Cycle: " + cycle); //updateNum = updateNum.substring(0,5); //09-16[WEB] become 09-16 if (REJECT_DATA.containsKey(updateNumKey)) { Map<String, List<String>> thisDTdata = REJECT_DATA.get(updateNumKey); if (thisDTdata.containsKey(cycle)) { List<String> transactions = thisDTdata.get(cycle); transactions.add(outputLine); addMemoText(transactions, status, memoText); //add memo text if there is any } else { List<String> transactions = new ArrayList<>(); setUpFirstPageTitle(transactions, postDT, updateNum, cycle, PROCESS_YEAR, ADSN); transactions.add(outputLine); addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(cycle, 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, cycle, PROCESS_YEAR, ADSN); transactions.add(outputLine); addMemoText(transactions, status, memoText); //add memo text if there is any thisDTdata.put(cycle, transactions); REJECT_DATA.put(updateNumKey, thisDTdata); } } count++; } } input.close(); } public void PdfGenerator(String pdfFileNameBase, List<String> cycles) throws IOException, COSVisitorException { GlobalVar.dirMake(new File(pdfFileNameBase)); //create a folder with the same name int rowCount = 0; int pageCount = 1; 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 lastCycle = null; System.out.println("REJECT_DATA keyset:" + REJECT_DATA.keySet()); System.out.println("Cycles empty? " + cycles.isEmpty() + cycles.size()); System.out.println(cycles); for (String updateDate : REJECT_DATA.keySet()) { Map<String, List<String>> thisDTData = REJECT_DATA.get(updateDate); lastUpdate = updateDate; System.out.println("thisDT_DATA keyset:" + thisDTData.keySet()); for (String cycle : thisDTData.keySet()) { if (cycles.isEmpty() || cycles.contains(cycle)) { PDDocument pdf = new PDDocument(); lastCycle = cycle; List<String> thisCycle = thisDTData.get(cycle); 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, cycle, 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, cycle, 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, lastCycle, lastUpdate); stream.endText(); stream.close(); pdf.addPage(page); String pdfFileName = pdfFileNameBase + "\\REJECT UPDT " + updateDate + " " + cycle + ".pdf"; pdf.save(pdfFileName); pdf.close(); } } } // pdf.save(pdfFileName); // pdf.close(); } 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(" Rejects in DJMS update"); //DTL transactions.add(" ADSN: " + ADSN); transactions.add( " Update Number: " + updateDT + " Cycle: " + cycle); 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 " "; } private String readUpdateNum(String info) { if (info != null) { info = info.replaceAll(" ", ""); return info; } 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); } }