package se.idega.idegaweb.commune.block.importer.business; import java.io.ByteArrayInputStream; import java.rmi.RemoteException; import java.sql.Date; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.transaction.SystemException; import javax.transaction.UserTransaction; import se.idega.idegaweb.commune.business.CommuneUserBusiness; import se.idega.idegaweb.commune.childcare.data.ChildCareQueue; import se.idega.idegaweb.commune.childcare.data.ChildCareQueueHome; import se.idega.util.PIDChecker; import com.idega.block.importer.business.ImportFileHandler; import com.idega.block.importer.data.ImportFile; import com.idega.block.school.data.School; import com.idega.block.school.data.SchoolHome; import com.idega.business.IBOServiceBean; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileBMPBean; import com.idega.core.file.data.ICFileHome; import com.idega.user.data.Gender; import com.idega.user.data.GenderHome; import com.idega.user.data.Group; import com.idega.user.data.User; import com.idega.user.data.UserHome; import com.idega.util.DateFormatException; import com.idega.util.IWTimestamp; import com.idega.util.Timer; /** * <p>Title: NackaQueueImportFileHandlerBean</p> * <p>Description: Imports the child care queue into the database.</p> * This is an abstract class that contains all the code that the extending classes use. * The extending classes will set the queueType to define what type of queue it will import * <p>Copyright (c) 2003</p> * <p>Company: Idega Software</p> * @author Joakim Johnson</a> * @version 1.0 */ public abstract class NackaQueueImportFileHandlerBean extends IBOServiceBean implements NackaQueueImportFileHandler, ImportFileHandler { private ImportFile file; private UserTransaction transaction; private ArrayList queueValues; private ArrayList failedSchools; private ArrayList failedChildren; private ArrayList notFoundChildren; private ArrayList failedRecords; private int successCount, failCount, alreadyChoosenCount, count = 0; private final int COLUMN_CONTRACT_ID = 0; private final int COLUMN_CHILD_NAME = 1; private final int COLUMN_CHILD_PERSONAL_ID = 2; private final int COLUMN_PROVIDER_NAME = 3; private final int COLUMN_PRIORITY = 4; private final int COLUMN_CHOICE_NUMBER = 5; // private final int COLUMN_SCHOOL_AREA = 6; private final int COLUMN_QUEUE_DATE = 6; private final int COLUMN_START_DATE = 7; //ID for what type of file is imported. These are the values that will be set in the DB protected final int DBV_WITH_PLACE = 0; protected final int DBV_WITHOUT_PLACE = 1; protected final int FS_WITH_PLACE = 2; protected final int FS_WITHOUT_PLACE = 3; //Holds the value of one of the above constants, set by the extending classes protected int queueType; private StringBuffer report; public NackaQueueImportFileHandlerBean() { } public boolean handleRecords() { failedSchools = new ArrayList(); failedChildren = new ArrayList(); notFoundChildren = new ArrayList(); failedRecords = new ArrayList(); count = 0; failCount = 0; successCount = 0; alreadyChoosenCount = 0; report = new StringBuffer(); transaction = this.getSessionContext().getUserTransaction(); Timer clock = new Timer(); clock.start(); try { //if the transaction failes all the users and their relations are removed transaction.begin(); //iterate through the records and process them String item; while (!(item = (String) file.getNextRecord()).equals("")) { if (!processRecord(item)){ failedRecords.add(item); } else { if ((count % 200) == 0) { System.out.println( "NackaQueueHandler processing RECORD [" + count + "] time: " + IWTimestamp.getTimestampRightNow().toString()); } } item = null; } printFailedRecords(); transaction.commit(); clock.stop(); report.append( "\nNackaQueueHandler processed " + successCount + " records successfuly out of " + count + "records.\n"); report.append(alreadyChoosenCount+" of the selections had already been imported.\n"); report.append( "Time to handleRecords: " + clock.getTime() + " ms OR " + ((int) (clock.getTime() / 1000)) + " s\n"); System.out.println("\n**REPORT**\n\n" + report + "\n**END OF REPORT**\n\n"); //Creating the report file in the DB filesystem. System.out.println("Attempting to access the reports folder"); ICFile reportFolder = null; ICFileHome fileHome = (ICFileHome) getIDOHome(ICFile.class); try { reportFolder = fileHome.findByFileName("Reports"); System.out.println("Reports folder found"); } catch (FinderException e) { System.out.println("Reports folder not found, attempting to create folder"); try { ICFile root = fileHome.findByFileName(ICFileBMPBean.IC_ROOT_FOLDER_NAME); System.out.println("Rootfolder found"); reportFolder = fileHome.create(); reportFolder.setName("Reports"); reportFolder.setMimeType("application/vnd.iw-folder"); reportFolder.store(); root.addChild(reportFolder); System.out.println("Reports folder created"); } catch (FinderException e1) { System.out.println("Error creating Reports folder."); } } ICFile reportFile; try { reportFile = ((com.idega.core.file.data.ICFileHome)com.idega.data.IDOLookup.getHome(ICFile.class)).create(); byte[] bytes = report.toString().getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); reportFile.setFileValue(bais); reportFile.setMimeType("text/plain"); //Have to find the name of the importfile, and add that here. String filename = file.getFile().getName(); int i = filename.indexOf('_'); if(i>0) { filename = filename.substring(i+1); } i = filename.lastIndexOf('.'); if(i>0) { filename = filename.substring(0,i); } reportFile.setName(filename+".report"); reportFile.setFileSize(report.length()); reportFile.store(); if(reportFolder!=null) { reportFolder.addChild(reportFile); System.out.println("Report added to folder."); } } catch (SQLException ex) { ex.printStackTrace(); } // System.gc(); //success commit changes return true; } catch (Exception ex) { report.append( "\nThe parsing of the file caused and error. Please veryfy that the file has correct format."); ex.printStackTrace(); try { transaction.rollback(); } catch (SystemException e) { e.printStackTrace(); } System.out.println("\n**REPORT**\n\n" + report + "\n**END OF REPORT**\n\n"); return false; } } /** * Reads the next line in the file and stores the values * @param record * @return true if the record was parsed and stored OK, otherwise false * @throws RemoteException */ private boolean processRecord(String record) { queueValues = file.getValuesFromRecordString(record); // System.out.println("Nacka queue THE RECORD = " + record); boolean success = true; try { success = storeUserInfo(); if (success) { // System.out.println("Record processed OK"); successCount++; count++; } else { report.append("The problems above comes from the following line in the file:\n" + record + "\n"); // System.out.println("Record could not be stored, please update."); failCount++; count++; } } catch (headerException e) { // We don�t really care about the header. Just make sure that it isn�t counted. } catch (alreadyCreatedeException e) { alreadyChoosenCount++; } queueValues = null; return success; } /** * Prints out a list of all imorts that failed, all users that couldn�t be found, * and all schools that couldn�t be found in the db */ public void printFailedRecords() { if (!failedRecords.isEmpty()) { report.append("\nImport failed for these records, please fix and import again:\n"); Iterator iter = failedRecords.iterator(); while (iter.hasNext()) { report.append((String) iter.next() + "\n"); } } if (!failedSchools.isEmpty()) { report.append("\nSchools missing from database or have different names:\n"); Iterator schools = failedSchools.iterator(); while (schools.hasNext()) { String name = (String) schools.next(); report.append("'" + name + "'\n"); } } if (!failedChildren.isEmpty()) { report.append("\nChildren missing from database or have different names:\n"); Iterator chIterator = failedChildren.iterator(); while (chIterator.hasNext()) { String name = (String) chIterator.next(); report.append(name + "\n"); } } if (!notFoundChildren.isEmpty()) { report.append("\nChildren missing from database or have different names:\n"); Iterator chIterator = notFoundChildren.iterator(); while (chIterator.hasNext()) { String name = (String) chIterator.next(); report.append(name + "\n"); } } } /** * Stores the info in the current line into persistant bean * * @return True if successful otherwise false * @throws RemoteException */ protected boolean storeUserInfo() throws headerException, alreadyCreatedeException { //variables boolean success = true; try { int id = 0; try { id = getIntQueueProperty(this.COLUMN_CONTRACT_ID); } catch (NumberFormatException e) { report.append("Failed parsing id number\n"); if (count == 0) { report.append("This is probably the header and shouldn't be parsed\n"); throw new headerException(); } } String childName = getQueueProperty(this.COLUMN_CHILD_NAME); if (childName == null) { report.append("Failed parsing name for line " + id + "\n"); success = false; } String childPersonalID = getQueueProperty(this.COLUMN_CHILD_PERSONAL_ID); if (childPersonalID == null) { report.append("Failed parsing personal ID for " + childName + "\n"); success = false; } if (!PIDChecker.getInstance().isValid(childPersonalID, true)) { report.append("Invalid personal ID for " + childName + " ("+childPersonalID+")\n"); success = false; } childPersonalID = PIDChecker.getInstance().trim(childPersonalID); UserHome uHome = (UserHome) this.getIDOHome(User.class); User child = null; try { child = uHome.findByPersonalID(childPersonalID); } catch (FinderException e) { report.append("Could not find any child with personal id " + childPersonalID + " "); report.append("Child name is " + childName + " "); String providerTemp=null; providerTemp=getQueueProperty(this.COLUMN_PROVIDER_NAME); if (providerTemp !=null) report.append("Provider is " + providerTemp + "\n"); else { report.append("\n"); } //create a temporary user for the child //initialize business beans and data homes CommuneUserBusiness biz; biz = (CommuneUserBusiness) this.getServiceInstance(CommuneUserBusiness.class); String firstName = null, lastName = null; Gender gender; GenderHome genderHome = (GenderHome) getIDOHome(Gender.class); char genderChar = childPersonalID.charAt(childPersonalID.length()-2); String maleStr = "13579"; if(maleStr.indexOf(genderChar)>-1){ gender = genderHome.getMaleGender(); }else { gender = genderHome.getFemaleGender(); } Date date = PIDChecker.getInstance().getDateFromPersonalID(childPersonalID); if (date == null) { report.append("Date of birth is null for " + childName + " ("+childPersonalID+")\n"); return false; } IWTimestamp dateOfBirth = new IWTimestamp(date); int com = childName.indexOf(','); if(com > -1){ lastName = childName.substring(0,com); firstName = childName.substring(com+1); } child = biz.createSpecialCitizen(firstName, "", lastName, childPersonalID, gender, dateOfBirth); if (!notFoundChildren.contains(childName)) { notFoundChildren.add(childName); } // success = false; } String provider = getQueueProperty(this.COLUMN_PROVIDER_NAME); if (provider == null) { report.append("Failed parsing provider" + childName + "\n"); // System.out.println("Failed parsing provider for " + childName); success = false; } else{ provider = provider.trim(); } SchoolHome sHome = (SchoolHome) getIDOHome(School.class); School school = null; try { school = sHome.findBySchoolName(provider); } catch (FinderException e1) { report.append("Could not find any school with name '" + provider + "'\n"); if (!failedSchools.contains(provider)) { failedSchools.add(provider); } success = false; } String prio = getQueueProperty(this.COLUMN_PRIORITY); if (prio == null) { prio = ""; } int choiceNr = 0; try { choiceNr = getIntQueueProperty(this.COLUMN_CHOICE_NUMBER); } catch (NumberFormatException e) { //report.append("Failed parsing choice number\n"); //success = false; choiceNr = 1; } String qDate = getQueueProperty(this.COLUMN_QUEUE_DATE); if (qDate == null) { report.append("Failed parsing queue date for " + childName + "\n"); success = false; } IWTimestamp qDateT = new IWTimestamp(); qDateT.setDate(qDate); String sDate = getQueueProperty(this.COLUMN_START_DATE); if (sDate == null) { report.append("Failed parsing start date " + childName + "\n"); success = false; } IWTimestamp sDateT = new IWTimestamp(); sDateT.setDate(sDate); // queue if (success) { //Check to see if this line already has been added. ChildCareQueueHome home = (ChildCareQueueHome) getIDOHome(ChildCareQueue.class); try { //home.findQueueByChildChoiceNumberAndQueueType(((Integer)child.getPrimaryKey()).intValue(), choiceNr, queueType); home.findQueueByChildAndChoiceNumberAndProviderID(((Integer)child.getPrimaryKey()).intValue(), choiceNr, ((Integer) school.getPrimaryKey()).intValue()); // report.append("Child and choice already in database "+childName + "\n"); throw new alreadyCreatedeException(); } catch (FinderException e) { //Only add in instance if a child with this choice isn�t already created ChildCareQueue queueInstance = home.create(); queueInstance.setContractId(id); queueInstance.setChildId(((Integer)child.getPrimaryKey()).intValue()); queueInstance.setProviderName(provider); queueInstance.setProviderId(((Integer) school.getPrimaryKey()).intValue()); queueInstance.setPriority(prio); queueInstance.setChoiceNumber(choiceNr); queueInstance.setQueueDate(qDateT.getDate()); queueInstance.setStartDate(sDateT.getDate()); queueInstance.setImportedDate(new IWTimestamp(new java.util.Date().getTime()).getDate()); queueInstance.setQueueType(queueType); queueInstance.setExported(false); queueInstance.store(); queueInstance = null; } } } catch (RemoteException e) { report.append("There was an error while writing the data to the database\n"); e.printStackTrace(); success = false; } catch (FinderException e) { report.append("There was an error while writing the data to the database\n"); e.printStackTrace(); success = false; } catch (DateFormatException e) { report.append("There was an error while writing the data to the database\n"); e.printStackTrace(); success = false; } catch (CreateException e) { report.append("There was an error while writing the data to the database\n"); e.printStackTrace(); success = false; } return success; } private class alreadyCreatedeException extends Exception{ public alreadyCreatedeException(){ super(); } public alreadyCreatedeException(String s){ super(s); } } private class headerException extends Exception{ public headerException(){ super(); } public headerException(String s){ super(s); } } /** * Sets the file to be used for the import * @param file to be imported */ public void setImportFile(ImportFile file) { this.file = file; } /** * Rturns the value from getQueueProperty() parsed into an int * @param columnIndex column to be parsed * @return int value of the column. 0 is returned, if no value or unparsable value is found. */ private int getIntQueueProperty(int columnIndex) throws NumberFormatException { String sValue = getQueueProperty(columnIndex); return Integer.parseInt(sValue); } /** * Then file to be parsed is read line by line. This function returns the value of * the specified column * * @param columnIndex column to fetch value for (use the constants) * @return String value of the selected column */ private String getQueueProperty(int columnIndex) { String value = null; if (queueValues != null) { try { value = (String) queueValues.get(columnIndex); } catch (RuntimeException e) { return null; } //System.out.println("Index: "+columnIndex+" Value: "+value); if (file.getEmptyValueString().equals(value)) return null; else return value; } else return null; } /** * @see com.idega.block.importer.business.ImportFileHandler#getFailedRecords() */ public List getFailedRecords() { return failedRecords; } /** * @see com.idega.block.importer.business.ImportFileHandler#setRootGroup(com.idega.user.data.Group) */ public void setRootGroup(Group rootGroup) { } }