diff --git a/COPYING.LESSER b/COPYING.LESSER new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..352bb81 --- /dev/null +++ b/build.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + Builds, tests, and runs the project mdcsvimporter. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/built-jar.properties b/build/built-jar.properties new file mode 100644 index 0000000..eec1fea --- /dev/null +++ b/build/built-jar.properties @@ -0,0 +1,4 @@ +#Wed, 31 Dec 2014 13:31:57 -0500 + + +F\:\\data\\java\\mdcsvimporter\\trunk= diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide b/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide new file mode 100644 index 0000000..978e989 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide @@ -0,0 +1,52 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide b/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide new file mode 100644 index 0000000..4472a46 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide @@ -0,0 +1,155 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.DateReminderPair; +import com.moneydance.apps.md.model.Reminder; +import com.moneydance.apps.md.model.ReminderSet; +import com.moneydance.apps.md.model.RootAccount; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Iterator; +import java.util.Vector; + +/** + * + * @author stan + */ + + +public class OtherActionsDialog extends javax.swing.JDialog { + + ImportDialog parent = null; + Main main = null; + + /** + * Creates new form otherActionsDialog + */ + //public otherActionsDialog(java.awt.Frame parent, boolean modal) { + public OtherActionsDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + //super(parent, modal); + initComponents(); + } + + public void setMain( Main main ) + { + this.main = main; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + + setTitle("Other Actions"); + + jButton1.setText("Delete Overdue Reminders"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(31, 31, 31) + .addComponent(jButton1) + .addContainerGap(204, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(39, 39, 39) + .addComponent(jButton1) + .addContainerGap(238, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + //java.util.Calendar today = new java.util.Calendar( + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Calendar cal = Calendar.getInstance(); + System.out.println(dateFormat.format(cal.getTime())); + RootAccount rootAccount = main.getRootAccount(); + ReminderSet reminderSet = rootAccount.getReminderSet(); + Vector remindersOverdueVec = reminderSet.getOverdueItems( cal ); + + //get an Iterator object for Vector using iterator() method. + Iterator itr = remindersOverdueVec.iterator(); + + //use hasNext() and next() methods of Iterator to iterate through the elements + System.out.println("Iterating through Vector elements..."); + while(itr.hasNext()) + { + DateReminderPair rem = (DateReminderPair) itr.next(); + //reminderSet.removeReminder( rem ); + + System.out.println( "rem.desc =" + rem. + "=" ); + } + }//GEN-LAST:event_jButton1ActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* + * Set the Nimbus look and feel + */ + // + /* + * If Nimbus (introduced in Java SE 6) is not available, stay with the + * default look and feel. For details see + * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* + * Create and display the dialog + */ + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + OtherActionsDialog dialog = new OtherActionsDialog(null, true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + // End of variables declaration//GEN-END:variables +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE new file mode 100644 index 0000000..b709611 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class BbvaCompassBankReader + extends TransactionReader { + + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CHECKNUM = "check #"; + private static final String CREDIT = "credit (+)"; + private static final String DEBIT = "debit (-)"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String checknum; + private String debit; + private String credit; + private static final int headerRows = 5; + + @Override + public boolean canParse(CSVData data) { +// System.out.println("enter BbvaCompassBankReader.canParse"); + try { + data.parseIntoLines(0); + } catch (IOException ex) { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + for (int i = 0; i < headerRows -1; i++) { + data.nextLine(); + if (null == data) { + continue; + } + //this next statement raises an exception - don't use it + //System.out.println("BbvaReader:skip: " + data.printCurrentLine()); + } + + boolean retVal = data.nextLine() + && data.nextField() && DATE.equalsIgnoreCase(data.getField()) + && data.nextField() && DESCRIPTION.equalsIgnoreCase(data.getField()) + && data.nextField() && CHECKNUM.equalsIgnoreCase(data.getField()) + && data.nextField() && DEBIT.equalsIgnoreCase(data.getField()) + && data.nextField() && CREDIT.equalsIgnoreCase(data.getField()) + && !data.nextField(); + + // find guessable date formats + if (retVal) { + DateGuesser guesser = new DateGuesser(); + while (data.nextLine()) { + if (data.nextField()) { + guesser.checkDateString(data.getField()); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if (dateFormatString == null + || !find(compatibleDateFormats, dateFormatString)) { + setDateFormat(guesser.getBestFormat()); + } + } + System.out.println("BbvaCompassBankReader.dateFormat = " + getDateFormat()); + System.out.println("BbvaCompassBankReader.canParse = " + String.valueOf(retVal)); + return retVal; + } + + @Override + public String getFormatName() { + return "BBVA Compass Bank NA"; + } + + @Override + protected boolean parseNext() throws IOException { + System.out.println("enter BbvaCompassBankReader parseNext"); + csvData.nextField(); + dateString = csvData.getField(); + if (dateString == null || dateString.length() == 0) { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + checknum = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + if (credit == null && debit == null) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are null."); + throwException("Invalid line"); + } + + if (credit.length() == 0 && debit.length() == 0) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are empty."); + throwException("Credit and debit fields are both empty."); + } + System.out.println("exit BbvaCompassBankReader parseNext"); + return true; + } + + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + System.out.println("enter BbvaCompassBankReader assignDataToTxn"); + long amount = 0; + try { + double amountDouble; + if (credit.length() > 0) { + System.out.println("credit = " + String.valueOf(credit)); + amountDouble = StringUtils.parseDoubleWithException(credit, '.'); + } else { + System.out.println("credit.length() <= 0"); + amountDouble = -StringUtils.parseDoubleWithException(debit, '.'); + } + System.out.println("amountDouble = " + String.valueOf(amountDouble)); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + + int date = dateFormat.parseInt(dateString); + + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setMemo(description); + txn.setCheckNum(checknum); + // MOVED to TransactionReader so everyone creates it the same way. + //txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + //for temp testing. TODO: remove next line after testing. 2011.11.25 ds + txn.setRefNum(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + System.out.println("exit BbvaCompassBankReader assignDataToTxn"); + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() { + return dateFormatString; + } + + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + if (!format.equals(dateFormatString)) { + dateFormat = new CustomDateFormat(format); + dateFormatString = format; + } + } + + private static boolean find(String[] compatibleDateFormats, String dateFormatString) { + if (dateFormatString == null) { + return false; + } + + for (String s : compatibleDateFormats) { + if (dateFormatString.equals(dateFormatString)) { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() { + return headerRows; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE new file mode 100644 index 0000000..4223077 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE @@ -0,0 +1,159 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class CitiBankCanadaReader + extends TransactionReader +{ + private static final String TRANSACTION_DATE = "transaction date"; + private static final String POSTING_DATE = "posting date"; + private static final String DESCRIPTION = "description"; + private static final String AMOUNT = "amount"; + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String description; +// private long amount; +// private int transactionDate; + private String transactionDateString; +// private int postingDate; + private String postingDateString; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && TRANSACTION_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && POSTING_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && AMOUNT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "CitiBank Canada"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + transactionDateString = csvData.getField(); + if ( transactionDateString.equalsIgnoreCase( "Date downloaded:" ) ) + { // skip the footer line + return false; + } + + csvData.nextField(); + postingDateString = csvData.getField(); + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + amountString = csvData.getField(); + if ( amountString == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int transactionDate = dateFormat.parseInt( transactionDateString ); + int postingDate = dateFormat.parseInt( postingDateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( postingDate + ":" + amountString + ":" + description ); + txn.setDatePostedInt( postingDate ); + txn.setDateInitiatedInt( transactionDate ); + txn.setDateAvailableInt( postingDate ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE new file mode 100644 index 0000000..61dea62 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE @@ -0,0 +1,198 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class INGNetherlandsReader + extends TransactionReader +{ + private static final String DATUM = "datum"; + private static final String NAAM_OMSCHRIJVING = "naam / omschrijving"; + private static final String REKENING = "rekening"; + private static final String TEGENREKENING = "tegenrekening"; + private static final String CODE = "code"; + private static final String AF_BIJ = "af bij"; + private static final String BEDRAG_EUR = "bedrag (eur)"; + private static final String MUTATIESORT = "mutatiesoort"; + private static final String MEDEDELINGEN = "mededelingen"; + private static final String DATE_FORMAT = "D-M-YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String mededelingen; + private String code; + private String datum; + private String bedrag; + private String naam; + private String rekening; + private String tegenrekening; + private String mutatiesort; + private String af_bij; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && DATUM.equals( data.getField().toLowerCase() ) && + data.nextField() && NAAM_OMSCHRIJVING.equals( data.getField().toLowerCase() ) && + data.nextField() && REKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && TEGENREKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && CODE.equals( data.getField().toLowerCase() ) && + data.nextField() && AF_BIJ.equals( data.getField().toLowerCase() ) && + data.nextField() && BEDRAG_EUR.equals( data.getField().toLowerCase() ) && + data.nextField() && MUTATIESORT.equals( data.getField().toLowerCase() ) && + data.nextField() && MEDEDELINGEN.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "ING The Netherlands"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + datum = csvData.getField(); + + csvData.nextField(); + naam = csvData.getField(); + + csvData.nextField(); + rekening = csvData.getField(); + + csvData.nextField(); + tegenrekening = csvData.getField(); + + csvData.nextField(); + code = csvData.getField(); + + csvData.nextField(); + af_bij = csvData.getField(); + + csvData.nextField(); + bedrag = csvData.getField(); + + csvData.nextField(); + mutatiesort = csvData.getField(); + + csvData.nextField(); + mededelingen = csvData.getField(); + if ( mededelingen == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( bedrag, ',' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + if ( af_bij.equalsIgnoreCase( "af" ) ) + { + amount = -amount; + } + else if ( af_bij.equalsIgnoreCase( "bij" ) ) + { + } + else + { + throwException( "Value of Af/Bij field must be 'Af' or 'Bij'." ); + } + + int date = dateFormat.parseInt( datum ); + + Integer hashCode = naam.hashCode() ^ rekening.hashCode() ^ + tegenrekening.hashCode() ^ code.hashCode() ^ af_bij.hashCode() ^ + mutatiesort.hashCode() ^ mededelingen.hashCode(); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( mededelingen ); + txn.setFITxnId( datum + ":" + bedrag + ":" + hashCode.toString() ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + txn.setPayeeName( naam ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE new file mode 100644 index 0000000..9bef54d --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class SimpleCreditDebitReader + extends TransactionReader +{ + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CREDIT = "credit"; + private static final String DEBIT = "debit"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String debit; + private String credit; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = data.nextLine() && + data.nextField() && DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && CREDIT.equals( data.getField().toLowerCase() ) && + data.nextField() && DEBIT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + + // find guessable date formats + if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + while ( data.nextLine() ) + { + if ( data.nextField() ) + { + guesser.checkDateString( data.getField() ); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if ( dateFormatString == null || + !find( compatibleDateFormats, dateFormatString ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Simple Date/Description/Credit/Debit"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + if ( credit == null && debit == null ) + { + throwException( "Invalid line." ); + } + + if ( credit.length() == 0 && debit.length() == 0 ) + { + throwException( "Credit and debit fields are both empty." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + if ( credit.length() > 0 ) + { + amountDouble = StringUtils.parseDoubleWithException( credit, '.' ); + } + else + { + amountDouble = -StringUtils.parseDoubleWithException( debit, '.' ); + } + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int date = dateFormat.parseInt( dateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + @Override + public String[] getSupportedDateFormats() + { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() + { + return dateFormatString; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + if ( !format.equals( dateFormatString ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatString = format; + } + } + + private static boolean find( String[] compatibleDateFormats, String dateFormatString ) + { + if ( dateFormatString == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( dateFormatString.equals( dateFormatString ) ) + { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE new file mode 100644 index 0000000..1304899 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE @@ -0,0 +1,191 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class WellsFargoReader + extends TransactionReader +{ + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT + }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String dateString; + private String description; +// private long amount; + private int date; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = true; + + while ( retVal && data.nextLine() ) + { + if ( !data.nextField() ) + { + continue; // skip empty lines + } + String dateTest = data.getField(); + if ( !dateTest.equals( dateFormat.format( dateFormat.parseInt( data.getField() ) ) ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() ) + { + retVal = false; + break; + } + try + { + StringUtils.parseDoubleWithException( data.getField(), '.' ); + } + catch ( Exception x ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.getField().equals( "*" ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.nextField() || data.nextField() ) + { + retVal = false; + break; + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Wells Fargo"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // skip empty lines + return false; + } + + csvData.nextField(); + amountString = csvData.getField(); + + csvData.nextField(); // skip '*' + + csvData.nextField(); // skip unknown number + + csvData.nextField(); + description = csvData.getField(); + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + date = dateFormat.parseInt( dateString ); + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 0; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE new file mode 100644 index 0000000..8fccf92 --- /dev/null +++ b/build/classes/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE @@ -0,0 +1,276 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + + */ +public class YodleeReader + extends TransactionReader { + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + private String dateFormatStringSelected = DATE_FORMAT_INTN; + private static String[] SUPPORTED_DATE_FORMATS = { + DATE_FORMAT_US, DATE_FORMAT_EU, DATE_FORMAT_JP, DATE_FORMAT_INTN + }; + private CustomDateFormat dateFormat = new CustomDateFormat(DATE_FORMAT_INTN); + private String dateFormatString; + private String status; + private String description; + private String splitType; + private String category; + private String currencyString; + private String amountString; + private long amount; + private String userDescription; + private String memo; + private String classification; + private int date; + private static final String STATUS = "status"; + private static final String DATE = "date"; + private static final String DESCRIPTION = "original description"; + private static final String SPLIT = "split type"; + private static final String CATEGORY = "category"; + private static final String CURRENCY = "currency"; + private static final String AMOUNT = "amount"; + private static final String USER_DESCRIPTION = "user description"; + private static final String MEMO = "memo"; + private static final String CLASSIFICATION = "classification"; + private static final String ACCOUNT = "account name"; + + @Override + public boolean canParse(CSVData data) { + try { + data.parseIntoLines(0); + } catch (IOException ex) { + return false; + } + + boolean retVal = data.nextLine() + && data.nextField() && STATUS.equals(data.getField().toLowerCase()) + && data.nextField() && DATE.equals(data.getField().toLowerCase()) + && data.nextField() && DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && SPLIT.equals(data.getField().toLowerCase()) + && data.nextField() && CATEGORY.equals(data.getField().toLowerCase()) + && data.nextField() && CURRENCY.equals(data.getField().toLowerCase()) + && data.nextField() && AMOUNT.equals(data.getField().toLowerCase()) + && data.nextField() && USER_DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && MEMO.equals(data.getField().toLowerCase()) + && data.nextField() && CLASSIFICATION.equals(data.getField().toLowerCase()) + && data.nextField() && ACCOUNT.equals(data.getField().toLowerCase()) + && !data.nextField(); + + System.out.println( "can parse Yodlee format =" + String.valueOf(retVal) + "=" ); + return retVal; + } + + @Override + public String getFormatName() { + return "Yodlee"; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + * + */ + @Override + protected boolean parseNext() throws IOException { + + csvData.nextField(); + status = csvData.getField(); +// System.out.println("status: " + status); + +// System.out.println("getting Yodlee dateString..."); + csvData.nextField(); + String dateString = csvData.getField(); + if (dateString == null || dateString.isEmpty()) { + // skip lines without valid dates (or empty) + return false; + } +// System.out.println("dateString: " + dateString); + + csvData.nextField(); + description = csvData.getField(); +// System.out.println("description: " + description); + + csvData.nextField(); + splitType = csvData.getField(); +// System.out.println("splitType: " + splitType); + + csvData.nextField(); + category = csvData.getField();//NOTE: don't set in Txn object! +// System.out.println("category: " + category); + + csvData.nextField(); + currencyString = csvData.getField();//NOTE: not used +// System.out.println("currencyString: " + currencyString); + + csvData.nextField(); + amountString = csvData.getField().trim(); +// System.out.println("amountString: " + amountString); + + csvData.nextField(); + userDescription = csvData.getField(); +// System.out.println("userDescription: " + userDescription); + + csvData.nextField(); + memo = csvData.getField(); +// System.out.println("memo: " + memo); + + csvData.nextField(); + classification = csvData.getField(); +// System.out.println("classification: " + classification); + + csvData.nextField(); + this.accountNameFromCSV = csvData.getField(); +// System.out.println("accountNameFromCSV: " + accountNameFromCSV); + +// System.out.println( "parsing Yodlee amount..."); +// amount = 0; +// try { +// double amountDouble; +// amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); +// System.out.println( "after parseDoubleWithException..."); +// amount = currency.getLongValue(amountDouble); +// } catch (Exception x) { +// throwException("Invalid amount."); +// } +// System.out.println( "parsing Yodlee date..."); + date = dateFormat.parseInt(dateString); + +// System.out.println( "parsed Yodlee txn on " + dateString + " for " + accountNameFromCSV); + return true; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + x Category + x Currency + * Amount + * User Description + * Memo + x Classification (Tag) + ^ Account Name + * + */ + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + amount = 0; + try { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); + System.out.println( "after parseDoubleWithException..."); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + txn.setMemo(memo); + txn.setRefNum(status + ":" + splitType + ":" + userDescription); + //TODO: classification (e.g., business or personal) + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats(String dateFormatArg) { + System.err.println("\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------"); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat(dateFormatArg); + } + + @Override + public String getDateFormat() { + return DATE_FORMAT_INTN; + } + +// @Override +// public void setDateFormat(String format) { +// if (!DATE_FORMAT.equals(format)) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// } + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + System.err.println("setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "="); + if (!format.equals(dateFormatStringSelected)) { + dateFormat = new CustomDateFormat(format); + dateFormatStringSelected = format; + } + + } + + @Override + protected int getHeaderCount() { + return 1; + } +} diff --git a/build/classes/com/moneydance/modules/features/mdcsvimporter/import.png b/build/classes/com/moneydance/modules/features/mdcsvimporter/import.png new file mode 100644 index 0000000..9614140 Binary files /dev/null and b/build/classes/com/moneydance/modules/features/mdcsvimporter/import.png differ diff --git a/dist/.svn/all-wcprops b/dist/.svn/all-wcprops new file mode 100644 index 0000000..76b3825 --- /dev/null +++ b/dist/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 27 +/svn/!svn/ver/14/trunk/dist +END diff --git a/dist/.svn/dir-prop-base b/dist/.svn/dir-prop-base new file mode 100644 index 0000000..1f596b0 --- /dev/null +++ b/dist/.svn/dir-prop-base @@ -0,0 +1,6 @@ +K 10 +svn:ignore +V 2 +* + +END diff --git a/dist/.svn/entries b/dist/.svn/entries new file mode 100644 index 0000000..472eede --- /dev/null +++ b/dist/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/dist +https://mdcsvimporter.googlecode.com/svn + + + +2009-03-25T18:17:54.009906Z +14 +Jovanovic.Milutin +has-props + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + diff --git a/dist/README.TXT b/dist/README.TXT new file mode 100644 index 0000000..78fa06e --- /dev/null +++ b/dist/README.TXT @@ -0,0 +1,32 @@ +======================== +BUILD OUTPUT DESCRIPTION +======================== + +When you build an Java application project that has a main class, the IDE +automatically copies all of the JAR +files on the projects classpath to your projects dist/lib folder. The IDE +also adds each of the JAR files to the Class-Path element in the application +JAR files manifest file (MANIFEST.MF). + +To run the project from the command line, go to the dist folder and +type the following: + +java -jar "mdcsvimporter.mxt" + +To distribute this project, zip up the dist folder (including the lib folder) +and distribute the ZIP file. + +Notes: + +* If two JAR files on the project classpath have the same name, only the first +JAR file is copied to the lib folder. +* Only JAR files are copied to the lib folder. +If the classpath contains other types of files or folders, these files (folders) +are not copied. +* If a library on the projects classpath also has a Class-Path element +specified in the manifest,the content of the Class-Path element has to be on +the projects runtime path. +* To set a main class in a standard Java project, right-click the project node +in the Projects window and choose Properties. Then click Run and enter the +class name in the Main Class field. Alternatively, you can manually type the +class name in the manifest Main-Class element. diff --git a/dist/mdcsvimporter.mxt b/dist/mdcsvimporter.mxt new file mode 100644 index 0000000..94a6695 Binary files /dev/null and b/dist/mdcsvimporter.mxt differ diff --git a/dist/mdcsvimporter.zip b/dist/mdcsvimporter.zip new file mode 100644 index 0000000..71eee4d Binary files /dev/null and b/dist/mdcsvimporter.zip differ diff --git a/externals/.svn/all-wcprops b/externals/.svn/all-wcprops new file mode 100644 index 0000000..9bafb2b --- /dev/null +++ b/externals/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 32 +/svn/!svn/ver/43/trunk/externals +END diff --git a/externals/.svn/entries b/externals/.svn/entries new file mode 100644 index 0000000..aa4070c --- /dev/null +++ b/externals/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/externals +https://mdcsvimporter.googlecode.com/svn + + + +2011-04-01T01:45:51.642278Z +43 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +junit +dir + +moneydance +dir + +swing-layout +dir + diff --git a/externals/junit/.svn/all-wcprops b/externals/junit/.svn/all-wcprops new file mode 100644 index 0000000..f309d15 --- /dev/null +++ b/externals/junit/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 37 +/svn/!svn/ver/5/trunk/externals/junit +END +junit-4.5.jar +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/5/trunk/externals/junit/junit-4.5.jar +END diff --git a/externals/junit/.svn/entries b/externals/junit/.svn/entries new file mode 100644 index 0000000..ccddf26 --- /dev/null +++ b/externals/junit/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/externals/junit +https://mdcsvimporter.googlecode.com/svn + + + +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +junit-4.5.jar +file + + + + +2011-10-03T21:48:26.000000Z +896973b9728a697494024163343c8112 +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +198945 + diff --git a/externals/junit/.svn/prop-base/junit-4.5.jar.svn-base b/externals/junit/.svn/prop-base/junit-4.5.jar.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/junit/.svn/prop-base/junit-4.5.jar.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/junit/.svn/text-base/junit-4.5.jar.svn-base b/externals/junit/.svn/text-base/junit-4.5.jar.svn-base new file mode 100644 index 0000000..7339216 Binary files /dev/null and b/externals/junit/.svn/text-base/junit-4.5.jar.svn-base differ diff --git a/externals/moneydance/.svn/all-wcprops b/externals/moneydance/.svn/all-wcprops new file mode 100644 index 0000000..d65a427 --- /dev/null +++ b/externals/moneydance/.svn/all-wcprops @@ -0,0 +1,17 @@ +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/!svn/ver/43/trunk/externals/moneydance +END +moneydance.jar +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/43/trunk/externals/moneydance/moneydance.jar +END +extadmin.jar +K 25 +svn:wc:ra_dav:version-url +V 55 +/svn/!svn/ver/2/trunk/externals/moneydance/extadmin.jar +END diff --git a/externals/moneydance/.svn/entries b/externals/moneydance/.svn/entries new file mode 100644 index 0000000..a9bc7c0 --- /dev/null +++ b/externals/moneydance/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/externals/moneydance +https://mdcsvimporter.googlecode.com/svn + + + +2011-04-01T01:45:51.642278Z +43 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +extadmin.jar +file + + + + +2011-10-03T21:48:08.000000Z +b957b9f85776c8b948925f080d4e4c81 +2009-03-10T03:04:35.851035Z +2 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +52835 + +moneydance.jar +file + + + + +2011-10-03T21:48:24.000000Z +759bd47451023d598acc855879bbd47b +2011-04-01T01:45:51.642278Z +43 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +5733367 + diff --git a/externals/moneydance/.svn/prop-base/extadmin.jar.svn-base b/externals/moneydance/.svn/prop-base/extadmin.jar.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/moneydance/.svn/prop-base/extadmin.jar.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/moneydance/.svn/prop-base/moneydance.jar.svn-base b/externals/moneydance/.svn/prop-base/moneydance.jar.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/moneydance/.svn/prop-base/moneydance.jar.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/moneydance/.svn/text-base/extadmin.jar.svn-base b/externals/moneydance/.svn/text-base/extadmin.jar.svn-base new file mode 100644 index 0000000..97df34e Binary files /dev/null and b/externals/moneydance/.svn/text-base/extadmin.jar.svn-base differ diff --git a/externals/moneydance/.svn/text-base/moneydance.jar.svn-base b/externals/moneydance/.svn/text-base/moneydance.jar.svn-base new file mode 100644 index 0000000..8b764bb Binary files /dev/null and b/externals/moneydance/.svn/text-base/moneydance.jar.svn-base differ diff --git a/externals/swing-layout/.svn/all-wcprops b/externals/swing-layout/.svn/all-wcprops new file mode 100644 index 0000000..d40f8b7 --- /dev/null +++ b/externals/swing-layout/.svn/all-wcprops @@ -0,0 +1,23 @@ +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/!svn/ver/2/trunk/externals/swing-layout +END +swing-layout-1.0.3.jar +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/2/trunk/externals/swing-layout/swing-layout-1.0.3.jar +END +swing-layout-1.0.3-doc.zip +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/2/trunk/externals/swing-layout/swing-layout-1.0.3-doc.zip +END +swing-layout-1.0.3-src.zip +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/2/trunk/externals/swing-layout/swing-layout-1.0.3-src.zip +END diff --git a/externals/swing-layout/.svn/entries b/externals/swing-layout/.svn/entries new file mode 100644 index 0000000..9b760e6 --- /dev/null +++ b/externals/swing-layout/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/externals/swing-layout +https://mdcsvimporter.googlecode.com/svn + + + +2009-03-10T03:04:35.851035Z +2 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +swing-layout-1.0.3-doc.zip +file + + + + +2011-10-03T21:48:25.000000Z +7a7b1f5e226d5ecf623a3620a0988b93 +2009-03-10T03:04:35.851035Z +2 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +77870 + +swing-layout-1.0.3-src.zip +file + + + + +2011-10-03T21:48:25.000000Z +0c93097262ac611d6ba2860cf0f9095f +2009-03-10T03:04:35.851035Z +2 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +49664 + +swing-layout-1.0.3.jar +file + + + + +2011-10-03T21:48:25.000000Z +118cab355d46b1d19228a1642ef55cad +2009-03-10T03:04:35.851035Z +2 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +118103 + diff --git a/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-doc.zip.svn-base b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-doc.zip.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-doc.zip.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-src.zip.svn-base b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-src.zip.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3-src.zip.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3.jar.svn-base b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3.jar.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/externals/swing-layout/.svn/prop-base/swing-layout-1.0.3.jar.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-doc.zip.svn-base b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-doc.zip.svn-base new file mode 100644 index 0000000..6fc35dd Binary files /dev/null and b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-doc.zip.svn-base differ diff --git a/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-src.zip.svn-base b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-src.zip.svn-base new file mode 100644 index 0000000..f5828ef Binary files /dev/null and b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3-src.zip.svn-base differ diff --git a/externals/swing-layout/.svn/text-base/swing-layout-1.0.3.jar.svn-base b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3.jar.svn-base new file mode 100644 index 0000000..6e1b43b Binary files /dev/null and b/externals/swing-layout/.svn/text-base/swing-layout-1.0.3.jar.svn-base differ diff --git a/externals/swing-layout/swing-layout-1.0.3-doc.zip b/externals/swing-layout/swing-layout-1.0.3-doc.zip new file mode 100644 index 0000000..6fc35dd Binary files /dev/null and b/externals/swing-layout/swing-layout-1.0.3-doc.zip differ diff --git a/externals/swing-layout/swing-layout-1.0.3-src.zip b/externals/swing-layout/swing-layout-1.0.3-src.zip new file mode 100644 index 0000000..f5828ef Binary files /dev/null and b/externals/swing-layout/swing-layout-1.0.3-src.zip differ diff --git a/nbproject/.svn/all-wcprops b/nbproject/.svn/all-wcprops new file mode 100644 index 0000000..b25e9ff --- /dev/null +++ b/nbproject/.svn/all-wcprops @@ -0,0 +1,29 @@ +K 25 +svn:wc:ra_dav:version-url +V 32 +/svn/!svn/ver/46/trunk/nbproject +END +project.xml +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/!svn/ver/5/trunk/nbproject/project.xml +END +project.properties +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/!svn/ver/64/trunk/nbproject/project.properties +END +build-impl.xml +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/!svn/ver/84/trunk/nbproject/build-impl.xml +END +genfiles.properties +K 25 +svn:wc:ra_dav:version-url +V 52 +/svn/!svn/ver/84/trunk/nbproject/genfiles.properties +END diff --git a/nbproject/.svn/dir-prop-base b/nbproject/.svn/dir-prop-base new file mode 100644 index 0000000..a7ce626 --- /dev/null +++ b/nbproject/.svn/dir-prop-base @@ -0,0 +1,6 @@ +K 10 +svn:ignore +V 8 +private + +END diff --git a/nbproject/.svn/entries b/nbproject/.svn/entries new file mode 100644 index 0000000..4032bd5 --- /dev/null +++ b/nbproject/.svn/entries @@ -0,0 +1,164 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/nbproject +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com +has-props + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +build-impl.xml +file +84 + + + +2013-06-08T14:39:05.929000Z +7b5f6f9ecc9e532091eb67d1f2b7fb50 +2013-06-18T04:37:07.822407Z +84 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +78919 + +genfiles.properties +file +84 + + + +2013-06-08T14:39:05.929000Z +c131202e05103ea2b927ca1edae837e1 +2013-06-18T04:37:07.822407Z +84 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +465 + +project.properties +file +64 + + + +2011-10-30T07:54:33.000000Z +3f587527af26a5af185e9892a1c76dbd +2011-10-14T04:28:47.589030Z +64 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +2916 + +project.xml +file + + + + +2011-10-03T21:48:26.000000Z +d9811e0cd1d43d92419a2630b36b240a +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin + + + + + + + + + + + + + + + + + + + + + +567 + diff --git a/nbproject/.svn/text-base/build-impl.xml.netbeans-base b/nbproject/.svn/text-base/build-impl.xml.netbeans-base new file mode 100644 index 0000000..e087235 --- /dev/null +++ b/nbproject/.svn/text-base/build-impl.xml.netbeans-base @@ -0,0 +1,1042 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/.svn/text-base/build-impl.xml.svn-base b/nbproject/.svn/text-base/build-impl.xml.svn-base new file mode 100644 index 0000000..e143a97 --- /dev/null +++ b/nbproject/.svn/text-base/build-impl.xml.svn-base @@ -0,0 +1,1411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/.svn/text-base/genfiles.properties.netbeans-base b/nbproject/.svn/text-base/genfiles.properties.netbeans-base new file mode 100644 index 0000000..599ef09 --- /dev/null +++ b/nbproject/.svn/text-base/genfiles.properties.netbeans-base @@ -0,0 +1,8 @@ +build.xml.data.CRC32=f4bff2ce +build.xml.script.CRC32=1ba685f9 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=0568f036 +nbproject/build-impl.xml.script.CRC32=1f43c2e4 +nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 diff --git a/nbproject/.svn/text-base/genfiles.properties.svn-base b/nbproject/.svn/text-base/genfiles.properties.svn-base new file mode 100644 index 0000000..599ef09 --- /dev/null +++ b/nbproject/.svn/text-base/genfiles.properties.svn-base @@ -0,0 +1,8 @@ +build.xml.data.CRC32=f4bff2ce +build.xml.script.CRC32=1ba685f9 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=0568f036 +nbproject/build-impl.xml.script.CRC32=1f43c2e4 +nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 diff --git a/nbproject/.svn/text-base/project.properties.netbeans-base b/nbproject/.svn/text-base/project.properties.netbeans-base new file mode 100644 index 0000000..2c8da6e --- /dev/null +++ b/nbproject/.svn/text-base/project.properties.netbeans-base @@ -0,0 +1,85 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +application.title=mdcsvimporter +application.vendor=Milutin Jovanovi\u0107 +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/mdcsvimporter.mxt +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.junit-4.5.jar=./externals/junit/junit-4.5.jar +file.reference.moneydance.jar=externals/moneydance/moneydance.jar +file.reference.swing-layout-1.0.3.jar=./externals/swing-layout/swing-layout-1.0.3.jar +includes=** +jar.compress=true +javac.classpath=\ + ${file.reference.moneydance.jar}:\ + ${file.reference.swing-layout-1.0.3.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${file.reference.junit-4.5.jar} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.codebase.type=local +jnlp.codebase.url="file:${dist.dir}" +jnlp.descriptor=application +jnlp.enabled=false +jnlp.offline-allowed=false +jnlp.signed=false +main.class=Moneydance +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + /Applications/Moneydance.app/Contents/Resources/Java/appsrc.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jcommon-1.0.12.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jfreechart-1.0.9.jar +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test +project.license=LGPL diff --git a/nbproject/.svn/text-base/project.properties.svn-base b/nbproject/.svn/text-base/project.properties.svn-base new file mode 100644 index 0000000..2c8da6e --- /dev/null +++ b/nbproject/.svn/text-base/project.properties.svn-base @@ -0,0 +1,85 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +application.title=mdcsvimporter +application.vendor=Milutin Jovanovi\u0107 +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/mdcsvimporter.mxt +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.junit-4.5.jar=./externals/junit/junit-4.5.jar +file.reference.moneydance.jar=externals/moneydance/moneydance.jar +file.reference.swing-layout-1.0.3.jar=./externals/swing-layout/swing-layout-1.0.3.jar +includes=** +jar.compress=true +javac.classpath=\ + ${file.reference.moneydance.jar}:\ + ${file.reference.swing-layout-1.0.3.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${file.reference.junit-4.5.jar} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.codebase.type=local +jnlp.codebase.url="file:${dist.dir}" +jnlp.descriptor=application +jnlp.enabled=false +jnlp.offline-allowed=false +jnlp.signed=false +main.class=Moneydance +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + /Applications/Moneydance.app/Contents/Resources/Java/appsrc.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jcommon-1.0.12.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jfreechart-1.0.9.jar +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test +project.license=LGPL diff --git a/nbproject/.svn/text-base/project.xml.svn-base b/nbproject/.svn/text-base/project.xml.svn-base new file mode 100644 index 0000000..e0d422f --- /dev/null +++ b/nbproject/.svn/text-base/project.xml.svn-base @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + mdcsvImporter + 1.6.5 + + + + + + + + + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..e731ed3 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..b6592b9 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=f4bff2ce +build.xml.script.CRC32=1ba685f9 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=0568f036 +nbproject/build-impl.xml.script.CRC32=73482bfd +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48 diff --git a/nbproject/private/config.properties b/nbproject/private/config.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..d84b473 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,6 @@ +compile.on.save=false +do.depend=false +do.jar=true +javac.debug=true +javadoc.preview=true +user.properties.file=C:\\Users\\stan\\AppData\\Roaming\\NetBeans\\8.0\\build.properties diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..efe4b3e --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,23 @@ + + + + + + + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/CSVReader.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderData.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/CSVData.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/RegexReader.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/CustomReader.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/Main.java + file:/F:/data/java/mdcsvimporter/trunk/test/com/moneydance/modules/features/mdcsvimporter/DateGuesserTest.java + file:/F:/data/java/mdcsvimporter/trunk/nbproject/project.properties + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/TransactionReader.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomTableCellRenderer.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java + file:/F:/data/java/mdcsvimporter/trunk/src/com/moneydance/modules/features/mdcsvimporter/Settings.java + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..8dfdcbc --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,97 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +application.title=mdcsvimporter +application.vendor=Stan Towianski, Milutin Jovanovi\u0107 +auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/mdcsvimporter.mxt +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.junit-4.5.jar=./externals/junit/junit-4.5.jar +file.reference.moneydance.jar=externals/moneydance/moneydance.jar +file.reference.swing-layout-1.0.3.jar=./externals/swing-layout/swing-layout-1.0.3.jar +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=true +jar.index=${jnlp.enabled} +javac.classpath=\ + ${file.reference.moneydance.jar}:\ + ${file.reference.swing-layout-1.0.3.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${file.reference.junit-4.5.jar} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.codebase.type=local +jnlp.codebase.url="file:${dist.dir}" +jnlp.descriptor=application +jnlp.enabled=false +jnlp.mixed.code=default +jnlp.offline-allowed=false +jnlp.signed=false +jnlp.signing= +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=Moneydance +# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed +manifest.custom.codebase= +# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions) +manifest.custom.permissions= +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + /Applications/Moneydance.app/Contents/Resources/Java/appsrc.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jcommon-1.0.12.jar:\ + /Applications/Moneydance.app/Contents/Resources/Java/jfreechart-1.0.9.jar +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test +project.license=LGPL diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..e0d422f --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + mdcsvImporter + 1.6.5 + + + + + + + + + diff --git a/private.key b/private.key new file mode 100644 index 0000000..4e86809 --- /dev/null +++ b/private.key @@ -0,0 +1,13 @@ +{ + "encrypted_x" = { + "ciphertext" = "BA1057A76803CB10CA2BF1F10F0036B2B94C9FD9D1FE999974347951CF4428046DB51B66BFE40AD1FB5D9D2FA1345F9C1D08B34AE46FEEB0" + "passwdhashalg" = "sha" + "alg" = "des" +} + + "g" = "174068207532402095185811980123523436538604490794561350978495831040599953488455823147851597408940950725307797094915759492368300574252438761037084473467180148876118103083043754985190983472601550494691329488083395492313850000361646482644608492304078721818959999056496097769368017749273708962006689187956744210730" + "q" = "864205495604807476120572616017955259175325408501" + "p" = "178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239" + "keytype" = "private" + "alg" = "dsa" +} diff --git a/public.key b/public.key new file mode 100644 index 0000000..41b4886 --- /dev/null +++ b/public.key @@ -0,0 +1,8 @@ +{ + "g" = "174068207532402095185811980123523436538604490794561350978495831040599953488455823147851597408940950725307797094915759492368300574252438761037084473467180148876118103083043754985190983472601550494691329488083395492313850000361646482644608492304078721818959999056496097769368017749273708962006689187956744210730" + "q" = "864205495604807476120572616017955259175325408501" + "p" = "178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239" + "y" = "59383850963019286727319937679818692587632144326689118561354203205652800109082126343339385902080405955315255500161226489300676264747000138820228843247855045950515085009834155724029097092074335381892661396130589786874160338352656342304224258682258645813752354325772041086313867140026516038552550980080529504085" + "keytype" = "public" + "alg" = "dsa" +} diff --git a/src/.svn/all-wcprops b/src/.svn/all-wcprops new file mode 100644 index 0000000..04625d3 --- /dev/null +++ b/src/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 26 +/svn/!svn/ver/46/trunk/src +END diff --git a/src/.svn/entries b/src/.svn/entries new file mode 100644 index 0000000..12b52e9 --- /dev/null +++ b/src/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +com +dir + diff --git a/src/com/.svn/all-wcprops b/src/com/.svn/all-wcprops new file mode 100644 index 0000000..56fa8a5 --- /dev/null +++ b/src/com/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 30 +/svn/!svn/ver/46/trunk/src/com +END diff --git a/src/com/.svn/entries b/src/com/.svn/entries new file mode 100644 index 0000000..e5b5bb3 --- /dev/null +++ b/src/com/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +moneydance +dir + diff --git a/src/com/moneydance/.svn/all-wcprops b/src/com/moneydance/.svn/all-wcprops new file mode 100644 index 0000000..c48a087 --- /dev/null +++ b/src/com/moneydance/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 41 +/svn/!svn/ver/46/trunk/src/com/moneydance +END diff --git a/src/com/moneydance/.svn/entries b/src/com/moneydance/.svn/entries new file mode 100644 index 0000000..d862238 --- /dev/null +++ b/src/com/moneydance/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com/moneydance +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +modules +dir + diff --git a/src/com/moneydance/modules/.svn/all-wcprops b/src/com/moneydance/modules/.svn/all-wcprops new file mode 100644 index 0000000..97740af --- /dev/null +++ b/src/com/moneydance/modules/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/!svn/ver/46/trunk/src/com/moneydance/modules +END diff --git a/src/com/moneydance/modules/.svn/entries b/src/com/moneydance/modules/.svn/entries new file mode 100644 index 0000000..4c2a82d --- /dev/null +++ b/src/com/moneydance/modules/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com/moneydance/modules +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +features +dir + diff --git a/src/com/moneydance/modules/features/.svn/all-wcprops b/src/com/moneydance/modules/features/.svn/all-wcprops new file mode 100644 index 0000000..6de04d0 --- /dev/null +++ b/src/com/moneydance/modules/features/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 58 +/svn/!svn/ver/46/trunk/src/com/moneydance/modules/features +END diff --git a/src/com/moneydance/modules/features/.svn/entries b/src/com/moneydance/modules/features/.svn/entries new file mode 100644 index 0000000..5a1c68c --- /dev/null +++ b/src/com/moneydance/modules/features/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com/moneydance/modules/features +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +mdcsvimporter +dir + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops b/src/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops new file mode 100644 index 0000000..12f610e --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops @@ -0,0 +1,131 @@ +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/46/trunk/src/com/moneydance/modules/features/mdcsvimporter +END +CSVData.java +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/CSVData.java +END +import.png +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/5/trunk/src/com/moneydance/modules/features/mdcsvimporter/import.png +END +DataField.java +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/!svn/ver/64/trunk/src/com/moneydance/modules/features/mdcsvimporter/DataField.java +END +PreviewImportWin.java +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.java +END +ImportDialog.java +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java +END +PreviewImportWin.form +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/!svn/ver/92/trunk/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.form +END +ImportDialog.form +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.form +END +RegexReader.java +K 25 +svn:wc:ra_dav:version-url +V 89 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/RegexReader.java +END +CSVReader.java +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/CSVReader.java +END +Settings.java +K 25 +svn:wc:ra_dav:version-url +V 86 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/Settings.java +END +CustomTableCellRenderer.java +K 25 +svn:wc:ra_dav:version-url +V 101 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomTableCellRenderer.java +END +TransactionReader.java +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/TransactionReader.java +END +CustomReaderData.java +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderData.java +END +OtherActionsDialog.form-hide +K 25 +svn:wc:ra_dav:version-url +V 101 +/svn/!svn/ver/92/trunk/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide +END +CustomReaderDialog.java +K 25 +svn:wc:ra_dav:version-url +V 96 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.java +END +OtherActionsDialog.java-hide +K 25 +svn:wc:ra_dav:version-url +V 101 +/svn/!svn/ver/92/trunk/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide +END +CustomReaderDialog.form +K 25 +svn:wc:ra_dav:version-url +V 96 +/svn/!svn/ver/93/trunk/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.form +END +Main.java +K 25 +svn:wc:ra_dav:version-url +V 82 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/Main.java +END +PreviewImportTblModel.java +K 25 +svn:wc:ra_dav:version-url +V 99 +/svn/!svn/ver/92/trunk/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportTblModel.java +END +DateGuesser.java +K 25 +svn:wc:ra_dav:version-url +V 89 +/svn/!svn/ver/69/trunk/src/com/moneydance/modules/features/mdcsvimporter/DateGuesser.java +END +SecureFileDeleter.java +K 25 +svn:wc:ra_dav:version-url +V 95 +/svn/!svn/ver/20/trunk/src/com/moneydance/modules/features/mdcsvimporter/SecureFileDeleter.java +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/entries b/src/com/moneydance/modules/features/mdcsvimporter/.svn/entries new file mode 100644 index 0000000..af131b2 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/entries @@ -0,0 +1,745 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com/moneydance/modules/features/mdcsvimporter +https://mdcsvimporter.googlecode.com/svn + + + +2011-06-23T18:06:21.588227Z +46 +jovanovic.milutin@gmail.com + + + + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +CSVData.java +file +97 + + + +2014-12-31T17:09:42.007000Z +6696e532c5b9200ec74fe3d54d11f5ff +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +7878 + +CSVReader.java +file +97 + + + +2014-12-28T05:10:24.427000Z +8ea8f01a0e92288e49149416a1ba10d5 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +9235 + +CustomReaderData.java +file +93 + + + +2014-11-23T08:07:09.761000Z +5278bc645cc05162b3bb9651750992a3 +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com +has-props + + + + + + + + + + + + + + + + + + + + +5273 + +CustomReaderDialog.form +file +93 + + + +2014-11-23T08:09:43.233000Z +69dbd53bbbc74edb64d9d5021e6b971d +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com +has-props + + + + + + + + + + + + + + + + + + + + +77544 + +CustomReaderDialog.java +file +97 + + + +2014-12-29T23:19:38.276000Z +69f86871d7c450494a462b17e1c06ead +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com +has-props + + + + + + + + + + + + + + + + + + + + +85904 + +CustomTableCellRenderer.java +file +93 + + + +2014-11-23T05:59:23.106000Z +c83b66414ecbf3bf25f3cc49e3a7c0b8 +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +1261 + +DataField.java +file +64 + + + +2011-08-08T16:33:51.000000Z +b7c277e37f276d05661290c57a5b0654 +2011-10-14T04:28:47.589030Z +64 +stashu.pub@gmail.com +has-props + + + + + + + + + + + + + + + + + + + + +271 + +DateGuesser.java +file +69 + + + +2011-11-03T03:44:40.000000Z +2627288da6b17d578c1004a468c214d3 +2011-11-03T03:58:32.452334Z +69 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +11131 + +ImportDialog.form +file +93 + + + +2014-11-23T08:03:31.311000Z +eeb411df588bbb2ef269fb0a55d70191 +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +28629 + +ImportDialog.java +file +97 + + + +2014-12-29T23:13:31.274000Z +526726ccede3758d6fb2cb8da8e9bfd3 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +66561 + +Main.java +file +97 + + + +2014-12-31T18:26:34.921000Z +cd261260fbf39db687fac7fde2579568 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + + + + + + + + +7085 + +OtherActionsDialog.form-hide +file +92 + + + +2013-01-30T01:44:15.508000Z +55941305ba9b86193d6241410a6db3e7 +2014-08-02T19:50:28.591090Z +92 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +2503 + +OtherActionsDialog.java-hide +file +92 + + + +2013-01-30T03:28:26.137000Z +d3f4c0c84713dea9b46ddfee6d649254 +2014-08-02T19:50:28.591090Z +92 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +5981 + +PreviewImportTblModel.java +file +92 + + + +2014-08-02T15:26:21.566000Z +340f85d87ed6010ea5f04e8f7ecf1995 +2014-08-02T19:50:28.591090Z +92 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +1493 + +PreviewImportWin.form +file +92 + + + +2014-07-26T22:46:18.158000Z +bb58146971fec3415a0579aaf51f2193 +2014-08-02T19:50:28.591090Z +92 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +3303 + +PreviewImportWin.java +file +93 + + + +2014-11-23T05:55:45.896000Z +e9413762f8471c5774a5302aee99cf95 +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +10248 + +RegexReader.java +file +97 + + + +2014-12-31T18:31:51.189000Z +eeb3ecc9c9a88f965e0e41281d129732 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +10654 + +SecureFileDeleter.java +file + + + + +2011-10-03T21:48:27.000000Z +3b944740e259ae8988b02b8f754e6bc1 +2009-08-16T13:55:28.656639Z +20 +Jovanovic.Milutin + + + + + + + + + + + + + + + + + + + + + +3085 + +Settings.java +file +93 + + + +2014-11-22T23:33:59.164000Z +ef14fbea37c8691e9cd163c27552cd13 +2014-11-23T08:24:03.010354Z +93 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +20775 + +TransactionReader.java +file +97 + + + +2014-12-29T23:16:27.107000Z +a86a75d3422f5667d2e5f58ce6ba369c +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +37471 + +formats +dir + +import.png +file + + + + +2011-10-03T21:48:27.000000Z +c3c45ea1f0eaf05d2deed637c4255e65 +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin +has-props + + + + + + + + + + + + + + + + + + + + +3072 + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderData.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderData.java.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderData.java.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.form.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.form.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.form.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.java.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/CustomReaderDialog.java.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/DataField.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/DataField.java.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/DataField.java.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/import.png.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/import.png.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/prop-base/import.png.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.netbeans-base new file mode 100644 index 0000000..28df405 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.netbeans-base @@ -0,0 +1,256 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + +/** + * + * @author miki and Stan Towianski + */ +public class CSVData +{ + private String[][] data; + private int currentLineIndex = -1; + private int currentFieldIndex = -1; + + public CSVReader reader; + + public CSVData( CSVReader readerArg ) + { + this.reader = readerArg; + } + + public void reset() + { + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public String[][] getData() + { + return data; + } + + public void parseIntoLines( CustomReaderData customReaderData ) + throws IOException + { + ArrayList line = new ArrayList(); + ArrayList file = new ArrayList(); + int fieldSeparator = customReaderData.getFieldSeparatorChar(); + + if ( customReaderData != null ) + { + reader.setFieldSeparator( fieldSeparator ); + } + + while ( reader.nextLine() ) + { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) + { + System.err.println( " line.add string =" + s + "=" ); + line.add( s ); + } + + System.err.println( " line.size() =" + line.size() + "=\n" ); + String[] newLine = new String[ line.size() ]; + line.toArray( newLine ); + file.add( newLine ); + line.clear(); + } + + data = new String[file.size()][]; + file.toArray( data ); + System.err.println( " parsed lines total =" + file.size() + "=" ); + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public void reverseListRangeOrder( long beg, long end ) + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + System.err.println( "revLine beg: " + beg ); + System.err.println( "revLine end: " + end ); + if ( end <= beg ) + { + return; + } + + int begInt = (int)beg; + int endInt = (int)end; + + String[] strArr = null; + + for ( ; endInt > begInt; endInt--, begInt++ ) + { + strArr = data[ endInt ]; + data[ endInt ] = data[ begInt ]; + data[ begInt ] = strArr; + } + } + + public boolean nextLine() + { + if ( currentLineIndex < data.length ) + { + ++currentLineIndex; + currentFieldIndex = -1; + } + + //System.err.println( "nextLine() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentLineIndex < data.length ? "true" : "false" ) ); + return currentLineIndex < data.length; + } + + public boolean hasEnoughFieldsPerCurrentLine( int neededFields ) + { + //System.err.println( "fieldsPerCurrentLine() data[currentLineIndex].length + 1 =" + (data[currentLineIndex].length + 1) ); + return data[currentLineIndex].length + 1 >= neededFields; + } + + public boolean nextField() + { + //System.err.println( "nextField() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "nextField() ---- return false" ); + return false; + } + + if ( currentFieldIndex < data[currentLineIndex].length ) + { + ++currentFieldIndex; + } + + //System.err.println( "nextField()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentFieldIndex < data[currentLineIndex].length ? "true" : "false" ) ); + return currentFieldIndex < data[currentLineIndex].length; + } + + public boolean hasZeroFields() + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "hasZeroFields() ---- return false" ); + return false; + } + + //System.err.println( "hasZeroFields()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (0 < data[currentLineIndex].length ? "true" : "false" ) ); + return 0 < data[currentLineIndex].length; + } + + public String getField() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + return null; + } + if ( currentFieldIndex < 0 || currentFieldIndex >= data[currentLineIndex].length ) + { + return null; + } + + return data[currentLineIndex][currentFieldIndex]; + } + + public int getCurrentLineIndex() + { + return currentLineIndex; + } + + public int getCurrentFieldIndex() + { + return currentFieldIndex; + } + + public int getCurrentLineIndexWithinBounds() + { + if ( currentLineIndex < 0 ) + { + return 0; + } + if ( currentLineIndex >= data.length ) + { + return data.length - 1; + } + return currentLineIndex; + } + + public int getCurrentFieldIndexWithinBounds() + { + if ( currentFieldIndex < 0 ) + { + return 0; + } + if ( currentFieldIndex >= data[currentLineIndex].length ) + { + return data[currentLineIndex].length - 1; + } + return currentFieldIndex; + } + + public String printCurrentLine() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + System.err.append( "currentLineIndex out of range =" + currentLineIndex ); + return null; + } + + System.err.append( "\n curr line >" ); + try { + for ( int i = 0; i < data[currentLineIndex].length; i ++ ) + { + if ( i > 0 ) + System.err.append( "|" ); + System.err.append( data[currentLineIndex][currentFieldIndex] ); + } + } + catch( Exception ex ) + { + System.err.append( "*** Error in printCurrentLine at currentLineIndex =" + currentLineIndex + " currentFieldIndex =" + currentFieldIndex ); + } + System.err.append( "< curr line." ); + return null; + } + + public void printFile() + { + System.err.append( "\n ------------- PRINT FILE ---------------" ); + int maxRows = data.length; + for ( int row = 0; row < maxRows; row++ ) + { + System.err.append( "\n line [" + row + "] >" ); + for ( int fieldIndex = 0; fieldIndex < data[ row ].length; fieldIndex++ ) + { + if ( fieldIndex > 0 ) + System.err.append( "|" ); + System.err.append( data[ row ][ fieldIndex ] ); + } + System.err.append( "<" ); + } + System.err.append( "\n ------------- END PRINT FILE ---------------" ); + } + + public CSVReader getReader() { + return this.reader; + } + + public void setReader(CSVReader reader) { + this.reader = reader; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.svn-base new file mode 100644 index 0000000..28df405 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVData.java.svn-base @@ -0,0 +1,256 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + +/** + * + * @author miki and Stan Towianski + */ +public class CSVData +{ + private String[][] data; + private int currentLineIndex = -1; + private int currentFieldIndex = -1; + + public CSVReader reader; + + public CSVData( CSVReader readerArg ) + { + this.reader = readerArg; + } + + public void reset() + { + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public String[][] getData() + { + return data; + } + + public void parseIntoLines( CustomReaderData customReaderData ) + throws IOException + { + ArrayList line = new ArrayList(); + ArrayList file = new ArrayList(); + int fieldSeparator = customReaderData.getFieldSeparatorChar(); + + if ( customReaderData != null ) + { + reader.setFieldSeparator( fieldSeparator ); + } + + while ( reader.nextLine() ) + { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) + { + System.err.println( " line.add string =" + s + "=" ); + line.add( s ); + } + + System.err.println( " line.size() =" + line.size() + "=\n" ); + String[] newLine = new String[ line.size() ]; + line.toArray( newLine ); + file.add( newLine ); + line.clear(); + } + + data = new String[file.size()][]; + file.toArray( data ); + System.err.println( " parsed lines total =" + file.size() + "=" ); + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public void reverseListRangeOrder( long beg, long end ) + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + System.err.println( "revLine beg: " + beg ); + System.err.println( "revLine end: " + end ); + if ( end <= beg ) + { + return; + } + + int begInt = (int)beg; + int endInt = (int)end; + + String[] strArr = null; + + for ( ; endInt > begInt; endInt--, begInt++ ) + { + strArr = data[ endInt ]; + data[ endInt ] = data[ begInt ]; + data[ begInt ] = strArr; + } + } + + public boolean nextLine() + { + if ( currentLineIndex < data.length ) + { + ++currentLineIndex; + currentFieldIndex = -1; + } + + //System.err.println( "nextLine() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentLineIndex < data.length ? "true" : "false" ) ); + return currentLineIndex < data.length; + } + + public boolean hasEnoughFieldsPerCurrentLine( int neededFields ) + { + //System.err.println( "fieldsPerCurrentLine() data[currentLineIndex].length + 1 =" + (data[currentLineIndex].length + 1) ); + return data[currentLineIndex].length + 1 >= neededFields; + } + + public boolean nextField() + { + //System.err.println( "nextField() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "nextField() ---- return false" ); + return false; + } + + if ( currentFieldIndex < data[currentLineIndex].length ) + { + ++currentFieldIndex; + } + + //System.err.println( "nextField()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentFieldIndex < data[currentLineIndex].length ? "true" : "false" ) ); + return currentFieldIndex < data[currentLineIndex].length; + } + + public boolean hasZeroFields() + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "hasZeroFields() ---- return false" ); + return false; + } + + //System.err.println( "hasZeroFields()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (0 < data[currentLineIndex].length ? "true" : "false" ) ); + return 0 < data[currentLineIndex].length; + } + + public String getField() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + return null; + } + if ( currentFieldIndex < 0 || currentFieldIndex >= data[currentLineIndex].length ) + { + return null; + } + + return data[currentLineIndex][currentFieldIndex]; + } + + public int getCurrentLineIndex() + { + return currentLineIndex; + } + + public int getCurrentFieldIndex() + { + return currentFieldIndex; + } + + public int getCurrentLineIndexWithinBounds() + { + if ( currentLineIndex < 0 ) + { + return 0; + } + if ( currentLineIndex >= data.length ) + { + return data.length - 1; + } + return currentLineIndex; + } + + public int getCurrentFieldIndexWithinBounds() + { + if ( currentFieldIndex < 0 ) + { + return 0; + } + if ( currentFieldIndex >= data[currentLineIndex].length ) + { + return data[currentLineIndex].length - 1; + } + return currentFieldIndex; + } + + public String printCurrentLine() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + System.err.append( "currentLineIndex out of range =" + currentLineIndex ); + return null; + } + + System.err.append( "\n curr line >" ); + try { + for ( int i = 0; i < data[currentLineIndex].length; i ++ ) + { + if ( i > 0 ) + System.err.append( "|" ); + System.err.append( data[currentLineIndex][currentFieldIndex] ); + } + } + catch( Exception ex ) + { + System.err.append( "*** Error in printCurrentLine at currentLineIndex =" + currentLineIndex + " currentFieldIndex =" + currentFieldIndex ); + } + System.err.append( "< curr line." ); + return null; + } + + public void printFile() + { + System.err.append( "\n ------------- PRINT FILE ---------------" ); + int maxRows = data.length; + for ( int row = 0; row < maxRows; row++ ) + { + System.err.append( "\n line [" + row + "] >" ); + for ( int fieldIndex = 0; fieldIndex < data[ row ].length; fieldIndex++ ) + { + if ( fieldIndex > 0 ) + System.err.append( "|" ); + System.err.append( data[ row ][ fieldIndex ] ); + } + System.err.append( "<" ); + } + System.err.append( "\n ------------- END PRINT FILE ---------------" ); + } + + public CSVReader getReader() { + return this.reader; + } + + public void setReader(CSVReader reader) { + this.reader = reader; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.netbeans-base new file mode 100644 index 0000000..5a48b4c --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.netbeans-base @@ -0,0 +1,349 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.Reader; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + public CSVReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public CSVReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //System.err.println( "nextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + + if ( isEol( lastChar ) || isEof( lastChar ) ) + { + //System.err.println( "nextField() return null for Eol or Eof" ); + return null; + } + + builder.setLength( 0 ); + + if ( isQuote( lastChar ) ) + { + // quoted field + lastChar = reader.read(); + while ( !isQuote( lastChar ) && !isEol( lastChar ) && !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + //System.err.println( "lastChar =" + lastChar + "=" ); + } + //System.err.println( "end field" ); + //System.err.println( "read field =" + builder.toString() + "=" ); + + if ( !isQuote( lastChar ) ) + { + throw new IOException( "Unexpected end of line." ); + } + + // skip quote + lastChar = reader.read(); + // skip spaces + while ( isWhitespace( lastChar ) ) + { + lastChar = reader.read(); + } + // and the next field separator + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + else + { + // plain value + while ( !isFieldSeparator( lastChar ) && !isEol( lastChar ) && + !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + } + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // TODO: skip separator + + if ( trimFields ) + { + //System.err.println( "CSVReader return nextField trim =" + builder.toString().trim() + "=" ); + return builder.toString().trim(); + } + else + { + //System.err.println( "CSVReader return nextField =" + builder.toString() + "=" ); + return builder.toString(); + } + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + + protected final boolean isWhitespace( int ch ) + { + return (ch == SPACE || ch == TAB) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isQuote( int ch ) + { + return ch == quoteCharacter; + } + + protected final boolean isFieldSeparator( int ch ) + { + return ch == fieldSeparator; + } + + protected final boolean isEol( int ch ) + { + return (ch == LF || ch == CR) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isEof( int ch ) + { + return ch < 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.svn-base new file mode 100644 index 0000000..5a48b4c --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReader.java.svn-base @@ -0,0 +1,349 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.Reader; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + public CSVReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public CSVReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //System.err.println( "nextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + + if ( isEol( lastChar ) || isEof( lastChar ) ) + { + //System.err.println( "nextField() return null for Eol or Eof" ); + return null; + } + + builder.setLength( 0 ); + + if ( isQuote( lastChar ) ) + { + // quoted field + lastChar = reader.read(); + while ( !isQuote( lastChar ) && !isEol( lastChar ) && !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + //System.err.println( "lastChar =" + lastChar + "=" ); + } + //System.err.println( "end field" ); + //System.err.println( "read field =" + builder.toString() + "=" ); + + if ( !isQuote( lastChar ) ) + { + throw new IOException( "Unexpected end of line." ); + } + + // skip quote + lastChar = reader.read(); + // skip spaces + while ( isWhitespace( lastChar ) ) + { + lastChar = reader.read(); + } + // and the next field separator + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + else + { + // plain value + while ( !isFieldSeparator( lastChar ) && !isEol( lastChar ) && + !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + } + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // TODO: skip separator + + if ( trimFields ) + { + //System.err.println( "CSVReader return nextField trim =" + builder.toString().trim() + "=" ); + return builder.toString().trim(); + } + else + { + //System.err.println( "CSVReader return nextField =" + builder.toString() + "=" ); + return builder.toString(); + } + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + + protected final boolean isWhitespace( int ch ) + { + return (ch == SPACE || ch == TAB) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isQuote( int ch ) + { + return ch == quoteCharacter; + } + + protected final boolean isFieldSeparator( int ch ) + { + return ch == fieldSeparator; + } + + protected final boolean isEol( int ch ) + { + return (ch == LF || ch == CR) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isEof( int ch ) + { + return ch < 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.netbeans-base new file mode 100644 index 0000000..dbe1b60 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.netbeans-base @@ -0,0 +1,196 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderData { + +// ArrayList dataTypesList = new ArrayList( 10 ); +// ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + int fieldSeparatorChar = ','; + int headerLines = 0; + int footerLines = 0; + int amountCurrencyChar = '$'; + int amountDecimalSignChar = '.'; + int amountGroupingSeparatorChar = ','; + String amountFormat = "#,###,###,##0.00;(#)"; + boolean importReverseOrderFlg = false; + boolean useRegexFlag = false; + String readerName = ""; + String dateFormatString = "MM/DD/YY"; + String fileEncoding = TransactionReader.DEFAULT_ENCODING; + String filenameMatcher = ".*\\.[Cc][Ss][Vv]"; + + + public ArrayList getRegexsList() { + return regexsList; + } + + public String getRegexsListEncoded() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append( "[" ); + for( String str : regexsList ) + { + sbuf.append( str ); + sbuf.append( "a" ); + } + sbuf.append( "]" ); + return sbuf.toString(); + } + + public void setRegexsList(ArrayList regexsList) { + this.regexsList = regexsList; + } + + public String getRegexsListEle( int c ) { + return regexsList.get( c ); + } + + public void setRegexsListEle( int c, String regex) { + this.regexsList.set( c, regex ); + } + + public ArrayList getDataTypesList() { + return dataTypesList; + } + + public void setDataTypesList(ArrayList dataTypesList) { + this.dataTypesList = dataTypesList; + } + + public ArrayList getEmptyFlagsList() { + return emptyFlagsList; + } + + public void setEmptyFlagsList(ArrayList emptyFlagsList) { + this.emptyFlagsList = emptyFlagsList; + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar; + } + + public void setFieldSeparatorChar(int fieldSeparatorChar) { + this.fieldSeparatorChar = fieldSeparatorChar; + } + + public int getHeaderLines() { + return headerLines; + } + + public void setHeaderLines(int headerLines) { + this.headerLines = headerLines; + } + + public String getReaderName() { + return readerName; + } + + public void setReaderName(String readerName) { + this.readerName = readerName; + } + + public String getDateFormatString() { + return dateFormatString; + } + + public void setDateFormatString(String dateFormatString) { + this.dateFormatString = dateFormatString; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public int getFooterLines() { + return footerLines; + } + + public void setFooterLines(int footerLines) { + this.footerLines = footerLines; + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar; + } + + public void setAmountCurrencyChar(int amountCurrencyChar) { + this.amountCurrencyChar = amountCurrencyChar; + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar; + } + + public void setAmountDecimalSignChar(int amountDecimalSignChar) { + this.amountDecimalSignChar = amountDecimalSignChar; + } + + public String getAmountFormat() { + return amountFormat; + } + + public void setAmountFormat(String amountFormat) { + this.amountFormat = amountFormat; + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar; + } + + public void setAmountGroupingSeparatorChar(int amountGroupingSeparatorChar) { + this.amountGroupingSeparatorChar = amountGroupingSeparatorChar; + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg; + } + + public void setImportReverseOrderFlg(boolean importReverseOrderFlg) { + this.importReverseOrderFlg = importReverseOrderFlg; + } + + public boolean getUseRegexFlag() { + return useRegexFlag; + } + + public void setUseRegexFlag(boolean useRegexFlag) { + this.useRegexFlag = useRegexFlag; + } + + public String getFileEncoding() { + return fileEncoding; + } + + public void setFileEncoding(String fileEncoding) { + this.fileEncoding = fileEncoding; + } + + public String getFilenameMatcher() { + return filenameMatcher; + } + + public void setFilenameMatcher(String filenameMatcher) { + this.filenameMatcher = filenameMatcher; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.svn-base new file mode 100644 index 0000000..dbe1b60 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderData.java.svn-base @@ -0,0 +1,196 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderData { + +// ArrayList dataTypesList = new ArrayList( 10 ); +// ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + int fieldSeparatorChar = ','; + int headerLines = 0; + int footerLines = 0; + int amountCurrencyChar = '$'; + int amountDecimalSignChar = '.'; + int amountGroupingSeparatorChar = ','; + String amountFormat = "#,###,###,##0.00;(#)"; + boolean importReverseOrderFlg = false; + boolean useRegexFlag = false; + String readerName = ""; + String dateFormatString = "MM/DD/YY"; + String fileEncoding = TransactionReader.DEFAULT_ENCODING; + String filenameMatcher = ".*\\.[Cc][Ss][Vv]"; + + + public ArrayList getRegexsList() { + return regexsList; + } + + public String getRegexsListEncoded() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append( "[" ); + for( String str : regexsList ) + { + sbuf.append( str ); + sbuf.append( "a" ); + } + sbuf.append( "]" ); + return sbuf.toString(); + } + + public void setRegexsList(ArrayList regexsList) { + this.regexsList = regexsList; + } + + public String getRegexsListEle( int c ) { + return regexsList.get( c ); + } + + public void setRegexsListEle( int c, String regex) { + this.regexsList.set( c, regex ); + } + + public ArrayList getDataTypesList() { + return dataTypesList; + } + + public void setDataTypesList(ArrayList dataTypesList) { + this.dataTypesList = dataTypesList; + } + + public ArrayList getEmptyFlagsList() { + return emptyFlagsList; + } + + public void setEmptyFlagsList(ArrayList emptyFlagsList) { + this.emptyFlagsList = emptyFlagsList; + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar; + } + + public void setFieldSeparatorChar(int fieldSeparatorChar) { + this.fieldSeparatorChar = fieldSeparatorChar; + } + + public int getHeaderLines() { + return headerLines; + } + + public void setHeaderLines(int headerLines) { + this.headerLines = headerLines; + } + + public String getReaderName() { + return readerName; + } + + public void setReaderName(String readerName) { + this.readerName = readerName; + } + + public String getDateFormatString() { + return dateFormatString; + } + + public void setDateFormatString(String dateFormatString) { + this.dateFormatString = dateFormatString; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public int getFooterLines() { + return footerLines; + } + + public void setFooterLines(int footerLines) { + this.footerLines = footerLines; + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar; + } + + public void setAmountCurrencyChar(int amountCurrencyChar) { + this.amountCurrencyChar = amountCurrencyChar; + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar; + } + + public void setAmountDecimalSignChar(int amountDecimalSignChar) { + this.amountDecimalSignChar = amountDecimalSignChar; + } + + public String getAmountFormat() { + return amountFormat; + } + + public void setAmountFormat(String amountFormat) { + this.amountFormat = amountFormat; + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar; + } + + public void setAmountGroupingSeparatorChar(int amountGroupingSeparatorChar) { + this.amountGroupingSeparatorChar = amountGroupingSeparatorChar; + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg; + } + + public void setImportReverseOrderFlg(boolean importReverseOrderFlg) { + this.importReverseOrderFlg = importReverseOrderFlg; + } + + public boolean getUseRegexFlag() { + return useRegexFlag; + } + + public void setUseRegexFlag(boolean useRegexFlag) { + this.useRegexFlag = useRegexFlag; + } + + public String getFileEncoding() { + return fileEncoding; + } + + public void setFileEncoding(String fileEncoding) { + this.fileEncoding = fileEncoding; + } + + public String getFilenameMatcher() { + return filenameMatcher; + } + + public void setFilenameMatcher(String filenameMatcher) { + this.filenameMatcher = filenameMatcher; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.netbeans-base new file mode 100644 index 0000000..eecbfeb --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.netbeans-base @@ -0,0 +1,1171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.svn-base new file mode 100644 index 0000000..eecbfeb --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.form.svn-base @@ -0,0 +1,1171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.netbeans-base new file mode 100644 index 0000000..ca849ec --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.netbeans-base @@ -0,0 +1,1874 @@ + +/* + * CustomerReaderDialog.java + * + * Created on Aug 3, 2011, 11:49:09 PM + */ + +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.nio.charset.Charset; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.*; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.KeyStroke; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderDialog extends javax.swing.JDialog { + + //javax.swing.JDialog parent = null; + ImportDialog parent = null; + + //String [] dataTypes = { "", "ignore", "-Payment-", "-Deposit-", "date", "dateAvailable", "dateInitiated", "datePosted", "datePurchased", "check number", "description", "memo", "account name" }; + + String [] dataTypes = { + CustomReader.DATA_TYPE_BLANK + , CustomReader.DATA_TYPE_IGNORE + , CustomReader.DATA_TYPE_IGNORE_REST + , CustomReader.DATA_TYPE_PAYMENT + , CustomReader.DATA_TYPE_DEPOSIT + , CustomReader.DATA_TYPE_DATE + , CustomReader.DATA_TYPE_DATE_AVAILABLE + , CustomReader.DATA_TYPE_DATE_INITIATED + , CustomReader.DATA_TYPE_DATE_POSTED + , CustomReader.DATA_TYPE_DATE_PURCHASED + , CustomReader.DATA_TYPE_CHECK_NUMBER + , CustomReader.DATA_TYPE_DESCRIPTION + , CustomReader.DATA_TYPE_MEMO + , CustomReader.DATA_TYPE_ACCOUNT_NAME + , CustomReader.DATA_TYPE_CATEGORY_NAME + }; + + String [] allowEmptyFlag = { "", "Can Be Blank", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +// ArrayList dataTypesList = new ArrayList( 10 ); + // ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + HashMap ReaderConfigsHM = new HashMap(); + HashMap ReaderHM = new HashMap(); + + SortedMap encodings = Charset.availableCharsets(); + Set fileEncodingNames = encodings.keySet(); + + //private static CitiBankCanadaReader citiBankCanadaReader = new CitiBankCanadaReader(); + //private static INGNetherlandsReader ingNetherlandsReader = new INGNetherlandsReader(); + //private static SimpleCreditDebitReader simpleCreditDebitReader = new SimpleCreditDebitReader(); + //private static WellsFargoReader wellsFargoReader = new WellsFargoReader(); + //private static YodleeReader yodleeReader = new YodleeReader(); + //private static BbvaCompassBankReader bbvaCompassReader = new BbvaCompassBankReader(); + + + /** Creates new form CustomerReaderDialog */ + public CustomReaderDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + initComponents(); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + + this.setModal( false ); + this.addEscapeListener( this ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + public boolean addReaderConfig() + { + message.setText( "" ); + if ( ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "A reader already exists by the name '" + readerName.getText() + "'" ); + return false; + } + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + /* + System.out.println( "add datatype===================================" ); + int i = 0; + for ( String dataType : customReaderData.getDataTypesList() ) + { + System.out.println( "add datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + listModel.addElement( readerName.getText() ); + + Settings.setCustomReaderConfig( customReaderData ); + + this.parent.comboFileFormat1AddItem( customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + return true; + } + + public boolean deleteReaderConfig() + { + message.setText( "" ); + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + //System.err.println( " selected index =" + index + " item =" + listModel.getElementAt( index ) + "=" ); + + Settings.removeCustomReaderConfig( ReaderConfigsHM.get( listModel.getElementAt( index ) ) ); + + ReaderConfigsHM.remove( listModel.getElementAt( index ) ); + ReaderHM.remove( listModel.getElementAt( index ) ); + + listModel.remove( index ); + clearReaderConfig(); + + return true; + } + + public TransactionReader getTransactionReader( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return null; + } + return ReaderHM.get( readerNameToGet ); + } + + public boolean getReaderConfig( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderConfigsHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return false; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerNameToGet ); + readerName.setText( readerNameToGet ); + regexsList = customReaderData.getRegexsList(); + dataTypesList = customReaderData.getDataTypesList(); + emptyFlagsList = customReaderData.getEmptyFlagsList(); + //dateFormatList = customReaderData.getDateFormatList(); + setFieldSeparatorChar( customReaderData.getFieldSeparatorChar() ); + setFileEncodingSelectedItem( customReaderData.getFileEncoding() ); + setHeaderLines( customReaderData.getHeaderLines() ); + setFooterLines( customReaderData.getFooterLines() ); + + setAmountCurrencyChar( customReaderData.getAmountCurrencyChar() ); + setAmountDecimalSignChar( customReaderData.getAmountDecimalSignChar() ); + setAmountGroupingSeparatorChar( customReaderData.getAmountGroupingSeparatorChar() ); + setAmountFormat( customReaderData.getAmountFormat() ); + setImportReverseOrderFlg( customReaderData.getImportReverseOrderFlg() ); + setUseRegexFlag( customReaderData.getUseRegexFlag() ); + setFilenameMatcher( customReaderData.getFilenameMatcher() ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + customReadersList.setSelectedValue( readerNameToGet, true ); + + System.err.println( "get regexsList arraylist =" + regexsList + "=" ); + System.err.println( "get dataTypesList arraylist =" + dataTypesList + "=" ); + System.err.println( "get emptyFlagsList arraylist =" + emptyFlagsList + "=" ); + + /* + int i = 0; +// System.out.println( "get datatype===================================" ); +// System.out.println( "get datatype===================================" ); + for ( String dataType : dataTypesList ) + { +// System.out.println( "get datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + +// System.out.println( "get regex ===================================" ); + regex0.setText( regexsList.get( 0 ) ); + regex1.setText( regexsList.get( 1 ) ); + regex2.setText( regexsList.get( 2 ) ); + regex3.setText( regexsList.get( 3 ) ); + regex4.setText( regexsList.get( 4 ) ); + regex5.setText( regexsList.get( 5 ) ); + regex6.setText( regexsList.get( 6 ) ); + regex7.setText( regexsList.get( 7 ) ); + regex8.setText( regexsList.get( 8 ) ); + regex9.setText( regexsList.get( 9 ) ); + +// System.out.println( "get datatype ===================================" ); + dataType0.setSelectedItem( dataTypesList.get( 0 ) ); + dataType1.setSelectedItem( dataTypesList.get( 1 ) ); + dataType2.setSelectedItem( dataTypesList.get( 2 ) ); + dataType3.setSelectedItem( dataTypesList.get( 3 ) ); + dataType4.setSelectedItem( dataTypesList.get( 4 ) ); + dataType5.setSelectedItem( dataTypesList.get( 5 ) ); + dataType6.setSelectedItem( dataTypesList.get( 6 ) ); + dataType7.setSelectedItem( dataTypesList.get( 7 ) ); + dataType8.setSelectedItem( dataTypesList.get( 8 ) ); + dataType9.setSelectedItem( dataTypesList.get( 9 ) ); + + /* + System.out.println( "get datatype===================================" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 0 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 1 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 2 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 3 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 4 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 5 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 6 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 7 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 8 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 9 ) + "=" ); + */ + + isNullable0.setSelectedItem( emptyFlagsList.get( 0 ) ); + isNullable1.setSelectedItem( emptyFlagsList.get( 1 ) ); + isNullable2.setSelectedItem( emptyFlagsList.get( 2 ) ); + isNullable3.setSelectedItem( emptyFlagsList.get( 3 ) ); + isNullable4.setSelectedItem( emptyFlagsList.get( 4 ) ); + isNullable5.setSelectedItem( emptyFlagsList.get( 5 ) ); + isNullable6.setSelectedItem( emptyFlagsList.get( 6 ) ); + isNullable7.setSelectedItem( emptyFlagsList.get( 7 ) ); + isNullable8.setSelectedItem( emptyFlagsList.get( 8 ) ); + isNullable9.setSelectedItem( emptyFlagsList.get( 9 ) ); + + /* + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + for ( String format : dateFormatList ) + { + System.out.println( "add date format =" + format + "=" ); + dateFormatModel.addElement( format ); + } + + dateFormatCB.setModel( dateFormatModel ); + if ( this.parent != null ) + { + this.parent.comboDateFormatSetModel( dateFormatModel ); + } + + TransactionReader customReader = ReaderHM.get( readerName.getText() ); + String [] tmpArray = new String[0]; + customReader.setSupportedDateFormats( dateFormatList.toArray( tmpArray ) ); + */ + + CustomReader customReader = (CustomReader) ReaderHM.get( readerName.getText() ); + setDateFormatString( customReaderData.getDateFormatString() ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + System.err.println( "getNumberOfCustomReaderFieldsUsed() =" + getNumberOfCustomReaderFieldsUsed() ); + return true; + } + + public void clearReaderConfig() + { + setFieldSeparatorChar( ',' ); + setFileEncodingSelectedItem( TransactionReader.DEFAULT_ENCODING ); + setHeaderLines( 1 ); + setFooterLines( 0 ); + + regex0.setText( "" ); + regex1.setText( "" ); + regex2.setText( "" ); + regex3.setText( "" ); + regex4.setText( "" ); + regex5.setText( "" ); + regex6.setText( "" ); + regex7.setText( "" ); + regex8.setText( "" ); + regex9.setText( "" ); + + dataType0.setSelectedIndex( 0 ); + dataType1.setSelectedIndex( 0 ); + dataType2.setSelectedIndex( 0 ); + dataType3.setSelectedIndex( 0 ); + dataType4.setSelectedIndex( 0 ); + dataType5.setSelectedIndex( 0 ); + dataType6.setSelectedIndex( 0 ); + dataType7.setSelectedIndex( 0 ); + dataType8.setSelectedIndex( 0 ); + dataType9.setSelectedIndex( 0 ); + + isNullable0.setSelectedIndex( 0 ); + isNullable1.setSelectedIndex( 0 ); + isNullable2.setSelectedIndex( 0 ); + isNullable3.setSelectedIndex( 0 ); + isNullable4.setSelectedIndex( 0 ); + isNullable5.setSelectedIndex( 0 ); + isNullable6.setSelectedIndex( 0 ); + isNullable7.setSelectedIndex( 0 ); + isNullable8.setSelectedIndex( 0 ); + isNullable9.setSelectedIndex( 0 ); + } + + public ArrayList createNewRegexsList() + { + ArrayList newRegexsList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, regexsList ); + + newRegexsList.add( ((String)regex0.getText())); + newRegexsList.add( ((String)regex1.getText())); + newRegexsList.add( ((String)regex2.getText())); + newRegexsList.add( ((String)regex3.getText())); + newRegexsList.add( ((String)regex4.getText())); + newRegexsList.add( ((String)regex5.getText())); + newRegexsList.add( ((String)regex6.getText())); + newRegexsList.add( ((String)regex7.getText())); + newRegexsList.add( ((String)regex8.getText())); + newRegexsList.add( ((String)regex9.getText())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newRegexsList; + } + + public ArrayList createNewDataTypesList() + { + ArrayList newDataTypesList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, dataTypesList ); + + newDataTypesList.add( ((String)dataType0.getSelectedItem())); + newDataTypesList.add( ((String)dataType1.getSelectedItem())); + newDataTypesList.add( ((String)dataType2.getSelectedItem())); + newDataTypesList.add( ((String)dataType3.getSelectedItem())); + newDataTypesList.add( ((String)dataType4.getSelectedItem())); + newDataTypesList.add( ((String)dataType5.getSelectedItem())); + newDataTypesList.add( ((String)dataType6.getSelectedItem())); + newDataTypesList.add( ((String)dataType7.getSelectedItem())); + newDataTypesList.add( ((String)dataType8.getSelectedItem())); + newDataTypesList.add( ((String)dataType9.getSelectedItem())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newDataTypesList; + } + + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + newEmptyFlagsList.add( ((String)isNullable0.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable1.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable2.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable3.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable4.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable5.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable6.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable7.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable8.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable9.getSelectedItem())); + return newEmptyFlagsList; + } + + /* + public ArrayList readDateFormatList() + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) dateFormatCB.getModel(); + + int max = dcbm.getSize(); + ArrayList newList = new ArrayList( max ); + for ( int i = 0; i < max; i++ ) + { + newList.add( ( (String) dcbm.getElementAt( i ) ) ); + } + return newList; + } + */ + /* + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + for ( int i = 0; i < 10; i ++ ) + { + javax.swing.JComboBox jcb = new javax.swing.JComboBox( new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + jcb.setSelectedItem( emptyFlagsList.get( i ).getSelectedItem() ); + newEmptyFlagsList.add( jcb ); + } + return newEmptyFlagsList; + } + */ + + public String getRegexsListSelectedItem( int index ) { + return (String) regexsList.get( index ); + } + + public String getDataTypesListSelectedItem( int index ) { + return (String) dataTypesList.get( index ); + } + + public String getEmptyFlagsListSelectedItem( int index ) { + return (String) emptyFlagsList.get( index ); + } + + public String getDateFormatSelected() { + //return (String) dateFormatCB.getSelectedItem(); + return (String) dateFormatCr.getText(); + } + + public void setDateFormatString( String xxx) { + //dateFormatCB.setSelectedItem( xxx ); + dateFormatCr.setText( xxx ); + } + + public String getDateFormatString() { + //return (String) dateFormatCB.getSelectedItem(); + return dateFormatCr.getText(); + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public void setHeaderLines( int xxx ) + { + headerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setHeaderLines(" + xxx +") text =" + headerLines.getText().trim() + "=" ); + } + + public int getHeaderLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getHeaderLines() text =" + headerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( headerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFooterLines( int xxx ) + { + footerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setFooterLines(" + xxx +") text =" + footerLines.getText().trim() + "=" ); + } + + public int getFooterLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getFooterLines() text =" + footerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( footerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFieldSeparatorChar( int xxx) { + fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar.getText().charAt( 0 ); + } + + public void setFileEncodingSelectedItem( String xxx) { + fileEncodingCB.setSelectedItem( xxx ); + } + + public String getFileEncodingSelectedItem() { + return (String) fileEncodingCB.getSelectedItem(); + } + + public void setAmountCurrencyChar( int xxx) { + amountCurrencyChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar.getText().charAt( 0 ); + } + + public void setAmountDecimalSignChar( int xxx) { + amountDecimalSignChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar.getText().charAt( 0 ); + } + + public void setAmountGroupingSeparatorChar( int xxx) { + amountGroupingSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar.getText().charAt( 0 ); + } + + public void setAmountFormat( String xxx) { + amountFormat.setText( xxx ); + } + + public String getAmountFormat() { + return (String) amountFormat.getText(); + } + + public void setImportReverseOrderFlg( boolean xxx) { + importReverseOrderFlg.setSelected( xxx ); + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg.isSelected(); + } + + public void setUseRegexFlag( boolean xxx) { + useRegexFlag.setSelected( xxx ); + } + + public boolean getUseRegexFlag() { + return useRegexFlag.isSelected(); + } + + public void setFilenameMatcher( String xxx) { + filenameMatcher.setText( xxx ); + } + + public String getFilenameMatcher() { + return (String) filenameMatcher.getText(); + } + + protected void init() + { + /* + dataType0.setSelectedItem( "date" ); + dataType1.setSelectedItem( "amount" ); + dataType2.setSelectedItem( "check number" ); + dataType3 .setSelectedItem( "skip" ); + dataType4.setSelectedItem( "description" ); + dataType5.setSelectedItem( "memo" ); + isNullable2.setSelectedItem( "Can Be Blank" ); + isNullable4.setSelectedItem( "Can Be Blank" ); + isNullable5.setSelectedItem( "Can Be Blank" ); + */ + + ReaderConfigsHM = Settings.createReaderConfigsHM(); + ReaderHM = Settings.getReaderHM(); // not great, but for now the call above must be first because it sets the value for this one to read also. + + /****** Quit using the built in readers ! Force people to make their own + ReaderConfigsHM.put( "citiBankCanadaReader", null ); + ReaderHM.put( "citiBankCanadaReader", citiBankCanadaReader ); + + ReaderConfigsHM.put( "ingNetherlandsReader", null ); + ReaderHM.put( "ingNetherlandsReader", ingNetherlandsReader ); + + ReaderConfigsHM.put( "simpleCreditDebitReader", null ); + ReaderHM.put( "simpleCreditDebitReader", simpleCreditDebitReader ); + + ReaderConfigsHM.put( "wellsFargoReader", null ); + ReaderHM.put( "wellsFargoReader", wellsFargoReader ); + + ReaderConfigsHM.put( "yodleeReader", null ); + ReaderHM.put( "yodleeReader", yodleeReader ); + + ReaderConfigsHM.put( "bbvaCompassReader", null ); + ReaderHM.put( "bbvaCompassReader", bbvaCompassReader ); + ******/ + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + +// ??? this.parent.comboFileFormat1AddItem( "" ); + + // For keys of a map + for ( Iterator it=ReaderHM.keySet().iterator(); it.hasNext(); ) + { + String readerName = (String) it.next(); + System.err.println( "fill out readerName =" + readerName + "=" ); + if ( ReaderHM.get( readerName ).isCustomReaderFlag() ) + { + listModel.addElement( readerName ); + + // needs to be in Settings() +// CustomReader customReader = (CustomReader) getTransactionReader( readerName ); +// CustomReaderData customReaderData = ReaderConfigsHM.get( readerName ); +// +// customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + if ( this.parent != null ) + { + System.err.println( "call add readerName to import dlg reader list =" + readerName + "=" ); + this.parent.comboFileFormat1AddItem( ReaderHM.get( readerName ) ); + } + } + + regexsList.add( (String)regex0.getText() ); + regexsList.add( (String)regex1.getText() ); + regexsList.add( (String)regex2.getText() ); + regexsList.add( (String)regex3.getText() ); + regexsList.add( (String)regex4.getText() ); + regexsList.add( (String)regex5.getText() ); + regexsList.add( (String)regex6.getText() ); + regexsList.add( (String)regex7.getText() ); + regexsList.add( (String)regex8.getText() ); + regexsList.add( (String)regex9.getText() ); + + dataTypesList.add( (String)dataType0.getSelectedItem() ); + dataTypesList.add( (String)dataType1.getSelectedItem() ); + dataTypesList.add( (String)dataType2.getSelectedItem() ); + dataTypesList.add( (String)dataType3.getSelectedItem() ); + dataTypesList.add( (String)dataType4.getSelectedItem() ); + dataTypesList.add( (String)dataType5.getSelectedItem() ); + dataTypesList.add( (String)dataType6.getSelectedItem() ); + dataTypesList.add( (String)dataType7.getSelectedItem() ); + dataTypesList.add( (String)dataType8.getSelectedItem() ); + dataTypesList.add( (String)dataType9.getSelectedItem() ); + + emptyFlagsList.add( (String)isNullable0.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable1.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable2.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable3.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable4.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable5.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable6.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable7.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable8.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable9.getSelectedItem() ); + + // Populate with all possible encodings + SortedMap encodings = Charset.availableCharsets(); + Set encodingNames = encodings.keySet(); + for ( Iterator i = encodingNames.iterator(); i.hasNext(); ) + { + fileEncodingCB.addItem( i.next() ); + } + // Set default Encoding to be UTF-8 + for ( int i = 0; i < fileEncodingCB.getItemCount(); i++ ) + { + if ( TransactionReader.DEFAULT_ENCODING.equals( fileEncodingCB.getItemAt( i ) ) ) + { + fileEncodingCB.setSelectedIndex( i ); + break; + } + } + + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel1 = new javax.swing.JLabel(); + readerName = new javax.swing.JTextField(); + dataType1 = new javax.swing.JComboBox(); + isNullable1 = new javax.swing.JComboBox(); + dataType2 = new javax.swing.JComboBox(); + dataType4 = new javax.swing.JComboBox(); + dataType0 = new javax.swing.JComboBox(); + isNullable0 = new javax.swing.JComboBox(); + isNullable2 = new javax.swing.JComboBox(); + isNullable3 = new javax.swing.JComboBox(); + isNullable4 = new javax.swing.JComboBox(); + isNullable5 = new javax.swing.JComboBox(); + isNullable6 = new javax.swing.JComboBox(); + isNullable7 = new javax.swing.JComboBox(); + isNullable8 = new javax.swing.JComboBox(); + isNullable9 = new javax.swing.JComboBox(); + dataType3 = new javax.swing.JComboBox(); + dataType5 = new javax.swing.JComboBox(); + dataType6 = new javax.swing.JComboBox(); + dataType7 = new javax.swing.JComboBox(); + dataType8 = new javax.swing.JComboBox(); + dataType9 = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + saveBtn = new javax.swing.JButton(); + jLabel12 = new javax.swing.JLabel(); + jLabel13 = new javax.swing.JLabel(); + headerLines = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + customReadersList = new javax.swing.JList(); + jLabel14 = new javax.swing.JLabel(); + addBtn = new javax.swing.JButton(); + deleteBtn = new javax.swing.JButton(); + jLabel15 = new javax.swing.JLabel(); + message = new javax.swing.JLabel(); + jLabel16 = new javax.swing.JLabel(); + jLabel17 = new javax.swing.JLabel(); + doneBtn = new javax.swing.JButton(); + jLabel18 = new javax.swing.JLabel(); + fieldSeparatorChar = new javax.swing.JTextField(); + resetFieldsBtn = new javax.swing.JButton(); + jLabel19 = new javax.swing.JLabel(); + dateFormatCr = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + jLabel21 = new javax.swing.JLabel(); + amountGroupingSeparatorChar = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + amountDecimalSignChar = new javax.swing.JTextField(); + jLabel23 = new javax.swing.JLabel(); + amountCurrencyChar = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + amountFormat = new javax.swing.JTextField(); + jLabel25 = new javax.swing.JLabel(); + jLabel26 = new javax.swing.JLabel(); + footerLines = new javax.swing.JTextField(); + importReverseOrderFlg = new javax.swing.JCheckBox(); + fileEncodingLbl = new javax.swing.JLabel(); + fileEncodingCB = new javax.swing.JComboBox(); + jLabel27 = new javax.swing.JLabel(); + regex0 = new javax.swing.JTextField(); + regex1 = new javax.swing.JTextField(); + regex2 = new javax.swing.JTextField(); + regex3 = new javax.swing.JTextField(); + regex4 = new javax.swing.JTextField(); + regex5 = new javax.swing.JTextField(); + regex6 = new javax.swing.JTextField(); + regex7 = new javax.swing.JTextField(); + regex8 = new javax.swing.JTextField(); + regex9 = new javax.swing.JTextField(); + useRegexFlag = new javax.swing.JCheckBox(); + filenameMatcher = new javax.swing.JTextField(); + jLabel28 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(780, 600)); + setPreferredSize(new java.awt.Dimension(780, 600)); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + jLabel1.setText("Reader Name:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel1, gridBagConstraints); + + readerName.setMinimumSize(new java.awt.Dimension(160, 25)); + readerName.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(readerName, gridBagConstraints); + + dataType1.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType1.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType1, gridBagConstraints); + + isNullable1.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable1.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 12; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable1, gridBagConstraints); + + dataType2.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType2.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType2, gridBagConstraints); + + dataType4.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType4.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType4, gridBagConstraints); + + dataType0.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType0.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType0, gridBagConstraints); + + isNullable0.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable0.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 11; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable0, gridBagConstraints); + + isNullable2.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable2.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 13; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable2, gridBagConstraints); + + isNullable3.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable3.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 14; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable3, gridBagConstraints); + + isNullable4.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable4.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 15; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable4, gridBagConstraints); + + isNullable5.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable5.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 16; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable5, gridBagConstraints); + + isNullable6.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable6.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 17; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable6, gridBagConstraints); + + isNullable7.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable7.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 18; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable7, gridBagConstraints); + + isNullable8.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable8.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 19; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable8, gridBagConstraints); + + isNullable9.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable9.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 20; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable9, gridBagConstraints); + + dataType3.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType3.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType3, gridBagConstraints); + + dataType5.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType5.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType5, gridBagConstraints); + + dataType6.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType6.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType6, gridBagConstraints); + + dataType7.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType7.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType7, gridBagConstraints); + + dataType8.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType8.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType8, gridBagConstraints); + + dataType9.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType9.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType9, gridBagConstraints); + + jLabel2.setText("1"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 11; + getContentPane().add(jLabel2, gridBagConstraints); + + jLabel3.setText("2"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 12; + getContentPane().add(jLabel3, gridBagConstraints); + + jLabel4.setText("3"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 13; + getContentPane().add(jLabel4, gridBagConstraints); + + jLabel5.setText("4"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel5, gridBagConstraints); + + jLabel6.setText("5"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 15; + getContentPane().add(jLabel6, gridBagConstraints); + + jLabel7.setText("6"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(jLabel7, gridBagConstraints); + + jLabel8.setText("7"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 17; + getContentPane().add(jLabel8, gridBagConstraints); + + jLabel9.setText("8"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 18; + getContentPane().add(jLabel9, gridBagConstraints); + + jLabel10.setText("9"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 19; + getContentPane().add(jLabel10, gridBagConstraints); + + jLabel11.setText("10"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 20; + getContentPane().add(jLabel11, gridBagConstraints); + + saveBtn.setText("Save"); + saveBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + saveBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + saveBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + saveBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 22; + getContentPane().add(saveBtn, gridBagConstraints); + + jLabel12.setText(" "); + jLabel12.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 8; + getContentPane().add(jLabel12, gridBagConstraints); + + jLabel13.setText("Number of Footer Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel13, gridBagConstraints); + + headerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + headerLines.setText("1"); + headerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + headerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + headerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + headerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(headerLines, gridBagConstraints); + + jScrollPane1.setMinimumSize(new java.awt.Dimension(160, 85)); + jScrollPane1.setPreferredSize(new java.awt.Dimension(160, 160)); + + customReadersList.setModel(new DefaultListModel() ); + customReadersList.setMaximumSize(new java.awt.Dimension(32767, 32767)); + customReadersList.setMinimumSize(new java.awt.Dimension(160, 85)); + customReadersList.setPreferredSize(new java.awt.Dimension(160, 85)); + customReadersList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + customReadersListMouseClicked(evt); + } + }); + jScrollPane1.setViewportView(customReadersList); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridheight = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; + getContentPane().add(jScrollPane1, gridBagConstraints); + + jLabel14.setText(" "); + jLabel14.setMaximumSize(new java.awt.Dimension(25, 15)); + jLabel14.setMinimumSize(new java.awt.Dimension(25, 15)); + jLabel14.setPreferredSize(new java.awt.Dimension(25, 15)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 10; + getContentPane().add(jLabel14, gridBagConstraints); + + addBtn.setText("Add"); + addBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + addBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + addBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + addBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + getContentPane().add(addBtn, gridBagConstraints); + + deleteBtn.setText("Delete"); + deleteBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + deleteBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + deleteBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + deleteBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 22; + gridBagConstraints.gridwidth = 2; + getContentPane().add(deleteBtn, gridBagConstraints); + + jLabel15.setText("List of Readers:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + getContentPane().add(jLabel15, gridBagConstraints); + + message.setForeground(new java.awt.Color(255, 0, 0)); + message.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 24; + gridBagConstraints.gridwidth = 5; + getContentPane().add(message, gridBagConstraints); + + jLabel16.setText(" "); + jLabel16.setMinimumSize(new java.awt.Dimension(150, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 23; + getContentPane().add(jLabel16, gridBagConstraints); + + jLabel17.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 21; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(jLabel17, gridBagConstraints); + + doneBtn.setText("Done"); + doneBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + doneBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + doneBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + doneBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + doneBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 22; + getContentPane().add(doneBtn, gridBagConstraints); + + jLabel18.setText("CSV Field Separator:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel18, gridBagConstraints); + + fieldSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + fieldSeparatorChar.setText(","); + fieldSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fieldSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fieldSeparatorChar, gridBagConstraints); + + resetFieldsBtn.setText("Reset Fields"); + resetFieldsBtn.setMinimumSize(new java.awt.Dimension(100, 25)); + resetFieldsBtn.setPreferredSize(new java.awt.Dimension(110, 25)); + resetFieldsBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resetFieldsBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 22; + gridBagConstraints.weightx = 0.2; + getContentPane().add(resetFieldsBtn, gridBagConstraints); + + jLabel19.setText("Date Format:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel19, gridBagConstraints); + + dateFormatCr.setText("YYYY-MM-DD"); + dateFormatCr.setToolTipText("\nYou can do things like: MM/DD/YYYY, MM.DD.YY, YY-MM-DD
\nhttp://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html"); + dateFormatCr.setMinimumSize(new java.awt.Dimension(100, 25)); + dateFormatCr.setPreferredSize(new java.awt.Dimension(100, 25)); + dateFormatCr.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dateFormatCrActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(dateFormatCr, gridBagConstraints); + + jLabel20.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 9; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel20, gridBagConstraints); + + jLabel21.setText("Grouping separator:"); + jLabel21.setEnabled(false); + jLabel21.setFocusable(false); + jLabel21.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel21, gridBagConstraints); + + amountGroupingSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountGroupingSeparatorChar.setText(","); + amountGroupingSeparatorChar.setEnabled(false); + amountGroupingSeparatorChar.setFocusable(false); + amountGroupingSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + amountGroupingSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountGroupingSeparatorChar, gridBagConstraints); + + jLabel22.setText("Decimal Sign:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel22, gridBagConstraints); + + amountDecimalSignChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountDecimalSignChar.setText("."); + amountDecimalSignChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountDecimalSignChar.setPreferredSize(new java.awt.Dimension(20, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountDecimalSignChar, gridBagConstraints); + + jLabel23.setText("Currency Symbol:"); + jLabel23.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel23, gridBagConstraints); + + amountCurrencyChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountCurrencyChar.setText(" "); + amountCurrencyChar.setEnabled(false); + amountCurrencyChar.setMinimumSize(new java.awt.Dimension(40, 25)); + amountCurrencyChar.setPreferredSize(new java.awt.Dimension(40, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountCurrencyChar, gridBagConstraints); + + jLabel24.setText("Amount Format:"); + jLabel24.setEnabled(false); + jLabel24.setFocusable(false); + jLabel24.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel24, gridBagConstraints); + + amountFormat.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountFormat.setText(" "); + amountFormat.setEnabled(false); + amountFormat.setFocusable(false); + amountFormat.setMinimumSize(new java.awt.Dimension(160, 25)); + amountFormat.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountFormat, gridBagConstraints); + + jLabel25.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 2; + getContentPane().add(jLabel25, gridBagConstraints); + + jLabel26.setText("Number of Header Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel26, gridBagConstraints); + + footerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + footerLines.setText("0"); + footerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + footerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + footerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + footerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(footerLines, gridBagConstraints); + + importReverseOrderFlg.setText("Import Transactions in Reverse Order."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 2; + getContentPane().add(importReverseOrderFlg, gridBagConstraints); + + fileEncodingLbl.setText("File Encoding:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(fileEncodingLbl, gridBagConstraints); + + fileEncodingCB.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + fileEncodingCB.setMinimumSize(new java.awt.Dimension(120, 25)); + fileEncodingCB.setPreferredSize(new java.awt.Dimension(140, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fileEncodingCB, gridBagConstraints); + + jLabel27.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + getContentPane().add(jLabel27, gridBagConstraints); + + regex0.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex0ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex0, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex1, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex2, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex3, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex4, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex5, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex6, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex7, gridBagConstraints); + + regex8.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex8ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex8, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex9, gridBagConstraints); + + useRegexFlag.setText("Use Regex to Parse Fields"); + useRegexFlag.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useRegexFlagActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 10; + getContentPane().add(useRegexFlag, gridBagConstraints); + + filenameMatcher.setText(".*\\.(csv|CSV)"); + filenameMatcher.setMinimumSize(new java.awt.Dimension(160, 25)); + filenameMatcher.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + getContentPane().add(filenameMatcher, gridBagConstraints); + + jLabel28.setText("Filename Matcher:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel28, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed + message.setText( "" ); + + if ( ! ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "There is no reader by that name '" + readerName.getText() + "'" ); + } + +// int i = 0; +// for ( String dataType : dataTypesList ) +// { +// System.out.println( "datatype " + i + " =" + dataType + "=" ); +// i++; +// } + + try + { + int x = Integer.parseInt( headerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Header Lines must be 0 or more" ); + return; + } + + try + { + int x = Integer.parseInt( footerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Footer Lines must be 0 or more" ); + return; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerName.getText() ); + + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + // *** I could get and replace the existing one but just do this for now until things work ! ! ! + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + Settings.setCustomReaderConfig( customReaderData ); + }//GEN-LAST:event_saveBtnActionPerformed + + private void headerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_headerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_headerLinesActionPerformed + + private void doneBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doneBtnActionPerformed + this.setVisible( false ); + + /** turning all this off so we do not test all readers when they hit 'Done' + parent.setSkipDuringInit( true ); + parent.fileChanged(); + this.parent.comboFileFormat1SetItem( ReaderHM.get( readerName.getText() ) ); + parent.setSkipDuringInit( false ); + //System.out.println( "done button (String) dateFormatCB.getSelectedItem() =" + (String) dateFormatCB.getSelectedItem() + "=" ); + //this.parent.comboDateFormatSetItem( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + **/ + }//GEN-LAST:event_doneBtnActionPerformed + + private void fieldSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fieldSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_fieldSeparatorCharActionPerformed + + private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed + addReaderConfig(); + }//GEN-LAST:event_addBtnActionPerformed + + private void deleteBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteBtnActionPerformed + deleteReaderConfig(); + }//GEN-LAST:event_deleteBtnActionPerformed + + private void customReadersListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_customReadersListMouseClicked + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + getReaderConfig( (String) listModel.getElementAt( index ) ); + useRegexFlagActionPerformed( null ); + }//GEN-LAST:event_customReadersListMouseClicked + + private void resetFieldsBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetFieldsBtnActionPerformed + clearReaderConfig(); + }//GEN-LAST:event_resetFieldsBtnActionPerformed + + private void dateFormatCrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateFormatCrActionPerformed + ; + }//GEN-LAST:event_dateFormatCrActionPerformed + + private void amountGroupingSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_amountGroupingSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_amountGroupingSeparatorCharActionPerformed + + private void footerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_footerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_footerLinesActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + DecimalFormatSymbols decForSyms = new DecimalFormatSymbols(); + DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(); + int numDigits = decFormat.getCurrency().getDefaultFractionDigits(); + amountCurrencyChar.setText( decFormat.getCurrency().getSymbol() ); + String format = "0"; + int i; + // if ( decFormat.getmax > 0 ) + // { + format += decForSyms.getDecimalSeparator(); + // } + //System.out.println( "decFormat.getMinimumIntegerDigits() =" + decFormat.getMinimumIntegerDigits() ); + for ( i = 0; i < 2; i ++ ) + { + format+= "0"; + } + + //amountDecimalSignChar.setText( ); + int groupSize = decFormat.getGroupingSize(); + char groupSep = decForSyms.getGroupingSeparator(); + amountGroupingSeparatorChar.setText( groupSep + "" ); + amountDecimalSignChar.setText( decForSyms.getDecimalSeparator() + "" ); + + int gscnt = 1; + for ( i = 1; i < 10; i ++ ) + { + if ( gscnt == groupSize ) + { + format = groupSep + format; + gscnt = 1; + } + else + { + gscnt ++; + } + format = "#" + format; + } + format = decForSyms.getCurrencySymbol() + format; + amountFormat.setText( format ); + }//GEN-LAST:event_formWindowOpened + + private void regex0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex0ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex0ActionPerformed + + private void regex8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex8ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex8ActionPerformed + + private void useRegexFlagActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useRegexFlagActionPerformed + if ( useRegexFlag.isSelected() ) + { + // This is just for a first time to give them a working example of a usable regex + if ( regex0.getText().isEmpty() + && regex1.getText().isEmpty() + && regex2.getText().isEmpty() + && regex3.getText().isEmpty() + && regex4.getText().isEmpty() + && regex5.getText().isEmpty() + ) + { + regex0.setText( "([^,]*([,]|\\Z)).*" ); + regex1.setText( "([^,]*([,]|\\Z)).*" ); + regex2.setText( "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*" ); + regex3.setText( "([^,]*([,]|\\Z)).*" ); + regex4.setText( "([^,]*([,]|\\Z)).*" ); + regex5.setText( "([^,]*([,]|\\Z)).*" ); + } + regex0.setVisible( true ); + regex1.setVisible( true ); + regex2.setVisible( true ); + regex3.setVisible( true ); + regex4.setVisible( true ); + regex5.setVisible( true ); + regex6.setVisible( true ); + regex7.setVisible( true ); + regex8.setVisible( true ); + regex9.setVisible( true ); + } + else + { +// regex0.setText( "" ); +// regex1.setText( "" ); +// regex2.setText( "" ); +// regex3.setText( "" ); +// regex4.setText( "" ); +// regex5.setText( "" ); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + } + }//GEN-LAST:event_useRegexFlagActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + CustomReaderDialog dialog = new CustomReaderDialog( null, true ); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addBtn; + private javax.swing.JTextField amountCurrencyChar; + private javax.swing.JTextField amountDecimalSignChar; + private javax.swing.JTextField amountFormat; + private javax.swing.JTextField amountGroupingSeparatorChar; + private javax.swing.JList customReadersList; + private javax.swing.JComboBox dataType0; + private javax.swing.JComboBox dataType1; + private javax.swing.JComboBox dataType2; + private javax.swing.JComboBox dataType3; + private javax.swing.JComboBox dataType4; + private javax.swing.JComboBox dataType5; + private javax.swing.JComboBox dataType6; + private javax.swing.JComboBox dataType7; + private javax.swing.JComboBox dataType8; + private javax.swing.JComboBox dataType9; + private javax.swing.JTextField dateFormatCr; + private javax.swing.JButton deleteBtn; + private javax.swing.JButton doneBtn; + private javax.swing.JTextField fieldSeparatorChar; + private javax.swing.JComboBox fileEncodingCB; + private javax.swing.JLabel fileEncodingLbl; + private javax.swing.JTextField filenameMatcher; + private javax.swing.JTextField footerLines; + private javax.swing.JTextField headerLines; + private javax.swing.JCheckBox importReverseOrderFlg; + private javax.swing.JComboBox isNullable0; + private javax.swing.JComboBox isNullable1; + private javax.swing.JComboBox isNullable2; + private javax.swing.JComboBox isNullable3; + private javax.swing.JComboBox isNullable4; + private javax.swing.JComboBox isNullable5; + private javax.swing.JComboBox isNullable6; + private javax.swing.JComboBox isNullable7; + private javax.swing.JComboBox isNullable8; + private javax.swing.JComboBox isNullable9; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel25; + private javax.swing.JLabel jLabel26; + private javax.swing.JLabel jLabel27; + private javax.swing.JLabel jLabel28; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel message; + private javax.swing.JTextField readerName; + private javax.swing.JTextField regex0; + private javax.swing.JTextField regex1; + private javax.swing.JTextField regex2; + private javax.swing.JTextField regex3; + private javax.swing.JTextField regex4; + private javax.swing.JTextField regex5; + private javax.swing.JTextField regex6; + private javax.swing.JTextField regex7; + private javax.swing.JTextField regex8; + private javax.swing.JTextField regex9; + private javax.swing.JButton resetFieldsBtn; + private javax.swing.JButton saveBtn; + private javax.swing.JCheckBox useRegexFlag; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.svn-base new file mode 100644 index 0000000..ca849ec --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialog.java.svn-base @@ -0,0 +1,1874 @@ + +/* + * CustomerReaderDialog.java + * + * Created on Aug 3, 2011, 11:49:09 PM + */ + +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.nio.charset.Charset; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.*; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.KeyStroke; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderDialog extends javax.swing.JDialog { + + //javax.swing.JDialog parent = null; + ImportDialog parent = null; + + //String [] dataTypes = { "", "ignore", "-Payment-", "-Deposit-", "date", "dateAvailable", "dateInitiated", "datePosted", "datePurchased", "check number", "description", "memo", "account name" }; + + String [] dataTypes = { + CustomReader.DATA_TYPE_BLANK + , CustomReader.DATA_TYPE_IGNORE + , CustomReader.DATA_TYPE_IGNORE_REST + , CustomReader.DATA_TYPE_PAYMENT + , CustomReader.DATA_TYPE_DEPOSIT + , CustomReader.DATA_TYPE_DATE + , CustomReader.DATA_TYPE_DATE_AVAILABLE + , CustomReader.DATA_TYPE_DATE_INITIATED + , CustomReader.DATA_TYPE_DATE_POSTED + , CustomReader.DATA_TYPE_DATE_PURCHASED + , CustomReader.DATA_TYPE_CHECK_NUMBER + , CustomReader.DATA_TYPE_DESCRIPTION + , CustomReader.DATA_TYPE_MEMO + , CustomReader.DATA_TYPE_ACCOUNT_NAME + , CustomReader.DATA_TYPE_CATEGORY_NAME + }; + + String [] allowEmptyFlag = { "", "Can Be Blank", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +// ArrayList dataTypesList = new ArrayList( 10 ); + // ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + HashMap ReaderConfigsHM = new HashMap(); + HashMap ReaderHM = new HashMap(); + + SortedMap encodings = Charset.availableCharsets(); + Set fileEncodingNames = encodings.keySet(); + + //private static CitiBankCanadaReader citiBankCanadaReader = new CitiBankCanadaReader(); + //private static INGNetherlandsReader ingNetherlandsReader = new INGNetherlandsReader(); + //private static SimpleCreditDebitReader simpleCreditDebitReader = new SimpleCreditDebitReader(); + //private static WellsFargoReader wellsFargoReader = new WellsFargoReader(); + //private static YodleeReader yodleeReader = new YodleeReader(); + //private static BbvaCompassBankReader bbvaCompassReader = new BbvaCompassBankReader(); + + + /** Creates new form CustomerReaderDialog */ + public CustomReaderDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + initComponents(); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + + this.setModal( false ); + this.addEscapeListener( this ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + public boolean addReaderConfig() + { + message.setText( "" ); + if ( ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "A reader already exists by the name '" + readerName.getText() + "'" ); + return false; + } + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + /* + System.out.println( "add datatype===================================" ); + int i = 0; + for ( String dataType : customReaderData.getDataTypesList() ) + { + System.out.println( "add datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + listModel.addElement( readerName.getText() ); + + Settings.setCustomReaderConfig( customReaderData ); + + this.parent.comboFileFormat1AddItem( customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + return true; + } + + public boolean deleteReaderConfig() + { + message.setText( "" ); + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + //System.err.println( " selected index =" + index + " item =" + listModel.getElementAt( index ) + "=" ); + + Settings.removeCustomReaderConfig( ReaderConfigsHM.get( listModel.getElementAt( index ) ) ); + + ReaderConfigsHM.remove( listModel.getElementAt( index ) ); + ReaderHM.remove( listModel.getElementAt( index ) ); + + listModel.remove( index ); + clearReaderConfig(); + + return true; + } + + public TransactionReader getTransactionReader( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return null; + } + return ReaderHM.get( readerNameToGet ); + } + + public boolean getReaderConfig( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderConfigsHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return false; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerNameToGet ); + readerName.setText( readerNameToGet ); + regexsList = customReaderData.getRegexsList(); + dataTypesList = customReaderData.getDataTypesList(); + emptyFlagsList = customReaderData.getEmptyFlagsList(); + //dateFormatList = customReaderData.getDateFormatList(); + setFieldSeparatorChar( customReaderData.getFieldSeparatorChar() ); + setFileEncodingSelectedItem( customReaderData.getFileEncoding() ); + setHeaderLines( customReaderData.getHeaderLines() ); + setFooterLines( customReaderData.getFooterLines() ); + + setAmountCurrencyChar( customReaderData.getAmountCurrencyChar() ); + setAmountDecimalSignChar( customReaderData.getAmountDecimalSignChar() ); + setAmountGroupingSeparatorChar( customReaderData.getAmountGroupingSeparatorChar() ); + setAmountFormat( customReaderData.getAmountFormat() ); + setImportReverseOrderFlg( customReaderData.getImportReverseOrderFlg() ); + setUseRegexFlag( customReaderData.getUseRegexFlag() ); + setFilenameMatcher( customReaderData.getFilenameMatcher() ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + customReadersList.setSelectedValue( readerNameToGet, true ); + + System.err.println( "get regexsList arraylist =" + regexsList + "=" ); + System.err.println( "get dataTypesList arraylist =" + dataTypesList + "=" ); + System.err.println( "get emptyFlagsList arraylist =" + emptyFlagsList + "=" ); + + /* + int i = 0; +// System.out.println( "get datatype===================================" ); +// System.out.println( "get datatype===================================" ); + for ( String dataType : dataTypesList ) + { +// System.out.println( "get datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + +// System.out.println( "get regex ===================================" ); + regex0.setText( regexsList.get( 0 ) ); + regex1.setText( regexsList.get( 1 ) ); + regex2.setText( regexsList.get( 2 ) ); + regex3.setText( regexsList.get( 3 ) ); + regex4.setText( regexsList.get( 4 ) ); + regex5.setText( regexsList.get( 5 ) ); + regex6.setText( regexsList.get( 6 ) ); + regex7.setText( regexsList.get( 7 ) ); + regex8.setText( regexsList.get( 8 ) ); + regex9.setText( regexsList.get( 9 ) ); + +// System.out.println( "get datatype ===================================" ); + dataType0.setSelectedItem( dataTypesList.get( 0 ) ); + dataType1.setSelectedItem( dataTypesList.get( 1 ) ); + dataType2.setSelectedItem( dataTypesList.get( 2 ) ); + dataType3.setSelectedItem( dataTypesList.get( 3 ) ); + dataType4.setSelectedItem( dataTypesList.get( 4 ) ); + dataType5.setSelectedItem( dataTypesList.get( 5 ) ); + dataType6.setSelectedItem( dataTypesList.get( 6 ) ); + dataType7.setSelectedItem( dataTypesList.get( 7 ) ); + dataType8.setSelectedItem( dataTypesList.get( 8 ) ); + dataType9.setSelectedItem( dataTypesList.get( 9 ) ); + + /* + System.out.println( "get datatype===================================" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 0 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 1 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 2 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 3 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 4 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 5 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 6 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 7 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 8 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 9 ) + "=" ); + */ + + isNullable0.setSelectedItem( emptyFlagsList.get( 0 ) ); + isNullable1.setSelectedItem( emptyFlagsList.get( 1 ) ); + isNullable2.setSelectedItem( emptyFlagsList.get( 2 ) ); + isNullable3.setSelectedItem( emptyFlagsList.get( 3 ) ); + isNullable4.setSelectedItem( emptyFlagsList.get( 4 ) ); + isNullable5.setSelectedItem( emptyFlagsList.get( 5 ) ); + isNullable6.setSelectedItem( emptyFlagsList.get( 6 ) ); + isNullable7.setSelectedItem( emptyFlagsList.get( 7 ) ); + isNullable8.setSelectedItem( emptyFlagsList.get( 8 ) ); + isNullable9.setSelectedItem( emptyFlagsList.get( 9 ) ); + + /* + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + for ( String format : dateFormatList ) + { + System.out.println( "add date format =" + format + "=" ); + dateFormatModel.addElement( format ); + } + + dateFormatCB.setModel( dateFormatModel ); + if ( this.parent != null ) + { + this.parent.comboDateFormatSetModel( dateFormatModel ); + } + + TransactionReader customReader = ReaderHM.get( readerName.getText() ); + String [] tmpArray = new String[0]; + customReader.setSupportedDateFormats( dateFormatList.toArray( tmpArray ) ); + */ + + CustomReader customReader = (CustomReader) ReaderHM.get( readerName.getText() ); + setDateFormatString( customReaderData.getDateFormatString() ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + System.err.println( "getNumberOfCustomReaderFieldsUsed() =" + getNumberOfCustomReaderFieldsUsed() ); + return true; + } + + public void clearReaderConfig() + { + setFieldSeparatorChar( ',' ); + setFileEncodingSelectedItem( TransactionReader.DEFAULT_ENCODING ); + setHeaderLines( 1 ); + setFooterLines( 0 ); + + regex0.setText( "" ); + regex1.setText( "" ); + regex2.setText( "" ); + regex3.setText( "" ); + regex4.setText( "" ); + regex5.setText( "" ); + regex6.setText( "" ); + regex7.setText( "" ); + regex8.setText( "" ); + regex9.setText( "" ); + + dataType0.setSelectedIndex( 0 ); + dataType1.setSelectedIndex( 0 ); + dataType2.setSelectedIndex( 0 ); + dataType3.setSelectedIndex( 0 ); + dataType4.setSelectedIndex( 0 ); + dataType5.setSelectedIndex( 0 ); + dataType6.setSelectedIndex( 0 ); + dataType7.setSelectedIndex( 0 ); + dataType8.setSelectedIndex( 0 ); + dataType9.setSelectedIndex( 0 ); + + isNullable0.setSelectedIndex( 0 ); + isNullable1.setSelectedIndex( 0 ); + isNullable2.setSelectedIndex( 0 ); + isNullable3.setSelectedIndex( 0 ); + isNullable4.setSelectedIndex( 0 ); + isNullable5.setSelectedIndex( 0 ); + isNullable6.setSelectedIndex( 0 ); + isNullable7.setSelectedIndex( 0 ); + isNullable8.setSelectedIndex( 0 ); + isNullable9.setSelectedIndex( 0 ); + } + + public ArrayList createNewRegexsList() + { + ArrayList newRegexsList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, regexsList ); + + newRegexsList.add( ((String)regex0.getText())); + newRegexsList.add( ((String)regex1.getText())); + newRegexsList.add( ((String)regex2.getText())); + newRegexsList.add( ((String)regex3.getText())); + newRegexsList.add( ((String)regex4.getText())); + newRegexsList.add( ((String)regex5.getText())); + newRegexsList.add( ((String)regex6.getText())); + newRegexsList.add( ((String)regex7.getText())); + newRegexsList.add( ((String)regex8.getText())); + newRegexsList.add( ((String)regex9.getText())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newRegexsList; + } + + public ArrayList createNewDataTypesList() + { + ArrayList newDataTypesList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, dataTypesList ); + + newDataTypesList.add( ((String)dataType0.getSelectedItem())); + newDataTypesList.add( ((String)dataType1.getSelectedItem())); + newDataTypesList.add( ((String)dataType2.getSelectedItem())); + newDataTypesList.add( ((String)dataType3.getSelectedItem())); + newDataTypesList.add( ((String)dataType4.getSelectedItem())); + newDataTypesList.add( ((String)dataType5.getSelectedItem())); + newDataTypesList.add( ((String)dataType6.getSelectedItem())); + newDataTypesList.add( ((String)dataType7.getSelectedItem())); + newDataTypesList.add( ((String)dataType8.getSelectedItem())); + newDataTypesList.add( ((String)dataType9.getSelectedItem())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newDataTypesList; + } + + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + newEmptyFlagsList.add( ((String)isNullable0.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable1.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable2.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable3.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable4.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable5.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable6.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable7.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable8.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable9.getSelectedItem())); + return newEmptyFlagsList; + } + + /* + public ArrayList readDateFormatList() + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) dateFormatCB.getModel(); + + int max = dcbm.getSize(); + ArrayList newList = new ArrayList( max ); + for ( int i = 0; i < max; i++ ) + { + newList.add( ( (String) dcbm.getElementAt( i ) ) ); + } + return newList; + } + */ + /* + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + for ( int i = 0; i < 10; i ++ ) + { + javax.swing.JComboBox jcb = new javax.swing.JComboBox( new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + jcb.setSelectedItem( emptyFlagsList.get( i ).getSelectedItem() ); + newEmptyFlagsList.add( jcb ); + } + return newEmptyFlagsList; + } + */ + + public String getRegexsListSelectedItem( int index ) { + return (String) regexsList.get( index ); + } + + public String getDataTypesListSelectedItem( int index ) { + return (String) dataTypesList.get( index ); + } + + public String getEmptyFlagsListSelectedItem( int index ) { + return (String) emptyFlagsList.get( index ); + } + + public String getDateFormatSelected() { + //return (String) dateFormatCB.getSelectedItem(); + return (String) dateFormatCr.getText(); + } + + public void setDateFormatString( String xxx) { + //dateFormatCB.setSelectedItem( xxx ); + dateFormatCr.setText( xxx ); + } + + public String getDateFormatString() { + //return (String) dateFormatCB.getSelectedItem(); + return dateFormatCr.getText(); + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public void setHeaderLines( int xxx ) + { + headerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setHeaderLines(" + xxx +") text =" + headerLines.getText().trim() + "=" ); + } + + public int getHeaderLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getHeaderLines() text =" + headerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( headerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFooterLines( int xxx ) + { + footerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setFooterLines(" + xxx +") text =" + footerLines.getText().trim() + "=" ); + } + + public int getFooterLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getFooterLines() text =" + footerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( footerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFieldSeparatorChar( int xxx) { + fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar.getText().charAt( 0 ); + } + + public void setFileEncodingSelectedItem( String xxx) { + fileEncodingCB.setSelectedItem( xxx ); + } + + public String getFileEncodingSelectedItem() { + return (String) fileEncodingCB.getSelectedItem(); + } + + public void setAmountCurrencyChar( int xxx) { + amountCurrencyChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar.getText().charAt( 0 ); + } + + public void setAmountDecimalSignChar( int xxx) { + amountDecimalSignChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar.getText().charAt( 0 ); + } + + public void setAmountGroupingSeparatorChar( int xxx) { + amountGroupingSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar.getText().charAt( 0 ); + } + + public void setAmountFormat( String xxx) { + amountFormat.setText( xxx ); + } + + public String getAmountFormat() { + return (String) amountFormat.getText(); + } + + public void setImportReverseOrderFlg( boolean xxx) { + importReverseOrderFlg.setSelected( xxx ); + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg.isSelected(); + } + + public void setUseRegexFlag( boolean xxx) { + useRegexFlag.setSelected( xxx ); + } + + public boolean getUseRegexFlag() { + return useRegexFlag.isSelected(); + } + + public void setFilenameMatcher( String xxx) { + filenameMatcher.setText( xxx ); + } + + public String getFilenameMatcher() { + return (String) filenameMatcher.getText(); + } + + protected void init() + { + /* + dataType0.setSelectedItem( "date" ); + dataType1.setSelectedItem( "amount" ); + dataType2.setSelectedItem( "check number" ); + dataType3 .setSelectedItem( "skip" ); + dataType4.setSelectedItem( "description" ); + dataType5.setSelectedItem( "memo" ); + isNullable2.setSelectedItem( "Can Be Blank" ); + isNullable4.setSelectedItem( "Can Be Blank" ); + isNullable5.setSelectedItem( "Can Be Blank" ); + */ + + ReaderConfigsHM = Settings.createReaderConfigsHM(); + ReaderHM = Settings.getReaderHM(); // not great, but for now the call above must be first because it sets the value for this one to read also. + + /****** Quit using the built in readers ! Force people to make their own + ReaderConfigsHM.put( "citiBankCanadaReader", null ); + ReaderHM.put( "citiBankCanadaReader", citiBankCanadaReader ); + + ReaderConfigsHM.put( "ingNetherlandsReader", null ); + ReaderHM.put( "ingNetherlandsReader", ingNetherlandsReader ); + + ReaderConfigsHM.put( "simpleCreditDebitReader", null ); + ReaderHM.put( "simpleCreditDebitReader", simpleCreditDebitReader ); + + ReaderConfigsHM.put( "wellsFargoReader", null ); + ReaderHM.put( "wellsFargoReader", wellsFargoReader ); + + ReaderConfigsHM.put( "yodleeReader", null ); + ReaderHM.put( "yodleeReader", yodleeReader ); + + ReaderConfigsHM.put( "bbvaCompassReader", null ); + ReaderHM.put( "bbvaCompassReader", bbvaCompassReader ); + ******/ + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + +// ??? this.parent.comboFileFormat1AddItem( "" ); + + // For keys of a map + for ( Iterator it=ReaderHM.keySet().iterator(); it.hasNext(); ) + { + String readerName = (String) it.next(); + System.err.println( "fill out readerName =" + readerName + "=" ); + if ( ReaderHM.get( readerName ).isCustomReaderFlag() ) + { + listModel.addElement( readerName ); + + // needs to be in Settings() +// CustomReader customReader = (CustomReader) getTransactionReader( readerName ); +// CustomReaderData customReaderData = ReaderConfigsHM.get( readerName ); +// +// customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + if ( this.parent != null ) + { + System.err.println( "call add readerName to import dlg reader list =" + readerName + "=" ); + this.parent.comboFileFormat1AddItem( ReaderHM.get( readerName ) ); + } + } + + regexsList.add( (String)regex0.getText() ); + regexsList.add( (String)regex1.getText() ); + regexsList.add( (String)regex2.getText() ); + regexsList.add( (String)regex3.getText() ); + regexsList.add( (String)regex4.getText() ); + regexsList.add( (String)regex5.getText() ); + regexsList.add( (String)regex6.getText() ); + regexsList.add( (String)regex7.getText() ); + regexsList.add( (String)regex8.getText() ); + regexsList.add( (String)regex9.getText() ); + + dataTypesList.add( (String)dataType0.getSelectedItem() ); + dataTypesList.add( (String)dataType1.getSelectedItem() ); + dataTypesList.add( (String)dataType2.getSelectedItem() ); + dataTypesList.add( (String)dataType3.getSelectedItem() ); + dataTypesList.add( (String)dataType4.getSelectedItem() ); + dataTypesList.add( (String)dataType5.getSelectedItem() ); + dataTypesList.add( (String)dataType6.getSelectedItem() ); + dataTypesList.add( (String)dataType7.getSelectedItem() ); + dataTypesList.add( (String)dataType8.getSelectedItem() ); + dataTypesList.add( (String)dataType9.getSelectedItem() ); + + emptyFlagsList.add( (String)isNullable0.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable1.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable2.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable3.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable4.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable5.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable6.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable7.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable8.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable9.getSelectedItem() ); + + // Populate with all possible encodings + SortedMap encodings = Charset.availableCharsets(); + Set encodingNames = encodings.keySet(); + for ( Iterator i = encodingNames.iterator(); i.hasNext(); ) + { + fileEncodingCB.addItem( i.next() ); + } + // Set default Encoding to be UTF-8 + for ( int i = 0; i < fileEncodingCB.getItemCount(); i++ ) + { + if ( TransactionReader.DEFAULT_ENCODING.equals( fileEncodingCB.getItemAt( i ) ) ) + { + fileEncodingCB.setSelectedIndex( i ); + break; + } + } + + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel1 = new javax.swing.JLabel(); + readerName = new javax.swing.JTextField(); + dataType1 = new javax.swing.JComboBox(); + isNullable1 = new javax.swing.JComboBox(); + dataType2 = new javax.swing.JComboBox(); + dataType4 = new javax.swing.JComboBox(); + dataType0 = new javax.swing.JComboBox(); + isNullable0 = new javax.swing.JComboBox(); + isNullable2 = new javax.swing.JComboBox(); + isNullable3 = new javax.swing.JComboBox(); + isNullable4 = new javax.swing.JComboBox(); + isNullable5 = new javax.swing.JComboBox(); + isNullable6 = new javax.swing.JComboBox(); + isNullable7 = new javax.swing.JComboBox(); + isNullable8 = new javax.swing.JComboBox(); + isNullable9 = new javax.swing.JComboBox(); + dataType3 = new javax.swing.JComboBox(); + dataType5 = new javax.swing.JComboBox(); + dataType6 = new javax.swing.JComboBox(); + dataType7 = new javax.swing.JComboBox(); + dataType8 = new javax.swing.JComboBox(); + dataType9 = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + saveBtn = new javax.swing.JButton(); + jLabel12 = new javax.swing.JLabel(); + jLabel13 = new javax.swing.JLabel(); + headerLines = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + customReadersList = new javax.swing.JList(); + jLabel14 = new javax.swing.JLabel(); + addBtn = new javax.swing.JButton(); + deleteBtn = new javax.swing.JButton(); + jLabel15 = new javax.swing.JLabel(); + message = new javax.swing.JLabel(); + jLabel16 = new javax.swing.JLabel(); + jLabel17 = new javax.swing.JLabel(); + doneBtn = new javax.swing.JButton(); + jLabel18 = new javax.swing.JLabel(); + fieldSeparatorChar = new javax.swing.JTextField(); + resetFieldsBtn = new javax.swing.JButton(); + jLabel19 = new javax.swing.JLabel(); + dateFormatCr = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + jLabel21 = new javax.swing.JLabel(); + amountGroupingSeparatorChar = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + amountDecimalSignChar = new javax.swing.JTextField(); + jLabel23 = new javax.swing.JLabel(); + amountCurrencyChar = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + amountFormat = new javax.swing.JTextField(); + jLabel25 = new javax.swing.JLabel(); + jLabel26 = new javax.swing.JLabel(); + footerLines = new javax.swing.JTextField(); + importReverseOrderFlg = new javax.swing.JCheckBox(); + fileEncodingLbl = new javax.swing.JLabel(); + fileEncodingCB = new javax.swing.JComboBox(); + jLabel27 = new javax.swing.JLabel(); + regex0 = new javax.swing.JTextField(); + regex1 = new javax.swing.JTextField(); + regex2 = new javax.swing.JTextField(); + regex3 = new javax.swing.JTextField(); + regex4 = new javax.swing.JTextField(); + regex5 = new javax.swing.JTextField(); + regex6 = new javax.swing.JTextField(); + regex7 = new javax.swing.JTextField(); + regex8 = new javax.swing.JTextField(); + regex9 = new javax.swing.JTextField(); + useRegexFlag = new javax.swing.JCheckBox(); + filenameMatcher = new javax.swing.JTextField(); + jLabel28 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(780, 600)); + setPreferredSize(new java.awt.Dimension(780, 600)); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + jLabel1.setText("Reader Name:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel1, gridBagConstraints); + + readerName.setMinimumSize(new java.awt.Dimension(160, 25)); + readerName.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(readerName, gridBagConstraints); + + dataType1.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType1.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType1, gridBagConstraints); + + isNullable1.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable1.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 12; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable1, gridBagConstraints); + + dataType2.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType2.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType2, gridBagConstraints); + + dataType4.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType4.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType4, gridBagConstraints); + + dataType0.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType0.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType0, gridBagConstraints); + + isNullable0.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable0.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 11; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable0, gridBagConstraints); + + isNullable2.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable2.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 13; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable2, gridBagConstraints); + + isNullable3.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable3.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 14; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable3, gridBagConstraints); + + isNullable4.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable4.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 15; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable4, gridBagConstraints); + + isNullable5.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable5.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 16; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable5, gridBagConstraints); + + isNullable6.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable6.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 17; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable6, gridBagConstraints); + + isNullable7.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable7.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 18; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable7, gridBagConstraints); + + isNullable8.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable8.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 19; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable8, gridBagConstraints); + + isNullable9.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable9.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 20; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable9, gridBagConstraints); + + dataType3.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType3.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType3, gridBagConstraints); + + dataType5.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType5.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType5, gridBagConstraints); + + dataType6.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType6.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType6, gridBagConstraints); + + dataType7.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType7.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType7, gridBagConstraints); + + dataType8.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType8.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType8, gridBagConstraints); + + dataType9.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType9.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType9, gridBagConstraints); + + jLabel2.setText("1"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 11; + getContentPane().add(jLabel2, gridBagConstraints); + + jLabel3.setText("2"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 12; + getContentPane().add(jLabel3, gridBagConstraints); + + jLabel4.setText("3"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 13; + getContentPane().add(jLabel4, gridBagConstraints); + + jLabel5.setText("4"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel5, gridBagConstraints); + + jLabel6.setText("5"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 15; + getContentPane().add(jLabel6, gridBagConstraints); + + jLabel7.setText("6"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(jLabel7, gridBagConstraints); + + jLabel8.setText("7"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 17; + getContentPane().add(jLabel8, gridBagConstraints); + + jLabel9.setText("8"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 18; + getContentPane().add(jLabel9, gridBagConstraints); + + jLabel10.setText("9"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 19; + getContentPane().add(jLabel10, gridBagConstraints); + + jLabel11.setText("10"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 20; + getContentPane().add(jLabel11, gridBagConstraints); + + saveBtn.setText("Save"); + saveBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + saveBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + saveBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + saveBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 22; + getContentPane().add(saveBtn, gridBagConstraints); + + jLabel12.setText(" "); + jLabel12.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 8; + getContentPane().add(jLabel12, gridBagConstraints); + + jLabel13.setText("Number of Footer Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel13, gridBagConstraints); + + headerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + headerLines.setText("1"); + headerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + headerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + headerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + headerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(headerLines, gridBagConstraints); + + jScrollPane1.setMinimumSize(new java.awt.Dimension(160, 85)); + jScrollPane1.setPreferredSize(new java.awt.Dimension(160, 160)); + + customReadersList.setModel(new DefaultListModel() ); + customReadersList.setMaximumSize(new java.awt.Dimension(32767, 32767)); + customReadersList.setMinimumSize(new java.awt.Dimension(160, 85)); + customReadersList.setPreferredSize(new java.awt.Dimension(160, 85)); + customReadersList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + customReadersListMouseClicked(evt); + } + }); + jScrollPane1.setViewportView(customReadersList); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridheight = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; + getContentPane().add(jScrollPane1, gridBagConstraints); + + jLabel14.setText(" "); + jLabel14.setMaximumSize(new java.awt.Dimension(25, 15)); + jLabel14.setMinimumSize(new java.awt.Dimension(25, 15)); + jLabel14.setPreferredSize(new java.awt.Dimension(25, 15)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 10; + getContentPane().add(jLabel14, gridBagConstraints); + + addBtn.setText("Add"); + addBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + addBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + addBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + addBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + getContentPane().add(addBtn, gridBagConstraints); + + deleteBtn.setText("Delete"); + deleteBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + deleteBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + deleteBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + deleteBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 22; + gridBagConstraints.gridwidth = 2; + getContentPane().add(deleteBtn, gridBagConstraints); + + jLabel15.setText("List of Readers:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + getContentPane().add(jLabel15, gridBagConstraints); + + message.setForeground(new java.awt.Color(255, 0, 0)); + message.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 24; + gridBagConstraints.gridwidth = 5; + getContentPane().add(message, gridBagConstraints); + + jLabel16.setText(" "); + jLabel16.setMinimumSize(new java.awt.Dimension(150, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 23; + getContentPane().add(jLabel16, gridBagConstraints); + + jLabel17.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 21; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(jLabel17, gridBagConstraints); + + doneBtn.setText("Done"); + doneBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + doneBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + doneBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + doneBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + doneBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 22; + getContentPane().add(doneBtn, gridBagConstraints); + + jLabel18.setText("CSV Field Separator:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel18, gridBagConstraints); + + fieldSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + fieldSeparatorChar.setText(","); + fieldSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fieldSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fieldSeparatorChar, gridBagConstraints); + + resetFieldsBtn.setText("Reset Fields"); + resetFieldsBtn.setMinimumSize(new java.awt.Dimension(100, 25)); + resetFieldsBtn.setPreferredSize(new java.awt.Dimension(110, 25)); + resetFieldsBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resetFieldsBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 22; + gridBagConstraints.weightx = 0.2; + getContentPane().add(resetFieldsBtn, gridBagConstraints); + + jLabel19.setText("Date Format:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel19, gridBagConstraints); + + dateFormatCr.setText("YYYY-MM-DD"); + dateFormatCr.setToolTipText("\nYou can do things like: MM/DD/YYYY, MM.DD.YY, YY-MM-DD
\nhttp://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html"); + dateFormatCr.setMinimumSize(new java.awt.Dimension(100, 25)); + dateFormatCr.setPreferredSize(new java.awt.Dimension(100, 25)); + dateFormatCr.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dateFormatCrActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(dateFormatCr, gridBagConstraints); + + jLabel20.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 9; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel20, gridBagConstraints); + + jLabel21.setText("Grouping separator:"); + jLabel21.setEnabled(false); + jLabel21.setFocusable(false); + jLabel21.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel21, gridBagConstraints); + + amountGroupingSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountGroupingSeparatorChar.setText(","); + amountGroupingSeparatorChar.setEnabled(false); + amountGroupingSeparatorChar.setFocusable(false); + amountGroupingSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + amountGroupingSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountGroupingSeparatorChar, gridBagConstraints); + + jLabel22.setText("Decimal Sign:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel22, gridBagConstraints); + + amountDecimalSignChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountDecimalSignChar.setText("."); + amountDecimalSignChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountDecimalSignChar.setPreferredSize(new java.awt.Dimension(20, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountDecimalSignChar, gridBagConstraints); + + jLabel23.setText("Currency Symbol:"); + jLabel23.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel23, gridBagConstraints); + + amountCurrencyChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountCurrencyChar.setText(" "); + amountCurrencyChar.setEnabled(false); + amountCurrencyChar.setMinimumSize(new java.awt.Dimension(40, 25)); + amountCurrencyChar.setPreferredSize(new java.awt.Dimension(40, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountCurrencyChar, gridBagConstraints); + + jLabel24.setText("Amount Format:"); + jLabel24.setEnabled(false); + jLabel24.setFocusable(false); + jLabel24.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel24, gridBagConstraints); + + amountFormat.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountFormat.setText(" "); + amountFormat.setEnabled(false); + amountFormat.setFocusable(false); + amountFormat.setMinimumSize(new java.awt.Dimension(160, 25)); + amountFormat.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountFormat, gridBagConstraints); + + jLabel25.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 2; + getContentPane().add(jLabel25, gridBagConstraints); + + jLabel26.setText("Number of Header Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel26, gridBagConstraints); + + footerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + footerLines.setText("0"); + footerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + footerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + footerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + footerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(footerLines, gridBagConstraints); + + importReverseOrderFlg.setText("Import Transactions in Reverse Order."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 2; + getContentPane().add(importReverseOrderFlg, gridBagConstraints); + + fileEncodingLbl.setText("File Encoding:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(fileEncodingLbl, gridBagConstraints); + + fileEncodingCB.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + fileEncodingCB.setMinimumSize(new java.awt.Dimension(120, 25)); + fileEncodingCB.setPreferredSize(new java.awt.Dimension(140, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fileEncodingCB, gridBagConstraints); + + jLabel27.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + getContentPane().add(jLabel27, gridBagConstraints); + + regex0.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex0ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex0, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex1, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex2, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex3, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex4, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex5, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex6, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex7, gridBagConstraints); + + regex8.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex8ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex8, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex9, gridBagConstraints); + + useRegexFlag.setText("Use Regex to Parse Fields"); + useRegexFlag.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useRegexFlagActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 10; + getContentPane().add(useRegexFlag, gridBagConstraints); + + filenameMatcher.setText(".*\\.(csv|CSV)"); + filenameMatcher.setMinimumSize(new java.awt.Dimension(160, 25)); + filenameMatcher.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + getContentPane().add(filenameMatcher, gridBagConstraints); + + jLabel28.setText("Filename Matcher:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel28, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed + message.setText( "" ); + + if ( ! ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "There is no reader by that name '" + readerName.getText() + "'" ); + } + +// int i = 0; +// for ( String dataType : dataTypesList ) +// { +// System.out.println( "datatype " + i + " =" + dataType + "=" ); +// i++; +// } + + try + { + int x = Integer.parseInt( headerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Header Lines must be 0 or more" ); + return; + } + + try + { + int x = Integer.parseInt( footerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Footer Lines must be 0 or more" ); + return; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerName.getText() ); + + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + // *** I could get and replace the existing one but just do this for now until things work ! ! ! + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + Settings.setCustomReaderConfig( customReaderData ); + }//GEN-LAST:event_saveBtnActionPerformed + + private void headerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_headerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_headerLinesActionPerformed + + private void doneBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doneBtnActionPerformed + this.setVisible( false ); + + /** turning all this off so we do not test all readers when they hit 'Done' + parent.setSkipDuringInit( true ); + parent.fileChanged(); + this.parent.comboFileFormat1SetItem( ReaderHM.get( readerName.getText() ) ); + parent.setSkipDuringInit( false ); + //System.out.println( "done button (String) dateFormatCB.getSelectedItem() =" + (String) dateFormatCB.getSelectedItem() + "=" ); + //this.parent.comboDateFormatSetItem( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + **/ + }//GEN-LAST:event_doneBtnActionPerformed + + private void fieldSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fieldSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_fieldSeparatorCharActionPerformed + + private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed + addReaderConfig(); + }//GEN-LAST:event_addBtnActionPerformed + + private void deleteBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteBtnActionPerformed + deleteReaderConfig(); + }//GEN-LAST:event_deleteBtnActionPerformed + + private void customReadersListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_customReadersListMouseClicked + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + getReaderConfig( (String) listModel.getElementAt( index ) ); + useRegexFlagActionPerformed( null ); + }//GEN-LAST:event_customReadersListMouseClicked + + private void resetFieldsBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetFieldsBtnActionPerformed + clearReaderConfig(); + }//GEN-LAST:event_resetFieldsBtnActionPerformed + + private void dateFormatCrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateFormatCrActionPerformed + ; + }//GEN-LAST:event_dateFormatCrActionPerformed + + private void amountGroupingSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_amountGroupingSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_amountGroupingSeparatorCharActionPerformed + + private void footerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_footerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_footerLinesActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + DecimalFormatSymbols decForSyms = new DecimalFormatSymbols(); + DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(); + int numDigits = decFormat.getCurrency().getDefaultFractionDigits(); + amountCurrencyChar.setText( decFormat.getCurrency().getSymbol() ); + String format = "0"; + int i; + // if ( decFormat.getmax > 0 ) + // { + format += decForSyms.getDecimalSeparator(); + // } + //System.out.println( "decFormat.getMinimumIntegerDigits() =" + decFormat.getMinimumIntegerDigits() ); + for ( i = 0; i < 2; i ++ ) + { + format+= "0"; + } + + //amountDecimalSignChar.setText( ); + int groupSize = decFormat.getGroupingSize(); + char groupSep = decForSyms.getGroupingSeparator(); + amountGroupingSeparatorChar.setText( groupSep + "" ); + amountDecimalSignChar.setText( decForSyms.getDecimalSeparator() + "" ); + + int gscnt = 1; + for ( i = 1; i < 10; i ++ ) + { + if ( gscnt == groupSize ) + { + format = groupSep + format; + gscnt = 1; + } + else + { + gscnt ++; + } + format = "#" + format; + } + format = decForSyms.getCurrencySymbol() + format; + amountFormat.setText( format ); + }//GEN-LAST:event_formWindowOpened + + private void regex0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex0ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex0ActionPerformed + + private void regex8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex8ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex8ActionPerformed + + private void useRegexFlagActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useRegexFlagActionPerformed + if ( useRegexFlag.isSelected() ) + { + // This is just for a first time to give them a working example of a usable regex + if ( regex0.getText().isEmpty() + && regex1.getText().isEmpty() + && regex2.getText().isEmpty() + && regex3.getText().isEmpty() + && regex4.getText().isEmpty() + && regex5.getText().isEmpty() + ) + { + regex0.setText( "([^,]*([,]|\\Z)).*" ); + regex1.setText( "([^,]*([,]|\\Z)).*" ); + regex2.setText( "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*" ); + regex3.setText( "([^,]*([,]|\\Z)).*" ); + regex4.setText( "([^,]*([,]|\\Z)).*" ); + regex5.setText( "([^,]*([,]|\\Z)).*" ); + } + regex0.setVisible( true ); + regex1.setVisible( true ); + regex2.setVisible( true ); + regex3.setVisible( true ); + regex4.setVisible( true ); + regex5.setVisible( true ); + regex6.setVisible( true ); + regex7.setVisible( true ); + regex8.setVisible( true ); + regex9.setVisible( true ); + } + else + { +// regex0.setText( "" ); +// regex1.setText( "" ); +// regex2.setText( "" ); +// regex3.setText( "" ); +// regex4.setText( "" ); +// regex5.setText( "" ); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + } + }//GEN-LAST:event_useRegexFlagActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + CustomReaderDialog dialog = new CustomReaderDialog( null, true ); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addBtn; + private javax.swing.JTextField amountCurrencyChar; + private javax.swing.JTextField amountDecimalSignChar; + private javax.swing.JTextField amountFormat; + private javax.swing.JTextField amountGroupingSeparatorChar; + private javax.swing.JList customReadersList; + private javax.swing.JComboBox dataType0; + private javax.swing.JComboBox dataType1; + private javax.swing.JComboBox dataType2; + private javax.swing.JComboBox dataType3; + private javax.swing.JComboBox dataType4; + private javax.swing.JComboBox dataType5; + private javax.swing.JComboBox dataType6; + private javax.swing.JComboBox dataType7; + private javax.swing.JComboBox dataType8; + private javax.swing.JComboBox dataType9; + private javax.swing.JTextField dateFormatCr; + private javax.swing.JButton deleteBtn; + private javax.swing.JButton doneBtn; + private javax.swing.JTextField fieldSeparatorChar; + private javax.swing.JComboBox fileEncodingCB; + private javax.swing.JLabel fileEncodingLbl; + private javax.swing.JTextField filenameMatcher; + private javax.swing.JTextField footerLines; + private javax.swing.JTextField headerLines; + private javax.swing.JCheckBox importReverseOrderFlg; + private javax.swing.JComboBox isNullable0; + private javax.swing.JComboBox isNullable1; + private javax.swing.JComboBox isNullable2; + private javax.swing.JComboBox isNullable3; + private javax.swing.JComboBox isNullable4; + private javax.swing.JComboBox isNullable5; + private javax.swing.JComboBox isNullable6; + private javax.swing.JComboBox isNullable7; + private javax.swing.JComboBox isNullable8; + private javax.swing.JComboBox isNullable9; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel25; + private javax.swing.JLabel jLabel26; + private javax.swing.JLabel jLabel27; + private javax.swing.JLabel jLabel28; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel message; + private javax.swing.JTextField readerName; + private javax.swing.JTextField regex0; + private javax.swing.JTextField regex1; + private javax.swing.JTextField regex2; + private javax.swing.JTextField regex3; + private javax.swing.JTextField regex4; + private javax.swing.JTextField regex5; + private javax.swing.JTextField regex6; + private javax.swing.JTextField regex7; + private javax.swing.JTextField regex8; + private javax.swing.JTextField regex9; + private javax.swing.JButton resetFieldsBtn; + private javax.swing.JButton saveBtn; + private javax.swing.JCheckBox useRegexFlag; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.netbeans-base new file mode 100644 index 0000000..1f5480e --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.netbeans-base @@ -0,0 +1,45 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.awt.Color; +import java.awt.Component; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * + * @author stan + */ + + +public class CustomTableCellRenderer extends DefaultTableCellRenderer { + + int forRow = -1; + int forCol = -1; + + public void setForRowCol( int row, int col ) + { + forRow = row; + forCol = col; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) + { + JLabel lbl = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + //Get the status for the current row. + PreviewImportTblModel tableModel = (PreviewImportTblModel) table.getModel(); + if ( (row == forRow || forRow < 0) && (col == forCol || forCol < 0) ) + { + lbl.setBackground( Color.RED ); + } + else + { + //lbl.setBackground( javax.swing.UIManager.getColor( "Table.dropCellBackground" ) ); + lbl.setBackground( Color.WHITE ); + } + //Return the JLabel which renders the cell. + return lbl; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.svn-base new file mode 100644 index 0000000..1f5480e --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomTableCellRenderer.java.svn-base @@ -0,0 +1,45 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.awt.Color; +import java.awt.Component; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * + * @author stan + */ + + +public class CustomTableCellRenderer extends DefaultTableCellRenderer { + + int forRow = -1; + int forCol = -1; + + public void setForRowCol( int row, int col ) + { + forRow = row; + forCol = col; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) + { + JLabel lbl = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + //Get the status for the current row. + PreviewImportTblModel tableModel = (PreviewImportTblModel) table.getModel(); + if ( (row == forRow || forRow < 0) && (col == forCol || forCol < 0) ) + { + lbl.setBackground( Color.RED ); + } + else + { + //lbl.setBackground( javax.swing.UIManager.getColor( "Table.dropCellBackground" ) ); + lbl.setBackground( Color.WHITE ); + } + //Return the JLabel which renders the cell. + return lbl; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DataField.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DataField.java.svn-base new file mode 100644 index 0000000..888147d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DataField.java.svn-base @@ -0,0 +1,14 @@ +// Error reading included file Templates/Beans/../Licenses/license-LGPL.txt +package com.moneydance.modules.features.mdcsvimporter; + +import java.beans.*; +import java.io.Serializable; + +/** + * + * @author stowians + */ +public class DataField implements Serializable { + + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesser.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesser.java.svn-base new file mode 100644 index 0000000..5686393 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesser.java.svn-base @@ -0,0 +1,421 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * + * @author miki + */ +public class DateGuesser +{ + private static final int EOF = -1; + private static final String D = "D"; + private static final String DD = "DD"; + private static final String M = "M"; + private static final String MM = "MM"; + private static final String YY = "YY"; + private static final String YYYY = "YYYY"; + private Map results = new HashMap(); + private int datesDetected = 0; + private String[] possibleFormats; + private double bestFormatProbability; + private StringBuilder field1 = new StringBuilder(); + private int field1Value; + private String field1Format; + private int separator1; + private StringBuilder field2 = new StringBuilder(); + private int field2Value; + private String field2Format; + private int separator2; + private StringBuilder field3 = new StringBuilder(); + private int field3Value; + private String field3Format; + private StringBuilder format = new StringBuilder(); + + public void checkDateString( String date ) + { + try + { + date = date.trim(); + StringReader reader = new StringReader( date ); + + separator1 = parseField( reader, field1 ); + separator2 = parseField( reader, field2 ); + int eof = parseField( reader, field3 ); + + if ( field1.length() == 0 || field2.length() == 0 || field3.length() == 0 || + !isEof( eof ) ) + { + return; + } + + field1Value = Integer.parseInt( field1.toString() ); + field2Value = Integer.parseInt( field2.toString() ); + field3Value = Integer.parseInt( field3.toString() ); + + if ( checkPossibleFormats() ) + { + ++datesDetected; + } + } + catch ( Exception x ) + { + // ignore errors, simply means this is probably not a date string + } + } + + private boolean checkPossibleFormats() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Value >= 1 && field1Value <= 31 && field1.length() <= 2 ) + { + if ( field1.length() == 1 ) + { + field1Format = D; + retVal |= checkPossibleFormats2(); + } + else + { + field1Format = DD; + retVal |= checkPossibleFormats2(); + if ( field1Value < 10 ) // >= 10 ) + { + field1Format = D; + retVal |= checkPossibleFormats2(); + } + } + } + + // check if its possible to be a month + if ( field1Value >= 1 && field1Value <= 12 && field1.length() <= 2 ) + { + if ( field1.length() == 1 ) + { + field1Format = M; + retVal |= checkPossibleFormats2(); + } + else + { + field1Format = MM; + retVal |= checkPossibleFormats2(); + if ( field1Value < 10 ) // >= 10 ) + { + field1Format = M; + retVal |= checkPossibleFormats2(); + } + } + } + + // check if its possible to be a year + if ( field1.length() == 2 ) + { + field1Format = YY; + retVal |= checkPossibleFormats2(); + } + else if ( field1.length() == 4 ) + { + field1Format = YYYY; + retVal |= checkPossibleFormats2(); + } + + return retVal; + } + + private boolean checkPossibleFormats2() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Format != D && field1Format != DD ) + { + if ( field2Value >= 1 && field2Value <= 31 && field2.length() <= 2 ) + { + if ( field2.length() == 1 ) + { + field2Format = D; + retVal |= checkPossibleFormats3(); + } + else + { + field2Format = DD; + retVal |= checkPossibleFormats3(); + if ( field2Value < 10 ) // >= 10 ) + { + field2Format = D; + retVal |= checkPossibleFormats3(); + } + } + } + } + + // check if its possible to be a month + if ( field1Format != M && field1Format != MM ) + { + if ( field2Value >= 1 && field2Value <= 12 && field2.length() <= 2 ) + { + if ( field2.length() == 1 ) + { + field2Format = M; + retVal |= checkPossibleFormats3(); + } + else + { + field2Format = MM; + retVal |= checkPossibleFormats3(); + if ( field2Value < 10 ) // >= 10 ) + { + field2Format = M; + retVal |= checkPossibleFormats3(); + } + } + } + } + + // check if its possible to be a year + if ( field1Format != YY && field1Format != YYYY ) + { + if ( field2.length() == 2 ) + { + field2Format = YY; + retVal |= checkPossibleFormats3(); + } + else if ( field2.length() == 4 ) + { + field2Format = YYYY; + retVal |= checkPossibleFormats3(); + } + } + + return retVal; + } + + private boolean checkPossibleFormats3() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Format != D && field1Format != DD && field2Format != D && field2Format != + DD ) + { + if ( field3Value >= 1 && field3Value <= 31 && field3.length() <= 2 ) + { + if ( field3.length() == 1 ) + { + field3Format = D; + retVal = true; + registerFormat(); + } + else + { + field3Format = DD; + retVal = true; + registerFormat(); + if ( field3Value < 10 ) // >= 10 ) + { + field3Format = D; + registerFormat(); + } + } + } + } + + // check if its possible to be a month + if ( field1Format != M && field1Format != MM && field2Format != M && field2Format != + MM ) + { + if ( field3Value >= 1 && field3Value <= 12 && field3.length() <= 2 ) + { + if ( field3.length() == 1 ) + { + field3Format = M; + retVal = true; + registerFormat(); + } + else + { + field3Format = MM; + retVal = true; + registerFormat(); + if ( field3Value < 10 ) // >= 10 ) + { + field3Format = M; + registerFormat(); + } + } + } + } + + // check if its possible to be a year + if ( field1Format != YY && field1Format != YYYY && field2Format != YY && + field2Format != YYYY ) + { + if ( field3.length() == 2 ) + { + field3Format = YY; + retVal = true; + registerFormat(); + } + else if ( field3.length() == 4 ) + { + field3Format = YYYY; + retVal = true; + registerFormat(); + } + } + + return retVal; + } + + private void registerFormat() + { + clearResults(); + + format.setLength( 0 ); + format.append( field1Format ); + format.appendCodePoint( separator1 ); + format.append( field2Format ); + format.appendCodePoint( separator2 ); + format.append( field3Format ); + + String key = format.toString(); + + Integer count = results.get( key ); + if ( count == null ) + { + System.err.println( "saving format key =" + key + "= count =" + 1 ); + results.put( key, 1 ); + } + else + { + System.err.println( "saving format key =" + key + "= count =" + (count + 1) ); + results.put( key, count + 1 ); + } + } + + public String getBestFormat() + { + calculateResults(); + + if ( possibleFormats.length > 0 ) + { + return possibleFormats[0]; + } + else + { + return null; + } + } + + public double getBestFormatProbability() + { + calculateResults(); + + return bestFormatProbability; + } + + public String[] getPossibleFormats() + { + calculateResults(); + + return possibleFormats; + } + + private void clearResults() + { + possibleFormats = null; + bestFormatProbability = 0; + } + + private void calculateResults() + { + if ( possibleFormats != null ) + { // are results already calculated? + return; + } + + SortedMap sortedResults = new TreeMap( + new Comparator() + { + public int compare( Integer o1, Integer o2 ) + { + return o2 - o1; + } + } ); + + for ( Map.Entry entry : results.entrySet() ) + { + System.err.println( "results before sort entry.getValue() =" + entry.getValue() + "= entry.getKey() =" + entry.getKey() + "=" ); + sortedResults.put( entry.getValue(), entry.getKey() ); + } + + possibleFormats = new String[sortedResults.size()]; + sortedResults.values().toArray( possibleFormats ); + + for ( String tmp : possibleFormats ) + { + System.err.println( "possibleFormats =" + tmp + "=" ); + } + + if ( datesDetected == 0 ) + { + bestFormatProbability = 0; + } + else + { + bestFormatProbability = sortedResults.firstKey().doubleValue() / + (double) datesDetected; + } + } + + protected static final int parseField( Reader reader, StringBuilder fieldValue ) + throws IOException + { + fieldValue.setLength( 0 ); + + if ( !reader.ready() ) + { + return -1; + } + + int ch; + for ( ch = reader.read(); isDigit( ch ); ch = reader.read() ) + { + fieldValue.appendCodePoint( ch ); + } + + return ch; + } + + private static final boolean isDigit( int ch ) + { + return ch >= '0' && ch <= '9'; + } + + private static final boolean isEof( int ch ) + { + return ch == EOF; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.netbeans-base new file mode 100644 index 0000000..83fcb7d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.netbeans-base @@ -0,0 +1,431 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.svn-base new file mode 100644 index 0000000..83fcb7d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.form.svn-base @@ -0,0 +1,431 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.netbeans-base new file mode 100644 index 0000000..eb4a225 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.netbeans-base @@ -0,0 +1,1493 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import static com.moneydance.modules.features.mdcsvimporter.TransactionReader.importDialog; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.JOptionPane; +import javax.swing.KeyStroke; + +/** + * + * @author miki & Stan Towianski + */ +public class ImportDialog + extends javax.swing.JDialog +{ + private OnlineManager onlineMgr = null; + private File selectedFile; + private CSVData csvData; + private Main main; + private HashMap runArgsHM; + protected final static String RUN_ARGS_FILE = "file"; + protected final static String RUN_ARGS_FILEFORMAT = "fileformat"; + protected final static String RUN_ARGS_DATEFORMAT = "dateformat"; + protected final static String RUN_ARGS_IMPORTACCOUNT = "importaccount"; + protected final static String RUN_ARGS_IMPORTTYPE = "importtype"; + protected final static String RUN_ARGS_PROCESSFLAG = "processflag"; + protected final static String RUN_ARGS_DELETECSVFILEFLAG = "deletecsvfileflag"; + protected final static String RUN_ARGS_NOPOPERRORSFLAG = "nopoperrorsflag"; + protected final static String RUN_ARGS_JUNIT = "junitflag"; + + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILE = 1; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE = 2; + protected final static int RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT = 3; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT = 4; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE = 5; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT = 6; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILE = 7; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT = 8; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT = 9; + + private CustomReaderDialog customReaderDialog = new CustomReaderDialog( this, true ); + private ArrayList errCodeList = new ArrayList(); + private boolean skipDuringInit = true; + private boolean autoProcessedAFile = false; + + private boolean GET_ALL_READERS = true; + private boolean GET_COMPATIBLE_READERS = false; + + public ImportDialog() + { + } + + public ImportDialog( Main main, HashMap runArgsHM ) + { + super( main.getMoneydanceWindow(), true ); + initComponents(); + this.runArgsHM = runArgsHM; + autoProcessedAFile = false; + + customReaderDialog.init(); + customReaderDialog.setLocationRelativeTo( getRootPane() ); + + /** + textFilename.getDocument().addDocumentListener( new DocumentListener() + { + public void insertUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void removeUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void changedUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + } ); + **/ + + this.main = main; + + if ( main.getMainContext() != null ) + { + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + + fillAccountCombo( main ); + } + + checkDeleteFile.setSelected( Settings.getBoolean( false, "delete.file" ) ); + onlineImportTypeRB.setSelected( Settings.getBoolean( false, "importtype.online.radiobutton" ) ); + + skipDuringInit = false; + this.setModal( false ); + this.addEscapeListener( this ); + TransactionReader.init( customReaderDialog, this, main.getRootAccount() ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + protected ArrayList processRunArguments() + { + errCodeList = new ArrayList(); + boolean errorInRunArgs = false; + + if ( runArgsHM.containsKey( RUN_ARGS_FILE ) ) + { + selectedFile = new File( (String) runArgsHM.get( RUN_ARGS_FILE ) ); + if ( ! selectedFile.exists() ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nfile \'" + + (String) runArgsHM.get( RUN_ARGS_FILE ) + "\' does not exist.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILE ); + errorInRunArgs = true; + } + else + { + textFilename.setSelectedItem( selectedFile.getPath() ); + fileChanged(); + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTTYPE ) ) + { + if ( "ONLINE".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + onlineImportTypeRB.setSelected( true ); + } + else if ( "REGULAR".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + regularImportTypeRB.setSelected( true ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTTYPE + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_DELETECSVFILEFLAG ) ) + { + checkDeleteFile.setSelected( true ); + } + + if ( runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + //if ( customReaderDialog.getReaderConfig( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ) ) + TransactionReader reqTransReader = customReaderDialog.getTransactionReader( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ); + if ( reqTransReader != null ) + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) comboFileFormat.getModel(); + int idx = dcbm.getIndexOf( reqTransReader ); + + if ( idx >= 0 ) + { + comboFileFormat.setSelectedItem( reqTransReader ); + processFileFormatChanged( reqTransReader ); // call it myself so I know when it is done. + if ( runArgsHM.containsKey( RUN_ARGS_DATEFORMAT ) ) + { + dcbm = (DefaultComboBoxModel) comboDateFormat.getModel(); + idx = dcbm.getIndexOf( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + + if ( idx >= 0 ) + { + comboDateFormat.setSelectedItem( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_DATEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) + "\' is not valid for the \'" + RUN_ARGS_FILEFORMAT + "\' used.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + dcbm = (DefaultComboBoxModel) comboAccount.getModel(); + int max = comboAccount.getItemCount(); + System.err.println( "runArgs at importaccount max =" + max ); + Account foundAccount = null; + + for ( idx = max - 1; idx >= 0; idx-- ) + { + System.err.println( "getAcountName() =" + ((Account) dcbm.getElementAt( idx )).getAccountName() + + "= importaccount =" + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "=" ); + if ( ((Account) dcbm.getElementAt( idx )).getAccountName().equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) ) ) + { + foundAccount = (Account) dcbm.getElementAt( idx ); + break; + } + } + + if ( idx >= 0 ) + { + comboAccount.setSelectedItem( foundAccount ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTACCOUNT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_FILEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\' is not valid for the file you gave.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + errorInRunArgs = true; + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nof invalid \'" + RUN_ARGS_FILEFORMAT + "\' value \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\'.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT ); + errorInRunArgs = true; + } + } // endif fileformat + + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILEFORMAT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT ); + errorInRunArgs = true; + } + else if ( ! runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_IMPORTACCOUNT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) && ! errorInRunArgs ) + { + btnProcessActionPerformed( null ); + autoProcessedAFile = true; + } + + } // END of arguments processing + else if ( runArgsHM.size() > 0 ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILE + "\' argument " + , "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + errorInRunArgs = true; + } + return errCodeList; + } + + private void fillAccountCombo( Main main ) + { + RootAccount rootAccount = main.getRootAccount(); + comboAccount.removeAllItems(); + + fillAccountCombo_( rootAccount ); + + if ( comboAccount.getItemCount() > 0 ) + { + System.err.println( "Settings.getInteger( false, \"selected.account\", 0 ) =" + Settings.getInteger( false, "selected.account", 0 ) ); + try { + comboAccount.setSelectedIndex( Settings.getInteger( false, "selected.account", 0 ) ); + } + catch( Exception ex ) + { + JOptionPane.showMessageDialog( rootPane, "Your 'Import to Account' is not longer valid. " + + "You will have to choose a new one.", + "Import to Account setting", + JOptionPane.ERROR_MESSAGE ); + } + } + } + + private void fillAccountCombo_( Account parentAccount ) + { + for ( int i = 0; i < parentAccount.getSubAccountCount(); ++i ) + { + Account account = parentAccount.getSubAccount( i ); + if ( account.isRegisterAccount() ) + { + comboAccount.addItem( account ); + } + else + { + fillAccountCombo_( account ); + } + } + } + + public boolean isSkipDuringInit() { + return skipDuringInit; + } + + public void setSkipDuringInit(boolean skipDuringInit) { + this.skipDuringInit = skipDuringInit; + } + + public boolean isSelectedOnlineImportTypeRB() { + System.err.println( "onlineImportTypeRB.isSelected() =" + onlineImportTypeRB.isSelected() + "=" ); + return onlineImportTypeRB.isSelected(); + } + + public boolean isAutoProcessedAFile() { + return autoProcessedAFile; + } + + public void setPropertiesFile() { + this.propertiesFile.setText( Settings.getFilename().toString() ); + } + + private void processFileFormatChanged( TransactionReader transReader ) + { + System.err.println( "processFileFormatChanged() --------------- " ); + + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + +// System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); +// System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + transReader.isUsingCategorynameFlag() + "=" ); +// if ( importDialog.isSelectedOnlineImportTypeRB() && transReader.isUsingCategorynameFlag() ) +// { +// JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\'" +// , "Message", JOptionPane.INFORMATION_MESSAGE ); +// } + } + + String[] formats = transReader.getSupportedDateFormats(); + System.err.println( "importDialog().processFileFormatChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel3 = new javax.swing.JLabel(); + buttonGroup1 = new javax.swing.ButtonGroup(); + lblSelectFile = new javax.swing.JLabel(); + btnBrowse = new javax.swing.JButton(); + checkDeleteFile = new javax.swing.JCheckBox(); + btnClose = new javax.swing.JButton(); + btnProcess = new javax.swing.JButton(); + lblAccount = new javax.swing.JLabel(); + comboAccount = new javax.swing.JComboBox(); + lblMessage = new javax.swing.JLabel(); + lblFileFormat = new javax.swing.JLabel(); + comboFileFormat = new javax.swing.JComboBox(); + onlineImportTypeRB = new javax.swing.JRadioButton(); + regularImportTypeRB = new javax.swing.JRadioButton(); + lblDateFormat = new javax.swing.JLabel(); + comboDateFormat = new javax.swing.JComboBox(); + jButton1 = new javax.swing.JButton(); + jLabel5 = new javax.swing.JLabel(); + comboFileFormatLabel = new javax.swing.JLabel(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + propertiesFile = new javax.swing.JLabel(); + PreviewImportBtn = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); + textFilename = new javax.swing.JComboBox(); + jButton4 = new javax.swing.JButton(); + jButton5 = new javax.swing.JButton(); + + jLabel3.setText("jLabel3"); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Import File: " + main.VERSION_STRING); + setName("importDialog"); // NOI18N + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + lblSelectFile.setText("Select Import File:"); + lblSelectFile.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblSelectFile, gridBagConstraints); + + btnBrowse.setText("..."); + btnBrowse.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnBrowseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 10); + getContentPane().add(btnBrowse, gridBagConstraints); + + checkDeleteFile.setText("Securely erase file after processing."); + checkDeleteFile.setToolTipText("If checked, the specified file will be securely erased (first overwritten, then deleted) after successful processing."); + checkDeleteFile.setPreferredSize(new java.awt.Dimension(250, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 13; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 10, 10, 0); + getContentPane().add(checkDeleteFile, gridBagConstraints); + + btnClose.setText("Close"); + btnClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCloseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnClose, gridBagConstraints); + + btnProcess.setText("Process"); + btnProcess.setEnabled(false); + btnProcess.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnProcessActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnProcess, gridBagConstraints); + + lblAccount.setText("Import to Account:"); + lblAccount.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblAccount, gridBagConstraints); + + comboAccount.setModel(new javax.swing.DefaultComboBoxModel(new Account[] { })); + comboAccount.setMaximumSize(new java.awt.Dimension(180, 29)); + comboAccount.setMinimumSize(new java.awt.Dimension(180, 29)); + comboAccount.setPreferredSize(new java.awt.Dimension(180, 29)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboAccount, gridBagConstraints); + + lblMessage.setForeground(new java.awt.Color(255, 0, 51)); + lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + lblMessage.setText(" "); + lblMessage.setMaximumSize(new java.awt.Dimension(200, 25)); + lblMessage.setMinimumSize(new java.awt.Dimension(100, 25)); + lblMessage.setOpaque(true); + lblMessage.setPreferredSize(new java.awt.Dimension(3, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 18; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.ipady = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(lblMessage, gridBagConstraints); + + lblFileFormat.setText("File Reader:"); + lblFileFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblFileFormat, gridBagConstraints); + + comboFileFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboFileFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboFileFormat.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + fileFormatChanged(evt); + } + }); + comboFileFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboFileFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboFileFormat, gridBagConstraints); + + buttonGroup1.add(onlineImportTypeRB); + onlineImportTypeRB.setText("Online"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(onlineImportTypeRB, gridBagConstraints); + + buttonGroup1.add(regularImportTypeRB); + regularImportTypeRB.setSelected(true); + regularImportTypeRB.setText("Regular"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(regularImportTypeRB, gridBagConstraints); + + lblDateFormat.setText("Date Format:"); + lblDateFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblDateFormat, gridBagConstraints); + + comboDateFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboDateFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboDateFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboDateFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboDateFormat, gridBagConstraints); + + jButton1.setText("Maintain Custom File Readers"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10); + getContentPane().add(jButton1, gridBagConstraints); + + jLabel5.setText("Import Transactions as:"); + jLabel5.setToolTipText("Online: These will not have a default category pre-set.
\nRegular: These are regular transactions and they get the default category for the account.
\n        You can also import a 'tag' field in the regular type."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); + getContentPane().add(jLabel5, gridBagConstraints); + + comboFileFormatLabel.setText(" "); + comboFileFormatLabel.setMaximumSize(new java.awt.Dimension(60, 25)); + comboFileFormatLabel.setMinimumSize(new java.awt.Dimension(40, 25)); + comboFileFormatLabel.setPreferredSize(new java.awt.Dimension(60, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(comboFileFormatLabel, gridBagConstraints); + + jButton2.setText("Suggestions"); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 13; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END; + getContentPane().add(jButton2, gridBagConstraints); + + jLabel1.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel1, gridBagConstraints); + + propertiesFile.setText(" "); + propertiesFile.setMaximumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setMinimumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setPreferredSize(new java.awt.Dimension(180, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 19; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH; + gridBagConstraints.insets = new java.awt.Insets(4, 10, 10, 10); + getContentPane().add(propertiesFile, gridBagConstraints); + + PreviewImportBtn.setText("Preview Import"); + PreviewImportBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + PreviewImportBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(PreviewImportBtn, gridBagConstraints); + + jButton3.setText("Find Reader(s) that Work on Import File"); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton3, gridBagConstraints); + + textFilename.setModel(new javax.swing.DefaultComboBoxModel(new String[] { " " })); + textFilename.setMinimumSize(new java.awt.Dimension(180, 29)); + textFilename.setPreferredSize(new java.awt.Dimension(180, 29)); + textFilename.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + textFilenameItemStateChanged(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(textFilename, gridBagConstraints); + + jButton4.setText("Find Import File(s) for this Reader"); + jButton4.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton4ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton4, gridBagConstraints); + + jButton5.setText("List All Readers"); + jButton5.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton5ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 2; + getContentPane().add(jButton5, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnBrowseActionPerformed + {//GEN-HEADEREND:event_btnBrowseActionPerformed + JFileChooser dialog = new JFileChooser(); + dialog.setFileHidingEnabled( true ); + dialog.setDialogTitle( "Select text file" ); + dialog.setCurrentDirectory( + new File( Settings.get( false, "last.directory", + dialog.getCurrentDirectory().getAbsolutePath() ) ) ); + dialog.addChoosableFileFilter( new FileFilter() + { + @Override + public boolean accept( File f ) + { + return f.isDirectory() || f.getName().toUpperCase().endsWith( ".CSV" ); + } + + @Override + public String getDescription() + { + return "Formatted Text File (*.csv)"; + } + } ); + if ( dialog.showDialog( this, "Select" ) == JFileChooser.APPROVE_OPTION ) + { + selectedFile = dialog.getSelectedFile(); + Settings.set( "last.directory", dialog.getCurrentDirectory().getAbsolutePath() ); + // textFilename.setSelectedItem( selectedFile.getPath() ); + String[] tt = { selectedFile.getPath() }; + popTextFilenameList( tt ); +// fileChanged(); + fileChanged2(); + btnProcess.setEnabled( false ); + } +}//GEN-LAST:event_btnBrowseActionPerformed + + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed + {//GEN-HEADEREND:event_btnCloseActionPerformed + this.setVisible( false ); + }//GEN-LAST:event_btnCloseActionPerformed + + private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnProcessActionPerformed + {//GEN-HEADEREND:event_btnProcessActionPerformed + System.err.println( "Process button entered" ); + Settings.setYesNo( "delete.file", checkDeleteFile.isSelected() ); + Settings.setYesNo( "importtype.online.radiobutton", onlineImportTypeRB.isSelected() ); + Settings.setInteger( "selected.account", comboAccount.getSelectedIndex() ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + System.err.println( "starting transReader.parse..." ); + transReader.parse( main, csvData, account, main.getRootAccount() ); + csvReader.close(); + System.out.println( "finished transReader.parse" ); + + //TESTING! DS +// onlineMgr.processDownloadedTxns( account ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem importing " + + " selected file, probably because the file format was wrong. Some items " + + "might have been added to your account.", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + + if ( checkDeleteFile.isSelected() ) + { + try + { + SecureFileDeleter.delete( selectedFile ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "The file was imported properly, " + + "however it could not be erased as requested.", "Cannot Delete File", + JOptionPane.ERROR_MESSAGE ); + return; + } + } + + if ( ! Settings.getBoolean( false, "success.dialog.shown", false ) ) + { + Settings.setYesNo( "success.dialog.shown", true ); + JOptionPane.showMessageDialog( rootPane, + "The file was imported properly. \n\n" + + "You can view the imported items when you open the account you have \n" + + "selected and click on the 'downloaded transactions' message at the \n" + + "bottom of the screen.", + "Import Successful", JOptionPane.INFORMATION_MESSAGE ); + } + + setVisible( false ); + }//GEN-LAST:event_btnProcessActionPerformed + + private void fileFormatChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_fileFormatChanged + {//GEN-HEADEREND:event_fileFormatChanged + System.err.println( "fileFormatChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "fileFormatChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "fileFormatChanged() event == ItemEvent.SELECTED ---------------" ); + if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader; + try + { + transReader = (TransactionReader) evt.getItem(); + } + catch ( ClassCastException x ) + { + transReader = null; + } + + processFileFormatChanged( transReader ); + } + + }//GEN-LAST:event_fileFormatChanged + + private void comboFileFormat1fileFormatChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboFileFormat1fileFormatChanged + // TODO add your handling code here: + }//GEN-LAST:event_comboFileFormat1fileFormatChanged + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + setPropertiesFile(); + customReaderDialog.setVisible( true ); + }//GEN-LAST:event_jButton1ActionPerformed + +private void comboDateFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboDateFormatActionPerformed + //customReaderDialog.setDateFormat( (String)comboDateFormat.getSelectedItem() ); +}//GEN-LAST:event_comboDateFormatActionPerformed + +private void comboFileFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboFileFormatActionPerformed + + btnProcess.setEnabled( false ); + /* use actionPerformed - not both ! +if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + } + + String[] formats = transReader.getSupportedDateFormats(); + + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + comboDateFormat.addItem( s ); + } + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } +*/ +}//GEN-LAST:event_comboFileFormatActionPerformed + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + JOptionPane.showMessageDialog( this, "Create a temporary bank account to import into.
When you are ok with the imported records, then \"Batch Change\"
them to the right account.
Not using \"Batch Change\" will mess up your accounts.

-Payment- and -Deposit- are just opposite signed amounts of each other
so if your amount comes into the wrong column, just flip them.
" + , "Message", JOptionPane.INFORMATION_MESSAGE ); + }//GEN-LAST:event_jButton2ActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + this.setPropertiesFile(); + }//GEN-LAST:event_formWindowOpened + + private void PreviewImportBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PreviewImportBtnActionPerformed + System.err.println( "Preview Import button entered" ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + //System.err.println( "starting transReader.parse..." ); + //transReader.parse( main, csvData, account, main.getRootAccount() ); + + transReader.setRootAccount( main.getRootAccount() ); + + PreviewImportWin previewImportWin = new PreviewImportWin(); + previewImportWin.myInit( this, transReader, csvData, csvReader ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem with Preview importing " + + " selected file, probably because the file format was wrong. ", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + }//GEN-LAST:event_PreviewImportBtnActionPerformed + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + fileChanged(); + }//GEN-LAST:event_jButton3ActionPerformed + + private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed + popTextFilenameList( null ); + btnProcess.setEnabled( false ); + }//GEN-LAST:event_jButton4ActionPerformed + + private void textFilenameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_textFilenameItemStateChanged + System.err.println( "textFilenameItemStateChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "textFilenameItemStateChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "textFilenameItemStateChanged() event == ItemEvent.SELECTED ---------------" ); + if ( textFilename.getSelectedItem() instanceof String ) + { + System.err.println( "textFilename is string =" + (String) textFilename.getSelectedItem() + "=" ); + textFilenameChanged(); + return; + } + } + }//GEN-LAST:event_textFilenameItemStateChanged + + private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed + fileChanged2(); + }//GEN-LAST:event_jButton5ActionPerformed + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + ImportDialog dialog = new ImportDialog(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton PreviewImportBtn; + private javax.swing.JButton btnBrowse; + private javax.swing.JButton btnClose; + protected javax.swing.JButton btnProcess; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JCheckBox checkDeleteFile; + private javax.swing.JComboBox comboAccount; + private javax.swing.JComboBox comboDateFormat; + private javax.swing.JComboBox comboFileFormat; + private javax.swing.JLabel comboFileFormatLabel; + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JButton jButton3; + private javax.swing.JButton jButton4; + private javax.swing.JButton jButton5; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel lblAccount; + private javax.swing.JLabel lblDateFormat; + private javax.swing.JLabel lblFileFormat; + private javax.swing.JLabel lblMessage; + private javax.swing.JLabel lblSelectFile; + private javax.swing.JRadioButton onlineImportTypeRB; + private javax.swing.JLabel propertiesFile; + private javax.swing.JRadioButton regularImportTypeRB; + private javax.swing.JComboBox textFilename; + // End of variables declaration//GEN-END:variables + + public void comboFileFormat1AddItem( TransactionReader customReader ) + { + System.err.println( "importDialog() add reader item =" + customReader.toString() + "=" ); + //customReaderCB.addItem( xxx ); + comboFileFormat.addItem( customReader ); + } + + public void comboFileFormat1SetItem( TransactionReader customReader ) + { + System.err.println( "importDialog() comboFileFormat1SetItem() =" + customReader.toString() + "=" ); + //customReaderCB.setSelectedItem( xxx ); + comboFileFormat.setSelectedItem( customReader ); + } + + public void comboDateFormatSetItem( String xxx ) + { + System.err.println( "importDialog() comboDateFormat.setSelectedItem( xxx ) =" + xxx + "=" ); + comboDateFormat.setSelectedItem( xxx ); + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + System.out.println( "ImportDialog.createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "=" ); + dateFormatModel.addElement( dateFormatArg ); + + comboDateFormat.setModel( dateFormatModel ); + + comboDateFormat.setSelectedIndex( 0 ); + } + + public String comboDateFormatGetItem() + { + System.err.println( "importDialog() comboDateFormat.comboDateFormat.getSelectedItem() =" + comboDateFormat.getSelectedItem() + "=" ); + return (String) comboDateFormat.getSelectedItem(); + } + + public void comboDateFormatAddItem( String format ) + { + System.err.println( "importDialog() add date format item =" + comboDateFormat + "=" ); + //customReaderCB.addItem( xxx ); + comboDateFormat.addItem( format ); + } + + public void comboDateFormatSetModel( DefaultComboBoxModel model ) + { + System.err.println( "importDialog() comboDateFormatSetModel()" ); + comboDateFormat.setModel( model ); + } + + private void textFilenameChanged() + { + File newFile = new File( (String) textFilename.getSelectedItem() ); + + if ( ! newFile.equals( selectedFile ) ) + { + selectedFile = newFile; +// fileChanged(); + } + } + + public void popTextFilenameList( String [] filenames ) + { + System.err.println( "entered popTextFilenameList()" ); + File dir = new File( Settings.get( false, "last.directory", "" ) ); + + if ( filenames == null ) + { + if ( dir.equals( "" ) ) + { + dir = (File.listRoots())[0]; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader.getCustomReaderData().getFilenameMatcher() == null || + transReader.getCustomReaderData().getFilenameMatcher().equals( "" ) ) + { + transReader.getCustomReaderData().setFilenameMatcher( ".*\\.[Cc][Ss][Vv]" ); + } + + // create new filename filter + FilenameFilter fileNameFilter = new FilenameFilter() + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + { + System.err.println( "popTextFilenameList() transReader.getFormatName() >" + transReader.getFormatName() + "<" ); + } + @Override + public boolean accept(File dir, String name) { + System.err.println( "popTextFilenameList() match name? >" + name + "<" ); + //System.err.println( "popTextFilenameList() getFilenameMatcher() >" + transReader.getCustomReaderData().getFilenameMatcher() + "<" ); + if ( name.matches( transReader.getCustomReaderData().getFilenameMatcher() ) ) + { + return true; + } + return false; + } + }; + + // returns pathnames for files and directory + filenames = dir.list( fileNameFilter ); + + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( dir + System.getProperty( "file.separator" ) + s ); + } + } + else + { + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( s ); + } + } + } + + public void popComboDateFormatList( String [] formats ) + { + System.err.println( "entered popComboDateFormatList()" ); + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + System.err.println( "popComboDateFormatList add format >" + s + "<" ); + comboDateFormat.addItem( s ); + } + } + + protected void fileChanged() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // try reading the file + /* + if ( !error ) + { + try + { + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + //csvReader.setFieldSeparator( '8' ); THIS WORKED ! + csvReader.setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + csvData = new CSVData( csvReader ); + } + catch ( Throwable x ) + { + error = true; + message = "Error reading file."; + Logger.getLogger( ImportDialog.class.getName() ).log( Level.SEVERE, null, x ); + } + } + * */ + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_COMPATIBLE_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + setLabel( "FindAReader", "No Matches" ); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + setLabel( "FindAReader", "Found" ); + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + if ( ! error ) + { + TransactionReader reader = (TransactionReader) comboFileFormat.getSelectedItem(); + String[] formats = reader.getSupportedDateFormats(); + System.err.println( "importDialog().fileChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Cannot recognize date format used in the file."; + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog.getDateFormatSelected()) =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + + System.err.println( "importDialog() error =" + error + "=" ); + System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); + System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + reader.isUsingCategorynameFlag() + "=" ); + if ( ! error && importDialog.isSelectedOnlineImportTypeRB() && isUsingCategorynameFlag ) + { + JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\' if you want that." + , "Message", JOptionPane.INFORMATION_MESSAGE ); + } + } + else + { + comboDateFormat.removeAllItems(); + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + protected void fileChanged2() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_ALL_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + public void setLabel( String objName, String message ) + { + JLabel label = null; + + if ( objName.equals( "main" ) ) + { + label = lblMessage; + } + else if ( objName.equals( "FindAReader" ) ) + { + label = comboFileFormatLabel; + } + if ( message != null ) + { + label.setVisible( true ); + label.setText( message ); + label.setForeground( new Color( 255, 0, 51 ) ); + } + else + { + label.setVisible( false ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.svn-base new file mode 100644 index 0000000..eb4a225 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/ImportDialog.java.svn-base @@ -0,0 +1,1493 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import static com.moneydance.modules.features.mdcsvimporter.TransactionReader.importDialog; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.JOptionPane; +import javax.swing.KeyStroke; + +/** + * + * @author miki & Stan Towianski + */ +public class ImportDialog + extends javax.swing.JDialog +{ + private OnlineManager onlineMgr = null; + private File selectedFile; + private CSVData csvData; + private Main main; + private HashMap runArgsHM; + protected final static String RUN_ARGS_FILE = "file"; + protected final static String RUN_ARGS_FILEFORMAT = "fileformat"; + protected final static String RUN_ARGS_DATEFORMAT = "dateformat"; + protected final static String RUN_ARGS_IMPORTACCOUNT = "importaccount"; + protected final static String RUN_ARGS_IMPORTTYPE = "importtype"; + protected final static String RUN_ARGS_PROCESSFLAG = "processflag"; + protected final static String RUN_ARGS_DELETECSVFILEFLAG = "deletecsvfileflag"; + protected final static String RUN_ARGS_NOPOPERRORSFLAG = "nopoperrorsflag"; + protected final static String RUN_ARGS_JUNIT = "junitflag"; + + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILE = 1; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE = 2; + protected final static int RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT = 3; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT = 4; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE = 5; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT = 6; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILE = 7; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT = 8; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT = 9; + + private CustomReaderDialog customReaderDialog = new CustomReaderDialog( this, true ); + private ArrayList errCodeList = new ArrayList(); + private boolean skipDuringInit = true; + private boolean autoProcessedAFile = false; + + private boolean GET_ALL_READERS = true; + private boolean GET_COMPATIBLE_READERS = false; + + public ImportDialog() + { + } + + public ImportDialog( Main main, HashMap runArgsHM ) + { + super( main.getMoneydanceWindow(), true ); + initComponents(); + this.runArgsHM = runArgsHM; + autoProcessedAFile = false; + + customReaderDialog.init(); + customReaderDialog.setLocationRelativeTo( getRootPane() ); + + /** + textFilename.getDocument().addDocumentListener( new DocumentListener() + { + public void insertUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void removeUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void changedUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + } ); + **/ + + this.main = main; + + if ( main.getMainContext() != null ) + { + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + + fillAccountCombo( main ); + } + + checkDeleteFile.setSelected( Settings.getBoolean( false, "delete.file" ) ); + onlineImportTypeRB.setSelected( Settings.getBoolean( false, "importtype.online.radiobutton" ) ); + + skipDuringInit = false; + this.setModal( false ); + this.addEscapeListener( this ); + TransactionReader.init( customReaderDialog, this, main.getRootAccount() ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + protected ArrayList processRunArguments() + { + errCodeList = new ArrayList(); + boolean errorInRunArgs = false; + + if ( runArgsHM.containsKey( RUN_ARGS_FILE ) ) + { + selectedFile = new File( (String) runArgsHM.get( RUN_ARGS_FILE ) ); + if ( ! selectedFile.exists() ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nfile \'" + + (String) runArgsHM.get( RUN_ARGS_FILE ) + "\' does not exist.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILE ); + errorInRunArgs = true; + } + else + { + textFilename.setSelectedItem( selectedFile.getPath() ); + fileChanged(); + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTTYPE ) ) + { + if ( "ONLINE".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + onlineImportTypeRB.setSelected( true ); + } + else if ( "REGULAR".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + regularImportTypeRB.setSelected( true ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTTYPE + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_DELETECSVFILEFLAG ) ) + { + checkDeleteFile.setSelected( true ); + } + + if ( runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + //if ( customReaderDialog.getReaderConfig( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ) ) + TransactionReader reqTransReader = customReaderDialog.getTransactionReader( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ); + if ( reqTransReader != null ) + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) comboFileFormat.getModel(); + int idx = dcbm.getIndexOf( reqTransReader ); + + if ( idx >= 0 ) + { + comboFileFormat.setSelectedItem( reqTransReader ); + processFileFormatChanged( reqTransReader ); // call it myself so I know when it is done. + if ( runArgsHM.containsKey( RUN_ARGS_DATEFORMAT ) ) + { + dcbm = (DefaultComboBoxModel) comboDateFormat.getModel(); + idx = dcbm.getIndexOf( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + + if ( idx >= 0 ) + { + comboDateFormat.setSelectedItem( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_DATEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) + "\' is not valid for the \'" + RUN_ARGS_FILEFORMAT + "\' used.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + dcbm = (DefaultComboBoxModel) comboAccount.getModel(); + int max = comboAccount.getItemCount(); + System.err.println( "runArgs at importaccount max =" + max ); + Account foundAccount = null; + + for ( idx = max - 1; idx >= 0; idx-- ) + { + System.err.println( "getAcountName() =" + ((Account) dcbm.getElementAt( idx )).getAccountName() + + "= importaccount =" + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "=" ); + if ( ((Account) dcbm.getElementAt( idx )).getAccountName().equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) ) ) + { + foundAccount = (Account) dcbm.getElementAt( idx ); + break; + } + } + + if ( idx >= 0 ) + { + comboAccount.setSelectedItem( foundAccount ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTACCOUNT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_FILEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\' is not valid for the file you gave.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + errorInRunArgs = true; + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nof invalid \'" + RUN_ARGS_FILEFORMAT + "\' value \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\'.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT ); + errorInRunArgs = true; + } + } // endif fileformat + + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILEFORMAT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT ); + errorInRunArgs = true; + } + else if ( ! runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_IMPORTACCOUNT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) && ! errorInRunArgs ) + { + btnProcessActionPerformed( null ); + autoProcessedAFile = true; + } + + } // END of arguments processing + else if ( runArgsHM.size() > 0 ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILE + "\' argument " + , "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + errorInRunArgs = true; + } + return errCodeList; + } + + private void fillAccountCombo( Main main ) + { + RootAccount rootAccount = main.getRootAccount(); + comboAccount.removeAllItems(); + + fillAccountCombo_( rootAccount ); + + if ( comboAccount.getItemCount() > 0 ) + { + System.err.println( "Settings.getInteger( false, \"selected.account\", 0 ) =" + Settings.getInteger( false, "selected.account", 0 ) ); + try { + comboAccount.setSelectedIndex( Settings.getInteger( false, "selected.account", 0 ) ); + } + catch( Exception ex ) + { + JOptionPane.showMessageDialog( rootPane, "Your 'Import to Account' is not longer valid. " + + "You will have to choose a new one.", + "Import to Account setting", + JOptionPane.ERROR_MESSAGE ); + } + } + } + + private void fillAccountCombo_( Account parentAccount ) + { + for ( int i = 0; i < parentAccount.getSubAccountCount(); ++i ) + { + Account account = parentAccount.getSubAccount( i ); + if ( account.isRegisterAccount() ) + { + comboAccount.addItem( account ); + } + else + { + fillAccountCombo_( account ); + } + } + } + + public boolean isSkipDuringInit() { + return skipDuringInit; + } + + public void setSkipDuringInit(boolean skipDuringInit) { + this.skipDuringInit = skipDuringInit; + } + + public boolean isSelectedOnlineImportTypeRB() { + System.err.println( "onlineImportTypeRB.isSelected() =" + onlineImportTypeRB.isSelected() + "=" ); + return onlineImportTypeRB.isSelected(); + } + + public boolean isAutoProcessedAFile() { + return autoProcessedAFile; + } + + public void setPropertiesFile() { + this.propertiesFile.setText( Settings.getFilename().toString() ); + } + + private void processFileFormatChanged( TransactionReader transReader ) + { + System.err.println( "processFileFormatChanged() --------------- " ); + + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + +// System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); +// System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + transReader.isUsingCategorynameFlag() + "=" ); +// if ( importDialog.isSelectedOnlineImportTypeRB() && transReader.isUsingCategorynameFlag() ) +// { +// JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\'" +// , "Message", JOptionPane.INFORMATION_MESSAGE ); +// } + } + + String[] formats = transReader.getSupportedDateFormats(); + System.err.println( "importDialog().processFileFormatChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel3 = new javax.swing.JLabel(); + buttonGroup1 = new javax.swing.ButtonGroup(); + lblSelectFile = new javax.swing.JLabel(); + btnBrowse = new javax.swing.JButton(); + checkDeleteFile = new javax.swing.JCheckBox(); + btnClose = new javax.swing.JButton(); + btnProcess = new javax.swing.JButton(); + lblAccount = new javax.swing.JLabel(); + comboAccount = new javax.swing.JComboBox(); + lblMessage = new javax.swing.JLabel(); + lblFileFormat = new javax.swing.JLabel(); + comboFileFormat = new javax.swing.JComboBox(); + onlineImportTypeRB = new javax.swing.JRadioButton(); + regularImportTypeRB = new javax.swing.JRadioButton(); + lblDateFormat = new javax.swing.JLabel(); + comboDateFormat = new javax.swing.JComboBox(); + jButton1 = new javax.swing.JButton(); + jLabel5 = new javax.swing.JLabel(); + comboFileFormatLabel = new javax.swing.JLabel(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + propertiesFile = new javax.swing.JLabel(); + PreviewImportBtn = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); + textFilename = new javax.swing.JComboBox(); + jButton4 = new javax.swing.JButton(); + jButton5 = new javax.swing.JButton(); + + jLabel3.setText("jLabel3"); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Import File: " + main.VERSION_STRING); + setName("importDialog"); // NOI18N + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + lblSelectFile.setText("Select Import File:"); + lblSelectFile.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblSelectFile, gridBagConstraints); + + btnBrowse.setText("..."); + btnBrowse.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnBrowseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 10); + getContentPane().add(btnBrowse, gridBagConstraints); + + checkDeleteFile.setText("Securely erase file after processing."); + checkDeleteFile.setToolTipText("If checked, the specified file will be securely erased (first overwritten, then deleted) after successful processing."); + checkDeleteFile.setPreferredSize(new java.awt.Dimension(250, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 13; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 10, 10, 0); + getContentPane().add(checkDeleteFile, gridBagConstraints); + + btnClose.setText("Close"); + btnClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCloseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnClose, gridBagConstraints); + + btnProcess.setText("Process"); + btnProcess.setEnabled(false); + btnProcess.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnProcessActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnProcess, gridBagConstraints); + + lblAccount.setText("Import to Account:"); + lblAccount.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblAccount, gridBagConstraints); + + comboAccount.setModel(new javax.swing.DefaultComboBoxModel(new Account[] { })); + comboAccount.setMaximumSize(new java.awt.Dimension(180, 29)); + comboAccount.setMinimumSize(new java.awt.Dimension(180, 29)); + comboAccount.setPreferredSize(new java.awt.Dimension(180, 29)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboAccount, gridBagConstraints); + + lblMessage.setForeground(new java.awt.Color(255, 0, 51)); + lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + lblMessage.setText(" "); + lblMessage.setMaximumSize(new java.awt.Dimension(200, 25)); + lblMessage.setMinimumSize(new java.awt.Dimension(100, 25)); + lblMessage.setOpaque(true); + lblMessage.setPreferredSize(new java.awt.Dimension(3, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 18; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.ipady = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(lblMessage, gridBagConstraints); + + lblFileFormat.setText("File Reader:"); + lblFileFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblFileFormat, gridBagConstraints); + + comboFileFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboFileFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboFileFormat.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + fileFormatChanged(evt); + } + }); + comboFileFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboFileFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboFileFormat, gridBagConstraints); + + buttonGroup1.add(onlineImportTypeRB); + onlineImportTypeRB.setText("Online"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(onlineImportTypeRB, gridBagConstraints); + + buttonGroup1.add(regularImportTypeRB); + regularImportTypeRB.setSelected(true); + regularImportTypeRB.setText("Regular"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(regularImportTypeRB, gridBagConstraints); + + lblDateFormat.setText("Date Format:"); + lblDateFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblDateFormat, gridBagConstraints); + + comboDateFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboDateFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboDateFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboDateFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboDateFormat, gridBagConstraints); + + jButton1.setText("Maintain Custom File Readers"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10); + getContentPane().add(jButton1, gridBagConstraints); + + jLabel5.setText("Import Transactions as:"); + jLabel5.setToolTipText("Online: These will not have a default category pre-set.
\nRegular: These are regular transactions and they get the default category for the account.
\n        You can also import a 'tag' field in the regular type."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); + getContentPane().add(jLabel5, gridBagConstraints); + + comboFileFormatLabel.setText(" "); + comboFileFormatLabel.setMaximumSize(new java.awt.Dimension(60, 25)); + comboFileFormatLabel.setMinimumSize(new java.awt.Dimension(40, 25)); + comboFileFormatLabel.setPreferredSize(new java.awt.Dimension(60, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(comboFileFormatLabel, gridBagConstraints); + + jButton2.setText("Suggestions"); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 13; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END; + getContentPane().add(jButton2, gridBagConstraints); + + jLabel1.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel1, gridBagConstraints); + + propertiesFile.setText(" "); + propertiesFile.setMaximumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setMinimumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setPreferredSize(new java.awt.Dimension(180, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 19; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH; + gridBagConstraints.insets = new java.awt.Insets(4, 10, 10, 10); + getContentPane().add(propertiesFile, gridBagConstraints); + + PreviewImportBtn.setText("Preview Import"); + PreviewImportBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + PreviewImportBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(PreviewImportBtn, gridBagConstraints); + + jButton3.setText("Find Reader(s) that Work on Import File"); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton3, gridBagConstraints); + + textFilename.setModel(new javax.swing.DefaultComboBoxModel(new String[] { " " })); + textFilename.setMinimumSize(new java.awt.Dimension(180, 29)); + textFilename.setPreferredSize(new java.awt.Dimension(180, 29)); + textFilename.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + textFilenameItemStateChanged(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(textFilename, gridBagConstraints); + + jButton4.setText("Find Import File(s) for this Reader"); + jButton4.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton4ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton4, gridBagConstraints); + + jButton5.setText("List All Readers"); + jButton5.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton5ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 2; + getContentPane().add(jButton5, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnBrowseActionPerformed + {//GEN-HEADEREND:event_btnBrowseActionPerformed + JFileChooser dialog = new JFileChooser(); + dialog.setFileHidingEnabled( true ); + dialog.setDialogTitle( "Select text file" ); + dialog.setCurrentDirectory( + new File( Settings.get( false, "last.directory", + dialog.getCurrentDirectory().getAbsolutePath() ) ) ); + dialog.addChoosableFileFilter( new FileFilter() + { + @Override + public boolean accept( File f ) + { + return f.isDirectory() || f.getName().toUpperCase().endsWith( ".CSV" ); + } + + @Override + public String getDescription() + { + return "Formatted Text File (*.csv)"; + } + } ); + if ( dialog.showDialog( this, "Select" ) == JFileChooser.APPROVE_OPTION ) + { + selectedFile = dialog.getSelectedFile(); + Settings.set( "last.directory", dialog.getCurrentDirectory().getAbsolutePath() ); + // textFilename.setSelectedItem( selectedFile.getPath() ); + String[] tt = { selectedFile.getPath() }; + popTextFilenameList( tt ); +// fileChanged(); + fileChanged2(); + btnProcess.setEnabled( false ); + } +}//GEN-LAST:event_btnBrowseActionPerformed + + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed + {//GEN-HEADEREND:event_btnCloseActionPerformed + this.setVisible( false ); + }//GEN-LAST:event_btnCloseActionPerformed + + private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnProcessActionPerformed + {//GEN-HEADEREND:event_btnProcessActionPerformed + System.err.println( "Process button entered" ); + Settings.setYesNo( "delete.file", checkDeleteFile.isSelected() ); + Settings.setYesNo( "importtype.online.radiobutton", onlineImportTypeRB.isSelected() ); + Settings.setInteger( "selected.account", comboAccount.getSelectedIndex() ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + System.err.println( "starting transReader.parse..." ); + transReader.parse( main, csvData, account, main.getRootAccount() ); + csvReader.close(); + System.out.println( "finished transReader.parse" ); + + //TESTING! DS +// onlineMgr.processDownloadedTxns( account ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem importing " + + " selected file, probably because the file format was wrong. Some items " + + "might have been added to your account.", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + + if ( checkDeleteFile.isSelected() ) + { + try + { + SecureFileDeleter.delete( selectedFile ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "The file was imported properly, " + + "however it could not be erased as requested.", "Cannot Delete File", + JOptionPane.ERROR_MESSAGE ); + return; + } + } + + if ( ! Settings.getBoolean( false, "success.dialog.shown", false ) ) + { + Settings.setYesNo( "success.dialog.shown", true ); + JOptionPane.showMessageDialog( rootPane, + "The file was imported properly. \n\n" + + "You can view the imported items when you open the account you have \n" + + "selected and click on the 'downloaded transactions' message at the \n" + + "bottom of the screen.", + "Import Successful", JOptionPane.INFORMATION_MESSAGE ); + } + + setVisible( false ); + }//GEN-LAST:event_btnProcessActionPerformed + + private void fileFormatChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_fileFormatChanged + {//GEN-HEADEREND:event_fileFormatChanged + System.err.println( "fileFormatChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "fileFormatChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "fileFormatChanged() event == ItemEvent.SELECTED ---------------" ); + if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader; + try + { + transReader = (TransactionReader) evt.getItem(); + } + catch ( ClassCastException x ) + { + transReader = null; + } + + processFileFormatChanged( transReader ); + } + + }//GEN-LAST:event_fileFormatChanged + + private void comboFileFormat1fileFormatChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboFileFormat1fileFormatChanged + // TODO add your handling code here: + }//GEN-LAST:event_comboFileFormat1fileFormatChanged + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + setPropertiesFile(); + customReaderDialog.setVisible( true ); + }//GEN-LAST:event_jButton1ActionPerformed + +private void comboDateFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboDateFormatActionPerformed + //customReaderDialog.setDateFormat( (String)comboDateFormat.getSelectedItem() ); +}//GEN-LAST:event_comboDateFormatActionPerformed + +private void comboFileFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboFileFormatActionPerformed + + btnProcess.setEnabled( false ); + /* use actionPerformed - not both ! +if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + } + + String[] formats = transReader.getSupportedDateFormats(); + + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + comboDateFormat.addItem( s ); + } + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } +*/ +}//GEN-LAST:event_comboFileFormatActionPerformed + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + JOptionPane.showMessageDialog( this, "Create a temporary bank account to import into.
When you are ok with the imported records, then \"Batch Change\"
them to the right account.
Not using \"Batch Change\" will mess up your accounts.

-Payment- and -Deposit- are just opposite signed amounts of each other
so if your amount comes into the wrong column, just flip them.
" + , "Message", JOptionPane.INFORMATION_MESSAGE ); + }//GEN-LAST:event_jButton2ActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + this.setPropertiesFile(); + }//GEN-LAST:event_formWindowOpened + + private void PreviewImportBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PreviewImportBtnActionPerformed + System.err.println( "Preview Import button entered" ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + //System.err.println( "starting transReader.parse..." ); + //transReader.parse( main, csvData, account, main.getRootAccount() ); + + transReader.setRootAccount( main.getRootAccount() ); + + PreviewImportWin previewImportWin = new PreviewImportWin(); + previewImportWin.myInit( this, transReader, csvData, csvReader ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem with Preview importing " + + " selected file, probably because the file format was wrong. ", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + }//GEN-LAST:event_PreviewImportBtnActionPerformed + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + fileChanged(); + }//GEN-LAST:event_jButton3ActionPerformed + + private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed + popTextFilenameList( null ); + btnProcess.setEnabled( false ); + }//GEN-LAST:event_jButton4ActionPerformed + + private void textFilenameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_textFilenameItemStateChanged + System.err.println( "textFilenameItemStateChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "textFilenameItemStateChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "textFilenameItemStateChanged() event == ItemEvent.SELECTED ---------------" ); + if ( textFilename.getSelectedItem() instanceof String ) + { + System.err.println( "textFilename is string =" + (String) textFilename.getSelectedItem() + "=" ); + textFilenameChanged(); + return; + } + } + }//GEN-LAST:event_textFilenameItemStateChanged + + private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed + fileChanged2(); + }//GEN-LAST:event_jButton5ActionPerformed + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + ImportDialog dialog = new ImportDialog(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton PreviewImportBtn; + private javax.swing.JButton btnBrowse; + private javax.swing.JButton btnClose; + protected javax.swing.JButton btnProcess; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JCheckBox checkDeleteFile; + private javax.swing.JComboBox comboAccount; + private javax.swing.JComboBox comboDateFormat; + private javax.swing.JComboBox comboFileFormat; + private javax.swing.JLabel comboFileFormatLabel; + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JButton jButton3; + private javax.swing.JButton jButton4; + private javax.swing.JButton jButton5; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel lblAccount; + private javax.swing.JLabel lblDateFormat; + private javax.swing.JLabel lblFileFormat; + private javax.swing.JLabel lblMessage; + private javax.swing.JLabel lblSelectFile; + private javax.swing.JRadioButton onlineImportTypeRB; + private javax.swing.JLabel propertiesFile; + private javax.swing.JRadioButton regularImportTypeRB; + private javax.swing.JComboBox textFilename; + // End of variables declaration//GEN-END:variables + + public void comboFileFormat1AddItem( TransactionReader customReader ) + { + System.err.println( "importDialog() add reader item =" + customReader.toString() + "=" ); + //customReaderCB.addItem( xxx ); + comboFileFormat.addItem( customReader ); + } + + public void comboFileFormat1SetItem( TransactionReader customReader ) + { + System.err.println( "importDialog() comboFileFormat1SetItem() =" + customReader.toString() + "=" ); + //customReaderCB.setSelectedItem( xxx ); + comboFileFormat.setSelectedItem( customReader ); + } + + public void comboDateFormatSetItem( String xxx ) + { + System.err.println( "importDialog() comboDateFormat.setSelectedItem( xxx ) =" + xxx + "=" ); + comboDateFormat.setSelectedItem( xxx ); + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + System.out.println( "ImportDialog.createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "=" ); + dateFormatModel.addElement( dateFormatArg ); + + comboDateFormat.setModel( dateFormatModel ); + + comboDateFormat.setSelectedIndex( 0 ); + } + + public String comboDateFormatGetItem() + { + System.err.println( "importDialog() comboDateFormat.comboDateFormat.getSelectedItem() =" + comboDateFormat.getSelectedItem() + "=" ); + return (String) comboDateFormat.getSelectedItem(); + } + + public void comboDateFormatAddItem( String format ) + { + System.err.println( "importDialog() add date format item =" + comboDateFormat + "=" ); + //customReaderCB.addItem( xxx ); + comboDateFormat.addItem( format ); + } + + public void comboDateFormatSetModel( DefaultComboBoxModel model ) + { + System.err.println( "importDialog() comboDateFormatSetModel()" ); + comboDateFormat.setModel( model ); + } + + private void textFilenameChanged() + { + File newFile = new File( (String) textFilename.getSelectedItem() ); + + if ( ! newFile.equals( selectedFile ) ) + { + selectedFile = newFile; +// fileChanged(); + } + } + + public void popTextFilenameList( String [] filenames ) + { + System.err.println( "entered popTextFilenameList()" ); + File dir = new File( Settings.get( false, "last.directory", "" ) ); + + if ( filenames == null ) + { + if ( dir.equals( "" ) ) + { + dir = (File.listRoots())[0]; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader.getCustomReaderData().getFilenameMatcher() == null || + transReader.getCustomReaderData().getFilenameMatcher().equals( "" ) ) + { + transReader.getCustomReaderData().setFilenameMatcher( ".*\\.[Cc][Ss][Vv]" ); + } + + // create new filename filter + FilenameFilter fileNameFilter = new FilenameFilter() + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + { + System.err.println( "popTextFilenameList() transReader.getFormatName() >" + transReader.getFormatName() + "<" ); + } + @Override + public boolean accept(File dir, String name) { + System.err.println( "popTextFilenameList() match name? >" + name + "<" ); + //System.err.println( "popTextFilenameList() getFilenameMatcher() >" + transReader.getCustomReaderData().getFilenameMatcher() + "<" ); + if ( name.matches( transReader.getCustomReaderData().getFilenameMatcher() ) ) + { + return true; + } + return false; + } + }; + + // returns pathnames for files and directory + filenames = dir.list( fileNameFilter ); + + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( dir + System.getProperty( "file.separator" ) + s ); + } + } + else + { + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( s ); + } + } + } + + public void popComboDateFormatList( String [] formats ) + { + System.err.println( "entered popComboDateFormatList()" ); + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + System.err.println( "popComboDateFormatList add format >" + s + "<" ); + comboDateFormat.addItem( s ); + } + } + + protected void fileChanged() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // try reading the file + /* + if ( !error ) + { + try + { + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + //csvReader.setFieldSeparator( '8' ); THIS WORKED ! + csvReader.setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + csvData = new CSVData( csvReader ); + } + catch ( Throwable x ) + { + error = true; + message = "Error reading file."; + Logger.getLogger( ImportDialog.class.getName() ).log( Level.SEVERE, null, x ); + } + } + * */ + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_COMPATIBLE_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + setLabel( "FindAReader", "No Matches" ); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + setLabel( "FindAReader", "Found" ); + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + if ( ! error ) + { + TransactionReader reader = (TransactionReader) comboFileFormat.getSelectedItem(); + String[] formats = reader.getSupportedDateFormats(); + System.err.println( "importDialog().fileChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Cannot recognize date format used in the file."; + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog.getDateFormatSelected()) =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + + System.err.println( "importDialog() error =" + error + "=" ); + System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); + System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + reader.isUsingCategorynameFlag() + "=" ); + if ( ! error && importDialog.isSelectedOnlineImportTypeRB() && isUsingCategorynameFlag ) + { + JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\' if you want that." + , "Message", JOptionPane.INFORMATION_MESSAGE ); + } + } + else + { + comboDateFormat.removeAllItems(); + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + protected void fileChanged2() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_ALL_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + public void setLabel( String objName, String message ) + { + JLabel label = null; + + if ( objName.equals( "main" ) ) + { + label = lblMessage; + } + else if ( objName.equals( "FindAReader" ) ) + { + label = comboFileFormatLabel; + } + if ( message != null ) + { + label.setVisible( true ); + label.setText( message ); + label.setForeground( new Color( 255, 0, 51 ) ); + } + else + { + label.setVisible( false ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.netbeans-base new file mode 100644 index 0000000..3314ffd --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.netbeans-base @@ -0,0 +1,233 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.controller.FeatureModule; +import com.moneydance.apps.md.controller.FeatureModuleContext; +import com.moneydance.apps.md.model.RootAccount; +import java.awt.Image; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +/** + * + * @author miki + */ +public class Main + extends FeatureModule +{ + private static final int VERSION = 18; + protected static final String VERSION_STRING = " Beta 18"; + private static final String NAME = "CSV Importer"; + private static final String VENDOR = "Stan Towianski, Milutin Jovanović"; + private static final String URL = "http://code.google.com/p/mdcsvimporter/"; + private static final String DESCRIPTION = + "Let's you create configs for say: Discover card, VISA, your private bank, etc... " + + "You denote columns like: -Payment-, -Deposit-, date, amount, memo, etc... " + + "It can test your file, giving you a list of all the readers that can handle your file. " + + "Importing does matching to skip duplicate entries." + ; + private static Image image; + + private ArrayList errCodeList = null; + + { + try + { + image = ImageIO.read( + Main.class.getResourceAsStream( "import.png" ) ); + } + catch ( IOException x ) + { + // ignore error; nothing we can do about it + } + } + + public Main() + { + } + + /* + public static void main(String args[]) + { + String amt = "($157.86)"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + + amt = "$123.86"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + } + */ + + @Override + public void init() + { + System.err.println( "name and version =" + NAME + " " + VERSION_STRING + "=" ); + FeatureModuleContext context = getContext(); + if ( context == null ) + { + System.err.println( "*** Error: got context == null" ); + return; + } + + context.registerFeature( this, "import", image, "Import File" ); + } + + RootAccount getRootAccount() + { + FeatureModuleContext context = getContext(); + return context.getRootAccount(); + } + + JFrame getMoneydanceWindow() + { + // Using undocumented feature. This way our windows and dialogs can have a parent, + // and behave more conformingly. Alternative is just returning null. Effects should + // be minor visual inconsistencies. + + FeatureModuleContext context = getContext(); + com.moneydance.apps.md.controller.Main main = + (com.moneydance.apps.md.controller.Main) context; + if ( main == null ) + { + return null; + } + com.moneydance.apps.md.view.gui.MoneydanceGUI gui = + (com.moneydance.apps.md.view.gui.MoneydanceGUI) main.getUI(); + if ( gui == null ) + { + return null; + } + return gui.getTopLevelFrame(); + } + + @Override + public String getName() + { + return NAME; + } + + @Override + public int getBuild() + { + return VERSION; + } + + @Override + public String getDescription() + { + return DESCRIPTION; + } + + @Override + public void invoke( String uri ) + { + /* + uri = ImportDialog.RUN_ARGS_FILE + "=/home/aaa/Downloads/aa-test.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online" + ; + */ + + /* + argsHM.put( "file", "/home/aaa/Downloads/aa-test.csv" ); + argsHM.put( "fileformat", "Discover Card" ); + //argsHM.put( "dateformat", "MM/DD/YYYY" ); + argsHM.put( "importaccount", "IMPORT BANK" ); + argsHM.put( "importtype", "online" ); + argsHM.put( "deletecsvfileflag", null ); + */ + + StringTokenizer tokenizer = new StringTokenizer( uri, "&" ); + HashMap argsHM = new HashMap(); + + //filename="file"&fileformat="file format"&dateformat="date format"&importaccount="my account" + //deletecsvfileflag&importtype="online|regular" + + //int count = tokenizer.countTokens(); + //String url = count + " tokens("; + System.err.println( "uri string =" + uri + "=" ); + + while ( tokenizer.hasMoreTokens() ) + { + //url = url.concat( tokenizer.nextToken() ); + String [] pcs = tokenizer.nextToken().split( "=" ); + System.err.println( "arg token [0] =" + pcs[0] + "= token[1] =" + (pcs.length < 2 ? "" : pcs[1]) + "=" ); + if ( pcs.length > 1 ) + { + if ( pcs[1].startsWith( "\"" ) ) + { + argsHM.put( pcs[0].toLowerCase(), pcs[1].substring( 1, pcs[1].length() - 1 ) ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1].substring( 1, pcs[1].length() - 1 ) + "=" ); + } + else + { + argsHM.put( pcs[0].toLowerCase(), pcs[1] ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1] + "=" ); + } + } + else + { + argsHM.put( pcs[0].toLowerCase(), null ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + null + "=" ); + } + } + argsHM.remove( "import" ); // This seems to be passed in and I do not know why. + + ImportDialog dialog = new ImportDialog( this, argsHM ); + + //------- This is for passing in arguments to do auto processing. ------- + errCodeList = dialog.processRunArguments(); + + dialog.setLocationRelativeTo( null ); + + if ( ! dialog.isAutoProcessedAFile() && ! argsHM.containsKey( "junitflag" ) ) + { + dialog.setVisible( true ); + } + } + + public ArrayList getErrCodeList() { + return errCodeList; + } + + @Override + public String getVendorURL() + { + return URL; + } + + @Override + public String getVendor() + { + return VENDOR; + } + + @Override + public Image getIconImage() + { + return image; + } + + public FeatureModuleContext getMainContext() + { + return getContext(); + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.svn-base new file mode 100644 index 0000000..3314ffd --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Main.java.svn-base @@ -0,0 +1,233 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.controller.FeatureModule; +import com.moneydance.apps.md.controller.FeatureModuleContext; +import com.moneydance.apps.md.model.RootAccount; +import java.awt.Image; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +/** + * + * @author miki + */ +public class Main + extends FeatureModule +{ + private static final int VERSION = 18; + protected static final String VERSION_STRING = " Beta 18"; + private static final String NAME = "CSV Importer"; + private static final String VENDOR = "Stan Towianski, Milutin Jovanović"; + private static final String URL = "http://code.google.com/p/mdcsvimporter/"; + private static final String DESCRIPTION = + "Let's you create configs for say: Discover card, VISA, your private bank, etc... " + + "You denote columns like: -Payment-, -Deposit-, date, amount, memo, etc... " + + "It can test your file, giving you a list of all the readers that can handle your file. " + + "Importing does matching to skip duplicate entries." + ; + private static Image image; + + private ArrayList errCodeList = null; + + { + try + { + image = ImageIO.read( + Main.class.getResourceAsStream( "import.png" ) ); + } + catch ( IOException x ) + { + // ignore error; nothing we can do about it + } + } + + public Main() + { + } + + /* + public static void main(String args[]) + { + String amt = "($157.86)"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + + amt = "$123.86"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + } + */ + + @Override + public void init() + { + System.err.println( "name and version =" + NAME + " " + VERSION_STRING + "=" ); + FeatureModuleContext context = getContext(); + if ( context == null ) + { + System.err.println( "*** Error: got context == null" ); + return; + } + + context.registerFeature( this, "import", image, "Import File" ); + } + + RootAccount getRootAccount() + { + FeatureModuleContext context = getContext(); + return context.getRootAccount(); + } + + JFrame getMoneydanceWindow() + { + // Using undocumented feature. This way our windows and dialogs can have a parent, + // and behave more conformingly. Alternative is just returning null. Effects should + // be minor visual inconsistencies. + + FeatureModuleContext context = getContext(); + com.moneydance.apps.md.controller.Main main = + (com.moneydance.apps.md.controller.Main) context; + if ( main == null ) + { + return null; + } + com.moneydance.apps.md.view.gui.MoneydanceGUI gui = + (com.moneydance.apps.md.view.gui.MoneydanceGUI) main.getUI(); + if ( gui == null ) + { + return null; + } + return gui.getTopLevelFrame(); + } + + @Override + public String getName() + { + return NAME; + } + + @Override + public int getBuild() + { + return VERSION; + } + + @Override + public String getDescription() + { + return DESCRIPTION; + } + + @Override + public void invoke( String uri ) + { + /* + uri = ImportDialog.RUN_ARGS_FILE + "=/home/aaa/Downloads/aa-test.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online" + ; + */ + + /* + argsHM.put( "file", "/home/aaa/Downloads/aa-test.csv" ); + argsHM.put( "fileformat", "Discover Card" ); + //argsHM.put( "dateformat", "MM/DD/YYYY" ); + argsHM.put( "importaccount", "IMPORT BANK" ); + argsHM.put( "importtype", "online" ); + argsHM.put( "deletecsvfileflag", null ); + */ + + StringTokenizer tokenizer = new StringTokenizer( uri, "&" ); + HashMap argsHM = new HashMap(); + + //filename="file"&fileformat="file format"&dateformat="date format"&importaccount="my account" + //deletecsvfileflag&importtype="online|regular" + + //int count = tokenizer.countTokens(); + //String url = count + " tokens("; + System.err.println( "uri string =" + uri + "=" ); + + while ( tokenizer.hasMoreTokens() ) + { + //url = url.concat( tokenizer.nextToken() ); + String [] pcs = tokenizer.nextToken().split( "=" ); + System.err.println( "arg token [0] =" + pcs[0] + "= token[1] =" + (pcs.length < 2 ? "" : pcs[1]) + "=" ); + if ( pcs.length > 1 ) + { + if ( pcs[1].startsWith( "\"" ) ) + { + argsHM.put( pcs[0].toLowerCase(), pcs[1].substring( 1, pcs[1].length() - 1 ) ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1].substring( 1, pcs[1].length() - 1 ) + "=" ); + } + else + { + argsHM.put( pcs[0].toLowerCase(), pcs[1] ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1] + "=" ); + } + } + else + { + argsHM.put( pcs[0].toLowerCase(), null ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + null + "=" ); + } + } + argsHM.remove( "import" ); // This seems to be passed in and I do not know why. + + ImportDialog dialog = new ImportDialog( this, argsHM ); + + //------- This is for passing in arguments to do auto processing. ------- + errCodeList = dialog.processRunArguments(); + + dialog.setLocationRelativeTo( null ); + + if ( ! dialog.isAutoProcessedAFile() && ! argsHM.containsKey( "junitflag" ) ) + { + dialog.setVisible( true ); + } + } + + public ArrayList getErrCodeList() { + return errCodeList; + } + + @Override + public String getVendorURL() + { + return URL; + } + + @Override + public String getVendor() + { + return VENDOR; + } + + @Override + public Image getIconImage() + { + return image; + } + + public FeatureModuleContext getMainContext() + { + return getContext(); + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.form-hide.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.form-hide.svn-base new file mode 100644 index 0000000..978e989 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.form-hide.svn-base @@ -0,0 +1,52 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.java-hide.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.java-hide.svn-base new file mode 100644 index 0000000..4472a46 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/OtherActionsDialog.java-hide.svn-base @@ -0,0 +1,155 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.DateReminderPair; +import com.moneydance.apps.md.model.Reminder; +import com.moneydance.apps.md.model.ReminderSet; +import com.moneydance.apps.md.model.RootAccount; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Iterator; +import java.util.Vector; + +/** + * + * @author stan + */ + + +public class OtherActionsDialog extends javax.swing.JDialog { + + ImportDialog parent = null; + Main main = null; + + /** + * Creates new form otherActionsDialog + */ + //public otherActionsDialog(java.awt.Frame parent, boolean modal) { + public OtherActionsDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + //super(parent, modal); + initComponents(); + } + + public void setMain( Main main ) + { + this.main = main; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + + setTitle("Other Actions"); + + jButton1.setText("Delete Overdue Reminders"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(31, 31, 31) + .addComponent(jButton1) + .addContainerGap(204, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(39, 39, 39) + .addComponent(jButton1) + .addContainerGap(238, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + //java.util.Calendar today = new java.util.Calendar( + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Calendar cal = Calendar.getInstance(); + System.out.println(dateFormat.format(cal.getTime())); + RootAccount rootAccount = main.getRootAccount(); + ReminderSet reminderSet = rootAccount.getReminderSet(); + Vector remindersOverdueVec = reminderSet.getOverdueItems( cal ); + + //get an Iterator object for Vector using iterator() method. + Iterator itr = remindersOverdueVec.iterator(); + + //use hasNext() and next() methods of Iterator to iterate through the elements + System.out.println("Iterating through Vector elements..."); + while(itr.hasNext()) + { + DateReminderPair rem = (DateReminderPair) itr.next(); + //reminderSet.removeReminder( rem ); + + System.out.println( "rem.desc =" + rem. + "=" ); + } + }//GEN-LAST:event_jButton1ActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* + * Set the Nimbus look and feel + */ + // + /* + * If Nimbus (introduced in Java SE 6) is not available, stay with the + * default look and feel. For details see + * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* + * Create and display the dialog + */ + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + OtherActionsDialog dialog = new OtherActionsDialog(null, true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.netbeans-base new file mode 100644 index 0000000..b7cab56 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.netbeans-base @@ -0,0 +1,53 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; +import javax.swing.table.AbstractTableModel; + +/** + * + * @author stan + */ + + +public class PreviewImportTblModel extends AbstractTableModel +{ + private ArrayListcolNames; + private String[][] data; + + public PreviewImportTblModel( ArrayList colNamesArg, String[][] dataArg ) + { + colNames = colNamesArg; + data = dataArg; + + System.err.println( "row count =" + data.length ); + System.err.println( "col count =" + data[0].length ); + } + + public int getColumnCount() { return data[0].length; } + public int getRowCount() { return data.length;} + public Object getValueAt(int row, int col) + { + //System.err.println( "getValueAt row =" + row + " col =" + col ); + try { + if ( data[row][col] == "" ) + { + //System.err.println( "NOT EXISTS getValueAt row =" + row + " col =" + col ); + } + } + catch( Exception ex ) + { + return ""; + } + return data[row][col]; + } + + public String getColumnName(int col) { + return colNames.get( col ); + } + + /* + public int getColumnCount() { return 10; } + public int getRowCount() { return 10;} + public Object getValueAt(int row, int col) { return new Integer(row*col); } + */ +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.svn-base new file mode 100644 index 0000000..b7cab56 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportTblModel.java.svn-base @@ -0,0 +1,53 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; +import javax.swing.table.AbstractTableModel; + +/** + * + * @author stan + */ + + +public class PreviewImportTblModel extends AbstractTableModel +{ + private ArrayListcolNames; + private String[][] data; + + public PreviewImportTblModel( ArrayList colNamesArg, String[][] dataArg ) + { + colNames = colNamesArg; + data = dataArg; + + System.err.println( "row count =" + data.length ); + System.err.println( "col count =" + data[0].length ); + } + + public int getColumnCount() { return data[0].length; } + public int getRowCount() { return data.length;} + public Object getValueAt(int row, int col) + { + //System.err.println( "getValueAt row =" + row + " col =" + col ); + try { + if ( data[row][col] == "" ) + { + //System.err.println( "NOT EXISTS getValueAt row =" + row + " col =" + col ); + } + } + catch( Exception ex ) + { + return ""; + } + return data[row][col]; + } + + public String getColumnName(int col) { + return colNames.get( col ); + } + + /* + public int getColumnCount() { return 10; } + public int getRowCount() { return 10;} + public Object getValueAt(int row, int col) { return new Integer(row*col); } + */ +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.netbeans-base new file mode 100644 index 0000000..38321f6 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.netbeans-base @@ -0,0 +1,55 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.svn-base new file mode 100644 index 0000000..38321f6 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.form.svn-base @@ -0,0 +1,55 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.netbeans-base new file mode 100644 index 0000000..f71dd17 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.netbeans-base @@ -0,0 +1,243 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE; +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE_REST; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.KeyStroke; + +/** + * + * @author stan + */ + + +public class PreviewImportWin extends javax.swing.JFrame { + + private TransactionReader transReader = null; + private CSVData csvData = null; + + /** + * Creates new form PreviewImportWin + */ + public PreviewImportWin() { + initComponents(); + } + + public void myInit( ImportDialog importDialog, TransactionReader transReaderArg, CSVData csvDataArg, CSVReader csvReader ) + { + System.err.println( "entered PreviewImportWin.myInit()" + "< ==============================" ); + transReader = transReaderArg; + csvData = csvDataArg; + boolean gotError = false; + + try { + if ( transReader.canParse( csvData ) ) + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file works having " + csvData.getData().length + " rows" ); + importDialog.btnProcess.setEnabled( true ); + System.err.println( "=============== at canparse WORKS for >" + transReader.getFormatName() + "< ===============" ); + } + else + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file does not work!" ); + importDialog.btnProcess.setEnabled( false ); + System.err.println( "=============== at canparse NOT WORK for >" + transReader.getFormatName() + " at row,col " + + csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + "< ===============" ); + gotError = true; + } + + //csvData.parseIntoLines( transReader.getCustomReaderData().getFieldSeparatorChar() ); + System.err.println( "after parse row count =" + csvData.getData().length ); + System.err.println( "after parse col count =" + (csvData.getData())[0].length ); + + // Find and Insert User DataTypes as a Header row to show if they line up: + + int fieldIndex = 0; + int maxFieldIndex = transReader.getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + ArrayList headerDataTypesList = new ArrayList(); + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = transReader.getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + headerDataTypesList.add( dataTypeExpecting ); + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + int cnt = x; + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + while ( x > 1 ) + { + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + x--; + } + } + else + { + headerDataTypesList.add( dataTypeExpecting ); + } + } + previewImportTbl.setModel( new PreviewImportTblModel( headerDataTypesList, csvData.getData() ) ); + if ( gotError ) + { + //csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + CustomTableCellRenderer customTableCellRenderer = new CustomTableCellRenderer(); + customTableCellRenderer.setForRowCol( csvData.getCurrentLineIndex(), csvData.getCurrentFieldIndex() ); + //previewImportTbl.getColumnModel().getColumn( csvData.getCurrentFieldIndexWithinBounds() ).setCellRenderer( customTableCellRenderer ); + previewImportTbl.setDefaultRenderer( Object.class, customTableCellRenderer ); + } + } + catch (Exception ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + //return false; + } + finally + { + try + { + csvReader.close(); + csvData = null; + transReader = null; + this.setSize( 800, 600 ); + this.setLocationRelativeTo( getRootPane() ); + this.setVisible( true ); + this.validate(); + this.addEscapeListener( this ); + } + catch( Exception fex ) + { + ; + } + } + } + + public static void addEscapeListener(final JFrame win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + PreviewImportWin dialog = new PreviewImportWin(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + ArrayList header = new ArrayList(Arrays.asList( "H1", "H2", "H3" ) ); + String[][] data = { + {"User", "Password", "Age"}, + {"1", "2", "3"}, + {"10", "20", "30"}, + }; + + //dialog.myInit( null, null ); + dialog.previewImportTbl.setModel( new PreviewImportTblModel( header, data ) ); + dialog.setSize( 800, 600 ); + dialog.setVisible(true); + dialog.addEscapeListener( dialog ); + } + }); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jScrollPane1 = new javax.swing.JScrollPane(); + previewImportTbl = new javax.swing.JTable(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + previewImportTbl.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String [] { + "Title 1", "Title 2", "Title 3", "Title 4" + } + )); + jScrollPane1.setViewportView(previewImportTbl); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.ipadx = 456; + gridBagConstraints.ipady = 400; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(jScrollPane1, gridBagConstraints); + }// //GEN-END:initComponents + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + try { + System.err.println( "previewImportWin formWindowClosing()" ); + } catch (Exception ex) { + Logger.getLogger(PreviewImportWin.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_formWindowClosing + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTable previewImportTbl; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.svn-base new file mode 100644 index 0000000..f71dd17 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/PreviewImportWin.java.svn-base @@ -0,0 +1,243 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE; +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE_REST; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.KeyStroke; + +/** + * + * @author stan + */ + + +public class PreviewImportWin extends javax.swing.JFrame { + + private TransactionReader transReader = null; + private CSVData csvData = null; + + /** + * Creates new form PreviewImportWin + */ + public PreviewImportWin() { + initComponents(); + } + + public void myInit( ImportDialog importDialog, TransactionReader transReaderArg, CSVData csvDataArg, CSVReader csvReader ) + { + System.err.println( "entered PreviewImportWin.myInit()" + "< ==============================" ); + transReader = transReaderArg; + csvData = csvDataArg; + boolean gotError = false; + + try { + if ( transReader.canParse( csvData ) ) + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file works having " + csvData.getData().length + " rows" ); + importDialog.btnProcess.setEnabled( true ); + System.err.println( "=============== at canparse WORKS for >" + transReader.getFormatName() + "< ===============" ); + } + else + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file does not work!" ); + importDialog.btnProcess.setEnabled( false ); + System.err.println( "=============== at canparse NOT WORK for >" + transReader.getFormatName() + " at row,col " + + csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + "< ===============" ); + gotError = true; + } + + //csvData.parseIntoLines( transReader.getCustomReaderData().getFieldSeparatorChar() ); + System.err.println( "after parse row count =" + csvData.getData().length ); + System.err.println( "after parse col count =" + (csvData.getData())[0].length ); + + // Find and Insert User DataTypes as a Header row to show if they line up: + + int fieldIndex = 0; + int maxFieldIndex = transReader.getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + ArrayList headerDataTypesList = new ArrayList(); + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = transReader.getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + headerDataTypesList.add( dataTypeExpecting ); + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + int cnt = x; + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + while ( x > 1 ) + { + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + x--; + } + } + else + { + headerDataTypesList.add( dataTypeExpecting ); + } + } + previewImportTbl.setModel( new PreviewImportTblModel( headerDataTypesList, csvData.getData() ) ); + if ( gotError ) + { + //csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + CustomTableCellRenderer customTableCellRenderer = new CustomTableCellRenderer(); + customTableCellRenderer.setForRowCol( csvData.getCurrentLineIndex(), csvData.getCurrentFieldIndex() ); + //previewImportTbl.getColumnModel().getColumn( csvData.getCurrentFieldIndexWithinBounds() ).setCellRenderer( customTableCellRenderer ); + previewImportTbl.setDefaultRenderer( Object.class, customTableCellRenderer ); + } + } + catch (Exception ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + //return false; + } + finally + { + try + { + csvReader.close(); + csvData = null; + transReader = null; + this.setSize( 800, 600 ); + this.setLocationRelativeTo( getRootPane() ); + this.setVisible( true ); + this.validate(); + this.addEscapeListener( this ); + } + catch( Exception fex ) + { + ; + } + } + } + + public static void addEscapeListener(final JFrame win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + PreviewImportWin dialog = new PreviewImportWin(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + ArrayList header = new ArrayList(Arrays.asList( "H1", "H2", "H3" ) ); + String[][] data = { + {"User", "Password", "Age"}, + {"1", "2", "3"}, + {"10", "20", "30"}, + }; + + //dialog.myInit( null, null ); + dialog.previewImportTbl.setModel( new PreviewImportTblModel( header, data ) ); + dialog.setSize( 800, 600 ); + dialog.setVisible(true); + dialog.addEscapeListener( dialog ); + } + }); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jScrollPane1 = new javax.swing.JScrollPane(); + previewImportTbl = new javax.swing.JTable(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + previewImportTbl.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String [] { + "Title 1", "Title 2", "Title 3", "Title 4" + } + )); + jScrollPane1.setViewportView(previewImportTbl); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.ipadx = 456; + gridBagConstraints.ipady = 400; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(jScrollPane1, gridBagConstraints); + }// //GEN-END:initComponents + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + try { + System.err.println( "previewImportWin formWindowClosing()" ); + } catch (Exception ex) { + Logger.getLogger(PreviewImportWin.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_formWindowClosing + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTable previewImportTbl; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.netbeans-base new file mode 100644 index 0000000..d0200b2 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.netbeans-base @@ -0,0 +1,373 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class RegexReader extends CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + private LineNumberReader lineReader; + private String rgLine = ""; + private int rgFieldCnt = 0; + + public RegexReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public RegexReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + lineReader = new LineNumberReader( reader ); + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine_HIDE() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //Pattern and Matcher are used here, not String.matches(regexp), + //since String.matches(regexp) would repeatedly compile the same + //regular expression + //String pat42 = "([^,]*([,]|\\Z)).*"; + //String pat5 = "Check[ ]#(\\d*)[^,]*|([^,]*)([,]|\\Z).*"; + /* was used + String pat42 = "([^,]*([,]|\\Z)).*"; + String pat5 = "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*"; + + Pattern regexp = Pattern.compile( pat42 ); + Pattern regexp2 = Pattern.compile( pat5 ); + */ + + ArrayList matcherAl = new ArrayList(); + /* + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp2.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + Matcher matcher = regexp.matcher(""); + */ + for ( String patString : customReaderData.getRegexsList() ) + { + matcherAl.add( Pattern.compile( patString ).matcher("") ); + //System.err.println( "patString =" + patString + "=" ); + } + Matcher matcher = matcherAl.get( 0 ); + + String item = null; + + //System.err.println( "\nnextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + +// if ( isEol( lastChar ) || isEof( lastChar ) ) +// { +// //System.err.println( "nextField() return null for Eol or Eof" ); +// return null; +// } + + if ( ! rgLine.isEmpty() ) + { + System.err.println( "\n----- left =" + rgLine + "= use regex =" + matcherAl.get( rgFieldCnt ).pattern() + "=" ); + matcher = (matcherAl.get( rgFieldCnt )); + matcher.reset( rgLine ); //reset the input + if ( matcher.matches() ) + { + //System.err.println("Num groups: " + matcher.groupCount()); + item = matcher.group(1) == null ? "" : matcher.group(1); + rgLine = rgLine.substring( item.length() ); + if ( item.endsWith( "," ) ) + item = item.substring( 0, item.length() - 1 ); + System.err.println( "rgFieldCnt =" + rgFieldCnt + " item >" + item + "< item2 >" + matcher.group(2) + "<" ); + } + else + { + System.err.println("Input does not match pattern."); + rgLine = ""; + return null; + } + rgFieldCnt++; + } + else + { + System.err.println( "No more fields left." ); + rgLine = ""; + return null; + } + + // TODO: skip separator + + if ( trimFields ) + { + System.err.println( "RegexReader return nextField trim =" + item.trim() + "=" ); + return item.trim(); + } + else + { + System.err.println( "RegexReader return nextField =" + item + "=" ); + return item; + } + } + + public boolean nextLine() + throws IOException + //public void regexParseIntoLines(String aFileName) + { + //Path path = Paths.get(aFileName); + try + //( + //BufferedReader reader = Files.newBufferedReader(path, ENCODING); + //LineNumberReader lineReader = new LineNumberReader( reader ); + //) + { + System.err.println( "entered RegexReader.nextLine()" ); + if ((rgLine = lineReader.readLine()) != null) + { + System.err.println( "\n---------- line =" + rgLine + "=" ); + rgFieldCnt = 0; + return true; + } + } + catch (IOException ex){ + ex.printStackTrace(); + } + return false; + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.svn-base new file mode 100644 index 0000000..d0200b2 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/RegexReader.java.svn-base @@ -0,0 +1,373 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class RegexReader extends CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + private LineNumberReader lineReader; + private String rgLine = ""; + private int rgFieldCnt = 0; + + public RegexReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public RegexReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + lineReader = new LineNumberReader( reader ); + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine_HIDE() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //Pattern and Matcher are used here, not String.matches(regexp), + //since String.matches(regexp) would repeatedly compile the same + //regular expression + //String pat42 = "([^,]*([,]|\\Z)).*"; + //String pat5 = "Check[ ]#(\\d*)[^,]*|([^,]*)([,]|\\Z).*"; + /* was used + String pat42 = "([^,]*([,]|\\Z)).*"; + String pat5 = "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*"; + + Pattern regexp = Pattern.compile( pat42 ); + Pattern regexp2 = Pattern.compile( pat5 ); + */ + + ArrayList matcherAl = new ArrayList(); + /* + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp2.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + Matcher matcher = regexp.matcher(""); + */ + for ( String patString : customReaderData.getRegexsList() ) + { + matcherAl.add( Pattern.compile( patString ).matcher("") ); + //System.err.println( "patString =" + patString + "=" ); + } + Matcher matcher = matcherAl.get( 0 ); + + String item = null; + + //System.err.println( "\nnextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + +// if ( isEol( lastChar ) || isEof( lastChar ) ) +// { +// //System.err.println( "nextField() return null for Eol or Eof" ); +// return null; +// } + + if ( ! rgLine.isEmpty() ) + { + System.err.println( "\n----- left =" + rgLine + "= use regex =" + matcherAl.get( rgFieldCnt ).pattern() + "=" ); + matcher = (matcherAl.get( rgFieldCnt )); + matcher.reset( rgLine ); //reset the input + if ( matcher.matches() ) + { + //System.err.println("Num groups: " + matcher.groupCount()); + item = matcher.group(1) == null ? "" : matcher.group(1); + rgLine = rgLine.substring( item.length() ); + if ( item.endsWith( "," ) ) + item = item.substring( 0, item.length() - 1 ); + System.err.println( "rgFieldCnt =" + rgFieldCnt + " item >" + item + "< item2 >" + matcher.group(2) + "<" ); + } + else + { + System.err.println("Input does not match pattern."); + rgLine = ""; + return null; + } + rgFieldCnt++; + } + else + { + System.err.println( "No more fields left." ); + rgLine = ""; + return null; + } + + // TODO: skip separator + + if ( trimFields ) + { + System.err.println( "RegexReader return nextField trim =" + item.trim() + "=" ); + return item.trim(); + } + else + { + System.err.println( "RegexReader return nextField =" + item + "=" ); + return item; + } + } + + public boolean nextLine() + throws IOException + //public void regexParseIntoLines(String aFileName) + { + //Path path = Paths.get(aFileName); + try + //( + //BufferedReader reader = Files.newBufferedReader(path, ENCODING); + //LineNumberReader lineReader = new LineNumberReader( reader ); + //) + { + System.err.println( "entered RegexReader.nextLine()" ); + if ((rgLine = lineReader.readLine()) != null) + { + System.err.println( "\n---------- line =" + rgLine + "=" ); + rgFieldCnt = 0; + return true; + } + } + catch (IOException ex){ + ex.printStackTrace(); + } + return false; + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/SecureFileDeleter.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/SecureFileDeleter.java.svn-base new file mode 100644 index 0000000..f0e1534 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/SecureFileDeleter.java.svn-base @@ -0,0 +1,97 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Random; + +/** + * + * @author miki + */ +public class SecureFileDeleter +{ + private static final int CHUNK_SIZE = 65536; + + /** + * Securely deletes the specified file. This is done by overwriting the file three + * times, by 0xFF's, random values and 0's, and finally deleting the file. + * @param file File to delete. + * @throws java.io.IOException IOException is thrown if file does not exist, if it is a directory, + * cannot be written to or if any other IO erroroccurs. + */ + public static void delete( File file ) + throws IOException + { + if ( !file.exists() || !file.isFile() || !file.canWrite() ) + { + throw new IOException( "Unable to securely delete specified file." ); + } + + Random random = new Random(); + byte[] buffer = new byte[CHUNK_SIZE]; + + // fill file with 0xFF + for ( int i = 0; i < CHUNK_SIZE; ++i ) + { + buffer[i] = (byte) 0xFF; + } + long fileLength = file.length(); + OutputStream output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + // fill file with random values + fileLength = file.length(); + output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + random.nextBytes( buffer ); + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + // fill file with 0's + for ( int i = 0; i < CHUNK_SIZE; ++i ) + { + buffer[i] = (byte) 0; + } + fileLength = file.length(); + output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + random.nextBytes( buffer ); + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + if ( !file.delete() ) + { + throw new IOException( "Failed to delete file." ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.netbeans-base new file mode 100644 index 0000000..11f23ab --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.netbeans-base @@ -0,0 +1,463 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public final class Settings +{ + static HashMap ReaderConfigsHM = null; + static HashMap ReaderHM = null; + static Properties currentProps = new Properties(); + static String emptyArrayProperty = "[,,,, , , , , , ]"; + // static String emptyRegexsArrayProperty = "[\u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F ]"; + //static String emptyRegexsArrayProperty = "[ a a a a a a a a a ]"; + public static File getFilename() + { + System.err.println( "os.name =" + System.getProperty( "os.name" ) + "=" ); + File moneydanceHome = null; + File moneydanceHome1 = null; + File moneydanceHome2 = null; + File moneydanceHome3 = null; + File moneydanceHome4 = null; + String missingHomeErrMsg = ""; + + if ( System.getProperty( "os.name" ).toLowerCase().startsWith( "mac" ) ) + { + moneydanceHome1 = new File( System.getProperty( "user.home" ) + "/Library/Application Support", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + { + moneydanceHome = moneydanceHome1; + } + else + { + moneydanceHome2 = new File( System.getProperty( "user.home" ) + "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome2 + "=" ); + if ( moneydanceHome2.exists() ) + { + moneydanceHome = moneydanceHome2; + } + else + { + moneydanceHome3 = new File( "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome3 + "=" ); + if ( moneydanceHome3.exists() ) + { + moneydanceHome = moneydanceHome3; + } + else + { + moneydanceHome4 = new File( System.getProperty( "user.home" ) + "/Library", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome4 + "=" ); + if ( moneydanceHome4.exists() ) + moneydanceHome = moneydanceHome4; + } // 3 + } // 2 + } // 1 + + // I am assuming at this point that these Mac folders do exist. + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = "\n\nI looked in these 4 places in this order: \n\n" + + moneydanceHome1 + "\n" + + moneydanceHome2 + "\n" + + moneydanceHome3 + "\n" + + moneydanceHome4 + "\n"; + } + } + else // windows + Linux : test for moneydance folder + { + moneydanceHome1 = new File( System.getProperty( "user.home" ), ".moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + moneydanceHome = moneydanceHome1; + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = ""; //\n\nI looked in this place: \n\n" + //+ moneydanceHome + "\n"; + } + } + + // for all os's + if ( ! moneydanceHome.exists() ) + { + boolean ok = moneydanceHome.mkdirs(); + JOptionPane.showMessageDialog( null, "Importer could not find a Moneydance Home directory so I created one here: \n\n" + moneydanceHome + + missingHomeErrMsg + ); + if ( ! ok ) + { + JOptionPane.showMessageDialog( null, "*** Error creating Moneydance Home directory: \n\n" + moneydanceHome ); + } + } + moneydanceHome = new File( moneydanceHome, "mdcsvimporter.props" ); + + // all systems - moneydanceHome now includes properties file path + try { + if ( ! moneydanceHome.exists() ) + { + moneydanceHome.createNewFile(); + JOptionPane.showMessageDialog( null, "Importer could not find its properties files so I created one here: \n\n" + moneydanceHome + ); + } + } + catch (IOException ex) + { + Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex); + } + + return moneydanceHome; + } + + private static Properties load() + throws IOException + { + currentProps = new Properties(); + + InputStream is; + try + { + is = new FileInputStream( getFilename() ); + } + catch ( FileNotFoundException ex ) + { + return currentProps; // no file is normal condition to start with empty props object + } + try + { + currentProps.load( is ); + } + finally + { + is.close(); + } + return currentProps; + } + + private static void save( Properties props ) + throws IOException + { + OutputStream os = new FileOutputStream( getFilename() ); //, Charset.forName( "UTF-8" ) ); //(String) transReader.getCustomReaderData().getFileEncoding() ) ); + try + { + props.store( os, "MDCSVImporter - Moneydance CSV Importer" ); + } + finally + { + os.close(); + load(); + } + } + + public static String get( boolean loadProps, String name ) + { + try + { + if ( loadProps ) + { + load(); + } + return currentProps.getProperty( name ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + } + + public static String get( boolean loadProps, String name, String defaultValue ) + { + String retVal = get( loadProps, name ); + if ( retVal == null ) + { + return defaultValue; + } + return retVal; + } + + public static void set( String name, String value ) + { + try + { + Properties props = load(); + + setOnly( props, name, value ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void setOnly( Properties props, String name, String value ) + { + // skip if values match (I am sorry for not optimizing the condition, it is early morning...) + String oldValue = props.getProperty( name ); + if ( (oldValue != null && oldValue.equals( value )) || + (value != null && value.equals( oldValue )) ) + { + return; + } + + props.setProperty( name, value ); + } + + public static boolean getBoolean( boolean loadProps, String name ) + { + return getBoolean( loadProps, name, false ); + } + + public static boolean getBoolean( boolean loadProps, String name, boolean defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + if ( value.equalsIgnoreCase( "true" ) || value.equalsIgnoreCase( "yes" ) || + value.equalsIgnoreCase( "1" ) ) + { + return true; + } + else + { + return false; + } + } + + public static void setBoolean( String name, boolean value ) + { + set( name, value ? "true" : "false" ); + } + + public static void setYesNo( String name, boolean value ) + { + set( name, value ? "yes" : "no" ); + } + + public static int getInteger( boolean loadProps, String name ) + { + return getInteger( loadProps, name, 0 ); + } + + public static int getInteger( boolean loadProps, String name, int defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + return Integer.parseInt( value ); + } + + public static void setInteger( String name, int value ) + { + set( name, Integer.toString( value ) ); + } + + public static HashMap createReaderConfigsHM() + { + ReaderConfigsHM = new HashMap(); + ReaderHM = new HashMap(); + + try + { + Properties props = load(); + + for ( Enumeration enu = props.propertyNames(); enu.hasMoreElements(); ) + { + String key = (String) enu.nextElement(); + System.out.println( "props key =" + key + "=" ); + if ( key.startsWith( "reader:" ) && key.endsWith( ".Name" ) ) + { + String readerName = key.replaceAll( "reader\\:(.*)\\..*", "reader:$1" ); + System.err.println( "readerName >" + readerName + "<" ); + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( props.getProperty( readerName + ".Name" ) ); + customReaderData.setFieldSeparatorChar( getInteger( false, readerName + ".FieldSeparator", ',' ) ); + customReaderData.setDateFormatString( props.getProperty( readerName + ".DateFormatString" ) ); + customReaderData.setFileEncoding( props.getProperty( readerName + ".FileEncodingString" ) ); + + customReaderData.setHeaderLines( getInteger( false, readerName + ".HeaderLines", 0 ) ); + customReaderData.setFooterLines( getInteger( false, readerName + ".FooterLines", 0 ) ); + + customReaderData.setAmountCurrencyChar( getInteger( false, readerName + ".AmountCurrencyChar", '$' ) ); + customReaderData.setAmountDecimalSignChar( getInteger( false, readerName + ".AmountDecimalSignChar", '.' ) ); + customReaderData.setAmountGroupingSeparatorChar( getInteger( false, readerName + ".AmountGroupingSeparatorChar", ',' ) ); + customReaderData.setAmountFormat( props.getProperty( readerName + ".AmountFormat" ) ); + customReaderData.setImportReverseOrderFlg( getBoolean( false, readerName + ".ImportReverseOrderFlag", false ) ); + customReaderData.setUseRegexFlag(getBoolean( false, readerName + ".UseRegexFlag", false ) ); + customReaderData.setFilenameMatcher(props.getProperty( readerName + ".FilenameMatcher" ) ); + + //customReaderData.setRegexsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".RegexsList", emptyRegexsArrayProperty ).split( "[\\[\\]a]" ) ) ) ); + //customReaderData.setRegexsList( new ArrayList( 10 ) ); + customReaderData.setRegexsList( new ArrayList(Arrays.asList( "", "", "", "", "", "", "", "", "", "" ) ) ); + customReaderData.setDataTypesList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DataTypesList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + customReaderData.setEmptyFlagsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".EmptyFlagsList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + + int max = customReaderData.getDataTypesList().size(); + System.err.println( "props customReaderData.getRegexsList().size() =" + customReaderData.getRegexsList().size() + "= max =" + max ); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getRegexsList().set( c - 1, props.getProperty( readerName + ".RegexsList." + (c-1), "" ) ); + //customReaderData.getRegexsList().set( c - 1,customReaderData.getRegexsList().get( c ).trim() ); + customReaderData.getDataTypesList().set( c - 1,customReaderData.getDataTypesList().get( c ).trim() ); + customReaderData.getEmptyFlagsList().set( c - 1,customReaderData.getEmptyFlagsList().get( c ).trim() ); + } + + /* + if ( props.getProperty( readerName + ".DateFormatList" ) != null ) + { + customReaderData.setDateFormatList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DateFormatList" ).split( "[\\[\\],]" ) ) ) ); + } + else + { + customReaderData.setDateFormatList( new ArrayList() ); + } + max = customReaderData.getDateFormatList().size(); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getDateFormatList().set( c - 1,customReaderData.getDateFormatList().get( c ).trim() ); + } + */ + System.err.println( "props readerName =" + customReaderData.getReaderName() + "=" ); + System.err.println( "props getFieldSeparatorChar() =" + customReaderData.getFieldSeparatorChar() + "=" ); + System.err.println( "props getFileEncoding() =" + customReaderData.getFileEncoding() + "=" ); + System.err.println( "props getDateFormatString() =" + customReaderData.getDateFormatString()+ "=" ); + System.err.println( "props getHeaderLines() =" + customReaderData.getHeaderLines() + "=" ); + System.err.println( "props getRegexsList() =" + customReaderData.getRegexsList() + "=" ); + System.err.println( "props getDataTypesList() =" + customReaderData.getDataTypesList() + "=" ); + System.err.println( "props getEmptyFlagsList() =" + customReaderData.getEmptyFlagsList() + "=" ); + + ReaderConfigsHM.put( props.getProperty( readerName + ".Name" ), customReaderData ); + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( props.getProperty( readerName + ".Name" ), customReader ); + + customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + } + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + + return ReaderConfigsHM; + } + + public static HashMap getReaderHM() { + return ReaderHM; + } + + public static void setCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + setOnly( props, "reader:" + customReaderData.getReaderName() + ".Name", customReaderData.getReaderName() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".HeaderLines", Integer.toString( customReaderData.getHeaderLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FooterLines", Integer.toString( customReaderData.getFooterLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FieldSeparator", Integer.toString( customReaderData.getFieldSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FileEncodingString", customReaderData.getFileEncoding() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatString", customReaderData.getDateFormatString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList", customReaderData.getRegexsListEncoded() ); + for( int c = 0; c < 10; c++ ) + { + setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList." + c, customReaderData.getRegexsListEle( c ) ); + } + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DataTypesList", customReaderData.getDataTypesList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList", customReaderData.getEmptyFlagsList().toString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatList", customReaderData.getDateFormatList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar", Integer.toString( customReaderData.getAmountCurrencyChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar", Integer.toString( customReaderData.getAmountDecimalSignChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar", Integer.toString( customReaderData.getAmountGroupingSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountFormat", customReaderData.getAmountFormat() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag", Boolean.toString( customReaderData.getImportReverseOrderFlg() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".UseRegexFlag", Boolean.toString( customReaderData.getUseRegexFlag() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FilenameMatcher", customReaderData.getFilenameMatcher() ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void removeCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + props.remove( "reader:" + customReaderData.getReaderName() + ".Name" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".HeaderLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FieldSeparator" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatString" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".RegexsList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DataTypesList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList" ); + //props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountFormat" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag" ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.svn-base new file mode 100644 index 0000000..11f23ab --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/Settings.java.svn-base @@ -0,0 +1,463 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public final class Settings +{ + static HashMap ReaderConfigsHM = null; + static HashMap ReaderHM = null; + static Properties currentProps = new Properties(); + static String emptyArrayProperty = "[,,,, , , , , , ]"; + // static String emptyRegexsArrayProperty = "[\u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F ]"; + //static String emptyRegexsArrayProperty = "[ a a a a a a a a a ]"; + public static File getFilename() + { + System.err.println( "os.name =" + System.getProperty( "os.name" ) + "=" ); + File moneydanceHome = null; + File moneydanceHome1 = null; + File moneydanceHome2 = null; + File moneydanceHome3 = null; + File moneydanceHome4 = null; + String missingHomeErrMsg = ""; + + if ( System.getProperty( "os.name" ).toLowerCase().startsWith( "mac" ) ) + { + moneydanceHome1 = new File( System.getProperty( "user.home" ) + "/Library/Application Support", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + { + moneydanceHome = moneydanceHome1; + } + else + { + moneydanceHome2 = new File( System.getProperty( "user.home" ) + "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome2 + "=" ); + if ( moneydanceHome2.exists() ) + { + moneydanceHome = moneydanceHome2; + } + else + { + moneydanceHome3 = new File( "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome3 + "=" ); + if ( moneydanceHome3.exists() ) + { + moneydanceHome = moneydanceHome3; + } + else + { + moneydanceHome4 = new File( System.getProperty( "user.home" ) + "/Library", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome4 + "=" ); + if ( moneydanceHome4.exists() ) + moneydanceHome = moneydanceHome4; + } // 3 + } // 2 + } // 1 + + // I am assuming at this point that these Mac folders do exist. + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = "\n\nI looked in these 4 places in this order: \n\n" + + moneydanceHome1 + "\n" + + moneydanceHome2 + "\n" + + moneydanceHome3 + "\n" + + moneydanceHome4 + "\n"; + } + } + else // windows + Linux : test for moneydance folder + { + moneydanceHome1 = new File( System.getProperty( "user.home" ), ".moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + moneydanceHome = moneydanceHome1; + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = ""; //\n\nI looked in this place: \n\n" + //+ moneydanceHome + "\n"; + } + } + + // for all os's + if ( ! moneydanceHome.exists() ) + { + boolean ok = moneydanceHome.mkdirs(); + JOptionPane.showMessageDialog( null, "Importer could not find a Moneydance Home directory so I created one here: \n\n" + moneydanceHome + + missingHomeErrMsg + ); + if ( ! ok ) + { + JOptionPane.showMessageDialog( null, "*** Error creating Moneydance Home directory: \n\n" + moneydanceHome ); + } + } + moneydanceHome = new File( moneydanceHome, "mdcsvimporter.props" ); + + // all systems - moneydanceHome now includes properties file path + try { + if ( ! moneydanceHome.exists() ) + { + moneydanceHome.createNewFile(); + JOptionPane.showMessageDialog( null, "Importer could not find its properties files so I created one here: \n\n" + moneydanceHome + ); + } + } + catch (IOException ex) + { + Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex); + } + + return moneydanceHome; + } + + private static Properties load() + throws IOException + { + currentProps = new Properties(); + + InputStream is; + try + { + is = new FileInputStream( getFilename() ); + } + catch ( FileNotFoundException ex ) + { + return currentProps; // no file is normal condition to start with empty props object + } + try + { + currentProps.load( is ); + } + finally + { + is.close(); + } + return currentProps; + } + + private static void save( Properties props ) + throws IOException + { + OutputStream os = new FileOutputStream( getFilename() ); //, Charset.forName( "UTF-8" ) ); //(String) transReader.getCustomReaderData().getFileEncoding() ) ); + try + { + props.store( os, "MDCSVImporter - Moneydance CSV Importer" ); + } + finally + { + os.close(); + load(); + } + } + + public static String get( boolean loadProps, String name ) + { + try + { + if ( loadProps ) + { + load(); + } + return currentProps.getProperty( name ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + } + + public static String get( boolean loadProps, String name, String defaultValue ) + { + String retVal = get( loadProps, name ); + if ( retVal == null ) + { + return defaultValue; + } + return retVal; + } + + public static void set( String name, String value ) + { + try + { + Properties props = load(); + + setOnly( props, name, value ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void setOnly( Properties props, String name, String value ) + { + // skip if values match (I am sorry for not optimizing the condition, it is early morning...) + String oldValue = props.getProperty( name ); + if ( (oldValue != null && oldValue.equals( value )) || + (value != null && value.equals( oldValue )) ) + { + return; + } + + props.setProperty( name, value ); + } + + public static boolean getBoolean( boolean loadProps, String name ) + { + return getBoolean( loadProps, name, false ); + } + + public static boolean getBoolean( boolean loadProps, String name, boolean defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + if ( value.equalsIgnoreCase( "true" ) || value.equalsIgnoreCase( "yes" ) || + value.equalsIgnoreCase( "1" ) ) + { + return true; + } + else + { + return false; + } + } + + public static void setBoolean( String name, boolean value ) + { + set( name, value ? "true" : "false" ); + } + + public static void setYesNo( String name, boolean value ) + { + set( name, value ? "yes" : "no" ); + } + + public static int getInteger( boolean loadProps, String name ) + { + return getInteger( loadProps, name, 0 ); + } + + public static int getInteger( boolean loadProps, String name, int defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + return Integer.parseInt( value ); + } + + public static void setInteger( String name, int value ) + { + set( name, Integer.toString( value ) ); + } + + public static HashMap createReaderConfigsHM() + { + ReaderConfigsHM = new HashMap(); + ReaderHM = new HashMap(); + + try + { + Properties props = load(); + + for ( Enumeration enu = props.propertyNames(); enu.hasMoreElements(); ) + { + String key = (String) enu.nextElement(); + System.out.println( "props key =" + key + "=" ); + if ( key.startsWith( "reader:" ) && key.endsWith( ".Name" ) ) + { + String readerName = key.replaceAll( "reader\\:(.*)\\..*", "reader:$1" ); + System.err.println( "readerName >" + readerName + "<" ); + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( props.getProperty( readerName + ".Name" ) ); + customReaderData.setFieldSeparatorChar( getInteger( false, readerName + ".FieldSeparator", ',' ) ); + customReaderData.setDateFormatString( props.getProperty( readerName + ".DateFormatString" ) ); + customReaderData.setFileEncoding( props.getProperty( readerName + ".FileEncodingString" ) ); + + customReaderData.setHeaderLines( getInteger( false, readerName + ".HeaderLines", 0 ) ); + customReaderData.setFooterLines( getInteger( false, readerName + ".FooterLines", 0 ) ); + + customReaderData.setAmountCurrencyChar( getInteger( false, readerName + ".AmountCurrencyChar", '$' ) ); + customReaderData.setAmountDecimalSignChar( getInteger( false, readerName + ".AmountDecimalSignChar", '.' ) ); + customReaderData.setAmountGroupingSeparatorChar( getInteger( false, readerName + ".AmountGroupingSeparatorChar", ',' ) ); + customReaderData.setAmountFormat( props.getProperty( readerName + ".AmountFormat" ) ); + customReaderData.setImportReverseOrderFlg( getBoolean( false, readerName + ".ImportReverseOrderFlag", false ) ); + customReaderData.setUseRegexFlag(getBoolean( false, readerName + ".UseRegexFlag", false ) ); + customReaderData.setFilenameMatcher(props.getProperty( readerName + ".FilenameMatcher" ) ); + + //customReaderData.setRegexsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".RegexsList", emptyRegexsArrayProperty ).split( "[\\[\\]a]" ) ) ) ); + //customReaderData.setRegexsList( new ArrayList( 10 ) ); + customReaderData.setRegexsList( new ArrayList(Arrays.asList( "", "", "", "", "", "", "", "", "", "" ) ) ); + customReaderData.setDataTypesList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DataTypesList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + customReaderData.setEmptyFlagsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".EmptyFlagsList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + + int max = customReaderData.getDataTypesList().size(); + System.err.println( "props customReaderData.getRegexsList().size() =" + customReaderData.getRegexsList().size() + "= max =" + max ); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getRegexsList().set( c - 1, props.getProperty( readerName + ".RegexsList." + (c-1), "" ) ); + //customReaderData.getRegexsList().set( c - 1,customReaderData.getRegexsList().get( c ).trim() ); + customReaderData.getDataTypesList().set( c - 1,customReaderData.getDataTypesList().get( c ).trim() ); + customReaderData.getEmptyFlagsList().set( c - 1,customReaderData.getEmptyFlagsList().get( c ).trim() ); + } + + /* + if ( props.getProperty( readerName + ".DateFormatList" ) != null ) + { + customReaderData.setDateFormatList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DateFormatList" ).split( "[\\[\\],]" ) ) ) ); + } + else + { + customReaderData.setDateFormatList( new ArrayList() ); + } + max = customReaderData.getDateFormatList().size(); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getDateFormatList().set( c - 1,customReaderData.getDateFormatList().get( c ).trim() ); + } + */ + System.err.println( "props readerName =" + customReaderData.getReaderName() + "=" ); + System.err.println( "props getFieldSeparatorChar() =" + customReaderData.getFieldSeparatorChar() + "=" ); + System.err.println( "props getFileEncoding() =" + customReaderData.getFileEncoding() + "=" ); + System.err.println( "props getDateFormatString() =" + customReaderData.getDateFormatString()+ "=" ); + System.err.println( "props getHeaderLines() =" + customReaderData.getHeaderLines() + "=" ); + System.err.println( "props getRegexsList() =" + customReaderData.getRegexsList() + "=" ); + System.err.println( "props getDataTypesList() =" + customReaderData.getDataTypesList() + "=" ); + System.err.println( "props getEmptyFlagsList() =" + customReaderData.getEmptyFlagsList() + "=" ); + + ReaderConfigsHM.put( props.getProperty( readerName + ".Name" ), customReaderData ); + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( props.getProperty( readerName + ".Name" ), customReader ); + + customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + } + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + + return ReaderConfigsHM; + } + + public static HashMap getReaderHM() { + return ReaderHM; + } + + public static void setCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + setOnly( props, "reader:" + customReaderData.getReaderName() + ".Name", customReaderData.getReaderName() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".HeaderLines", Integer.toString( customReaderData.getHeaderLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FooterLines", Integer.toString( customReaderData.getFooterLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FieldSeparator", Integer.toString( customReaderData.getFieldSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FileEncodingString", customReaderData.getFileEncoding() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatString", customReaderData.getDateFormatString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList", customReaderData.getRegexsListEncoded() ); + for( int c = 0; c < 10; c++ ) + { + setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList." + c, customReaderData.getRegexsListEle( c ) ); + } + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DataTypesList", customReaderData.getDataTypesList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList", customReaderData.getEmptyFlagsList().toString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatList", customReaderData.getDateFormatList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar", Integer.toString( customReaderData.getAmountCurrencyChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar", Integer.toString( customReaderData.getAmountDecimalSignChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar", Integer.toString( customReaderData.getAmountGroupingSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountFormat", customReaderData.getAmountFormat() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag", Boolean.toString( customReaderData.getImportReverseOrderFlg() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".UseRegexFlag", Boolean.toString( customReaderData.getUseRegexFlag() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FilenameMatcher", customReaderData.getFilenameMatcher() ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void removeCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + props.remove( "reader:" + customReaderData.getReaderName() + ".Name" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".HeaderLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FieldSeparator" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatString" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".RegexsList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DataTypesList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList" ); + //props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountFormat" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag" ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/TransactionReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/TransactionReader.java.netbeans-base new file mode 100644 index 0000000..d7255dd --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/TransactionReader.java.netbeans-base @@ -0,0 +1,852 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.TransactionSet; +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.model.CurrencyType; +import com.moneydance.apps.md.model.AbstractTxn; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.apps.md.model.OnlineTxnList; +import com.moneydance.apps.md.model.ParentTxn; +import com.moneydance.apps.md.model.SplitTxn; + +import com.moneydance.apps.md.model.TxnSet; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public abstract class TransactionReader +{ + private boolean customReaderFlag = false; + private CustomReaderData customReaderData = null; + + protected static ImportDialog importDialog = null; + protected static CustomReaderDialog customReaderDialog = null; + protected static RootAccount rootAccount = null; + + protected CSVData csvData; + protected Account account; + protected String accountNameFromCSV;//for reading account from CSV file + protected String priorAccountNameFromCSV = "";//for efficiency only + protected OnlineTxnList transactionList; + protected TransactionSet txnSet; + protected CurrencyType currency; + protected HashSet tsetMatcherKey = new HashSet(); + protected HashSet tsetFITxnIdMatcherKey = new HashSet(); + //protected HashSet onlineMatcherKey = new HashSet(); + protected int defProtocolId = 999; // per Sean at MD + protected final static String DEFAULT_ENCODING = "UTF-8"; // "UTF-16LE"; "windows-1250"; Preselect this value in Encoding JComboBox. + //protected String fileEncoding = DEFAULT_ENCODING; + protected boolean isUsingCategorynameFlag = false; + + protected abstract boolean canParse( CSVData data ); + + protected abstract boolean parseNext() throws IOException; + +// protected abstract boolean parseNext(OnlineTxn txn) throws IOException; + + protected abstract boolean assignDataToTxn( OnlineTxn txn ) throws IOException; + + public abstract String getFormatName(); + + public abstract String[] getSupportedDateFormats(); + + public abstract void setSupportedDateFormats( String[] supportedDateFormats ); + + public abstract String getDateFormat(); + + public abstract void setDateFormat( String format ); + + //public abstract int getFieldSeparator(); + + //public abstract void setFieldSeparator( int xxx ); + + protected final void throwException( String message ) + throws IOException + { + throw new IOException( message ); + } + + public static void init( CustomReaderDialog customReaderDialogArg, ImportDialog importDialogArg, RootAccount rootAccountArg ) + { + customReaderDialog = customReaderDialogArg; + importDialog = importDialogArg; + rootAccount = rootAccountArg; + } + + protected final void setRootAccount( RootAccount rootAccount ) + { + this.rootAccount = rootAccount; + } + + public final String calcFITxnIdAbstract( AbstractTxn atxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( AbstractTxn ) -------------" ); + //System.err.println( "key.getDescription() =" + atxn.getDescription() + "= atxn.getFiTxnId( 1 ) =" + atxn.getFiTxnId( 1 ) + "=" ); + //System.err.println( "atxn.getFiTxnId( 1 ) [" + k + "] =" + atxn.getFiTxnId( 1 ) + "= atxn.getFiTxnId( 0 ) [" + k + "] =" + atxn.getFiTxnId( 0 ) + "=" ); + //tsetMatcherKey.add( atxn.getFiTxnId( 1 ) ); + + // Here I am manually recreating the FiTxnId that I set on imported txn's because I could not figure + // out how to simply read it. + + + //String tmp = atxn.getDateInt() + ":" + currency.format( atxn.getValue(), '.' ) + ":" + atxn.getDescription() + ":" + atxn.getCheckNumber(); + + // Create a pattern to match comments + //dave Pattern ckNumPat = Pattern.compile("^.*\\\"chknum\\\" = \\\"(.+?)\\\"\n.*$", Pattern.MULTILINE); + // I think I want to stick with (.*) instead of (.+) because I want to catch () either way. Stan + Pattern ckNumPat = Pattern.compile( "^.*\\\"chknum\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + Pattern amtPat = Pattern.compile( "^.*\\\"amt\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + String amt = null; + String origCheckNumber = null; + String desc = null; + + /* + + ol.orig-txn + { "dtinit-int" = "20110824" "name" = "whatever desc" "amt" = "-9824" "fitxnid" = "20110824:-98.24:whatever desc" "dtpstd-int" = "20110824" "dtavail-int" = "20110824" "invst.totalamt" = "-9824" "chknum" = "001234" "ptype" = "1" } + + */ + + String origtxn = atxn.getTag( "ol.orig-txn" ); + //String origCheckNumber = origtxn.replaceAll( ".*\\\"chknum\\\" = \\\"(.*?)\\\"\\\n.*", "$1" ); + + //System.out.println( "\norigtxn ="+origtxn + "=" ); + + // Run some matches + if ( origtxn != null ) + { + Matcher m = ckNumPat.matcher( origtxn ); + if ( m.find() ) + { + origCheckNumber = m.group( 1 ); + //System.out.println("Found orig check num ="+m.group( 1 ) + "=" ); + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + + m = amtPat.matcher( origtxn ); + if ( m.find() ) + { + long lamt = Long.valueOf( m.group( 1 ) ).longValue(); + amt = currency.format( lamt, '.' ); + //System.out.println("Found orig amt ="+m.group( 1 ) + "= formatted =" + amt ); + } + else + { + amt = currency.format( atxn.getValue(), '.' ); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("no orig check num so use getchecknum() ="+origCheckNumber + "=" ); + amt = currency.format( atxn.getValue(), '.' ); + } + + //long value = atxn.getParentTxn().getValue(); + + if ( atxn.getTag( "ol.orig-payee" ) == null ) + { + desc = atxn.getDescription(); + } + else + { + desc = atxn.getTag( "ol.orig-payee" ); + } + + // This new way compare using the ORIGINAL payee and memo fields so if the user changes them, it will still match. Stan + String tmp = atxn.getDateInt() + ":" + amt + + ":" + desc + + ":" + (origCheckNumber == null ? "" : origCheckNumber.replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (atxn.getTag( "ol.orig-memo" ) == null ? "" : atxn.getTag( "ol.orig-memo" )); + + //System.err.println( "calc abstract FITxnld >" + tmp + "<" ); + return tmp; + } + + + public final String calcFITxnId( OnlineTxn onlinetxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( onlinetxn ) -------------" ); + // txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + + String tmp = onlinetxn.getDateInitiatedInt() + ":" + currency.format( onlinetxn.getAmount(), '.' ) + + ":" + (onlinetxn.getName() == null ? "" : onlinetxn.getName() ) // used payeeName once + + ":" + (onlinetxn.getCheckNum() == null ? "" : onlinetxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (onlinetxn.getMemo() == null ? "" : onlinetxn.getMemo() ) + ; + + //System.err.println( "calc online FITxnld >" + tmp + "<" ); + return tmp; + } + + private final void makeSetOfExistingTxns( TxnSet tset ) + throws IOException + { + int k = 0; + for ( AbstractTxn atxn : tset ) + { + String tmp = calcFITxnIdAbstract( atxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + tsetMatcherKey.add( tmp ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( OnlineTxn.PROTO_TYPE_OFX ) ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( defProtocolId ) ); + + k++; + //if ( k > 9 ) + // break; + } + //System.err.println( "\n--------- end: make set of existing account transactions -------------" ); + } + + /* + ************************************************************************************************ + */ + public final void parse( Main main, CSVData csvDataArg, Account accountIn, RootAccount rootAccount ) + throws IOException + { + System.err.println("\n--------- entered TransactionReader().parse() -------------"); + + this.csvData = csvDataArg; + this.rootAccount = rootAccount; + this.txnSet = rootAccount.getTransactionSet(); + this.tsetMatcherKey = new HashSet(); + this.tsetFITxnIdMatcherKey = new HashSet(); + +// //begin testing +// //this is part of what would be needed to match account names +// //using regex or partial matching instead of exact and complete matching. +// HashMap accountMap = new HashMap(); +// Enumeration accountListEnum = rootAccount.getSubAccounts(); +// while (accountListEnum.hasMoreElements()) { +// Account a = (Account)accountListEnum.nextElement(); +// accountMap.put(a.getAccountName(), a); +// } +// //getAllAccountNames - is only path from root to present acct +// //end testing + + System.err.println("\n--------- beg: make set of existing account transactions -------------"); + //System.err.println( "number of trans list =" +this.txnSet.getTransactionsForAccount( account ).getSize() ); + System.err.println("size of txnSet.getAllTxns = " + this.txnSet.getAllTxns().getSize()); + // cannot get just for account because I am putting them into a temp/empty account ! + //Enumeration tenums = this.txnSet.getTransactionsForAccount( account ).getAllTxns(); + TxnSet tset = this.txnSet.getAllTxns(); + + //TODO: refactor this. + //Currently, if the CSV file contains transactions from different accounts + //with different currencies, we don't handle that. However, we could. + //By separating the parsing from the matching, we could easily handle it. + //For now, the account selected on the dialog will provide the currency + //for all accounts. + //Fixing this is a low priority because + // 1) not everyone has multiple accounts in a single file + // 2) most people with multiple accounts will have them in the same currency + //If someone needs multiple currencies and accounts in one file, + //it can be implemented as described above. + this.currency = accountIn.getCurrencyType(); + //TODO: after refacting, call this only after each line of CSV file has been processed + //TODO: parse CSV first, then iterate again to match FITxnId + makeSetOfExistingTxns( tset ); + + /* + while ( tenums.hasMoreElements() ) + { + AbstractTxn key = tenums.nextElement(); + System.err.println( "key.getDescription() =" + key.getDescription() + "= key.getFiTxnId( 0 )" + key.getFiTxnId( 0 ) + "=" ); + tsetMatcherKey.add( key.getFiTxnId( 0 ) ); + } + * + */ + + /* THIS DOES NOT SEEM TO HAVE ENTRIES SO i AM LEAVING IT OUT + int max = transactionList.getTxnCount(); + for ( k = 0; k < max; k++ ) // OnlineTxn onlinetxn : transactionList ) + { + OnlineTxn onlinetxn = transactionList.getTxn( k ); + String tmp = calcFITxnId( onlinetxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + onlineMatcherKey.add( tmp ); + + //if ( k > 9 ) + // break; + } + */ + System.err.println( "\n--------- end: make set of existing account online transactions -------------" ); + + //csvData.reset(); + if ( this instanceof CustomReader ) + { + csvData.parseIntoLines( customReaderData ); + } + else + { + csvData.parseIntoLines( null ); + } + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + csvData.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( csvData.nextLine() ) + { + fileLineCount ++; + if ( ! csvData.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + + csvData.reset(); + //----- Skip Header Lines ----- + System.err.println( "getHeaderCount() =" + getHeaderCount() ); + for ( int hdrCnt = getHeaderCount(); hdrCnt > 0; --hdrCnt ) + { + csvData.nextLine(); // skip the header + System.err.println( "skip header" ); + } + long begAtLine = csvData.getCurrentLineIndex() + 1; + + //testing + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + OnlineManager onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + +// this.account = account; +// this.transactionList = account.getDownloadedTxns(); + long totalProcessed = 0; + long totalAccepted = 0; + long totalRejected = 0; + long totalDuplicates = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + boolean accountMissingError = false; + +// csvData.printFile(); + System.err.println( "ImportReverseOrderFlg(): " + getCustomReaderData().getImportReverseOrderFlg() ); + if ( getCustomReaderData().getImportReverseOrderFlg() ) + { + csvData.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); + // csvData.printFile(); + } + + while ( csvData.nextLine() && totalProcessed < stopAtLine ) + { + accountNameFromCSV = ""; + totalProcessed++; + // System.out.println("calling parseNext..."); + + if ( parseNext() ) + { + if ( null == accountNameFromCSV || accountNameFromCSV.isEmpty() ) + { + System.out.println( "accountNameFromCSV is empty. Used selected acct." ); + this.account = accountIn; + } + else + { + this.account = rootAccount.getAccountByName( accountNameFromCSV ); + System.out.println( "accountNameFromCSV: " + accountNameFromCSV ); + if ( this.account == null ) + { + System.err.println( "ERROR: account is null" ); + //TODO: make new account? + if ( ! accountMissingError ) + { + JOptionPane.showMessageDialog(importDialog, "The account in the CSV file must \nalready exist in Money Dance. \nPlease create it first."); + } + accountMissingError = true; + totalRejected++; + continue; + } + System.out.println( "account.getAccountName(): " + this.account.getAccountName() ); + } + //TODO: per-account currency assignment is unfinished. + //it requires separating parsing logic from matching logic. 2011.11.25 ds + //this.currency = account.getCurrencyType(); + + + // if (null != this.transactionList && + // ! accountNameFromCSV.contentEquals(priorAccountNameFromCSV)) { + // priorAccountNameFromCSV = accountNameFromCSV; + this.transactionList = account.getDownloadedTxns();//TODO: move this out of loop + System.err.println( "tset.getSize() = " + tset.getSize() + " online txns.getSize() = " + transactionList.getTxnCount() ); + + // } + System.out.println("OnlineTxn txn = transactionList.newTxn();"); + OnlineTxn txn = transactionList.newTxn(); + assignDataToTxn( txn ); + txn.setProtocolType( OnlineTxn.PROTO_TYPE_OFX ); + + /* + if ( ! importDialog.isSelectedOnlineImportTypeRB() ) + { + // Flip signs for regular txn's + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + */ + System.err.println( "if (account.balanceIsNegated())" ); + if ( account.balanceIsNegated() ) + { + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + + //System.err.println( "call to calc fitxnid - should be online type" ); + String onlineMatchKey = calcFITxnId( txn ); + txn.setFITxnId( onlineMatchKey ); + + // ! onlineMatcherKey.contains( onlineMatchKey ) && + if ( ! tsetMatcherKey.contains( onlineMatchKey ) && + ! tsetFITxnIdMatcherKey.contains( onlineMatchKey ) + ) + { + System.err.println( "will add transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "= txn.getFIID() =" + txn.getFIID() + "=" ); + // + "\n or onlineMatchKey =" + onlineMatchKey + "=" ); + //System.err.println( "importDialog =" + importDialog + "=" ); + + /* NOTE: This is to convert the online txn to an regular txn. This would let me set categories and tags + * on incoming txn's, but it automatically sets the category to the default account one and I like it + * better using the onlineTxn where it prompts the user to select a category for imported txn's. Stan + */ + if ( importDialog.isSelectedOnlineImportTypeRB() ) + { + System.err.println( "add new onlineTxn" ); + transactionList.addNewTxn( txn ); + } + else + { + System.err.println( "add new parentTxn/splitTxn" ); + ParentTxn pTxn = onlineToParentTxn( account, rootAccount, txn ); + if ( pTxn != null ) + { + txnSet.addNewTxn( pTxn ); + } + } + totalAccepted ++; + // I don't know why, but for now this works here, but not below, after the main loop - Stan. Maybe because of using multiple account names? + System.err.println( "onlineMgr.processDownloadedTxns for account :" + account.getAccountName() ); + onlineMgr.processDownloadedTxns( account ); + } + else + { + System.err.println( "will NOT add Duplicate transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "=" ); + totalDuplicates ++; + } + } // parseNext() + else + { + // need to fixxx that it counts blank lines which it skips, as rejecteds + csvData.printCurrentLine(); + totalRejected++; + } + } // end while() + + JOptionPane.showMessageDialog( importDialog, "Total Records Process: " + totalProcessed + + "\nRecords Imported: " + totalAccepted + + "\nDuplicates Skipped: " + totalDuplicates + + "\nRejected Records: " + totalRejected + ); + + + /** NOTE: This is what I would like to do but I do not understand enough about this + * transactionList and why you create a newTxn() and then later call addNewTxn(). + * newTxn seems to be some kind of 'service' as opposed to a regular object??? Stan + */ + /* + int ans = JOptionPane.showConfirmDialog( importDialog, "Total Records Processed: " + totalProcessed + + "\nNew Records: " + totalAccepted + + "\nDuplicate Records: " + totalDuplicates + + "\nRejected Records: " + totalRejected + + "\n\nDo you want to import the New records ?" + , "Results", JOptionPane.YES_NO_OPTION ); + System.err.println( "ans =" + ans + "= JOptionPane.YES_OPTION =" + JOptionPane.YES_OPTION + "= JOptionPane.NO_OPTION =" + JOptionPane.NO_OPTION + "=" ); + if ( ans == JOptionPane.YES_OPTION ) + { + + OnlineTxnList transactionListCurrent = account.getDownloadedTxns(); + int max = transactionList.getTxnCount(); + System.err.println( "getTxnCount()/max =" + max + "=" ); + + for ( int j = 0; j < max; j ++ ) + { + System.err.println( "transactionList.getTxn( " + j + " ) =" + transactionList.getTxn( j ) + "=" ); + transactionListCurrent.addNewTxn( transactionList.getTxn( j ) ); + } + + + JOptionPane.showMessageDialog( importDialog, totalAccepted + " records were added" ); + } + else + { + JOptionPane.showMessageDialog( importDialog, "No records were added" ); + } + */ + + /* + int max = transactionList.getTxnCount(); + + for ( int j = 0; j < max; j ++ ) + { + transactionList.removeTxn( j ); + } + * + */ + } + + /* + * Note: Create a ParentTxn from a filled out OnlineTxn + */ + // @ Override + protected ParentTxn onlineToParentTxn( Account account, RootAccount rootAccount, OnlineTxn oTxn ) + throws IOException + { + Account category = null; + + String ckNum = oTxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ); + + // Don't know why I have to do this but I had to to make Online and Regular transactions use the same sign. + // actually I noticed that the 'Type of Account' determines the sign of an amount also. + // Bank accounts input as: Payment, Deposit + // Charge accounts input as: Charge, Payment and are reversed sign ! + // I am not going to worry about that at this point. It doesn't really matter. Just define your reader to compensate. + oTxn.setAmount( - oTxn.getAmount() ); + oTxn.setTotalAmount( - oTxn.getTotalAmount() ); + + ParentTxn pTxn = new ParentTxn( oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt() + , ckNum, account, oTxn.getName(), oTxn.getMemo() + , -1, AbstractTxn.STATUS_UNRECONCILED ); + try { + System.err.println( "find category for oTxn.getSubAccountTo() =" + oTxn.getSubAccountTo() + "=" ); + category = getAccount( account, oTxn.getSubAccountTo(), com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct( account ).getAccountName() //rr.getString("default_category"), + , oTxn.getAmount() <= 0 ? Account.ACCOUNT_TYPE_EXPENSE : Account.ACCOUNT_TYPE_INCOME ); + System.err.println( "found category =" + category + "=" ); + + } catch (Exception ex) { + Logger.getLogger(TransactionReader.class.getName()).log(Level.SEVERE, null, ex); + return null; // skip this transaction - do not add + } + + SplitTxn sptxn = new SplitTxn( pTxn, oTxn.getAmount(), oTxn.getAmount(), 1.0 + , category //com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct(account) /* category */ + , pTxn.getDescription(), -1, AbstractTxn.STATUS_UNRECONCILED ); + + sptxn.setIsNew( true ); + pTxn.addSplit( sptxn ); + + pTxn.setIsNew( true ); + + pTxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + sptxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + + return pTxn; + } + + public void setCustomReaderDialog( CustomReaderDialog customReaderDialog ) + { + System.err.println( "custreader set custreaderdialog" ); + this.customReaderDialog = customReaderDialog; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + if ( this.customReaderDialog == null ) + return 0; + else + return this.customReaderDialog.getNumberOfCustomReaderFieldsUsed(); + } + + public static TransactionReader[] getCompatibleReaders( boolean getAllReadersList, File selectedFile, ImportDialog importDialogArg, RootAccount rootAccount ) + { + ArrayList formats = new ArrayList(); +// moving importDialog = importDialogArg; + + System.err.println( "getCompatibleReaders() call cust read canParse()" ); + CSVReader csvReader = null; + + for ( String key : Settings.getReaderHM().keySet() ) + { + TransactionReader transactionReader = Settings.getReaderHM().get( key ); + System.err.println( "\n================ at canparse for transReader >" + key + "< ===============" ); + + try + { + System.err.println( "using fileEncoding >" + transactionReader.getCustomReaderData().getFileEncoding() + "< ===============" ); + if ( transactionReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + transactionReader.setRootAccount( rootAccount ); + if ( getAllReadersList ) + { + System.err.println( "=============== add all readers for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else if ( transactionReader.canParse( csvData ) ) + { + System.err.println( "=============== at canparse WORKS for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else + { + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + } + } + catch ( Throwable x ) + { + System.err.println( "at canparse error reading file !" ); + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + System.err.println( "File Error: " ); + x.printStackTrace(); + } + finally + { + try + { + csvReader.close(); + } + catch( Exception fex ) + { + ; + } + } + } + + /* + if ( customerReaderName != null && ! customerReaderName.equals( "" ) ) +s { + + System.err.println( "at canparse getFieldSeparator() =" + (char)data.getReader().getFieldSeparator() + "=" ); + + //data.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + +//s System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + + customReader.setDateFormat( importDialog.comboDateFormatGetItem() ); + System.err.println( "at canparse importDialog.comboDateFormatGetItem() after set =" + importDialog.comboDateFormatGetItem() + "=" ); + + if ( customReader.canParse( data ) ) + { + formats.add( customReader ); + } + } + + if ( citiBankCanadaReader.canParse( data ) ) + { + formats.add( citiBankCanadaReader ); + } + + if ( ingNetherlandsReader.canParse( data ) ) + { + formats.add( ingNetherlandsReader ); + } + + if ( simpleCreditDebitReader.canParse( data ) ) + { + formats.add( simpleCreditDebitReader ); + } + + if ( wellsFargoReader.canParse( data ) ) + { + formats.add( wellsFargoReader ); + } + */ + + TransactionReader[] retVal = new TransactionReader[formats.size()]; + formats.toArray( retVal ); + return retVal; + } + + @Override + public String toString() + { + return getFormatName(); + } + + //protected abstract boolean haveHeader(); + protected abstract int getHeaderCount(); + + /* + protected String convertParensToMinusSign( String amt ) + { + return amt.replaceAll( "\(.*\)", "-\$1" ); + } + */ + + public boolean isCustomReaderFlag() { + return customReaderFlag; + } + + public void setCustomReaderFlag(boolean customReaderFlag) { + this.customReaderFlag = customReaderFlag; + } + + public CustomReaderData getCustomReaderData() { + return customReaderData; + } + + public void setCustomReaderData(CustomReaderData customReaderData) { + this.customReaderData = customReaderData; + } + + public boolean isUsingCategorynameFlag() { + return isUsingCategorynameFlag; + } + + public void setUsingCategorynameFlag(boolean xx) { + this.isUsingCategorynameFlag = xx; + //System.err.println( "set isUsingCategorynameFlag to =" + isUsingCategorynameFlag + "=" ); + } + + /**************************************************************************************/ + + /** Find and return the ACCOUNT field in the appropriate format. */ + private final Account getAccount( Account account, String categoryName, String defaultAccount, + int defaultAcctType ) + throws Exception + { + //String acctStr = getField(fieldValues, 1 /*ACCOUNT*/, null); + if ( categoryName == null ) return addNewAccount( defaultAccount, account.getCurrencyType(), + rootAccount, "", defaultAcctType, true, -1 ); + //acctStr = acctStr.trim(); + return addNewAccount( categoryName, account.getCurrencyType(), rootAccount, "", + defaultAcctType, true, -1 ); + } + + /************************************************** + * Copied from Text File Importer code with permission from Reilly Technologies, L.L.C. + * I unfortunately do not understand what this code does. + **************************************************/ + + private Account addNewAccount( String accountName, CurrencyType currencyType, + Account parentAccount, String description, + int accountType, boolean lenientMatch, + int currAccountId) + throws Exception + { + if(accountName.indexOf(':')==0 && + parentAccount.getAccountType()==Account.ACCOUNT_TYPE_ROOT) { + accountName = accountName.substring(1); + } + + int colIndex = accountName.indexOf(':'); + String restOfAcctName; + String thisAcctName; + if(colIndex>=0) { + restOfAcctName = accountName.substring(colIndex+1); + thisAcctName = accountName.substring(0,colIndex); + } else { + restOfAcctName = null; + thisAcctName = accountName; + } + + Account newAccount = null; + for(int i=0; i. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.TransactionSet; +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.model.CurrencyType; +import com.moneydance.apps.md.model.AbstractTxn; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.apps.md.model.OnlineTxnList; +import com.moneydance.apps.md.model.ParentTxn; +import com.moneydance.apps.md.model.SplitTxn; + +import com.moneydance.apps.md.model.TxnSet; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public abstract class TransactionReader +{ + private boolean customReaderFlag = false; + private CustomReaderData customReaderData = null; + + protected static ImportDialog importDialog = null; + protected static CustomReaderDialog customReaderDialog = null; + protected static RootAccount rootAccount = null; + + protected CSVData csvData; + protected Account account; + protected String accountNameFromCSV;//for reading account from CSV file + protected String priorAccountNameFromCSV = "";//for efficiency only + protected OnlineTxnList transactionList; + protected TransactionSet txnSet; + protected CurrencyType currency; + protected HashSet tsetMatcherKey = new HashSet(); + protected HashSet tsetFITxnIdMatcherKey = new HashSet(); + //protected HashSet onlineMatcherKey = new HashSet(); + protected int defProtocolId = 999; // per Sean at MD + protected final static String DEFAULT_ENCODING = "UTF-8"; // "UTF-16LE"; "windows-1250"; Preselect this value in Encoding JComboBox. + //protected String fileEncoding = DEFAULT_ENCODING; + protected boolean isUsingCategorynameFlag = false; + + protected abstract boolean canParse( CSVData data ); + + protected abstract boolean parseNext() throws IOException; + +// protected abstract boolean parseNext(OnlineTxn txn) throws IOException; + + protected abstract boolean assignDataToTxn( OnlineTxn txn ) throws IOException; + + public abstract String getFormatName(); + + public abstract String[] getSupportedDateFormats(); + + public abstract void setSupportedDateFormats( String[] supportedDateFormats ); + + public abstract String getDateFormat(); + + public abstract void setDateFormat( String format ); + + //public abstract int getFieldSeparator(); + + //public abstract void setFieldSeparator( int xxx ); + + protected final void throwException( String message ) + throws IOException + { + throw new IOException( message ); + } + + public static void init( CustomReaderDialog customReaderDialogArg, ImportDialog importDialogArg, RootAccount rootAccountArg ) + { + customReaderDialog = customReaderDialogArg; + importDialog = importDialogArg; + rootAccount = rootAccountArg; + } + + protected final void setRootAccount( RootAccount rootAccount ) + { + this.rootAccount = rootAccount; + } + + public final String calcFITxnIdAbstract( AbstractTxn atxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( AbstractTxn ) -------------" ); + //System.err.println( "key.getDescription() =" + atxn.getDescription() + "= atxn.getFiTxnId( 1 ) =" + atxn.getFiTxnId( 1 ) + "=" ); + //System.err.println( "atxn.getFiTxnId( 1 ) [" + k + "] =" + atxn.getFiTxnId( 1 ) + "= atxn.getFiTxnId( 0 ) [" + k + "] =" + atxn.getFiTxnId( 0 ) + "=" ); + //tsetMatcherKey.add( atxn.getFiTxnId( 1 ) ); + + // Here I am manually recreating the FiTxnId that I set on imported txn's because I could not figure + // out how to simply read it. + + + //String tmp = atxn.getDateInt() + ":" + currency.format( atxn.getValue(), '.' ) + ":" + atxn.getDescription() + ":" + atxn.getCheckNumber(); + + // Create a pattern to match comments + //dave Pattern ckNumPat = Pattern.compile("^.*\\\"chknum\\\" = \\\"(.+?)\\\"\n.*$", Pattern.MULTILINE); + // I think I want to stick with (.*) instead of (.+) because I want to catch () either way. Stan + Pattern ckNumPat = Pattern.compile( "^.*\\\"chknum\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + Pattern amtPat = Pattern.compile( "^.*\\\"amt\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + String amt = null; + String origCheckNumber = null; + String desc = null; + + /* + + ol.orig-txn + { "dtinit-int" = "20110824" "name" = "whatever desc" "amt" = "-9824" "fitxnid" = "20110824:-98.24:whatever desc" "dtpstd-int" = "20110824" "dtavail-int" = "20110824" "invst.totalamt" = "-9824" "chknum" = "001234" "ptype" = "1" } + + */ + + String origtxn = atxn.getTag( "ol.orig-txn" ); + //String origCheckNumber = origtxn.replaceAll( ".*\\\"chknum\\\" = \\\"(.*?)\\\"\\\n.*", "$1" ); + + //System.out.println( "\norigtxn ="+origtxn + "=" ); + + // Run some matches + if ( origtxn != null ) + { + Matcher m = ckNumPat.matcher( origtxn ); + if ( m.find() ) + { + origCheckNumber = m.group( 1 ); + //System.out.println("Found orig check num ="+m.group( 1 ) + "=" ); + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + + m = amtPat.matcher( origtxn ); + if ( m.find() ) + { + long lamt = Long.valueOf( m.group( 1 ) ).longValue(); + amt = currency.format( lamt, '.' ); + //System.out.println("Found orig amt ="+m.group( 1 ) + "= formatted =" + amt ); + } + else + { + amt = currency.format( atxn.getValue(), '.' ); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("no orig check num so use getchecknum() ="+origCheckNumber + "=" ); + amt = currency.format( atxn.getValue(), '.' ); + } + + //long value = atxn.getParentTxn().getValue(); + + if ( atxn.getTag( "ol.orig-payee" ) == null ) + { + desc = atxn.getDescription(); + } + else + { + desc = atxn.getTag( "ol.orig-payee" ); + } + + // This new way compare using the ORIGINAL payee and memo fields so if the user changes them, it will still match. Stan + String tmp = atxn.getDateInt() + ":" + amt + + ":" + desc + + ":" + (origCheckNumber == null ? "" : origCheckNumber.replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (atxn.getTag( "ol.orig-memo" ) == null ? "" : atxn.getTag( "ol.orig-memo" )); + + //System.err.println( "calc abstract FITxnld >" + tmp + "<" ); + return tmp; + } + + + public final String calcFITxnId( OnlineTxn onlinetxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( onlinetxn ) -------------" ); + // txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + + String tmp = onlinetxn.getDateInitiatedInt() + ":" + currency.format( onlinetxn.getAmount(), '.' ) + + ":" + (onlinetxn.getName() == null ? "" : onlinetxn.getName() ) // used payeeName once + + ":" + (onlinetxn.getCheckNum() == null ? "" : onlinetxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (onlinetxn.getMemo() == null ? "" : onlinetxn.getMemo() ) + ; + + //System.err.println( "calc online FITxnld >" + tmp + "<" ); + return tmp; + } + + private final void makeSetOfExistingTxns( TxnSet tset ) + throws IOException + { + int k = 0; + for ( AbstractTxn atxn : tset ) + { + String tmp = calcFITxnIdAbstract( atxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + tsetMatcherKey.add( tmp ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( OnlineTxn.PROTO_TYPE_OFX ) ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( defProtocolId ) ); + + k++; + //if ( k > 9 ) + // break; + } + //System.err.println( "\n--------- end: make set of existing account transactions -------------" ); + } + + /* + ************************************************************************************************ + */ + public final void parse( Main main, CSVData csvDataArg, Account accountIn, RootAccount rootAccount ) + throws IOException + { + System.err.println("\n--------- entered TransactionReader().parse() -------------"); + + this.csvData = csvDataArg; + this.rootAccount = rootAccount; + this.txnSet = rootAccount.getTransactionSet(); + this.tsetMatcherKey = new HashSet(); + this.tsetFITxnIdMatcherKey = new HashSet(); + +// //begin testing +// //this is part of what would be needed to match account names +// //using regex or partial matching instead of exact and complete matching. +// HashMap accountMap = new HashMap(); +// Enumeration accountListEnum = rootAccount.getSubAccounts(); +// while (accountListEnum.hasMoreElements()) { +// Account a = (Account)accountListEnum.nextElement(); +// accountMap.put(a.getAccountName(), a); +// } +// //getAllAccountNames - is only path from root to present acct +// //end testing + + System.err.println("\n--------- beg: make set of existing account transactions -------------"); + //System.err.println( "number of trans list =" +this.txnSet.getTransactionsForAccount( account ).getSize() ); + System.err.println("size of txnSet.getAllTxns = " + this.txnSet.getAllTxns().getSize()); + // cannot get just for account because I am putting them into a temp/empty account ! + //Enumeration tenums = this.txnSet.getTransactionsForAccount( account ).getAllTxns(); + TxnSet tset = this.txnSet.getAllTxns(); + + //TODO: refactor this. + //Currently, if the CSV file contains transactions from different accounts + //with different currencies, we don't handle that. However, we could. + //By separating the parsing from the matching, we could easily handle it. + //For now, the account selected on the dialog will provide the currency + //for all accounts. + //Fixing this is a low priority because + // 1) not everyone has multiple accounts in a single file + // 2) most people with multiple accounts will have them in the same currency + //If someone needs multiple currencies and accounts in one file, + //it can be implemented as described above. + this.currency = accountIn.getCurrencyType(); + //TODO: after refacting, call this only after each line of CSV file has been processed + //TODO: parse CSV first, then iterate again to match FITxnId + makeSetOfExistingTxns( tset ); + + /* + while ( tenums.hasMoreElements() ) + { + AbstractTxn key = tenums.nextElement(); + System.err.println( "key.getDescription() =" + key.getDescription() + "= key.getFiTxnId( 0 )" + key.getFiTxnId( 0 ) + "=" ); + tsetMatcherKey.add( key.getFiTxnId( 0 ) ); + } + * + */ + + /* THIS DOES NOT SEEM TO HAVE ENTRIES SO i AM LEAVING IT OUT + int max = transactionList.getTxnCount(); + for ( k = 0; k < max; k++ ) // OnlineTxn onlinetxn : transactionList ) + { + OnlineTxn onlinetxn = transactionList.getTxn( k ); + String tmp = calcFITxnId( onlinetxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + onlineMatcherKey.add( tmp ); + + //if ( k > 9 ) + // break; + } + */ + System.err.println( "\n--------- end: make set of existing account online transactions -------------" ); + + //csvData.reset(); + if ( this instanceof CustomReader ) + { + csvData.parseIntoLines( customReaderData ); + } + else + { + csvData.parseIntoLines( null ); + } + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + csvData.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( csvData.nextLine() ) + { + fileLineCount ++; + if ( ! csvData.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + + csvData.reset(); + //----- Skip Header Lines ----- + System.err.println( "getHeaderCount() =" + getHeaderCount() ); + for ( int hdrCnt = getHeaderCount(); hdrCnt > 0; --hdrCnt ) + { + csvData.nextLine(); // skip the header + System.err.println( "skip header" ); + } + long begAtLine = csvData.getCurrentLineIndex() + 1; + + //testing + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + OnlineManager onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + +// this.account = account; +// this.transactionList = account.getDownloadedTxns(); + long totalProcessed = 0; + long totalAccepted = 0; + long totalRejected = 0; + long totalDuplicates = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + boolean accountMissingError = false; + +// csvData.printFile(); + System.err.println( "ImportReverseOrderFlg(): " + getCustomReaderData().getImportReverseOrderFlg() ); + if ( getCustomReaderData().getImportReverseOrderFlg() ) + { + csvData.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); + // csvData.printFile(); + } + + while ( csvData.nextLine() && totalProcessed < stopAtLine ) + { + accountNameFromCSV = ""; + totalProcessed++; + // System.out.println("calling parseNext..."); + + if ( parseNext() ) + { + if ( null == accountNameFromCSV || accountNameFromCSV.isEmpty() ) + { + System.out.println( "accountNameFromCSV is empty. Used selected acct." ); + this.account = accountIn; + } + else + { + this.account = rootAccount.getAccountByName( accountNameFromCSV ); + System.out.println( "accountNameFromCSV: " + accountNameFromCSV ); + if ( this.account == null ) + { + System.err.println( "ERROR: account is null" ); + //TODO: make new account? + if ( ! accountMissingError ) + { + JOptionPane.showMessageDialog(importDialog, "The account in the CSV file must \nalready exist in Money Dance. \nPlease create it first."); + } + accountMissingError = true; + totalRejected++; + continue; + } + System.out.println( "account.getAccountName(): " + this.account.getAccountName() ); + } + //TODO: per-account currency assignment is unfinished. + //it requires separating parsing logic from matching logic. 2011.11.25 ds + //this.currency = account.getCurrencyType(); + + + // if (null != this.transactionList && + // ! accountNameFromCSV.contentEquals(priorAccountNameFromCSV)) { + // priorAccountNameFromCSV = accountNameFromCSV; + this.transactionList = account.getDownloadedTxns();//TODO: move this out of loop + System.err.println( "tset.getSize() = " + tset.getSize() + " online txns.getSize() = " + transactionList.getTxnCount() ); + + // } + System.out.println("OnlineTxn txn = transactionList.newTxn();"); + OnlineTxn txn = transactionList.newTxn(); + assignDataToTxn( txn ); + txn.setProtocolType( OnlineTxn.PROTO_TYPE_OFX ); + + /* + if ( ! importDialog.isSelectedOnlineImportTypeRB() ) + { + // Flip signs for regular txn's + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + */ + System.err.println( "if (account.balanceIsNegated())" ); + if ( account.balanceIsNegated() ) + { + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + + //System.err.println( "call to calc fitxnid - should be online type" ); + String onlineMatchKey = calcFITxnId( txn ); + txn.setFITxnId( onlineMatchKey ); + + // ! onlineMatcherKey.contains( onlineMatchKey ) && + if ( ! tsetMatcherKey.contains( onlineMatchKey ) && + ! tsetFITxnIdMatcherKey.contains( onlineMatchKey ) + ) + { + System.err.println( "will add transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "= txn.getFIID() =" + txn.getFIID() + "=" ); + // + "\n or onlineMatchKey =" + onlineMatchKey + "=" ); + //System.err.println( "importDialog =" + importDialog + "=" ); + + /* NOTE: This is to convert the online txn to an regular txn. This would let me set categories and tags + * on incoming txn's, but it automatically sets the category to the default account one and I like it + * better using the onlineTxn where it prompts the user to select a category for imported txn's. Stan + */ + if ( importDialog.isSelectedOnlineImportTypeRB() ) + { + System.err.println( "add new onlineTxn" ); + transactionList.addNewTxn( txn ); + } + else + { + System.err.println( "add new parentTxn/splitTxn" ); + ParentTxn pTxn = onlineToParentTxn( account, rootAccount, txn ); + if ( pTxn != null ) + { + txnSet.addNewTxn( pTxn ); + } + } + totalAccepted ++; + // I don't know why, but for now this works here, but not below, after the main loop - Stan. Maybe because of using multiple account names? + System.err.println( "onlineMgr.processDownloadedTxns for account :" + account.getAccountName() ); + onlineMgr.processDownloadedTxns( account ); + } + else + { + System.err.println( "will NOT add Duplicate transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "=" ); + totalDuplicates ++; + } + } // parseNext() + else + { + // need to fixxx that it counts blank lines which it skips, as rejecteds + csvData.printCurrentLine(); + totalRejected++; + } + } // end while() + + JOptionPane.showMessageDialog( importDialog, "Total Records Process: " + totalProcessed + + "\nRecords Imported: " + totalAccepted + + "\nDuplicates Skipped: " + totalDuplicates + + "\nRejected Records: " + totalRejected + ); + + + /** NOTE: This is what I would like to do but I do not understand enough about this + * transactionList and why you create a newTxn() and then later call addNewTxn(). + * newTxn seems to be some kind of 'service' as opposed to a regular object??? Stan + */ + /* + int ans = JOptionPane.showConfirmDialog( importDialog, "Total Records Processed: " + totalProcessed + + "\nNew Records: " + totalAccepted + + "\nDuplicate Records: " + totalDuplicates + + "\nRejected Records: " + totalRejected + + "\n\nDo you want to import the New records ?" + , "Results", JOptionPane.YES_NO_OPTION ); + System.err.println( "ans =" + ans + "= JOptionPane.YES_OPTION =" + JOptionPane.YES_OPTION + "= JOptionPane.NO_OPTION =" + JOptionPane.NO_OPTION + "=" ); + if ( ans == JOptionPane.YES_OPTION ) + { + + OnlineTxnList transactionListCurrent = account.getDownloadedTxns(); + int max = transactionList.getTxnCount(); + System.err.println( "getTxnCount()/max =" + max + "=" ); + + for ( int j = 0; j < max; j ++ ) + { + System.err.println( "transactionList.getTxn( " + j + " ) =" + transactionList.getTxn( j ) + "=" ); + transactionListCurrent.addNewTxn( transactionList.getTxn( j ) ); + } + + + JOptionPane.showMessageDialog( importDialog, totalAccepted + " records were added" ); + } + else + { + JOptionPane.showMessageDialog( importDialog, "No records were added" ); + } + */ + + /* + int max = transactionList.getTxnCount(); + + for ( int j = 0; j < max; j ++ ) + { + transactionList.removeTxn( j ); + } + * + */ + } + + /* + * Note: Create a ParentTxn from a filled out OnlineTxn + */ + // @ Override + protected ParentTxn onlineToParentTxn( Account account, RootAccount rootAccount, OnlineTxn oTxn ) + throws IOException + { + Account category = null; + + String ckNum = oTxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ); + + // Don't know why I have to do this but I had to to make Online and Regular transactions use the same sign. + // actually I noticed that the 'Type of Account' determines the sign of an amount also. + // Bank accounts input as: Payment, Deposit + // Charge accounts input as: Charge, Payment and are reversed sign ! + // I am not going to worry about that at this point. It doesn't really matter. Just define your reader to compensate. + oTxn.setAmount( - oTxn.getAmount() ); + oTxn.setTotalAmount( - oTxn.getTotalAmount() ); + + ParentTxn pTxn = new ParentTxn( oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt() + , ckNum, account, oTxn.getName(), oTxn.getMemo() + , -1, AbstractTxn.STATUS_UNRECONCILED ); + try { + System.err.println( "find category for oTxn.getSubAccountTo() =" + oTxn.getSubAccountTo() + "=" ); + category = getAccount( account, oTxn.getSubAccountTo(), com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct( account ).getAccountName() //rr.getString("default_category"), + , oTxn.getAmount() <= 0 ? Account.ACCOUNT_TYPE_EXPENSE : Account.ACCOUNT_TYPE_INCOME ); + System.err.println( "found category =" + category + "=" ); + + } catch (Exception ex) { + Logger.getLogger(TransactionReader.class.getName()).log(Level.SEVERE, null, ex); + return null; // skip this transaction - do not add + } + + SplitTxn sptxn = new SplitTxn( pTxn, oTxn.getAmount(), oTxn.getAmount(), 1.0 + , category //com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct(account) /* category */ + , pTxn.getDescription(), -1, AbstractTxn.STATUS_UNRECONCILED ); + + sptxn.setIsNew( true ); + pTxn.addSplit( sptxn ); + + pTxn.setIsNew( true ); + + pTxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + sptxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + + return pTxn; + } + + public void setCustomReaderDialog( CustomReaderDialog customReaderDialog ) + { + System.err.println( "custreader set custreaderdialog" ); + this.customReaderDialog = customReaderDialog; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + if ( this.customReaderDialog == null ) + return 0; + else + return this.customReaderDialog.getNumberOfCustomReaderFieldsUsed(); + } + + public static TransactionReader[] getCompatibleReaders( boolean getAllReadersList, File selectedFile, ImportDialog importDialogArg, RootAccount rootAccount ) + { + ArrayList formats = new ArrayList(); +// moving importDialog = importDialogArg; + + System.err.println( "getCompatibleReaders() call cust read canParse()" ); + CSVReader csvReader = null; + + for ( String key : Settings.getReaderHM().keySet() ) + { + TransactionReader transactionReader = Settings.getReaderHM().get( key ); + System.err.println( "\n================ at canparse for transReader >" + key + "< ===============" ); + + try + { + System.err.println( "using fileEncoding >" + transactionReader.getCustomReaderData().getFileEncoding() + "< ===============" ); + if ( transactionReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + transactionReader.setRootAccount( rootAccount ); + if ( getAllReadersList ) + { + System.err.println( "=============== add all readers for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else if ( transactionReader.canParse( csvData ) ) + { + System.err.println( "=============== at canparse WORKS for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else + { + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + } + } + catch ( Throwable x ) + { + System.err.println( "at canparse error reading file !" ); + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + System.err.println( "File Error: " ); + x.printStackTrace(); + } + finally + { + try + { + csvReader.close(); + } + catch( Exception fex ) + { + ; + } + } + } + + /* + if ( customerReaderName != null && ! customerReaderName.equals( "" ) ) +s { + + System.err.println( "at canparse getFieldSeparator() =" + (char)data.getReader().getFieldSeparator() + "=" ); + + //data.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + +//s System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + + customReader.setDateFormat( importDialog.comboDateFormatGetItem() ); + System.err.println( "at canparse importDialog.comboDateFormatGetItem() after set =" + importDialog.comboDateFormatGetItem() + "=" ); + + if ( customReader.canParse( data ) ) + { + formats.add( customReader ); + } + } + + if ( citiBankCanadaReader.canParse( data ) ) + { + formats.add( citiBankCanadaReader ); + } + + if ( ingNetherlandsReader.canParse( data ) ) + { + formats.add( ingNetherlandsReader ); + } + + if ( simpleCreditDebitReader.canParse( data ) ) + { + formats.add( simpleCreditDebitReader ); + } + + if ( wellsFargoReader.canParse( data ) ) + { + formats.add( wellsFargoReader ); + } + */ + + TransactionReader[] retVal = new TransactionReader[formats.size()]; + formats.toArray( retVal ); + return retVal; + } + + @Override + public String toString() + { + return getFormatName(); + } + + //protected abstract boolean haveHeader(); + protected abstract int getHeaderCount(); + + /* + protected String convertParensToMinusSign( String amt ) + { + return amt.replaceAll( "\(.*\)", "-\$1" ); + } + */ + + public boolean isCustomReaderFlag() { + return customReaderFlag; + } + + public void setCustomReaderFlag(boolean customReaderFlag) { + this.customReaderFlag = customReaderFlag; + } + + public CustomReaderData getCustomReaderData() { + return customReaderData; + } + + public void setCustomReaderData(CustomReaderData customReaderData) { + this.customReaderData = customReaderData; + } + + public boolean isUsingCategorynameFlag() { + return isUsingCategorynameFlag; + } + + public void setUsingCategorynameFlag(boolean xx) { + this.isUsingCategorynameFlag = xx; + //System.err.println( "set isUsingCategorynameFlag to =" + isUsingCategorynameFlag + "=" ); + } + + /**************************************************************************************/ + + /** Find and return the ACCOUNT field in the appropriate format. */ + private final Account getAccount( Account account, String categoryName, String defaultAccount, + int defaultAcctType ) + throws Exception + { + //String acctStr = getField(fieldValues, 1 /*ACCOUNT*/, null); + if ( categoryName == null ) return addNewAccount( defaultAccount, account.getCurrencyType(), + rootAccount, "", defaultAcctType, true, -1 ); + //acctStr = acctStr.trim(); + return addNewAccount( categoryName, account.getCurrencyType(), rootAccount, "", + defaultAcctType, true, -1 ); + } + + /************************************************** + * Copied from Text File Importer code with permission from Reilly Technologies, L.L.C. + * I unfortunately do not understand what this code does. + **************************************************/ + + private Account addNewAccount( String accountName, CurrencyType currencyType, + Account parentAccount, String description, + int accountType, boolean lenientMatch, + int currAccountId) + throws Exception + { + if(accountName.indexOf(':')==0 && + parentAccount.getAccountType()==Account.ACCOUNT_TYPE_ROOT) { + accountName = accountName.substring(1); + } + + int colIndex = accountName.indexOf(':'); + String restOfAcctName; + String thisAcctName; + if(colIndex>=0) { + restOfAcctName = accountName.substring(colIndex+1); + thisAcctName = accountName.substring(0,colIndex); + } else { + restOfAcctName = null; + thisAcctName = accountName; + } + + Account newAccount = null; + for(int i=0; i. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + +/** + * + * @author miki and Stan Towianski + */ +public class CSVData +{ + private String[][] data; + private int currentLineIndex = -1; + private int currentFieldIndex = -1; + + public CSVReader reader; + + public CSVData( CSVReader readerArg ) + { + this.reader = readerArg; + } + + public void reset() + { + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public String[][] getData() + { + return data; + } + + public void parseIntoLines( CustomReaderData customReaderData ) + throws IOException + { + ArrayList line = new ArrayList(); + ArrayList file = new ArrayList(); + int fieldSeparator = customReaderData.getFieldSeparatorChar(); + + if ( customReaderData != null ) + { + reader.setFieldSeparator( fieldSeparator ); + } + + while ( reader.nextLine() ) + { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) + { + System.err.println( " line.add string =" + s + "=" ); + line.add( s ); + } + + System.err.println( " line.size() =" + line.size() + "=\n" ); + String[] newLine = new String[ line.size() ]; + line.toArray( newLine ); + file.add( newLine ); + line.clear(); + } + + data = new String[file.size()][]; + file.toArray( data ); + System.err.println( " parsed lines total =" + file.size() + "=" ); + currentLineIndex = -1; + currentFieldIndex = -1; + } + + public void reverseListRangeOrder( long beg, long end ) + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + System.err.println( "revLine beg: " + beg ); + System.err.println( "revLine end: " + end ); + if ( end <= beg ) + { + return; + } + + int begInt = (int)beg; + int endInt = (int)end; + + String[] strArr = null; + + for ( ; endInt > begInt; endInt--, begInt++ ) + { + strArr = data[ endInt ]; + data[ endInt ] = data[ begInt ]; + data[ begInt ] = strArr; + } + } + + public boolean nextLine() + { + if ( currentLineIndex < data.length ) + { + ++currentLineIndex; + currentFieldIndex = -1; + } + + //System.err.println( "nextLine() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentLineIndex < data.length ? "true" : "false" ) ); + return currentLineIndex < data.length; + } + + public boolean hasEnoughFieldsPerCurrentLine( int neededFields ) + { + //System.err.println( "fieldsPerCurrentLine() data[currentLineIndex].length + 1 =" + (data[currentLineIndex].length + 1) ); + return data[currentLineIndex].length + 1 >= neededFields; + } + + public boolean nextField() + { + //System.err.println( "nextField() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "nextField() ---- return false" ); + return false; + } + + if ( currentFieldIndex < data[currentLineIndex].length ) + { + ++currentFieldIndex; + } + + //System.err.println( "nextField()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (currentFieldIndex < data[currentLineIndex].length ? "true" : "false" ) ); + return currentFieldIndex < data[currentLineIndex].length; + } + + public boolean hasZeroFields() + { + //System.err.println( "hasZeroFields() ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length ); + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + //System.err.println( "hasZeroFields() ---- return false" ); + return false; + } + + //System.err.println( "hasZeroFields()2 ---- currentLineIndex =" + currentLineIndex + "= data.length =" + data.length + " ans =" + (0 < data[currentLineIndex].length ? "true" : "false" ) ); + return 0 < data[currentLineIndex].length; + } + + public String getField() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + return null; + } + if ( currentFieldIndex < 0 || currentFieldIndex >= data[currentLineIndex].length ) + { + return null; + } + + return data[currentLineIndex][currentFieldIndex]; + } + + public int getCurrentLineIndex() + { + return currentLineIndex; + } + + public int getCurrentFieldIndex() + { + return currentFieldIndex; + } + + public int getCurrentLineIndexWithinBounds() + { + if ( currentLineIndex < 0 ) + { + return 0; + } + if ( currentLineIndex >= data.length ) + { + return data.length - 1; + } + return currentLineIndex; + } + + public int getCurrentFieldIndexWithinBounds() + { + if ( currentFieldIndex < 0 ) + { + return 0; + } + if ( currentFieldIndex >= data[currentLineIndex].length ) + { + return data[currentLineIndex].length - 1; + } + return currentFieldIndex; + } + + public String printCurrentLine() + { + if ( currentLineIndex < 0 || currentLineIndex >= data.length ) + { + System.err.append( "currentLineIndex out of range =" + currentLineIndex ); + return null; + } + + System.err.append( "\n curr line >" ); + try { + for ( int i = 0; i < data[currentLineIndex].length; i ++ ) + { + if ( i > 0 ) + System.err.append( "|" ); + System.err.append( data[currentLineIndex][currentFieldIndex] ); + } + } + catch( Exception ex ) + { + System.err.append( "*** Error in printCurrentLine at currentLineIndex =" + currentLineIndex + " currentFieldIndex =" + currentFieldIndex ); + } + System.err.append( "< curr line." ); + return null; + } + + public void printFile() + { + System.err.append( "\n ------------- PRINT FILE ---------------" ); + int maxRows = data.length; + for ( int row = 0; row < maxRows; row++ ) + { + System.err.append( "\n line [" + row + "] >" ); + for ( int fieldIndex = 0; fieldIndex < data[ row ].length; fieldIndex++ ) + { + if ( fieldIndex > 0 ) + System.err.append( "|" ); + System.err.append( data[ row ][ fieldIndex ] ); + } + System.err.append( "<" ); + } + System.err.append( "\n ------------- END PRINT FILE ---------------" ); + } + + public CSVReader getReader() { + return this.reader; + } + + public void setReader(CSVReader reader) { + this.reader = reader; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/CSVReader.java b/src/com/moneydance/modules/features/mdcsvimporter/CSVReader.java new file mode 100644 index 0000000..5a48b4c --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/CSVReader.java @@ -0,0 +1,349 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.Reader; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + public CSVReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public CSVReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //System.err.println( "nextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + + if ( isEol( lastChar ) || isEof( lastChar ) ) + { + //System.err.println( "nextField() return null for Eol or Eof" ); + return null; + } + + builder.setLength( 0 ); + + if ( isQuote( lastChar ) ) + { + // quoted field + lastChar = reader.read(); + while ( !isQuote( lastChar ) && !isEol( lastChar ) && !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + //System.err.println( "lastChar =" + lastChar + "=" ); + } + //System.err.println( "end field" ); + //System.err.println( "read field =" + builder.toString() + "=" ); + + if ( !isQuote( lastChar ) ) + { + throw new IOException( "Unexpected end of line." ); + } + + // skip quote + lastChar = reader.read(); + // skip spaces + while ( isWhitespace( lastChar ) ) + { + lastChar = reader.read(); + } + // and the next field separator + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + else + { + // plain value + while ( !isFieldSeparator( lastChar ) && !isEol( lastChar ) && + !isEof( lastChar ) ) + { + builder.appendCodePoint( lastChar ); + lastChar = reader.read(); + } + if ( isFieldSeparator( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // TODO: skip separator + + if ( trimFields ) + { + //System.err.println( "CSVReader return nextField trim =" + builder.toString().trim() + "=" ); + return builder.toString().trim(); + } + else + { + //System.err.println( "CSVReader return nextField =" + builder.toString() + "=" ); + return builder.toString(); + } + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + + protected final boolean isWhitespace( int ch ) + { + return (ch == SPACE || ch == TAB) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isQuote( int ch ) + { + return ch == quoteCharacter; + } + + protected final boolean isFieldSeparator( int ch ) + { + return ch == fieldSeparator; + } + + protected final boolean isEol( int ch ) + { + return (ch == LF || ch == CR) && !isQuote( ch ) && !isFieldSeparator( ch ); + } + + protected final boolean isEof( int ch ) + { + return ch < 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderData.java b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderData.java new file mode 100644 index 0000000..dbe1b60 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderData.java @@ -0,0 +1,196 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderData { + +// ArrayList dataTypesList = new ArrayList( 10 ); +// ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + int fieldSeparatorChar = ','; + int headerLines = 0; + int footerLines = 0; + int amountCurrencyChar = '$'; + int amountDecimalSignChar = '.'; + int amountGroupingSeparatorChar = ','; + String amountFormat = "#,###,###,##0.00;(#)"; + boolean importReverseOrderFlg = false; + boolean useRegexFlag = false; + String readerName = ""; + String dateFormatString = "MM/DD/YY"; + String fileEncoding = TransactionReader.DEFAULT_ENCODING; + String filenameMatcher = ".*\\.[Cc][Ss][Vv]"; + + + public ArrayList getRegexsList() { + return regexsList; + } + + public String getRegexsListEncoded() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append( "[" ); + for( String str : regexsList ) + { + sbuf.append( str ); + sbuf.append( "a" ); + } + sbuf.append( "]" ); + return sbuf.toString(); + } + + public void setRegexsList(ArrayList regexsList) { + this.regexsList = regexsList; + } + + public String getRegexsListEle( int c ) { + return regexsList.get( c ); + } + + public void setRegexsListEle( int c, String regex) { + this.regexsList.set( c, regex ); + } + + public ArrayList getDataTypesList() { + return dataTypesList; + } + + public void setDataTypesList(ArrayList dataTypesList) { + this.dataTypesList = dataTypesList; + } + + public ArrayList getEmptyFlagsList() { + return emptyFlagsList; + } + + public void setEmptyFlagsList(ArrayList emptyFlagsList) { + this.emptyFlagsList = emptyFlagsList; + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar; + } + + public void setFieldSeparatorChar(int fieldSeparatorChar) { + this.fieldSeparatorChar = fieldSeparatorChar; + } + + public int getHeaderLines() { + return headerLines; + } + + public void setHeaderLines(int headerLines) { + this.headerLines = headerLines; + } + + public String getReaderName() { + return readerName; + } + + public void setReaderName(String readerName) { + this.readerName = readerName; + } + + public String getDateFormatString() { + return dateFormatString; + } + + public void setDateFormatString(String dateFormatString) { + this.dateFormatString = dateFormatString; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public int getFooterLines() { + return footerLines; + } + + public void setFooterLines(int footerLines) { + this.footerLines = footerLines; + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar; + } + + public void setAmountCurrencyChar(int amountCurrencyChar) { + this.amountCurrencyChar = amountCurrencyChar; + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar; + } + + public void setAmountDecimalSignChar(int amountDecimalSignChar) { + this.amountDecimalSignChar = amountDecimalSignChar; + } + + public String getAmountFormat() { + return amountFormat; + } + + public void setAmountFormat(String amountFormat) { + this.amountFormat = amountFormat; + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar; + } + + public void setAmountGroupingSeparatorChar(int amountGroupingSeparatorChar) { + this.amountGroupingSeparatorChar = amountGroupingSeparatorChar; + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg; + } + + public void setImportReverseOrderFlg(boolean importReverseOrderFlg) { + this.importReverseOrderFlg = importReverseOrderFlg; + } + + public boolean getUseRegexFlag() { + return useRegexFlag; + } + + public void setUseRegexFlag(boolean useRegexFlag) { + this.useRegexFlag = useRegexFlag; + } + + public String getFileEncoding() { + return fileEncoding; + } + + public void setFileEncoding(String fileEncoding) { + this.fileEncoding = fileEncoding; + } + + public String getFilenameMatcher() { + return filenameMatcher; + } + + public void setFilenameMatcher(String filenameMatcher) { + this.filenameMatcher = filenameMatcher; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.form b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.form new file mode 100644 index 0000000..eecbfeb --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.form @@ -0,0 +1,1171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.java b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.java new file mode 100644 index 0000000..ca849ec --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialog.java @@ -0,0 +1,1874 @@ + +/* + * CustomerReaderDialog.java + * + * Created on Aug 3, 2011, 11:49:09 PM + */ + +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.nio.charset.Charset; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.*; +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.KeyStroke; + +/** + * + * @author Stan Towianski + */ + + +public class CustomReaderDialog extends javax.swing.JDialog { + + //javax.swing.JDialog parent = null; + ImportDialog parent = null; + + //String [] dataTypes = { "", "ignore", "-Payment-", "-Deposit-", "date", "dateAvailable", "dateInitiated", "datePosted", "datePurchased", "check number", "description", "memo", "account name" }; + + String [] dataTypes = { + CustomReader.DATA_TYPE_BLANK + , CustomReader.DATA_TYPE_IGNORE + , CustomReader.DATA_TYPE_IGNORE_REST + , CustomReader.DATA_TYPE_PAYMENT + , CustomReader.DATA_TYPE_DEPOSIT + , CustomReader.DATA_TYPE_DATE + , CustomReader.DATA_TYPE_DATE_AVAILABLE + , CustomReader.DATA_TYPE_DATE_INITIATED + , CustomReader.DATA_TYPE_DATE_POSTED + , CustomReader.DATA_TYPE_DATE_PURCHASED + , CustomReader.DATA_TYPE_CHECK_NUMBER + , CustomReader.DATA_TYPE_DESCRIPTION + , CustomReader.DATA_TYPE_MEMO + , CustomReader.DATA_TYPE_ACCOUNT_NAME + , CustomReader.DATA_TYPE_CATEGORY_NAME + }; + + String [] allowEmptyFlag = { "", "Can Be Blank", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; +// ArrayList dataTypesList = new ArrayList( 10 ); + // ArrayList emptyFlagsList = new ArrayList( 10 ); + ArrayList regexsList = new ArrayList( 10 ); + ArrayList dataTypesList = new ArrayList( 10 ); + ArrayList emptyFlagsList = new ArrayList( 10 ); + //ArrayList dateFormatList = new ArrayList( 10 ); + HashMap ReaderConfigsHM = new HashMap(); + HashMap ReaderHM = new HashMap(); + + SortedMap encodings = Charset.availableCharsets(); + Set fileEncodingNames = encodings.keySet(); + + //private static CitiBankCanadaReader citiBankCanadaReader = new CitiBankCanadaReader(); + //private static INGNetherlandsReader ingNetherlandsReader = new INGNetherlandsReader(); + //private static SimpleCreditDebitReader simpleCreditDebitReader = new SimpleCreditDebitReader(); + //private static WellsFargoReader wellsFargoReader = new WellsFargoReader(); + //private static YodleeReader yodleeReader = new YodleeReader(); + //private static BbvaCompassBankReader bbvaCompassReader = new BbvaCompassBankReader(); + + + /** Creates new form CustomerReaderDialog */ + public CustomReaderDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + initComponents(); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + + this.setModal( false ); + this.addEscapeListener( this ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + public boolean addReaderConfig() + { + message.setText( "" ); + if ( ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "A reader already exists by the name '" + readerName.getText() + "'" ); + return false; + } + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + /* + System.out.println( "add datatype===================================" ); + int i = 0; + for ( String dataType : customReaderData.getDataTypesList() ) + { + System.out.println( "add datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + listModel.addElement( readerName.getText() ); + + Settings.setCustomReaderConfig( customReaderData ); + + this.parent.comboFileFormat1AddItem( customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + return true; + } + + public boolean deleteReaderConfig() + { + message.setText( "" ); + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + //System.err.println( " selected index =" + index + " item =" + listModel.getElementAt( index ) + "=" ); + + Settings.removeCustomReaderConfig( ReaderConfigsHM.get( listModel.getElementAt( index ) ) ); + + ReaderConfigsHM.remove( listModel.getElementAt( index ) ); + ReaderHM.remove( listModel.getElementAt( index ) ); + + listModel.remove( index ); + clearReaderConfig(); + + return true; + } + + public TransactionReader getTransactionReader( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return null; + } + return ReaderHM.get( readerNameToGet ); + } + + public boolean getReaderConfig( String readerNameToGet ) + { + message.setText( "" ); + if ( ! ReaderConfigsHM.containsKey( readerNameToGet ) ) + { + message.setText( "There is no reader by that name '" + readerNameToGet + "'" ); + return false; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerNameToGet ); + readerName.setText( readerNameToGet ); + regexsList = customReaderData.getRegexsList(); + dataTypesList = customReaderData.getDataTypesList(); + emptyFlagsList = customReaderData.getEmptyFlagsList(); + //dateFormatList = customReaderData.getDateFormatList(); + setFieldSeparatorChar( customReaderData.getFieldSeparatorChar() ); + setFileEncodingSelectedItem( customReaderData.getFileEncoding() ); + setHeaderLines( customReaderData.getHeaderLines() ); + setFooterLines( customReaderData.getFooterLines() ); + + setAmountCurrencyChar( customReaderData.getAmountCurrencyChar() ); + setAmountDecimalSignChar( customReaderData.getAmountDecimalSignChar() ); + setAmountGroupingSeparatorChar( customReaderData.getAmountGroupingSeparatorChar() ); + setAmountFormat( customReaderData.getAmountFormat() ); + setImportReverseOrderFlg( customReaderData.getImportReverseOrderFlg() ); + setUseRegexFlag( customReaderData.getUseRegexFlag() ); + setFilenameMatcher( customReaderData.getFilenameMatcher() ); + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + customReadersList.setSelectedValue( readerNameToGet, true ); + + System.err.println( "get regexsList arraylist =" + regexsList + "=" ); + System.err.println( "get dataTypesList arraylist =" + dataTypesList + "=" ); + System.err.println( "get emptyFlagsList arraylist =" + emptyFlagsList + "=" ); + + /* + int i = 0; +// System.out.println( "get datatype===================================" ); +// System.out.println( "get datatype===================================" ); + for ( String dataType : dataTypesList ) + { +// System.out.println( "get datatype " + i + " =" + dataType + "=" ); + i++; + } + */ + +// System.out.println( "get regex ===================================" ); + regex0.setText( regexsList.get( 0 ) ); + regex1.setText( regexsList.get( 1 ) ); + regex2.setText( regexsList.get( 2 ) ); + regex3.setText( regexsList.get( 3 ) ); + regex4.setText( regexsList.get( 4 ) ); + regex5.setText( regexsList.get( 5 ) ); + regex6.setText( regexsList.get( 6 ) ); + regex7.setText( regexsList.get( 7 ) ); + regex8.setText( regexsList.get( 8 ) ); + regex9.setText( regexsList.get( 9 ) ); + +// System.out.println( "get datatype ===================================" ); + dataType0.setSelectedItem( dataTypesList.get( 0 ) ); + dataType1.setSelectedItem( dataTypesList.get( 1 ) ); + dataType2.setSelectedItem( dataTypesList.get( 2 ) ); + dataType3.setSelectedItem( dataTypesList.get( 3 ) ); + dataType4.setSelectedItem( dataTypesList.get( 4 ) ); + dataType5.setSelectedItem( dataTypesList.get( 5 ) ); + dataType6.setSelectedItem( dataTypesList.get( 6 ) ); + dataType7.setSelectedItem( dataTypesList.get( 7 ) ); + dataType8.setSelectedItem( dataTypesList.get( 8 ) ); + dataType9.setSelectedItem( dataTypesList.get( 9 ) ); + + /* + System.out.println( "get datatype===================================" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 0 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 1 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 2 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 3 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 4 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 5 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 6 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 7 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 8 ) + "=" ); + System.out.println( "get datatype " + i + " =" + dataTypesList.get( 9 ) + "=" ); + */ + + isNullable0.setSelectedItem( emptyFlagsList.get( 0 ) ); + isNullable1.setSelectedItem( emptyFlagsList.get( 1 ) ); + isNullable2.setSelectedItem( emptyFlagsList.get( 2 ) ); + isNullable3.setSelectedItem( emptyFlagsList.get( 3 ) ); + isNullable4.setSelectedItem( emptyFlagsList.get( 4 ) ); + isNullable5.setSelectedItem( emptyFlagsList.get( 5 ) ); + isNullable6.setSelectedItem( emptyFlagsList.get( 6 ) ); + isNullable7.setSelectedItem( emptyFlagsList.get( 7 ) ); + isNullable8.setSelectedItem( emptyFlagsList.get( 8 ) ); + isNullable9.setSelectedItem( emptyFlagsList.get( 9 ) ); + + /* + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + for ( String format : dateFormatList ) + { + System.out.println( "add date format =" + format + "=" ); + dateFormatModel.addElement( format ); + } + + dateFormatCB.setModel( dateFormatModel ); + if ( this.parent != null ) + { + this.parent.comboDateFormatSetModel( dateFormatModel ); + } + + TransactionReader customReader = ReaderHM.get( readerName.getText() ); + String [] tmpArray = new String[0]; + customReader.setSupportedDateFormats( dateFormatList.toArray( tmpArray ) ); + */ + + CustomReader customReader = (CustomReader) ReaderHM.get( readerName.getText() ); + setDateFormatString( customReaderData.getDateFormatString() ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + System.err.println( "getNumberOfCustomReaderFieldsUsed() =" + getNumberOfCustomReaderFieldsUsed() ); + return true; + } + + public void clearReaderConfig() + { + setFieldSeparatorChar( ',' ); + setFileEncodingSelectedItem( TransactionReader.DEFAULT_ENCODING ); + setHeaderLines( 1 ); + setFooterLines( 0 ); + + regex0.setText( "" ); + regex1.setText( "" ); + regex2.setText( "" ); + regex3.setText( "" ); + regex4.setText( "" ); + regex5.setText( "" ); + regex6.setText( "" ); + regex7.setText( "" ); + regex8.setText( "" ); + regex9.setText( "" ); + + dataType0.setSelectedIndex( 0 ); + dataType1.setSelectedIndex( 0 ); + dataType2.setSelectedIndex( 0 ); + dataType3.setSelectedIndex( 0 ); + dataType4.setSelectedIndex( 0 ); + dataType5.setSelectedIndex( 0 ); + dataType6.setSelectedIndex( 0 ); + dataType7.setSelectedIndex( 0 ); + dataType8.setSelectedIndex( 0 ); + dataType9.setSelectedIndex( 0 ); + + isNullable0.setSelectedIndex( 0 ); + isNullable1.setSelectedIndex( 0 ); + isNullable2.setSelectedIndex( 0 ); + isNullable3.setSelectedIndex( 0 ); + isNullable4.setSelectedIndex( 0 ); + isNullable5.setSelectedIndex( 0 ); + isNullable6.setSelectedIndex( 0 ); + isNullable7.setSelectedIndex( 0 ); + isNullable8.setSelectedIndex( 0 ); + isNullable9.setSelectedIndex( 0 ); + } + + public ArrayList createNewRegexsList() + { + ArrayList newRegexsList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, regexsList ); + + newRegexsList.add( ((String)regex0.getText())); + newRegexsList.add( ((String)regex1.getText())); + newRegexsList.add( ((String)regex2.getText())); + newRegexsList.add( ((String)regex3.getText())); + newRegexsList.add( ((String)regex4.getText())); + newRegexsList.add( ((String)regex5.getText())); + newRegexsList.add( ((String)regex6.getText())); + newRegexsList.add( ((String)regex7.getText())); + newRegexsList.add( ((String)regex8.getText())); + newRegexsList.add( ((String)regex9.getText())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newRegexsList; + } + + public ArrayList createNewDataTypesList() + { + ArrayList newDataTypesList = new ArrayList( 10 ); +// Collections.copy( newDataTypesList, dataTypesList ); + + newDataTypesList.add( ((String)dataType0.getSelectedItem())); + newDataTypesList.add( ((String)dataType1.getSelectedItem())); + newDataTypesList.add( ((String)dataType2.getSelectedItem())); + newDataTypesList.add( ((String)dataType3.getSelectedItem())); + newDataTypesList.add( ((String)dataType4.getSelectedItem())); + newDataTypesList.add( ((String)dataType5.getSelectedItem())); + newDataTypesList.add( ((String)dataType6.getSelectedItem())); + newDataTypesList.add( ((String)dataType7.getSelectedItem())); + newDataTypesList.add( ((String)dataType8.getSelectedItem())); + newDataTypesList.add( ((String)dataType9.getSelectedItem())); + +// for ( int i = 0; i < 10; i ++ ) +// { +// newDataTypesList.add( new String( dataTypesList.get( i ) ) ); +// } + return newDataTypesList; + } + + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + newEmptyFlagsList.add( ((String)isNullable0.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable1.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable2.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable3.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable4.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable5.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable6.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable7.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable8.getSelectedItem())); + newEmptyFlagsList.add( ((String)isNullable9.getSelectedItem())); + return newEmptyFlagsList; + } + + /* + public ArrayList readDateFormatList() + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) dateFormatCB.getModel(); + + int max = dcbm.getSize(); + ArrayList newList = new ArrayList( max ); + for ( int i = 0; i < max; i++ ) + { + newList.add( ( (String) dcbm.getElementAt( i ) ) ); + } + return newList; + } + */ + /* + public ArrayList createNewEmptyFlagsList() + { + ArrayList newEmptyFlagsList = new ArrayList( 10 ); + for ( int i = 0; i < 10; i ++ ) + { + javax.swing.JComboBox jcb = new javax.swing.JComboBox( new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + jcb.setSelectedItem( emptyFlagsList.get( i ).getSelectedItem() ); + newEmptyFlagsList.add( jcb ); + } + return newEmptyFlagsList; + } + */ + + public String getRegexsListSelectedItem( int index ) { + return (String) regexsList.get( index ); + } + + public String getDataTypesListSelectedItem( int index ) { + return (String) dataTypesList.get( index ); + } + + public String getEmptyFlagsListSelectedItem( int index ) { + return (String) emptyFlagsList.get( index ); + } + + public String getDateFormatSelected() { + //return (String) dateFormatCB.getSelectedItem(); + return (String) dateFormatCr.getText(); + } + + public void setDateFormatString( String xxx) { + //dateFormatCB.setSelectedItem( xxx ); + dateFormatCr.setText( xxx ); + } + + public String getDateFormatString() { + //return (String) dateFormatCB.getSelectedItem(); + return dateFormatCr.getText(); + } + + public int getNumberOfCustomReaderFieldsUsed() + { + int c = 0; + int max = dataTypesList.size(); + + for ( ; c < max; c++ ) + { + //System.err.println( "(String) dataTypesList.get(" + c + ") =" + (String) dataTypesList.get( c ) + "=" ); + if ( ((String) dataTypesList.get( c )).equalsIgnoreCase( "" ) ) + return c; + } + return c; + } + + public void setHeaderLines( int xxx ) + { + headerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setHeaderLines(" + xxx +") text =" + headerLines.getText().trim() + "=" ); + } + + public int getHeaderLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getHeaderLines() text =" + headerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( headerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFooterLines( int xxx ) + { + footerLines.setText( String.valueOf( xxx ) ); + //System.err.println( "CustomReaderDialog.setFooterLines(" + xxx +") text =" + footerLines.getText().trim() + "=" ); + } + + public int getFooterLines() { + int x = 0; + //System.err.println( "CustomReaderDialog.getFooterLines() text =" + footerLines.getText().trim() + "=" ); + try + { + x = Integer.parseInt( footerLines.getText().trim() ); + } + catch ( Exception ex ) + { + ; + } + return x; + } + + public void setFieldSeparatorChar( int xxx) { + fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getFieldSeparatorChar() { + return fieldSeparatorChar.getText().charAt( 0 ); + } + + public void setFileEncodingSelectedItem( String xxx) { + fileEncodingCB.setSelectedItem( xxx ); + } + + public String getFileEncodingSelectedItem() { + return (String) fileEncodingCB.getSelectedItem(); + } + + public void setAmountCurrencyChar( int xxx) { + amountCurrencyChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountCurrencyChar() { + return amountCurrencyChar.getText().charAt( 0 ); + } + + public void setAmountDecimalSignChar( int xxx) { + amountDecimalSignChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountDecimalSignChar() { + return amountDecimalSignChar.getText().charAt( 0 ); + } + + public void setAmountGroupingSeparatorChar( int xxx) { + amountGroupingSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); + } + + public int getAmountGroupingSeparatorChar() { + return amountGroupingSeparatorChar.getText().charAt( 0 ); + } + + public void setAmountFormat( String xxx) { + amountFormat.setText( xxx ); + } + + public String getAmountFormat() { + return (String) amountFormat.getText(); + } + + public void setImportReverseOrderFlg( boolean xxx) { + importReverseOrderFlg.setSelected( xxx ); + } + + public boolean getImportReverseOrderFlg() { + return importReverseOrderFlg.isSelected(); + } + + public void setUseRegexFlag( boolean xxx) { + useRegexFlag.setSelected( xxx ); + } + + public boolean getUseRegexFlag() { + return useRegexFlag.isSelected(); + } + + public void setFilenameMatcher( String xxx) { + filenameMatcher.setText( xxx ); + } + + public String getFilenameMatcher() { + return (String) filenameMatcher.getText(); + } + + protected void init() + { + /* + dataType0.setSelectedItem( "date" ); + dataType1.setSelectedItem( "amount" ); + dataType2.setSelectedItem( "check number" ); + dataType3 .setSelectedItem( "skip" ); + dataType4.setSelectedItem( "description" ); + dataType5.setSelectedItem( "memo" ); + isNullable2.setSelectedItem( "Can Be Blank" ); + isNullable4.setSelectedItem( "Can Be Blank" ); + isNullable5.setSelectedItem( "Can Be Blank" ); + */ + + ReaderConfigsHM = Settings.createReaderConfigsHM(); + ReaderHM = Settings.getReaderHM(); // not great, but for now the call above must be first because it sets the value for this one to read also. + + /****** Quit using the built in readers ! Force people to make their own + ReaderConfigsHM.put( "citiBankCanadaReader", null ); + ReaderHM.put( "citiBankCanadaReader", citiBankCanadaReader ); + + ReaderConfigsHM.put( "ingNetherlandsReader", null ); + ReaderHM.put( "ingNetherlandsReader", ingNetherlandsReader ); + + ReaderConfigsHM.put( "simpleCreditDebitReader", null ); + ReaderHM.put( "simpleCreditDebitReader", simpleCreditDebitReader ); + + ReaderConfigsHM.put( "wellsFargoReader", null ); + ReaderHM.put( "wellsFargoReader", wellsFargoReader ); + + ReaderConfigsHM.put( "yodleeReader", null ); + ReaderHM.put( "yodleeReader", yodleeReader ); + + ReaderConfigsHM.put( "bbvaCompassReader", null ); + ReaderHM.put( "bbvaCompassReader", bbvaCompassReader ); + ******/ + + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + +// ??? this.parent.comboFileFormat1AddItem( "" ); + + // For keys of a map + for ( Iterator it=ReaderHM.keySet().iterator(); it.hasNext(); ) + { + String readerName = (String) it.next(); + System.err.println( "fill out readerName =" + readerName + "=" ); + if ( ReaderHM.get( readerName ).isCustomReaderFlag() ) + { + listModel.addElement( readerName ); + + // needs to be in Settings() +// CustomReader customReader = (CustomReader) getTransactionReader( readerName ); +// CustomReaderData customReaderData = ReaderConfigsHM.get( readerName ); +// +// customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + if ( this.parent != null ) + { + System.err.println( "call add readerName to import dlg reader list =" + readerName + "=" ); + this.parent.comboFileFormat1AddItem( ReaderHM.get( readerName ) ); + } + } + + regexsList.add( (String)regex0.getText() ); + regexsList.add( (String)regex1.getText() ); + regexsList.add( (String)regex2.getText() ); + regexsList.add( (String)regex3.getText() ); + regexsList.add( (String)regex4.getText() ); + regexsList.add( (String)regex5.getText() ); + regexsList.add( (String)regex6.getText() ); + regexsList.add( (String)regex7.getText() ); + regexsList.add( (String)regex8.getText() ); + regexsList.add( (String)regex9.getText() ); + + dataTypesList.add( (String)dataType0.getSelectedItem() ); + dataTypesList.add( (String)dataType1.getSelectedItem() ); + dataTypesList.add( (String)dataType2.getSelectedItem() ); + dataTypesList.add( (String)dataType3.getSelectedItem() ); + dataTypesList.add( (String)dataType4.getSelectedItem() ); + dataTypesList.add( (String)dataType5.getSelectedItem() ); + dataTypesList.add( (String)dataType6.getSelectedItem() ); + dataTypesList.add( (String)dataType7.getSelectedItem() ); + dataTypesList.add( (String)dataType8.getSelectedItem() ); + dataTypesList.add( (String)dataType9.getSelectedItem() ); + + emptyFlagsList.add( (String)isNullable0.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable1.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable2.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable3.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable4.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable5.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable6.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable7.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable8.getSelectedItem() ); + emptyFlagsList.add( (String)isNullable9.getSelectedItem() ); + + // Populate with all possible encodings + SortedMap encodings = Charset.availableCharsets(); + Set encodingNames = encodings.keySet(); + for ( Iterator i = encodingNames.iterator(); i.hasNext(); ) + { + fileEncodingCB.addItem( i.next() ); + } + // Set default Encoding to be UTF-8 + for ( int i = 0; i < fileEncodingCB.getItemCount(); i++ ) + { + if ( TransactionReader.DEFAULT_ENCODING.equals( fileEncodingCB.getItemAt( i ) ) ) + { + fileEncodingCB.setSelectedIndex( i ); + break; + } + } + + } + + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel1 = new javax.swing.JLabel(); + readerName = new javax.swing.JTextField(); + dataType1 = new javax.swing.JComboBox(); + isNullable1 = new javax.swing.JComboBox(); + dataType2 = new javax.swing.JComboBox(); + dataType4 = new javax.swing.JComboBox(); + dataType0 = new javax.swing.JComboBox(); + isNullable0 = new javax.swing.JComboBox(); + isNullable2 = new javax.swing.JComboBox(); + isNullable3 = new javax.swing.JComboBox(); + isNullable4 = new javax.swing.JComboBox(); + isNullable5 = new javax.swing.JComboBox(); + isNullable6 = new javax.swing.JComboBox(); + isNullable7 = new javax.swing.JComboBox(); + isNullable8 = new javax.swing.JComboBox(); + isNullable9 = new javax.swing.JComboBox(); + dataType3 = new javax.swing.JComboBox(); + dataType5 = new javax.swing.JComboBox(); + dataType6 = new javax.swing.JComboBox(); + dataType7 = new javax.swing.JComboBox(); + dataType8 = new javax.swing.JComboBox(); + dataType9 = new javax.swing.JComboBox(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jLabel9 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jLabel11 = new javax.swing.JLabel(); + saveBtn = new javax.swing.JButton(); + jLabel12 = new javax.swing.JLabel(); + jLabel13 = new javax.swing.JLabel(); + headerLines = new javax.swing.JTextField(); + jScrollPane1 = new javax.swing.JScrollPane(); + customReadersList = new javax.swing.JList(); + jLabel14 = new javax.swing.JLabel(); + addBtn = new javax.swing.JButton(); + deleteBtn = new javax.swing.JButton(); + jLabel15 = new javax.swing.JLabel(); + message = new javax.swing.JLabel(); + jLabel16 = new javax.swing.JLabel(); + jLabel17 = new javax.swing.JLabel(); + doneBtn = new javax.swing.JButton(); + jLabel18 = new javax.swing.JLabel(); + fieldSeparatorChar = new javax.swing.JTextField(); + resetFieldsBtn = new javax.swing.JButton(); + jLabel19 = new javax.swing.JLabel(); + dateFormatCr = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + jLabel21 = new javax.swing.JLabel(); + amountGroupingSeparatorChar = new javax.swing.JTextField(); + jLabel22 = new javax.swing.JLabel(); + amountDecimalSignChar = new javax.swing.JTextField(); + jLabel23 = new javax.swing.JLabel(); + amountCurrencyChar = new javax.swing.JTextField(); + jLabel24 = new javax.swing.JLabel(); + amountFormat = new javax.swing.JTextField(); + jLabel25 = new javax.swing.JLabel(); + jLabel26 = new javax.swing.JLabel(); + footerLines = new javax.swing.JTextField(); + importReverseOrderFlg = new javax.swing.JCheckBox(); + fileEncodingLbl = new javax.swing.JLabel(); + fileEncodingCB = new javax.swing.JComboBox(); + jLabel27 = new javax.swing.JLabel(); + regex0 = new javax.swing.JTextField(); + regex1 = new javax.swing.JTextField(); + regex2 = new javax.swing.JTextField(); + regex3 = new javax.swing.JTextField(); + regex4 = new javax.swing.JTextField(); + regex5 = new javax.swing.JTextField(); + regex6 = new javax.swing.JTextField(); + regex7 = new javax.swing.JTextField(); + regex8 = new javax.swing.JTextField(); + regex9 = new javax.swing.JTextField(); + useRegexFlag = new javax.swing.JCheckBox(); + filenameMatcher = new javax.swing.JTextField(); + jLabel28 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(780, 600)); + setPreferredSize(new java.awt.Dimension(780, 600)); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + jLabel1.setText("Reader Name:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel1, gridBagConstraints); + + readerName.setMinimumSize(new java.awt.Dimension(160, 25)); + readerName.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(readerName, gridBagConstraints); + + dataType1.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType1.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType1, gridBagConstraints); + + isNullable1.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable1.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable1.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 12; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable1, gridBagConstraints); + + dataType2.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType2.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType2, gridBagConstraints); + + dataType4.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType4.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType4, gridBagConstraints); + + dataType0.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType0.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType0, gridBagConstraints); + + isNullable0.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable0.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable0.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 11; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable0, gridBagConstraints); + + isNullable2.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable2.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable2.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 13; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable2, gridBagConstraints); + + isNullable3.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable3.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 14; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable3, gridBagConstraints); + + isNullable4.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable4.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable4.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 15; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable4, gridBagConstraints); + + isNullable5.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable5.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 16; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable5, gridBagConstraints); + + isNullable6.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable6.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 17; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable6, gridBagConstraints); + + isNullable7.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable7.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 18; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable7, gridBagConstraints); + + isNullable8.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable8.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 19; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable8, gridBagConstraints); + + isNullable9.setModel(new javax.swing.DefaultComboBoxModel( allowEmptyFlag ) ); + isNullable9.setMinimumSize(new java.awt.Dimension(150, 25)); + isNullable9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 20; + gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); + getContentPane().add(isNullable9, gridBagConstraints); + + dataType3.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType3.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType3.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType3, gridBagConstraints); + + dataType5.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType5.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType5.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType5, gridBagConstraints); + + dataType6.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType6.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType6.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType6, gridBagConstraints); + + dataType7.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType7.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType7.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType7, gridBagConstraints); + + dataType8.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType8.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType8.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType8, gridBagConstraints); + + dataType9.setModel(new javax.swing.DefaultComboBoxModel( dataTypes ) ); + dataType9.setMinimumSize(new java.awt.Dimension(150, 25)); + dataType9.setPreferredSize(new java.awt.Dimension(100, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(dataType9, gridBagConstraints); + + jLabel2.setText("1"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 11; + getContentPane().add(jLabel2, gridBagConstraints); + + jLabel3.setText("2"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 12; + getContentPane().add(jLabel3, gridBagConstraints); + + jLabel4.setText("3"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 13; + getContentPane().add(jLabel4, gridBagConstraints); + + jLabel5.setText("4"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel5, gridBagConstraints); + + jLabel6.setText("5"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 15; + getContentPane().add(jLabel6, gridBagConstraints); + + jLabel7.setText("6"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(jLabel7, gridBagConstraints); + + jLabel8.setText("7"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 17; + getContentPane().add(jLabel8, gridBagConstraints); + + jLabel9.setText("8"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 18; + getContentPane().add(jLabel9, gridBagConstraints); + + jLabel10.setText("9"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 19; + getContentPane().add(jLabel10, gridBagConstraints); + + jLabel11.setText("10"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 20; + getContentPane().add(jLabel11, gridBagConstraints); + + saveBtn.setText("Save"); + saveBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + saveBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + saveBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + saveBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 22; + getContentPane().add(saveBtn, gridBagConstraints); + + jLabel12.setText(" "); + jLabel12.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 8; + getContentPane().add(jLabel12, gridBagConstraints); + + jLabel13.setText("Number of Footer Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 5; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel13, gridBagConstraints); + + headerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + headerLines.setText("1"); + headerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + headerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + headerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + headerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(headerLines, gridBagConstraints); + + jScrollPane1.setMinimumSize(new java.awt.Dimension(160, 85)); + jScrollPane1.setPreferredSize(new java.awt.Dimension(160, 160)); + + customReadersList.setModel(new DefaultListModel() ); + customReadersList.setMaximumSize(new java.awt.Dimension(32767, 32767)); + customReadersList.setMinimumSize(new java.awt.Dimension(160, 85)); + customReadersList.setPreferredSize(new java.awt.Dimension(160, 85)); + customReadersList.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + customReadersListMouseClicked(evt); + } + }); + jScrollPane1.setViewportView(customReadersList); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 11; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridheight = 10; + gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL; + getContentPane().add(jScrollPane1, gridBagConstraints); + + jLabel14.setText(" "); + jLabel14.setMaximumSize(new java.awt.Dimension(25, 15)); + jLabel14.setMinimumSize(new java.awt.Dimension(25, 15)); + jLabel14.setPreferredSize(new java.awt.Dimension(25, 15)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 10; + getContentPane().add(jLabel14, gridBagConstraints); + + addBtn.setText("Add"); + addBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + addBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + addBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + addBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + getContentPane().add(addBtn, gridBagConstraints); + + deleteBtn.setText("Delete"); + deleteBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + deleteBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + deleteBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + deleteBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 22; + gridBagConstraints.gridwidth = 2; + getContentPane().add(deleteBtn, gridBagConstraints); + + jLabel15.setText("List of Readers:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + getContentPane().add(jLabel15, gridBagConstraints); + + message.setForeground(new java.awt.Color(255, 0, 0)); + message.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 24; + gridBagConstraints.gridwidth = 5; + getContentPane().add(message, gridBagConstraints); + + jLabel16.setText(" "); + jLabel16.setMinimumSize(new java.awt.Dimension(150, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 23; + getContentPane().add(jLabel16, gridBagConstraints); + + jLabel17.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 21; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + getContentPane().add(jLabel17, gridBagConstraints); + + doneBtn.setText("Done"); + doneBtn.setMaximumSize(new java.awt.Dimension(85, 35)); + doneBtn.setMinimumSize(new java.awt.Dimension(74, 24)); + doneBtn.setPreferredSize(new java.awt.Dimension(74, 24)); + doneBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + doneBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 22; + getContentPane().add(doneBtn, gridBagConstraints); + + jLabel18.setText("CSV Field Separator:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel18, gridBagConstraints); + + fieldSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + fieldSeparatorChar.setText(","); + fieldSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + fieldSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fieldSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fieldSeparatorChar, gridBagConstraints); + + resetFieldsBtn.setText("Reset Fields"); + resetFieldsBtn.setMinimumSize(new java.awt.Dimension(100, 25)); + resetFieldsBtn.setPreferredSize(new java.awt.Dimension(110, 25)); + resetFieldsBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + resetFieldsBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 22; + gridBagConstraints.weightx = 0.2; + getContentPane().add(resetFieldsBtn, gridBagConstraints); + + jLabel19.setText("Date Format:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel19, gridBagConstraints); + + dateFormatCr.setText("YYYY-MM-DD"); + dateFormatCr.setToolTipText("\nYou can do things like: MM/DD/YYYY, MM.DD.YY, YY-MM-DD
\nhttp://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html"); + dateFormatCr.setMinimumSize(new java.awt.Dimension(100, 25)); + dateFormatCr.setPreferredSize(new java.awt.Dimension(100, 25)); + dateFormatCr.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dateFormatCrActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(dateFormatCr, gridBagConstraints); + + jLabel20.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 9; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel20, gridBagConstraints); + + jLabel21.setText("Grouping separator:"); + jLabel21.setEnabled(false); + jLabel21.setFocusable(false); + jLabel21.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel21, gridBagConstraints); + + amountGroupingSeparatorChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountGroupingSeparatorChar.setText(","); + amountGroupingSeparatorChar.setEnabled(false); + amountGroupingSeparatorChar.setFocusable(false); + amountGroupingSeparatorChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.setPreferredSize(new java.awt.Dimension(20, 25)); + amountGroupingSeparatorChar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + amountGroupingSeparatorCharActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountGroupingSeparatorChar, gridBagConstraints); + + jLabel22.setText("Decimal Sign:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel22, gridBagConstraints); + + amountDecimalSignChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountDecimalSignChar.setText("."); + amountDecimalSignChar.setMinimumSize(new java.awt.Dimension(20, 25)); + amountDecimalSignChar.setPreferredSize(new java.awt.Dimension(20, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountDecimalSignChar, gridBagConstraints); + + jLabel23.setText("Currency Symbol:"); + jLabel23.setEnabled(false); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel23, gridBagConstraints); + + amountCurrencyChar.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountCurrencyChar.setText(" "); + amountCurrencyChar.setEnabled(false); + amountCurrencyChar.setMinimumSize(new java.awt.Dimension(40, 25)); + amountCurrencyChar.setPreferredSize(new java.awt.Dimension(40, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountCurrencyChar, gridBagConstraints); + + jLabel24.setText("Amount Format:"); + jLabel24.setEnabled(false); + jLabel24.setFocusable(false); + jLabel24.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 6; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel24, gridBagConstraints); + + amountFormat.setHorizontalAlignment(javax.swing.JTextField.CENTER); + amountFormat.setText(" "); + amountFormat.setEnabled(false); + amountFormat.setFocusable(false); + amountFormat.setMinimumSize(new java.awt.Dimension(160, 25)); + amountFormat.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + getContentPane().add(amountFormat, gridBagConstraints); + + jLabel25.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 2; + getContentPane().add(jLabel25, gridBagConstraints); + + jLabel26.setText("Number of Header Lines:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel26, gridBagConstraints); + + footerLines.setHorizontalAlignment(javax.swing.JTextField.CENTER); + footerLines.setText("0"); + footerLines.setMinimumSize(new java.awt.Dimension(40, 25)); + footerLines.setPreferredSize(new java.awt.Dimension(40, 25)); + footerLines.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + footerLinesActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(footerLines, gridBagConstraints); + + importReverseOrderFlg.setText("Import Transactions in Reverse Order."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 2; + getContentPane().add(importReverseOrderFlg, gridBagConstraints); + + fileEncodingLbl.setText("File Encoding:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(fileEncodingLbl, gridBagConstraints); + + fileEncodingCB.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + fileEncodingCB.setMinimumSize(new java.awt.Dimension(120, 25)); + fileEncodingCB.setPreferredSize(new java.awt.Dimension(140, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(fileEncodingCB, gridBagConstraints); + + jLabel27.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + getContentPane().add(jLabel27, gridBagConstraints); + + regex0.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex0ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 11; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex0, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 12; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex1, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 13; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex2, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 14; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex3, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 15; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex4, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 16; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex5, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 17; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex6, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 18; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex7, gridBagConstraints); + + regex8.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + regex8ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 19; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex8, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 20; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5); + getContentPane().add(regex9, gridBagConstraints); + + useRegexFlag.setText("Use Regex to Parse Fields"); + useRegexFlag.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useRegexFlagActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 10; + getContentPane().add(useRegexFlag, gridBagConstraints); + + filenameMatcher.setText(".*\\.(csv|CSV)"); + filenameMatcher.setMinimumSize(new java.awt.Dimension(160, 25)); + filenameMatcher.setPreferredSize(new java.awt.Dimension(160, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 8; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 10); + getContentPane().add(filenameMatcher, gridBagConstraints); + + jLabel28.setText("Filename Matcher:"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4); + getContentPane().add(jLabel28, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed + message.setText( "" ); + + if ( ! ReaderConfigsHM.containsKey( readerName.getText() ) ) + { + message.setText( "There is no reader by that name '" + readerName.getText() + "'" ); + } + +// int i = 0; +// for ( String dataType : dataTypesList ) +// { +// System.out.println( "datatype " + i + " =" + dataType + "=" ); +// i++; +// } + + try + { + int x = Integer.parseInt( headerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Header Lines must be 0 or more" ); + return; + } + + try + { + int x = Integer.parseInt( footerLines.getText().trim() ); + if ( x < 0 ) + throw new Exception(); + } + catch ( Exception ex ) + { + message.setText( "Number of Footer Lines must be 0 or more" ); + return; + } + + CustomReaderData customReaderData = ReaderConfigsHM.get( readerName.getText() ); + + customReaderData.setReaderName( readerName.getText() ); + customReaderData.setRegexsList( createNewRegexsList() ); + customReaderData.setDataTypesList( createNewDataTypesList() ); + customReaderData.setEmptyFlagsList( createNewEmptyFlagsList() ); + //customReaderData.setDateFormatList( readDateFormatList() ); + customReaderData.setFieldSeparatorChar( getFieldSeparatorChar() ); + customReaderData.setFileEncoding( getFileEncodingSelectedItem() ); + customReaderData.setHeaderLines( getHeaderLines() ); + customReaderData.setFooterLines( getFooterLines() ); + customReaderData.setDateFormatString( getDateFormatString() ); + + customReaderData.setAmountCurrencyChar( getAmountCurrencyChar() ); + customReaderData.setAmountDecimalSignChar( getAmountDecimalSignChar() ); + customReaderData.setAmountGroupingSeparatorChar( getAmountGroupingSeparatorChar() ); + customReaderData.setAmountFormat( getAmountFormat() ); + customReaderData.setImportReverseOrderFlg( getImportReverseOrderFlg() ); + customReaderData.setUseRegexFlag( getUseRegexFlag() ); + customReaderData.setFilenameMatcher( getFilenameMatcher() ); + + ReaderConfigsHM.put( readerName.getText(), customReaderData ); + // *** I could get and replace the existing one but just do this for now until things work ! ! ! + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( readerName.getText(), customReader ); + + customReader.createSupportedDateFormats( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + + Settings.setCustomReaderConfig( customReaderData ); + }//GEN-LAST:event_saveBtnActionPerformed + + private void headerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_headerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_headerLinesActionPerformed + + private void doneBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_doneBtnActionPerformed + this.setVisible( false ); + + /** turning all this off so we do not test all readers when they hit 'Done' + parent.setSkipDuringInit( true ); + parent.fileChanged(); + this.parent.comboFileFormat1SetItem( ReaderHM.get( readerName.getText() ) ); + parent.setSkipDuringInit( false ); + //System.out.println( "done button (String) dateFormatCB.getSelectedItem() =" + (String) dateFormatCB.getSelectedItem() + "=" ); + //this.parent.comboDateFormatSetItem( getDateFormatString() ); + this.parent.createSupportedDateFormats( getDateFormatString() ); + **/ + }//GEN-LAST:event_doneBtnActionPerformed + + private void fieldSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fieldSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_fieldSeparatorCharActionPerformed + + private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed + addReaderConfig(); + }//GEN-LAST:event_addBtnActionPerformed + + private void deleteBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteBtnActionPerformed + deleteReaderConfig(); + }//GEN-LAST:event_deleteBtnActionPerformed + + private void customReadersListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_customReadersListMouseClicked + DefaultListModel listModel = (DefaultListModel) customReadersList.getModel(); + int index = customReadersList.getSelectedIndex(); + getReaderConfig( (String) listModel.getElementAt( index ) ); + useRegexFlagActionPerformed( null ); + }//GEN-LAST:event_customReadersListMouseClicked + + private void resetFieldsBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetFieldsBtnActionPerformed + clearReaderConfig(); + }//GEN-LAST:event_resetFieldsBtnActionPerformed + + private void dateFormatCrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateFormatCrActionPerformed + ; + }//GEN-LAST:event_dateFormatCrActionPerformed + + private void amountGroupingSeparatorCharActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_amountGroupingSeparatorCharActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_amountGroupingSeparatorCharActionPerformed + + private void footerLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_footerLinesActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_footerLinesActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + DecimalFormatSymbols decForSyms = new DecimalFormatSymbols(); + DecimalFormat decFormat = (DecimalFormat) DecimalFormat.getInstance(); + int numDigits = decFormat.getCurrency().getDefaultFractionDigits(); + amountCurrencyChar.setText( decFormat.getCurrency().getSymbol() ); + String format = "0"; + int i; + // if ( decFormat.getmax > 0 ) + // { + format += decForSyms.getDecimalSeparator(); + // } + //System.out.println( "decFormat.getMinimumIntegerDigits() =" + decFormat.getMinimumIntegerDigits() ); + for ( i = 0; i < 2; i ++ ) + { + format+= "0"; + } + + //amountDecimalSignChar.setText( ); + int groupSize = decFormat.getGroupingSize(); + char groupSep = decForSyms.getGroupingSeparator(); + amountGroupingSeparatorChar.setText( groupSep + "" ); + amountDecimalSignChar.setText( decForSyms.getDecimalSeparator() + "" ); + + int gscnt = 1; + for ( i = 1; i < 10; i ++ ) + { + if ( gscnt == groupSize ) + { + format = groupSep + format; + gscnt = 1; + } + else + { + gscnt ++; + } + format = "#" + format; + } + format = decForSyms.getCurrencySymbol() + format; + amountFormat.setText( format ); + }//GEN-LAST:event_formWindowOpened + + private void regex0ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex0ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex0ActionPerformed + + private void regex8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regex8ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_regex8ActionPerformed + + private void useRegexFlagActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useRegexFlagActionPerformed + if ( useRegexFlag.isSelected() ) + { + // This is just for a first time to give them a working example of a usable regex + if ( regex0.getText().isEmpty() + && regex1.getText().isEmpty() + && regex2.getText().isEmpty() + && regex3.getText().isEmpty() + && regex4.getText().isEmpty() + && regex5.getText().isEmpty() + ) + { + regex0.setText( "([^,]*([,]|\\Z)).*" ); + regex1.setText( "([^,]*([,]|\\Z)).*" ); + regex2.setText( "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*" ); + regex3.setText( "([^,]*([,]|\\Z)).*" ); + regex4.setText( "([^,]*([,]|\\Z)).*" ); + regex5.setText( "([^,]*([,]|\\Z)).*" ); + } + regex0.setVisible( true ); + regex1.setVisible( true ); + regex2.setVisible( true ); + regex3.setVisible( true ); + regex4.setVisible( true ); + regex5.setVisible( true ); + regex6.setVisible( true ); + regex7.setVisible( true ); + regex8.setVisible( true ); + regex9.setVisible( true ); + } + else + { +// regex0.setText( "" ); +// regex1.setText( "" ); +// regex2.setText( "" ); +// regex3.setText( "" ); +// regex4.setText( "" ); +// regex5.setText( "" ); + + regex0.setVisible( false ); + regex1.setVisible( false ); + regex2.setVisible( false ); + regex3.setVisible( false ); + regex4.setVisible( false ); + regex5.setVisible( false ); + regex6.setVisible( false ); + regex7.setVisible( false ); + regex8.setVisible( false ); + regex9.setVisible( false ); + } + }//GEN-LAST:event_useRegexFlagActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + CustomReaderDialog dialog = new CustomReaderDialog( null, true ); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addBtn; + private javax.swing.JTextField amountCurrencyChar; + private javax.swing.JTextField amountDecimalSignChar; + private javax.swing.JTextField amountFormat; + private javax.swing.JTextField amountGroupingSeparatorChar; + private javax.swing.JList customReadersList; + private javax.swing.JComboBox dataType0; + private javax.swing.JComboBox dataType1; + private javax.swing.JComboBox dataType2; + private javax.swing.JComboBox dataType3; + private javax.swing.JComboBox dataType4; + private javax.swing.JComboBox dataType5; + private javax.swing.JComboBox dataType6; + private javax.swing.JComboBox dataType7; + private javax.swing.JComboBox dataType8; + private javax.swing.JComboBox dataType9; + private javax.swing.JTextField dateFormatCr; + private javax.swing.JButton deleteBtn; + private javax.swing.JButton doneBtn; + private javax.swing.JTextField fieldSeparatorChar; + private javax.swing.JComboBox fileEncodingCB; + private javax.swing.JLabel fileEncodingLbl; + private javax.swing.JTextField filenameMatcher; + private javax.swing.JTextField footerLines; + private javax.swing.JTextField headerLines; + private javax.swing.JCheckBox importReverseOrderFlg; + private javax.swing.JComboBox isNullable0; + private javax.swing.JComboBox isNullable1; + private javax.swing.JComboBox isNullable2; + private javax.swing.JComboBox isNullable3; + private javax.swing.JComboBox isNullable4; + private javax.swing.JComboBox isNullable5; + private javax.swing.JComboBox isNullable6; + private javax.swing.JComboBox isNullable7; + private javax.swing.JComboBox isNullable8; + private javax.swing.JComboBox isNullable9; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel25; + private javax.swing.JLabel jLabel26; + private javax.swing.JLabel jLabel27; + private javax.swing.JLabel jLabel28; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JLabel message; + private javax.swing.JTextField readerName; + private javax.swing.JTextField regex0; + private javax.swing.JTextField regex1; + private javax.swing.JTextField regex2; + private javax.swing.JTextField regex3; + private javax.swing.JTextField regex4; + private javax.swing.JTextField regex5; + private javax.swing.JTextField regex6; + private javax.swing.JTextField regex7; + private javax.swing.JTextField regex8; + private javax.swing.JTextField regex9; + private javax.swing.JButton resetFieldsBtn; + private javax.swing.JButton saveBtn; + private javax.swing.JCheckBox useRegexFlag; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/CustomTableCellRenderer.java b/src/com/moneydance/modules/features/mdcsvimporter/CustomTableCellRenderer.java new file mode 100644 index 0000000..1f5480e --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/CustomTableCellRenderer.java @@ -0,0 +1,45 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.awt.Color; +import java.awt.Component; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * + * @author stan + */ + + +public class CustomTableCellRenderer extends DefaultTableCellRenderer { + + int forRow = -1; + int forCol = -1; + + public void setForRowCol( int row, int col ) + { + forRow = row; + forCol = col; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) + { + JLabel lbl = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); + + //Get the status for the current row. + PreviewImportTblModel tableModel = (PreviewImportTblModel) table.getModel(); + if ( (row == forRow || forRow < 0) && (col == forCol || forCol < 0) ) + { + lbl.setBackground( Color.RED ); + } + else + { + //lbl.setBackground( javax.swing.UIManager.getColor( "Table.dropCellBackground" ) ); + lbl.setBackground( Color.WHITE ); + } + //Return the JLabel which renders the cell. + return lbl; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/DataField.java b/src/com/moneydance/modules/features/mdcsvimporter/DataField.java new file mode 100644 index 0000000..888147d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/DataField.java @@ -0,0 +1,14 @@ +// Error reading included file Templates/Beans/../Licenses/license-LGPL.txt +package com.moneydance.modules.features.mdcsvimporter; + +import java.beans.*; +import java.io.Serializable; + +/** + * + * @author stowians + */ +public class DataField implements Serializable { + + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/DateGuesser.java b/src/com/moneydance/modules/features/mdcsvimporter/DateGuesser.java new file mode 100644 index 0000000..5686393 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/DateGuesser.java @@ -0,0 +1,421 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * + * @author miki + */ +public class DateGuesser +{ + private static final int EOF = -1; + private static final String D = "D"; + private static final String DD = "DD"; + private static final String M = "M"; + private static final String MM = "MM"; + private static final String YY = "YY"; + private static final String YYYY = "YYYY"; + private Map results = new HashMap(); + private int datesDetected = 0; + private String[] possibleFormats; + private double bestFormatProbability; + private StringBuilder field1 = new StringBuilder(); + private int field1Value; + private String field1Format; + private int separator1; + private StringBuilder field2 = new StringBuilder(); + private int field2Value; + private String field2Format; + private int separator2; + private StringBuilder field3 = new StringBuilder(); + private int field3Value; + private String field3Format; + private StringBuilder format = new StringBuilder(); + + public void checkDateString( String date ) + { + try + { + date = date.trim(); + StringReader reader = new StringReader( date ); + + separator1 = parseField( reader, field1 ); + separator2 = parseField( reader, field2 ); + int eof = parseField( reader, field3 ); + + if ( field1.length() == 0 || field2.length() == 0 || field3.length() == 0 || + !isEof( eof ) ) + { + return; + } + + field1Value = Integer.parseInt( field1.toString() ); + field2Value = Integer.parseInt( field2.toString() ); + field3Value = Integer.parseInt( field3.toString() ); + + if ( checkPossibleFormats() ) + { + ++datesDetected; + } + } + catch ( Exception x ) + { + // ignore errors, simply means this is probably not a date string + } + } + + private boolean checkPossibleFormats() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Value >= 1 && field1Value <= 31 && field1.length() <= 2 ) + { + if ( field1.length() == 1 ) + { + field1Format = D; + retVal |= checkPossibleFormats2(); + } + else + { + field1Format = DD; + retVal |= checkPossibleFormats2(); + if ( field1Value < 10 ) // >= 10 ) + { + field1Format = D; + retVal |= checkPossibleFormats2(); + } + } + } + + // check if its possible to be a month + if ( field1Value >= 1 && field1Value <= 12 && field1.length() <= 2 ) + { + if ( field1.length() == 1 ) + { + field1Format = M; + retVal |= checkPossibleFormats2(); + } + else + { + field1Format = MM; + retVal |= checkPossibleFormats2(); + if ( field1Value < 10 ) // >= 10 ) + { + field1Format = M; + retVal |= checkPossibleFormats2(); + } + } + } + + // check if its possible to be a year + if ( field1.length() == 2 ) + { + field1Format = YY; + retVal |= checkPossibleFormats2(); + } + else if ( field1.length() == 4 ) + { + field1Format = YYYY; + retVal |= checkPossibleFormats2(); + } + + return retVal; + } + + private boolean checkPossibleFormats2() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Format != D && field1Format != DD ) + { + if ( field2Value >= 1 && field2Value <= 31 && field2.length() <= 2 ) + { + if ( field2.length() == 1 ) + { + field2Format = D; + retVal |= checkPossibleFormats3(); + } + else + { + field2Format = DD; + retVal |= checkPossibleFormats3(); + if ( field2Value < 10 ) // >= 10 ) + { + field2Format = D; + retVal |= checkPossibleFormats3(); + } + } + } + } + + // check if its possible to be a month + if ( field1Format != M && field1Format != MM ) + { + if ( field2Value >= 1 && field2Value <= 12 && field2.length() <= 2 ) + { + if ( field2.length() == 1 ) + { + field2Format = M; + retVal |= checkPossibleFormats3(); + } + else + { + field2Format = MM; + retVal |= checkPossibleFormats3(); + if ( field2Value < 10 ) // >= 10 ) + { + field2Format = M; + retVal |= checkPossibleFormats3(); + } + } + } + } + + // check if its possible to be a year + if ( field1Format != YY && field1Format != YYYY ) + { + if ( field2.length() == 2 ) + { + field2Format = YY; + retVal |= checkPossibleFormats3(); + } + else if ( field2.length() == 4 ) + { + field2Format = YYYY; + retVal |= checkPossibleFormats3(); + } + } + + return retVal; + } + + private boolean checkPossibleFormats3() + { + boolean retVal = false; + + // check if its possible to be a day + if ( field1Format != D && field1Format != DD && field2Format != D && field2Format != + DD ) + { + if ( field3Value >= 1 && field3Value <= 31 && field3.length() <= 2 ) + { + if ( field3.length() == 1 ) + { + field3Format = D; + retVal = true; + registerFormat(); + } + else + { + field3Format = DD; + retVal = true; + registerFormat(); + if ( field3Value < 10 ) // >= 10 ) + { + field3Format = D; + registerFormat(); + } + } + } + } + + // check if its possible to be a month + if ( field1Format != M && field1Format != MM && field2Format != M && field2Format != + MM ) + { + if ( field3Value >= 1 && field3Value <= 12 && field3.length() <= 2 ) + { + if ( field3.length() == 1 ) + { + field3Format = M; + retVal = true; + registerFormat(); + } + else + { + field3Format = MM; + retVal = true; + registerFormat(); + if ( field3Value < 10 ) // >= 10 ) + { + field3Format = M; + registerFormat(); + } + } + } + } + + // check if its possible to be a year + if ( field1Format != YY && field1Format != YYYY && field2Format != YY && + field2Format != YYYY ) + { + if ( field3.length() == 2 ) + { + field3Format = YY; + retVal = true; + registerFormat(); + } + else if ( field3.length() == 4 ) + { + field3Format = YYYY; + retVal = true; + registerFormat(); + } + } + + return retVal; + } + + private void registerFormat() + { + clearResults(); + + format.setLength( 0 ); + format.append( field1Format ); + format.appendCodePoint( separator1 ); + format.append( field2Format ); + format.appendCodePoint( separator2 ); + format.append( field3Format ); + + String key = format.toString(); + + Integer count = results.get( key ); + if ( count == null ) + { + System.err.println( "saving format key =" + key + "= count =" + 1 ); + results.put( key, 1 ); + } + else + { + System.err.println( "saving format key =" + key + "= count =" + (count + 1) ); + results.put( key, count + 1 ); + } + } + + public String getBestFormat() + { + calculateResults(); + + if ( possibleFormats.length > 0 ) + { + return possibleFormats[0]; + } + else + { + return null; + } + } + + public double getBestFormatProbability() + { + calculateResults(); + + return bestFormatProbability; + } + + public String[] getPossibleFormats() + { + calculateResults(); + + return possibleFormats; + } + + private void clearResults() + { + possibleFormats = null; + bestFormatProbability = 0; + } + + private void calculateResults() + { + if ( possibleFormats != null ) + { // are results already calculated? + return; + } + + SortedMap sortedResults = new TreeMap( + new Comparator() + { + public int compare( Integer o1, Integer o2 ) + { + return o2 - o1; + } + } ); + + for ( Map.Entry entry : results.entrySet() ) + { + System.err.println( "results before sort entry.getValue() =" + entry.getValue() + "= entry.getKey() =" + entry.getKey() + "=" ); + sortedResults.put( entry.getValue(), entry.getKey() ); + } + + possibleFormats = new String[sortedResults.size()]; + sortedResults.values().toArray( possibleFormats ); + + for ( String tmp : possibleFormats ) + { + System.err.println( "possibleFormats =" + tmp + "=" ); + } + + if ( datesDetected == 0 ) + { + bestFormatProbability = 0; + } + else + { + bestFormatProbability = sortedResults.firstKey().doubleValue() / + (double) datesDetected; + } + } + + protected static final int parseField( Reader reader, StringBuilder fieldValue ) + throws IOException + { + fieldValue.setLength( 0 ); + + if ( !reader.ready() ) + { + return -1; + } + + int ch; + for ( ch = reader.read(); isDigit( ch ); ch = reader.read() ) + { + fieldValue.appendCodePoint( ch ); + } + + return ch; + } + + private static final boolean isDigit( int ch ) + { + return ch >= '0' && ch <= '9'; + } + + private static final boolean isEof( int ch ) + { + return ch == EOF; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.form b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.form new file mode 100644 index 0000000..83fcb7d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.form @@ -0,0 +1,431 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java new file mode 100644 index 0000000..eb4a225 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java @@ -0,0 +1,1493 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import static com.moneydance.modules.features.mdcsvimporter.TransactionReader.importDialog; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.JOptionPane; +import javax.swing.KeyStroke; + +/** + * + * @author miki & Stan Towianski + */ +public class ImportDialog + extends javax.swing.JDialog +{ + private OnlineManager onlineMgr = null; + private File selectedFile; + private CSVData csvData; + private Main main; + private HashMap runArgsHM; + protected final static String RUN_ARGS_FILE = "file"; + protected final static String RUN_ARGS_FILEFORMAT = "fileformat"; + protected final static String RUN_ARGS_DATEFORMAT = "dateformat"; + protected final static String RUN_ARGS_IMPORTACCOUNT = "importaccount"; + protected final static String RUN_ARGS_IMPORTTYPE = "importtype"; + protected final static String RUN_ARGS_PROCESSFLAG = "processflag"; + protected final static String RUN_ARGS_DELETECSVFILEFLAG = "deletecsvfileflag"; + protected final static String RUN_ARGS_NOPOPERRORSFLAG = "nopoperrorsflag"; + protected final static String RUN_ARGS_JUNIT = "junitflag"; + + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILE = 1; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE = 2; + protected final static int RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT = 3; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT = 4; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE = 5; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT = 6; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILE = 7; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT = 8; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT = 9; + + private CustomReaderDialog customReaderDialog = new CustomReaderDialog( this, true ); + private ArrayList errCodeList = new ArrayList(); + private boolean skipDuringInit = true; + private boolean autoProcessedAFile = false; + + private boolean GET_ALL_READERS = true; + private boolean GET_COMPATIBLE_READERS = false; + + public ImportDialog() + { + } + + public ImportDialog( Main main, HashMap runArgsHM ) + { + super( main.getMoneydanceWindow(), true ); + initComponents(); + this.runArgsHM = runArgsHM; + autoProcessedAFile = false; + + customReaderDialog.init(); + customReaderDialog.setLocationRelativeTo( getRootPane() ); + + /** + textFilename.getDocument().addDocumentListener( new DocumentListener() + { + public void insertUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void removeUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void changedUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + } ); + **/ + + this.main = main; + + if ( main.getMainContext() != null ) + { + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + + fillAccountCombo( main ); + } + + checkDeleteFile.setSelected( Settings.getBoolean( false, "delete.file" ) ); + onlineImportTypeRB.setSelected( Settings.getBoolean( false, "importtype.online.radiobutton" ) ); + + skipDuringInit = false; + this.setModal( false ); + this.addEscapeListener( this ); + TransactionReader.init( customReaderDialog, this, main.getRootAccount() ); + } + + public static void addEscapeListener(final JDialog win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + protected ArrayList processRunArguments() + { + errCodeList = new ArrayList(); + boolean errorInRunArgs = false; + + if ( runArgsHM.containsKey( RUN_ARGS_FILE ) ) + { + selectedFile = new File( (String) runArgsHM.get( RUN_ARGS_FILE ) ); + if ( ! selectedFile.exists() ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nfile \'" + + (String) runArgsHM.get( RUN_ARGS_FILE ) + "\' does not exist.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILE ); + errorInRunArgs = true; + } + else + { + textFilename.setSelectedItem( selectedFile.getPath() ); + fileChanged(); + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTTYPE ) ) + { + if ( "ONLINE".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + onlineImportTypeRB.setSelected( true ); + } + else if ( "REGULAR".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + regularImportTypeRB.setSelected( true ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTTYPE + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_DELETECSVFILEFLAG ) ) + { + checkDeleteFile.setSelected( true ); + } + + if ( runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + //if ( customReaderDialog.getReaderConfig( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ) ) + TransactionReader reqTransReader = customReaderDialog.getTransactionReader( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ); + if ( reqTransReader != null ) + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) comboFileFormat.getModel(); + int idx = dcbm.getIndexOf( reqTransReader ); + + if ( idx >= 0 ) + { + comboFileFormat.setSelectedItem( reqTransReader ); + processFileFormatChanged( reqTransReader ); // call it myself so I know when it is done. + if ( runArgsHM.containsKey( RUN_ARGS_DATEFORMAT ) ) + { + dcbm = (DefaultComboBoxModel) comboDateFormat.getModel(); + idx = dcbm.getIndexOf( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + + if ( idx >= 0 ) + { + comboDateFormat.setSelectedItem( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_DATEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) + "\' is not valid for the \'" + RUN_ARGS_FILEFORMAT + "\' used.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + dcbm = (DefaultComboBoxModel) comboAccount.getModel(); + int max = comboAccount.getItemCount(); + System.err.println( "runArgs at importaccount max =" + max ); + Account foundAccount = null; + + for ( idx = max - 1; idx >= 0; idx-- ) + { + System.err.println( "getAcountName() =" + ((Account) dcbm.getElementAt( idx )).getAccountName() + + "= importaccount =" + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "=" ); + if ( ((Account) dcbm.getElementAt( idx )).getAccountName().equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) ) ) + { + foundAccount = (Account) dcbm.getElementAt( idx ); + break; + } + } + + if ( idx >= 0 ) + { + comboAccount.setSelectedItem( foundAccount ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTACCOUNT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_FILEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\' is not valid for the file you gave.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + errorInRunArgs = true; + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nof invalid \'" + RUN_ARGS_FILEFORMAT + "\' value \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\'.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT ); + errorInRunArgs = true; + } + } // endif fileformat + + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILEFORMAT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT ); + errorInRunArgs = true; + } + else if ( ! runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_IMPORTACCOUNT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) && ! errorInRunArgs ) + { + btnProcessActionPerformed( null ); + autoProcessedAFile = true; + } + + } // END of arguments processing + else if ( runArgsHM.size() > 0 ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILE + "\' argument " + , "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + errorInRunArgs = true; + } + return errCodeList; + } + + private void fillAccountCombo( Main main ) + { + RootAccount rootAccount = main.getRootAccount(); + comboAccount.removeAllItems(); + + fillAccountCombo_( rootAccount ); + + if ( comboAccount.getItemCount() > 0 ) + { + System.err.println( "Settings.getInteger( false, \"selected.account\", 0 ) =" + Settings.getInteger( false, "selected.account", 0 ) ); + try { + comboAccount.setSelectedIndex( Settings.getInteger( false, "selected.account", 0 ) ); + } + catch( Exception ex ) + { + JOptionPane.showMessageDialog( rootPane, "Your 'Import to Account' is not longer valid. " + + "You will have to choose a new one.", + "Import to Account setting", + JOptionPane.ERROR_MESSAGE ); + } + } + } + + private void fillAccountCombo_( Account parentAccount ) + { + for ( int i = 0; i < parentAccount.getSubAccountCount(); ++i ) + { + Account account = parentAccount.getSubAccount( i ); + if ( account.isRegisterAccount() ) + { + comboAccount.addItem( account ); + } + else + { + fillAccountCombo_( account ); + } + } + } + + public boolean isSkipDuringInit() { + return skipDuringInit; + } + + public void setSkipDuringInit(boolean skipDuringInit) { + this.skipDuringInit = skipDuringInit; + } + + public boolean isSelectedOnlineImportTypeRB() { + System.err.println( "onlineImportTypeRB.isSelected() =" + onlineImportTypeRB.isSelected() + "=" ); + return onlineImportTypeRB.isSelected(); + } + + public boolean isAutoProcessedAFile() { + return autoProcessedAFile; + } + + public void setPropertiesFile() { + this.propertiesFile.setText( Settings.getFilename().toString() ); + } + + private void processFileFormatChanged( TransactionReader transReader ) + { + System.err.println( "processFileFormatChanged() --------------- " ); + + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + +// System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); +// System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + transReader.isUsingCategorynameFlag() + "=" ); +// if ( importDialog.isSelectedOnlineImportTypeRB() && transReader.isUsingCategorynameFlag() ) +// { +// JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\'" +// , "Message", JOptionPane.INFORMATION_MESSAGE ); +// } + } + + String[] formats = transReader.getSupportedDateFormats(); + System.err.println( "importDialog().processFileFormatChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel3 = new javax.swing.JLabel(); + buttonGroup1 = new javax.swing.ButtonGroup(); + lblSelectFile = new javax.swing.JLabel(); + btnBrowse = new javax.swing.JButton(); + checkDeleteFile = new javax.swing.JCheckBox(); + btnClose = new javax.swing.JButton(); + btnProcess = new javax.swing.JButton(); + lblAccount = new javax.swing.JLabel(); + comboAccount = new javax.swing.JComboBox(); + lblMessage = new javax.swing.JLabel(); + lblFileFormat = new javax.swing.JLabel(); + comboFileFormat = new javax.swing.JComboBox(); + onlineImportTypeRB = new javax.swing.JRadioButton(); + regularImportTypeRB = new javax.swing.JRadioButton(); + lblDateFormat = new javax.swing.JLabel(); + comboDateFormat = new javax.swing.JComboBox(); + jButton1 = new javax.swing.JButton(); + jLabel5 = new javax.swing.JLabel(); + comboFileFormatLabel = new javax.swing.JLabel(); + jButton2 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + propertiesFile = new javax.swing.JLabel(); + PreviewImportBtn = new javax.swing.JButton(); + jButton3 = new javax.swing.JButton(); + textFilename = new javax.swing.JComboBox(); + jButton4 = new javax.swing.JButton(); + jButton5 = new javax.swing.JButton(); + + jLabel3.setText("jLabel3"); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Import File: " + main.VERSION_STRING); + setName("importDialog"); // NOI18N + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowOpened(java.awt.event.WindowEvent evt) { + formWindowOpened(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + lblSelectFile.setText("Select Import File:"); + lblSelectFile.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblSelectFile, gridBagConstraints); + + btnBrowse.setText("..."); + btnBrowse.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnBrowseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 10); + getContentPane().add(btnBrowse, gridBagConstraints); + + checkDeleteFile.setText("Securely erase file after processing."); + checkDeleteFile.setToolTipText("If checked, the specified file will be securely erased (first overwritten, then deleted) after successful processing."); + checkDeleteFile.setPreferredSize(new java.awt.Dimension(250, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 13; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 10, 10, 0); + getContentPane().add(checkDeleteFile, gridBagConstraints); + + btnClose.setText("Close"); + btnClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCloseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnClose, gridBagConstraints); + + btnProcess.setText("Process"); + btnProcess.setEnabled(false); + btnProcess.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnProcessActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnProcess, gridBagConstraints); + + lblAccount.setText("Import to Account:"); + lblAccount.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblAccount, gridBagConstraints); + + comboAccount.setModel(new javax.swing.DefaultComboBoxModel(new Account[] { })); + comboAccount.setMaximumSize(new java.awt.Dimension(180, 29)); + comboAccount.setMinimumSize(new java.awt.Dimension(180, 29)); + comboAccount.setPreferredSize(new java.awt.Dimension(180, 29)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboAccount, gridBagConstraints); + + lblMessage.setForeground(new java.awt.Color(255, 0, 51)); + lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + lblMessage.setText(" "); + lblMessage.setMaximumSize(new java.awt.Dimension(200, 25)); + lblMessage.setMinimumSize(new java.awt.Dimension(100, 25)); + lblMessage.setOpaque(true); + lblMessage.setPreferredSize(new java.awt.Dimension(3, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 18; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.ipady = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(lblMessage, gridBagConstraints); + + lblFileFormat.setText("File Reader:"); + lblFileFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblFileFormat, gridBagConstraints); + + comboFileFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboFileFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboFileFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboFileFormat.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + fileFormatChanged(evt); + } + }); + comboFileFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboFileFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboFileFormat, gridBagConstraints); + + buttonGroup1.add(onlineImportTypeRB); + onlineImportTypeRB.setText("Online"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(onlineImportTypeRB, gridBagConstraints); + + buttonGroup1.add(regularImportTypeRB); + regularImportTypeRB.setSelected(true); + regularImportTypeRB.setText("Regular"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 10; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(regularImportTypeRB, gridBagConstraints); + + lblDateFormat.setText("Date Format:"); + lblDateFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblDateFormat, gridBagConstraints); + + comboDateFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboDateFormat.setMaximumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setMinimumSize(new java.awt.Dimension(180, 29)); + comboDateFormat.setPreferredSize(new java.awt.Dimension(180, 29)); + comboDateFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboDateFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboDateFormat, gridBagConstraints); + + jButton1.setText("Maintain Custom File Readers"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 16; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10); + getContentPane().add(jButton1, gridBagConstraints); + + jLabel5.setText("Import Transactions as:"); + jLabel5.setToolTipText("Online: These will not have a default category pre-set.
\nRegular: These are regular transactions and they get the default category for the account.
\n        You can also import a 'tag' field in the regular type."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 10; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); + getContentPane().add(jLabel5, gridBagConstraints); + + comboFileFormatLabel.setText(" "); + comboFileFormatLabel.setMaximumSize(new java.awt.Dimension(60, 25)); + comboFileFormatLabel.setMinimumSize(new java.awt.Dimension(40, 25)); + comboFileFormatLabel.setPreferredSize(new java.awt.Dimension(60, 25)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 7; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(comboFileFormatLabel, gridBagConstraints); + + jButton2.setText("Suggestions"); + jButton2.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton2ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 13; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END; + getContentPane().add(jButton2, gridBagConstraints); + + jLabel1.setText(" "); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 14; + getContentPane().add(jLabel1, gridBagConstraints); + + propertiesFile.setText(" "); + propertiesFile.setMaximumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setMinimumSize(new java.awt.Dimension(180, 23)); + propertiesFile.setPreferredSize(new java.awt.Dimension(180, 23)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 19; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH; + gridBagConstraints.insets = new java.awt.Insets(4, 10, 10, 10); + getContentPane().add(propertiesFile, gridBagConstraints); + + PreviewImportBtn.setText("Preview Import"); + PreviewImportBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + PreviewImportBtnActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 16; + getContentPane().add(PreviewImportBtn, gridBagConstraints); + + jButton3.setText("Find Reader(s) that Work on Import File"); + jButton3.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton3ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton3, gridBagConstraints); + + textFilename.setModel(new javax.swing.DefaultComboBoxModel(new String[] { " " })); + textFilename.setMinimumSize(new java.awt.Dimension(180, 29)); + textFilename.setPreferredSize(new java.awt.Dimension(180, 29)); + textFilename.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + textFilenameItemStateChanged(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 6; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(textFilename, gridBagConstraints); + + jButton4.setText("Find Import File(s) for this Reader"); + jButton4.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton4ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 5, 0); + getContentPane().add(jButton4, gridBagConstraints); + + jButton5.setText("List All Readers"); + jButton5.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton5ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 2; + getContentPane().add(jButton5, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnBrowseActionPerformed + {//GEN-HEADEREND:event_btnBrowseActionPerformed + JFileChooser dialog = new JFileChooser(); + dialog.setFileHidingEnabled( true ); + dialog.setDialogTitle( "Select text file" ); + dialog.setCurrentDirectory( + new File( Settings.get( false, "last.directory", + dialog.getCurrentDirectory().getAbsolutePath() ) ) ); + dialog.addChoosableFileFilter( new FileFilter() + { + @Override + public boolean accept( File f ) + { + return f.isDirectory() || f.getName().toUpperCase().endsWith( ".CSV" ); + } + + @Override + public String getDescription() + { + return "Formatted Text File (*.csv)"; + } + } ); + if ( dialog.showDialog( this, "Select" ) == JFileChooser.APPROVE_OPTION ) + { + selectedFile = dialog.getSelectedFile(); + Settings.set( "last.directory", dialog.getCurrentDirectory().getAbsolutePath() ); + // textFilename.setSelectedItem( selectedFile.getPath() ); + String[] tt = { selectedFile.getPath() }; + popTextFilenameList( tt ); +// fileChanged(); + fileChanged2(); + btnProcess.setEnabled( false ); + } +}//GEN-LAST:event_btnBrowseActionPerformed + + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed + {//GEN-HEADEREND:event_btnCloseActionPerformed + this.setVisible( false ); + }//GEN-LAST:event_btnCloseActionPerformed + + private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnProcessActionPerformed + {//GEN-HEADEREND:event_btnProcessActionPerformed + System.err.println( "Process button entered" ); + Settings.setYesNo( "delete.file", checkDeleteFile.isSelected() ); + Settings.setYesNo( "importtype.online.radiobutton", onlineImportTypeRB.isSelected() ); + Settings.setInteger( "selected.account", comboAccount.getSelectedIndex() ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + System.err.println( "starting transReader.parse..." ); + transReader.parse( main, csvData, account, main.getRootAccount() ); + csvReader.close(); + System.out.println( "finished transReader.parse" ); + + //TESTING! DS +// onlineMgr.processDownloadedTxns( account ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem importing " + + " selected file, probably because the file format was wrong. Some items " + + "might have been added to your account.", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + + if ( checkDeleteFile.isSelected() ) + { + try + { + SecureFileDeleter.delete( selectedFile ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "The file was imported properly, " + + "however it could not be erased as requested.", "Cannot Delete File", + JOptionPane.ERROR_MESSAGE ); + return; + } + } + + if ( ! Settings.getBoolean( false, "success.dialog.shown", false ) ) + { + Settings.setYesNo( "success.dialog.shown", true ); + JOptionPane.showMessageDialog( rootPane, + "The file was imported properly. \n\n" + + "You can view the imported items when you open the account you have \n" + + "selected and click on the 'downloaded transactions' message at the \n" + + "bottom of the screen.", + "Import Successful", JOptionPane.INFORMATION_MESSAGE ); + } + + setVisible( false ); + }//GEN-LAST:event_btnProcessActionPerformed + + private void fileFormatChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_fileFormatChanged + {//GEN-HEADEREND:event_fileFormatChanged + System.err.println( "fileFormatChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "fileFormatChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "fileFormatChanged() event == ItemEvent.SELECTED ---------------" ); + if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader; + try + { + transReader = (TransactionReader) evt.getItem(); + } + catch ( ClassCastException x ) + { + transReader = null; + } + + processFileFormatChanged( transReader ); + } + + }//GEN-LAST:event_fileFormatChanged + + private void comboFileFormat1fileFormatChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboFileFormat1fileFormatChanged + // TODO add your handling code here: + }//GEN-LAST:event_comboFileFormat1fileFormatChanged + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + setPropertiesFile(); + customReaderDialog.setVisible( true ); + }//GEN-LAST:event_jButton1ActionPerformed + +private void comboDateFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboDateFormatActionPerformed + //customReaderDialog.setDateFormat( (String)comboDateFormat.getSelectedItem() ); +}//GEN-LAST:event_comboDateFormatActionPerformed + +private void comboFileFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboFileFormatActionPerformed + + btnProcess.setEnabled( false ); + /* use actionPerformed - not both ! +if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + } + + String[] formats = transReader.getSupportedDateFormats(); + + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + comboDateFormat.addItem( s ); + } + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } +*/ +}//GEN-LAST:event_comboFileFormatActionPerformed + + private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed + JOptionPane.showMessageDialog( this, "Create a temporary bank account to import into.
When you are ok with the imported records, then \"Batch Change\"
them to the right account.
Not using \"Batch Change\" will mess up your accounts.

-Payment- and -Deposit- are just opposite signed amounts of each other
so if your amount comes into the wrong column, just flip them.
" + , "Message", JOptionPane.INFORMATION_MESSAGE ); + }//GEN-LAST:event_jButton2ActionPerformed + + private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened + this.setPropertiesFile(); + }//GEN-LAST:event_formWindowOpened + + private void PreviewImportBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_PreviewImportBtnActionPerformed + System.err.println( "Preview Import button entered" ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + CSVReader csvReader = null; + + if ( transReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( (String) transReader.getCustomReaderData().getFileEncoding() )), transReader.getCustomReaderData() ); + } + + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + //System.err.println( "starting transReader.parse..." ); + //transReader.parse( main, csvData, account, main.getRootAccount() ); + + transReader.setRootAccount( main.getRootAccount() ); + + PreviewImportWin previewImportWin = new PreviewImportWin(); + previewImportWin.myInit( this, transReader, csvData, csvReader ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem with Preview importing " + + " selected file, probably because the file format was wrong. ", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + }//GEN-LAST:event_PreviewImportBtnActionPerformed + + private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed + fileChanged(); + }//GEN-LAST:event_jButton3ActionPerformed + + private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed + popTextFilenameList( null ); + btnProcess.setEnabled( false ); + }//GEN-LAST:event_jButton4ActionPerformed + + private void textFilenameItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_textFilenameItemStateChanged + System.err.println( "textFilenameItemStateChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "textFilenameItemStateChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "textFilenameItemStateChanged() event == ItemEvent.SELECTED ---------------" ); + if ( textFilename.getSelectedItem() instanceof String ) + { + System.err.println( "textFilename is string =" + (String) textFilename.getSelectedItem() + "=" ); + textFilenameChanged(); + return; + } + } + }//GEN-LAST:event_textFilenameItemStateChanged + + private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed + fileChanged2(); + }//GEN-LAST:event_jButton5ActionPerformed + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + ImportDialog dialog = new ImportDialog(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton PreviewImportBtn; + private javax.swing.JButton btnBrowse; + private javax.swing.JButton btnClose; + protected javax.swing.JButton btnProcess; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JCheckBox checkDeleteFile; + private javax.swing.JComboBox comboAccount; + private javax.swing.JComboBox comboDateFormat; + private javax.swing.JComboBox comboFileFormat; + private javax.swing.JLabel comboFileFormatLabel; + private javax.swing.JButton jButton1; + private javax.swing.JButton jButton2; + private javax.swing.JButton jButton3; + private javax.swing.JButton jButton4; + private javax.swing.JButton jButton5; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel lblAccount; + private javax.swing.JLabel lblDateFormat; + private javax.swing.JLabel lblFileFormat; + private javax.swing.JLabel lblMessage; + private javax.swing.JLabel lblSelectFile; + private javax.swing.JRadioButton onlineImportTypeRB; + private javax.swing.JLabel propertiesFile; + private javax.swing.JRadioButton regularImportTypeRB; + private javax.swing.JComboBox textFilename; + // End of variables declaration//GEN-END:variables + + public void comboFileFormat1AddItem( TransactionReader customReader ) + { + System.err.println( "importDialog() add reader item =" + customReader.toString() + "=" ); + //customReaderCB.addItem( xxx ); + comboFileFormat.addItem( customReader ); + } + + public void comboFileFormat1SetItem( TransactionReader customReader ) + { + System.err.println( "importDialog() comboFileFormat1SetItem() =" + customReader.toString() + "=" ); + //customReaderCB.setSelectedItem( xxx ); + comboFileFormat.setSelectedItem( customReader ); + } + + public void comboDateFormatSetItem( String xxx ) + { + System.err.println( "importDialog() comboDateFormat.setSelectedItem( xxx ) =" + xxx + "=" ); + comboDateFormat.setSelectedItem( xxx ); + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + System.out.println( "ImportDialog.createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "=" ); + dateFormatModel.addElement( dateFormatArg ); + + comboDateFormat.setModel( dateFormatModel ); + + comboDateFormat.setSelectedIndex( 0 ); + } + + public String comboDateFormatGetItem() + { + System.err.println( "importDialog() comboDateFormat.comboDateFormat.getSelectedItem() =" + comboDateFormat.getSelectedItem() + "=" ); + return (String) comboDateFormat.getSelectedItem(); + } + + public void comboDateFormatAddItem( String format ) + { + System.err.println( "importDialog() add date format item =" + comboDateFormat + "=" ); + //customReaderCB.addItem( xxx ); + comboDateFormat.addItem( format ); + } + + public void comboDateFormatSetModel( DefaultComboBoxModel model ) + { + System.err.println( "importDialog() comboDateFormatSetModel()" ); + comboDateFormat.setModel( model ); + } + + private void textFilenameChanged() + { + File newFile = new File( (String) textFilename.getSelectedItem() ); + + if ( ! newFile.equals( selectedFile ) ) + { + selectedFile = newFile; +// fileChanged(); + } + } + + public void popTextFilenameList( String [] filenames ) + { + System.err.println( "entered popTextFilenameList()" ); + File dir = new File( Settings.get( false, "last.directory", "" ) ); + + if ( filenames == null ) + { + if ( dir.equals( "" ) ) + { + dir = (File.listRoots())[0]; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader.getCustomReaderData().getFilenameMatcher() == null || + transReader.getCustomReaderData().getFilenameMatcher().equals( "" ) ) + { + transReader.getCustomReaderData().setFilenameMatcher( ".*\\.[Cc][Ss][Vv]" ); + } + + // create new filename filter + FilenameFilter fileNameFilter = new FilenameFilter() + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + { + System.err.println( "popTextFilenameList() transReader.getFormatName() >" + transReader.getFormatName() + "<" ); + } + @Override + public boolean accept(File dir, String name) { + System.err.println( "popTextFilenameList() match name? >" + name + "<" ); + //System.err.println( "popTextFilenameList() getFilenameMatcher() >" + transReader.getCustomReaderData().getFilenameMatcher() + "<" ); + if ( name.matches( transReader.getCustomReaderData().getFilenameMatcher() ) ) + { + return true; + } + return false; + } + }; + + // returns pathnames for files and directory + filenames = dir.list( fileNameFilter ); + + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( dir + System.getProperty( "file.separator" ) + s ); + } + } + else + { + textFilename.removeAllItems(); + for ( String s : filenames ) + { + System.err.println( "popTextFilenameList add format >" + s + "<" ); + textFilename.addItem( s ); + } + } + } + + public void popComboDateFormatList( String [] formats ) + { + System.err.println( "entered popComboDateFormatList()" ); + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + System.err.println( "popComboDateFormatList add format >" + s + "<" ); + comboDateFormat.addItem( s ); + } + } + + protected void fileChanged() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // try reading the file + /* + if ( !error ) + { + try + { + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + //csvReader.setFieldSeparator( '8' ); THIS WORKED ! + csvReader.setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + csvData = new CSVData( csvReader ); + } + catch ( Throwable x ) + { + error = true; + message = "Error reading file."; + Logger.getLogger( ImportDialog.class.getName() ).log( Level.SEVERE, null, x ); + } + } + * */ + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_COMPATIBLE_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + setLabel( "FindAReader", "No Matches" ); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + setLabel( "FindAReader", "Found" ); + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + if ( ! error ) + { + TransactionReader reader = (TransactionReader) comboFileFormat.getSelectedItem(); + String[] formats = reader.getSupportedDateFormats(); + System.err.println( "importDialog().fileChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Cannot recognize date format used in the file."; + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog.getDateFormatSelected()) =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + + System.err.println( "importDialog() error =" + error + "=" ); + System.err.println( "importDialog() isSelectedOnlineImportTypeRB()) =" + isSelectedOnlineImportTypeRB()+ "=" ); + System.err.println( "importDialog() reader.isUsingCategorynameFlag() =" + reader.isUsingCategorynameFlag() + "=" ); + if ( ! error && importDialog.isSelectedOnlineImportTypeRB() && isUsingCategorynameFlag ) + { + JOptionPane.showMessageDialog( this, "Categories will not import using \'Online\' import type. Set to \'Regular\' if you want that." + , "Message", JOptionPane.INFORMATION_MESSAGE ); + } + } + else + { + comboDateFormat.removeAllItems(); + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + protected void fileChanged2() + { + String message = null; + boolean error = false; + boolean isUsingCategorynameFlag = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // detect file format + if ( ! error ) + { +// moving TransactionReader.customReaderDialog = customReaderDialog; + + setLabel( "FindAReader", "Find Reader" ); + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( GET_ALL_READERS, selectedFile, this, main.getRootAccount() ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + if ( reader.isUsingCategorynameFlag() ) + isUsingCategorynameFlag = true; + } + + if ( fileFormats.length == 0 ) + { + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + setLabel( "FindAReader", "Pick One" ); + comboFileFormat.setEnabled( true ); + } + } + else + { + setLabel( "FindAReader", "No File" ); + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + setLabel( "main", message ); + } + + public void setLabel( String objName, String message ) + { + JLabel label = null; + + if ( objName.equals( "main" ) ) + { + label = lblMessage; + } + else if ( objName.equals( "FindAReader" ) ) + { + label = comboFileFormatLabel; + } + if ( message != null ) + { + label.setVisible( true ); + label.setText( message ); + label.setForeground( new Color( 255, 0, 51 ) ); + } + else + { + label.setVisible( false ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java~ b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java~ new file mode 100644 index 0000000..3ed52af --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/ImportDialog.java~ @@ -0,0 +1,1097 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import java.awt.Color; +import java.awt.event.ItemEvent; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JFileChooser; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.JOptionPane; + +/** + * + * @author miki & Stan Towianski + */ +public class ImportDialog + extends javax.swing.JDialog +{ + private OnlineManager onlineMgr = null; + private File selectedFile; + private CSVData csvData; + private Main main; + private HashMap runArgsHM; + protected final static String RUN_ARGS_FILE = "file"; + protected final static String RUN_ARGS_FILEFORMAT = "fileformat"; + protected final static String RUN_ARGS_DATEFORMAT = "dateformat"; + protected final static String RUN_ARGS_IMPORTACCOUNT = "importaccount"; + protected final static String RUN_ARGS_IMPORTTYPE = "importtype"; + protected final static String RUN_ARGS_PROCESSFLAG = "processflag"; + protected final static String RUN_ARGS_DELETECSVFILEFLAG = "deletecsvfileflag"; + protected final static String RUN_ARGS_NOPOPERRORSFLAG = "nopoperrorsflag"; + protected final static String RUN_ARGS_JUNIT = "junitflag"; + + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILE = 1; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE = 2; + protected final static int RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT = 3; + protected final static int RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT = 4; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE = 5; + protected final static int RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT = 6; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILE = 7; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT = 8; + protected final static int RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT = 9; + + private CustomReaderDialog customReaderDialog = new CustomReaderDialog( this, true ); + private ArrayList errCodeList = new ArrayList(); + private boolean skipDuringInit = true; + private boolean autoProcessedAFile = false; + + public ImportDialog() + { + } + + public ImportDialog( Main main, HashMap runArgsHM ) + { + super( main.getMoneydanceWindow(), true ); + initComponents(); + this.runArgsHM = runArgsHM; + autoProcessedAFile = false; + + customReaderDialog.init(); + customReaderDialog.setLocationRelativeTo( getRootPane() ); + + textFilename.getDocument().addDocumentListener( new DocumentListener() + { + public void insertUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void removeUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + + public void changedUpdate( DocumentEvent e ) + { + textFilenameChanged(); + } + } ); + + this.main = main; + + if ( main.getMainContext() != null ) + { + + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + + fillAccountCombo( main ); + } + + checkDeleteFile.setSelected( Settings.getBoolean( "delete.file" ) ); + onlineImportTypeRB.setSelected( Settings.getBoolean( "importtype.online.radiobutton" ) ); + + skipDuringInit = false; + } + + protected ArrayList processRunArguments() + { + errCodeList = new ArrayList(); + boolean errorInRunArgs = false; + + if ( runArgsHM.containsKey( RUN_ARGS_FILE ) ) + { + selectedFile = new File( (String) runArgsHM.get( RUN_ARGS_FILE ) ); + if ( ! selectedFile.exists() ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nfile \'" + + (String) runArgsHM.get( RUN_ARGS_FILE ) + "\' does not exist.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILE ); + errorInRunArgs = true; + } + else + { + textFilename.setText( selectedFile.getPath() ); + fileChanged(); + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTTYPE ) ) + { + if ( "ONLINE".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + onlineImportTypeRB.setSelected( true ); + } + else if ( "REGULAR".equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) ) ) + { + regularImportTypeRB.setSelected( true ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTTYPE + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTTYPE ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTTYPE ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_DELETECSVFILEFLAG ) ) + { + checkDeleteFile.setSelected( true ); + } + + if ( runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + //if ( customReaderDialog.getReaderConfig( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ) ) + TransactionReader reqTransReader = customReaderDialog.getTransactionReader( (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) ); + if ( reqTransReader != null ) + { + DefaultComboBoxModel dcbm = (DefaultComboBoxModel) comboFileFormat.getModel(); + int idx = dcbm.getIndexOf( reqTransReader ); + + if ( idx >= 0 ) + { + comboFileFormat.setSelectedItem( reqTransReader ); + processFileFormatChanged( reqTransReader ); // call it myself so I know when it is done. + if ( runArgsHM.containsKey( RUN_ARGS_DATEFORMAT ) ) + { + dcbm = (DefaultComboBoxModel) comboDateFormat.getModel(); + idx = dcbm.getIndexOf( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + + if ( idx >= 0 ) + { + comboDateFormat.setSelectedItem( (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_DATEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_DATEFORMAT ) + "\' is not valid for the \'" + RUN_ARGS_FILEFORMAT + "\' used.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_DATEFORMAT_FOR_FILEFORMAT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + dcbm = (DefaultComboBoxModel) comboAccount.getModel(); + int max = comboAccount.getItemCount(); + System.err.println( "runArgs at importaccount max =" + max ); + Account foundAccount = null; + + for ( idx = max - 1; idx >= 0; idx-- ) + { + System.err.println( "getAcountName() =" + ((Account) dcbm.getElementAt( idx )).getAccountName() + + "= importaccount =" + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "=" ); + if ( ((Account) dcbm.getElementAt( idx )).getAccountName().equalsIgnoreCase( (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) ) ) + { + foundAccount = (Account) dcbm.getElementAt( idx ); + break; + } + } + + if ( idx >= 0 ) + { + comboAccount.setSelectedItem( foundAccount ); + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_IMPORTACCOUNT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_IMPORTACCOUNT ) + "\' is not valid.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nthe \'" + RUN_ARGS_FILEFORMAT + "\' you chose \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\' is not valid for the file you gave.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + errorInRunArgs = true; + } + } + else + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed with processing of csv file because \nof invalid \'" + RUN_ARGS_FILEFORMAT + "\' value \'" + + (String) runArgsHM.get( RUN_ARGS_FILEFORMAT ) + "\'.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT ); + errorInRunArgs = true; + } + } // endif fileformat + + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_FILEFORMAT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILEFORMAT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILEFORMAT ); + errorInRunArgs = true; + } + else if ( ! runArgsHM.containsKey( RUN_ARGS_IMPORTACCOUNT ) ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_IMPORTACCOUNT + "\' argument " + + "if you use the \'" + RUN_ARGS_PROCESSFLAG + "\' argument.", "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_IMPORTACCOUNT ); + errorInRunArgs = true; + } + } + + if ( runArgsHM.containsKey( RUN_ARGS_PROCESSFLAG ) && ! errorInRunArgs ) + { + btnProcessActionPerformed( null ); + autoProcessedAFile = true; + } + + } // END of arguments processing + else if ( runArgsHM.size() > 0 ) + { + if ( ! runArgsHM.containsKey( RUN_ARGS_JUNIT ) && ! runArgsHM.containsKey( RUN_ARGS_NOPOPERRORSFLAG ) ) + { + JOptionPane.showMessageDialog( this, "Cannot proceed without a \'" + RUN_ARGS_FILE + "\' argument " + , "Error", JOptionPane.ERROR_MESSAGE ); + } + errCodeList.add( RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + errorInRunArgs = true; + } + return errCodeList; + } + + private void fillAccountCombo( Main main ) + { + RootAccount rootAccount = main.getRootAccount(); + comboAccount.removeAllItems(); + + fillAccountCombo_( rootAccount ); + + if ( comboAccount.getItemCount() > 0 ) + { + comboAccount.setSelectedIndex( Settings.getInteger( "selected.account", 0 ) ); + } + } + + private void fillAccountCombo_( Account parentAccount ) + { + for ( int i = 0; i < parentAccount.getSubAccountCount(); ++i ) + { + Account account = parentAccount.getSubAccount( i ); + if ( account.isRegisterAccount() ) + { + comboAccount.addItem( account ); + } + else + { + fillAccountCombo_( account ); + } + } + } + + public boolean isSkipDuringInit() { + return skipDuringInit; + } + + public void setSkipDuringInit(boolean skipDuringInit) { + this.skipDuringInit = skipDuringInit; + } + + public boolean isSelectedOnlineImportTypeRB() { + System.err.println( "onlineImportTypeRB.isSelected() =" + onlineImportTypeRB.isSelected() + "=" ); + return onlineImportTypeRB.isSelected(); + } + + public boolean isAutoProcessedAFile() { + return autoProcessedAFile; + } + + private void processFileFormatChanged( TransactionReader transReader ) + { + System.err.println( "processFileFormatChanged() --------------- " ); + + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + } + + String[] formats = transReader.getSupportedDateFormats(); + System.err.println( "importDialog().processFileFormatChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel3 = new javax.swing.JLabel(); + buttonGroup1 = new javax.swing.ButtonGroup(); + lblSelectFile = new javax.swing.JLabel(); + textFilename = new javax.swing.JTextField(); + btnBrowse = new javax.swing.JButton(); + checkDeleteFile = new javax.swing.JCheckBox(); + btnClose = new javax.swing.JButton(); + btnProcess = new javax.swing.JButton(); + lblAccount = new javax.swing.JLabel(); + comboAccount = new javax.swing.JComboBox(); + lblMessage = new javax.swing.JLabel(); + lblFileFormat = new javax.swing.JLabel(); + comboFileFormat = new javax.swing.JComboBox(); + onlineImportTypeRB = new javax.swing.JRadioButton(); + regularImportTypeRB = new javax.swing.JRadioButton(); + lblDateFormat = new javax.swing.JLabel(); + comboDateFormat = new javax.swing.JComboBox(); + jButton1 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + + jLabel3.setText("jLabel3"); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Import File: " + main.VERSION_STRING); + setName("importDialog"); // NOI18N + setResizable(false); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + lblSelectFile.setText("Select Import File:"); + lblSelectFile.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblSelectFile, gridBagConstraints); + + textFilename.setMaximumSize(new java.awt.Dimension(180, 24)); + textFilename.setMinimumSize(new java.awt.Dimension(180, 24)); + textFilename.setPreferredSize(new java.awt.Dimension(180, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 0.1; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(textFilename, gridBagConstraints); + + btnBrowse.setText("..."); + btnBrowse.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnBrowseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 6; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 10); + getContentPane().add(btnBrowse, gridBagConstraints); + + checkDeleteFile.setText("Securely erase file after processing."); + checkDeleteFile.setToolTipText("If checked, the specified file will be securely erased (first overwritten, then deleted) after successful processing."); + checkDeleteFile.setPreferredSize(new java.awt.Dimension(250, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 9; + gridBagConstraints.gridwidth = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 10, 5, 0); + getContentPane().add(checkDeleteFile, gridBagConstraints); + + btnClose.setText("Close"); + btnClose.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCloseActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 12; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(btnClose, gridBagConstraints); + + btnProcess.setText("Process"); + btnProcess.setEnabled(false); + btnProcess.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnProcessActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 12; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + getContentPane().add(btnProcess, gridBagConstraints); + + lblAccount.setText("Import to Account:"); + lblAccount.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblAccount, gridBagConstraints); + + comboAccount.setModel(new javax.swing.DefaultComboBoxModel(new Account[] { })); + comboAccount.setMaximumSize(new java.awt.Dimension(180, 24)); + comboAccount.setMinimumSize(new java.awt.Dimension(180, 24)); + comboAccount.setPreferredSize(new java.awt.Dimension(180, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 4; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboAccount, gridBagConstraints); + + lblMessage.setForeground(new java.awt.Color(255, 0, 51)); + lblMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + lblMessage.setText(" "); + lblMessage.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 14; + gridBagConstraints.gridwidth = 7; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.ipady = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(lblMessage, gridBagConstraints); + + lblFileFormat.setText("File Reader Format:"); + lblFileFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblFileFormat, gridBagConstraints); + + comboFileFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboFileFormat.setMaximumSize(new java.awt.Dimension(180, 24)); + comboFileFormat.setMinimumSize(new java.awt.Dimension(180, 24)); + comboFileFormat.setPreferredSize(new java.awt.Dimension(180, 24)); + comboFileFormat.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + fileFormatChanged(evt); + } + }); + comboFileFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboFileFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 2; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboFileFormat, gridBagConstraints); + + buttonGroup1.add(onlineImportTypeRB); + onlineImportTypeRB.setText("Online"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 8; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(onlineImportTypeRB, gridBagConstraints); + + buttonGroup1.add(regularImportTypeRB); + regularImportTypeRB.setSelected(true); + regularImportTypeRB.setText("Regular"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 8; + gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); + getContentPane().add(regularImportTypeRB, gridBagConstraints); + + lblDateFormat.setText("Date Format:"); + lblDateFormat.setPreferredSize(new java.awt.Dimension(120, 24)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 0); + getContentPane().add(lblDateFormat, gridBagConstraints); + + comboDateFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { })); + comboDateFormat.setMaximumSize(new java.awt.Dimension(180, 24)); + comboDateFormat.setMinimumSize(new java.awt.Dimension(180, 24)); + comboDateFormat.setPreferredSize(new java.awt.Dimension(180, 24)); + comboDateFormat.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboDateFormatActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 3; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(10, 4, 10, 0); + getContentPane().add(comboDateFormat, gridBagConstraints); + + jButton1.setText("Maintain Custom File Readers"); + jButton1.setMaximumSize(new java.awt.Dimension(43, 25)); + jButton1.setMinimumSize(new java.awt.Dimension(220, 25)); + jButton1.setPreferredSize(new java.awt.Dimension(220, 25)); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 12; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10); + getContentPane().add(jButton1, gridBagConstraints); + + jLabel1.setText("Suggestion: Create a temporary bank account to import into."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 5; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(jLabel1, gridBagConstraints); + + jLabel2.setText("When you are ok with the imported records, then batch move"); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(jLabel2, gridBagConstraints); + + jLabel4.setText("them to the right account."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 7; + gridBagConstraints.gridwidth = 5; + gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; + getContentPane().add(jLabel4, gridBagConstraints); + + jLabel5.setText("Import Transactions as:"); + jLabel5.setToolTipText("Online: These will not have a default category pre-set.
\nRegular: These are regular transactions and they get the default category for the account.
\n        You can also import a 'tag' field in the regular type."); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 8; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0); + getContentPane().add(jLabel5, gridBagConstraints); + + pack(); + }//
//GEN-END:initComponents + + private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnBrowseActionPerformed + {//GEN-HEADEREND:event_btnBrowseActionPerformed + JFileChooser dialog = new JFileChooser(); + dialog.setFileHidingEnabled( true ); + dialog.setDialogTitle( "Select text file" ); + dialog.setCurrentDirectory( + new File( Settings.get( "last.directory", + dialog.getCurrentDirectory().getAbsolutePath() ) ) ); + dialog.addChoosableFileFilter( new FileFilter() + { + @Override + public boolean accept( File f ) + { + return f.isDirectory() || f.getName().toUpperCase().endsWith( ".CSV" ); + } + + @Override + public String getDescription() + { + return "Formatted Text File (*.csv)"; + } + } ); + if ( dialog.showDialog( this, "Select" ) == JFileChooser.APPROVE_OPTION ) + { + selectedFile = dialog.getSelectedFile(); + Settings.set( "last.directory", dialog.getCurrentDirectory().getAbsolutePath() ); + textFilename.setText( selectedFile.getPath() ); + fileChanged(); + } +}//GEN-LAST:event_btnBrowseActionPerformed + + private void btnCloseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCloseActionPerformed + {//GEN-HEADEREND:event_btnCloseActionPerformed + this.setVisible( false ); + }//GEN-LAST:event_btnCloseActionPerformed + + private void btnProcessActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnProcessActionPerformed + {//GEN-HEADEREND:event_btnProcessActionPerformed + System.err.println( "Process button entered" ); + Settings.setYesNo( "delete.file", checkDeleteFile.isSelected() ); + Settings.setYesNo( "importtype.online.radiobutton", onlineImportTypeRB.isSelected() ); + Settings.setInteger( "selected.account", comboAccount.getSelectedIndex() ); + + try + { + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + System.err.println( "comboFileFormat is string =" + transReader.toString() + "=" ); + transReader.setDateFormat( (String) comboDateFormat.getSelectedItem() ); + + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + CSVData csvData = new CSVData( csvReader ); + + //System.err.println( "btnProcessActionPerformed customReaderDialog.getFieldSeparatorChar() =" + (char)customReaderDialog.getFieldSeparatorChar() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + + Account account = (Account) comboAccount.getSelectedItem(); + RootAccount rootAccount = main.getRootAccount(); + + transReader.parse( csvData, account, rootAccount ); + csvReader.close(); + + onlineMgr.processDownloadedTxns( account ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "There was a problem importing " + + " selected file, probably because the file format was wrong. Some items " + + "might have been added to your account.", + "Error Importing File", + JOptionPane.ERROR_MESSAGE ); + return; + } + + if ( checkDeleteFile.isSelected() ) + { + try + { + SecureFileDeleter.delete( selectedFile ); + } + catch ( IOException x ) + { + JOptionPane.showMessageDialog( rootPane, "The file was imported properly, " + + "however it could not be erased as requested.", "Cannot Delete File", + JOptionPane.ERROR_MESSAGE ); + return; + } + } + + if ( ! Settings.getBoolean( "success.dialog.shown", false ) ) + { + Settings.setYesNo( "success.dialog.shown", true ); + JOptionPane.showMessageDialog( rootPane, + "The file was imported properly. \n\n" + + "You can view the imported items when you open the account you have \n" + + "selected and click on the 'downloaded transactions' message at the \n" + + "bottom of the screen.", + "Import Successful", JOptionPane.INFORMATION_MESSAGE ); + } + + setVisible( false ); + }//GEN-LAST:event_btnProcessActionPerformed + + private void fileFormatChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_fileFormatChanged + {//GEN-HEADEREND:event_fileFormatChanged + System.err.println( "fileFormatChanged() event --------------- " + evt ); + if ( skipDuringInit ) + { + System.err.println( "fileFormatChanged() skipDuringInit ---------------" ); + return; + } + + if ( evt.getStateChange() == ItemEvent.SELECTED ) + { + System.err.println( "fileFormatChanged() event == ItemEvent.SELECTED ---------------" ); + if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader; + try + { + transReader = (TransactionReader) evt.getItem(); + } + catch ( ClassCastException x ) + { + transReader = null; + } + + processFileFormatChanged( transReader ); + } + + }//GEN-LAST:event_fileFormatChanged + + private void comboFileFormat1fileFormatChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboFileFormat1fileFormatChanged + // TODO add your handling code here: + }//GEN-LAST:event_comboFileFormat1fileFormatChanged + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + customReaderDialog.setVisible( true ); + }//GEN-LAST:event_jButton1ActionPerformed + +private void comboDateFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboDateFormatActionPerformed + //customReaderDialog.setDateFormat( (String)comboDateFormat.getSelectedItem() ); +}//GEN-LAST:event_comboDateFormatActionPerformed + +private void comboFileFormatActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboFileFormatActionPerformed + /* use actionPerformed - not both ! +if ( comboFileFormat.getSelectedItem() instanceof String ) + { + System.err.println( "comboFileFormat is string =" + (String) comboFileFormat.getSelectedItem() + "=" ); + return; + } + + TransactionReader transReader = (TransactionReader) comboFileFormat.getSelectedItem(); + if ( transReader != null ) + { + if ( transReader.isCustomReaderFlag() ) + { + System.err.println( "Have a custom reader. Read config for =" + transReader.toString() + "=" ); + customReaderDialog.getReaderConfig( transReader.toString() ); + } + + String[] formats = transReader.getSupportedDateFormats(); + + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + comboDateFormat.addItem( s ); + } + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog set Date Format Selected =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } +*/ +}//GEN-LAST:event_comboFileFormatActionPerformed + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + ImportDialog dialog = new ImportDialog(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnBrowse; + private javax.swing.JButton btnClose; + private javax.swing.JButton btnProcess; + private javax.swing.ButtonGroup buttonGroup1; + private javax.swing.JCheckBox checkDeleteFile; + private javax.swing.JComboBox comboAccount; + private javax.swing.JComboBox comboDateFormat; + private javax.swing.JComboBox comboFileFormat; + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel lblAccount; + private javax.swing.JLabel lblDateFormat; + private javax.swing.JLabel lblFileFormat; + private javax.swing.JLabel lblMessage; + private javax.swing.JLabel lblSelectFile; + private javax.swing.JRadioButton onlineImportTypeRB; + private javax.swing.JRadioButton regularImportTypeRB; + private javax.swing.JTextField textFilename; + // End of variables declaration//GEN-END:variables + + public void comboFileFormat1AddItem( TransactionReader customReader ) + { + System.err.println( "importDialog() add reader item =" + customReader.toString() + "=" ); + //customReaderCB.addItem( xxx ); + comboFileFormat.addItem( customReader ); + } + + public void comboFileFormat1SetItem( TransactionReader customReader ) + { + System.err.println( "importDialog() comboFileFormat1SetItem() =" + customReader.toString() + "=" ); + //customReaderCB.setSelectedItem( xxx ); + comboFileFormat.setSelectedItem( customReader ); + } + + public void comboDateFormatSetItem( String xxx ) + { + System.err.println( "importDialog() comboDateFormat.setSelectedItem( xxx ) =" + xxx + "=" ); + comboDateFormat.setSelectedItem( xxx ); + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + DefaultComboBoxModel dateFormatModel = new DefaultComboBoxModel(); + System.out.println( "createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "=" ); + dateFormatModel.addElement( dateFormatArg ); + + comboDateFormat.setModel( dateFormatModel ); + + comboDateFormat.setSelectedIndex( 0 ); + } + + public String comboDateFormatGetItem() + { + System.err.println( "importDialog() comboDateFormat.comboDateFormat.getSelectedItem() =" + comboDateFormat.getSelectedItem() + "=" ); + return (String) comboDateFormat.getSelectedItem(); + } + + public void comboDateFormatAddItem( String format ) + { + System.err.println( "importDialog() add date format item =" + comboDateFormat + "=" ); + //customReaderCB.addItem( xxx ); + comboDateFormat.addItem( format ); + } + + public void comboDateFormatSetModel( DefaultComboBoxModel model ) + { + System.err.println( "importDialog() comboDateFormatSetModel()" ); + comboDateFormat.setModel( model ); + } + + private void textFilenameChanged() + { + File newFile = new File( textFilename.getText() ); + + if ( !newFile.equals( selectedFile ) ) + { + selectedFile = newFile; + fileChanged(); + } + } + + public void popComboDateFormatList( String [] formats ) + { + System.err.println( "entered popComboDateFormatList()" ); + comboDateFormat.removeAllItems(); + for ( String s : formats ) + { + System.err.println( "popComboDateFormatList add format >" + s + "<" ); + comboDateFormat.addItem( s ); + } + } + + protected void fileChanged() + { + String message = null; + boolean error = false; + + // see if the file is selected + if ( selectedFile == null || !selectedFile.exists() || !selectedFile.isFile() ) + { + message = "Please select a valid file."; + error = true; + } + + // try reading the file + /* + if ( !error ) + { + try + { + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + //csvReader.setFieldSeparator( '8' ); THIS WORKED ! + csvReader.setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + csvData = new CSVData( csvReader ); + } + catch ( Throwable x ) + { + error = true; + message = "Error reading file."; + Logger.getLogger( ImportDialog.class.getName() ).log( Level.SEVERE, null, x ); + } + } + * */ + + // detect file format + if ( ! error ) + { + TransactionReader.customReaderDialog = customReaderDialog; + + TransactionReader[] fileFormats = TransactionReader.getCompatibleReaders( selectedFile, this ); + + comboFileFormat.removeAllItems(); + for ( TransactionReader reader : fileFormats ) + { + comboFileFormat.addItem( reader ); + } + + if ( fileFormats.length == 0 ) + { + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Unsupported CSV file format."; + } + else if ( fileFormats.length == 1 ) + { + comboFileFormat.setSelectedIndex( 0 ); + comboFileFormat.setEnabled( false ); + } + else + { + comboFileFormat.setEnabled( true ); + } + } + else + { + comboFileFormat.removeAllItems(); + comboFileFormat.addItem( "Format not recognized" ); + comboFileFormat.setEnabled( false ); + } + + if ( !error ) + { + TransactionReader reader = (TransactionReader) comboFileFormat.getSelectedItem(); + String[] formats = reader.getSupportedDateFormats(); + System.err.println( "importDialog().fileChanged() formats =" + formats + "=" ); + + popComboDateFormatList( formats ); + + if ( formats.length == 0 ) + { + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + error = true; + message = "Cannot recognize date format used in the file."; + } + else if ( formats.length == 1 ) + { + comboDateFormat.setSelectedIndex( 0 ); + comboDateFormat.setEnabled( false ); + } + else + { + comboDateFormat.setEnabled( true ); + System.err.println( "importDialog() customReaderDialog.getDateFormatSelected()) =" + customReaderDialog.getDateFormatSelected() + "=" ); + comboDateFormat.setSelectedItem( customReaderDialog.getDateFormatSelected() ); + } + } + else + { + comboDateFormat.removeAllItems(); + comboDateFormat.addItem( "Date format not recognized" ); + comboDateFormat.setEnabled( false ); + } + + btnProcess.setEnabled( !error ); + if ( error ) + { + csvData = null; + } + if ( message != null ) + { + lblMessage.setVisible( true ); + lblMessage.setText( message ); + lblMessage.setForeground( new Color( 255, 0, 51 ) ); + } + else + { + lblMessage.setVisible( false ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/Main.java b/src/com/moneydance/modules/features/mdcsvimporter/Main.java new file mode 100644 index 0000000..3314ffd --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/Main.java @@ -0,0 +1,233 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.controller.FeatureModule; +import com.moneydance.apps.md.controller.FeatureModuleContext; +import com.moneydance.apps.md.model.RootAccount; +import java.awt.Image; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +/** + * + * @author miki + */ +public class Main + extends FeatureModule +{ + private static final int VERSION = 18; + protected static final String VERSION_STRING = " Beta 18"; + private static final String NAME = "CSV Importer"; + private static final String VENDOR = "Stan Towianski, Milutin Jovanović"; + private static final String URL = "http://code.google.com/p/mdcsvimporter/"; + private static final String DESCRIPTION = + "Let's you create configs for say: Discover card, VISA, your private bank, etc... " + + "You denote columns like: -Payment-, -Deposit-, date, amount, memo, etc... " + + "It can test your file, giving you a list of all the readers that can handle your file. " + + "Importing does matching to skip duplicate entries." + ; + private static Image image; + + private ArrayList errCodeList = null; + + { + try + { + image = ImageIO.read( + Main.class.getResourceAsStream( "import.png" ) ); + } + catch ( IOException x ) + { + // ignore error; nothing we can do about it + } + } + + public Main() + { + } + + /* + public static void main(String args[]) + { + String amt = "($157.86)"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + + amt = "$123.86"; + System.out.println( "converted amount =" + amt.replaceAll( "\\((.*)\\)", "-$1" ) ); + } + */ + + @Override + public void init() + { + System.err.println( "name and version =" + NAME + " " + VERSION_STRING + "=" ); + FeatureModuleContext context = getContext(); + if ( context == null ) + { + System.err.println( "*** Error: got context == null" ); + return; + } + + context.registerFeature( this, "import", image, "Import File" ); + } + + RootAccount getRootAccount() + { + FeatureModuleContext context = getContext(); + return context.getRootAccount(); + } + + JFrame getMoneydanceWindow() + { + // Using undocumented feature. This way our windows and dialogs can have a parent, + // and behave more conformingly. Alternative is just returning null. Effects should + // be minor visual inconsistencies. + + FeatureModuleContext context = getContext(); + com.moneydance.apps.md.controller.Main main = + (com.moneydance.apps.md.controller.Main) context; + if ( main == null ) + { + return null; + } + com.moneydance.apps.md.view.gui.MoneydanceGUI gui = + (com.moneydance.apps.md.view.gui.MoneydanceGUI) main.getUI(); + if ( gui == null ) + { + return null; + } + return gui.getTopLevelFrame(); + } + + @Override + public String getName() + { + return NAME; + } + + @Override + public int getBuild() + { + return VERSION; + } + + @Override + public String getDescription() + { + return DESCRIPTION; + } + + @Override + public void invoke( String uri ) + { + /* + uri = ImportDialog.RUN_ARGS_FILE + "=/home/aaa/Downloads/aa-test.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online" + ; + */ + + /* + argsHM.put( "file", "/home/aaa/Downloads/aa-test.csv" ); + argsHM.put( "fileformat", "Discover Card" ); + //argsHM.put( "dateformat", "MM/DD/YYYY" ); + argsHM.put( "importaccount", "IMPORT BANK" ); + argsHM.put( "importtype", "online" ); + argsHM.put( "deletecsvfileflag", null ); + */ + + StringTokenizer tokenizer = new StringTokenizer( uri, "&" ); + HashMap argsHM = new HashMap(); + + //filename="file"&fileformat="file format"&dateformat="date format"&importaccount="my account" + //deletecsvfileflag&importtype="online|regular" + + //int count = tokenizer.countTokens(); + //String url = count + " tokens("; + System.err.println( "uri string =" + uri + "=" ); + + while ( tokenizer.hasMoreTokens() ) + { + //url = url.concat( tokenizer.nextToken() ); + String [] pcs = tokenizer.nextToken().split( "=" ); + System.err.println( "arg token [0] =" + pcs[0] + "= token[1] =" + (pcs.length < 2 ? "" : pcs[1]) + "=" ); + if ( pcs.length > 1 ) + { + if ( pcs[1].startsWith( "\"" ) ) + { + argsHM.put( pcs[0].toLowerCase(), pcs[1].substring( 1, pcs[1].length() - 1 ) ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1].substring( 1, pcs[1].length() - 1 ) + "=" ); + } + else + { + argsHM.put( pcs[0].toLowerCase(), pcs[1] ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + pcs[1] + "=" ); + } + } + else + { + argsHM.put( pcs[0].toLowerCase(), null ); + System.err.println( "arg key =" + pcs[0].toLowerCase() + "= value =" + null + "=" ); + } + } + argsHM.remove( "import" ); // This seems to be passed in and I do not know why. + + ImportDialog dialog = new ImportDialog( this, argsHM ); + + //------- This is for passing in arguments to do auto processing. ------- + errCodeList = dialog.processRunArguments(); + + dialog.setLocationRelativeTo( null ); + + if ( ! dialog.isAutoProcessedAFile() && ! argsHM.containsKey( "junitflag" ) ) + { + dialog.setVisible( true ); + } + } + + public ArrayList getErrCodeList() { + return errCodeList; + } + + @Override + public String getVendorURL() + { + return URL; + } + + @Override + public String getVendor() + { + return VENDOR; + } + + @Override + public Image getIconImage() + { + return image; + } + + public FeatureModuleContext getMainContext() + { + return getContext(); + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide b/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide new file mode 100644 index 0000000..978e989 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.form-hide @@ -0,0 +1,52 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide b/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide new file mode 100644 index 0000000..4472a46 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/OtherActionsDialog.java-hide @@ -0,0 +1,155 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.DateReminderPair; +import com.moneydance.apps.md.model.Reminder; +import com.moneydance.apps.md.model.ReminderSet; +import com.moneydance.apps.md.model.RootAccount; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Iterator; +import java.util.Vector; + +/** + * + * @author stan + */ + + +public class OtherActionsDialog extends javax.swing.JDialog { + + ImportDialog parent = null; + Main main = null; + + /** + * Creates new form otherActionsDialog + */ + //public otherActionsDialog(java.awt.Frame parent, boolean modal) { + public OtherActionsDialog( ImportDialog parent, boolean modal) { + super(parent, modal); + this.parent = parent; + //super(parent, modal); + initComponents(); + } + + public void setMain( Main main ) + { + this.main = main; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + + setTitle("Other Actions"); + + jButton1.setText("Delete Overdue Reminders"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(31, 31, 31) + .addComponent(jButton1) + .addContainerGap(204, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(39, 39, 39) + .addComponent(jButton1) + .addContainerGap(238, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + //java.util.Calendar today = new java.util.Calendar( + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Calendar cal = Calendar.getInstance(); + System.out.println(dateFormat.format(cal.getTime())); + RootAccount rootAccount = main.getRootAccount(); + ReminderSet reminderSet = rootAccount.getReminderSet(); + Vector remindersOverdueVec = reminderSet.getOverdueItems( cal ); + + //get an Iterator object for Vector using iterator() method. + Iterator itr = remindersOverdueVec.iterator(); + + //use hasNext() and next() methods of Iterator to iterate through the elements + System.out.println("Iterating through Vector elements..."); + while(itr.hasNext()) + { + DateReminderPair rem = (DateReminderPair) itr.next(); + //reminderSet.removeReminder( rem ); + + System.out.println( "rem.desc =" + rem. + "=" ); + } + }//GEN-LAST:event_jButton1ActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* + * Set the Nimbus look and feel + */ + // + /* + * If Nimbus (introduced in Java SE 6) is not available, stay with the + * default look and feel. For details see + * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(OtherActionsDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* + * Create and display the dialog + */ + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + OtherActionsDialog dialog = new OtherActionsDialog(null, true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportTblModel.java b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportTblModel.java new file mode 100644 index 0000000..b7cab56 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportTblModel.java @@ -0,0 +1,53 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import java.util.ArrayList; +import javax.swing.table.AbstractTableModel; + +/** + * + * @author stan + */ + + +public class PreviewImportTblModel extends AbstractTableModel +{ + private ArrayListcolNames; + private String[][] data; + + public PreviewImportTblModel( ArrayList colNamesArg, String[][] dataArg ) + { + colNames = colNamesArg; + data = dataArg; + + System.err.println( "row count =" + data.length ); + System.err.println( "col count =" + data[0].length ); + } + + public int getColumnCount() { return data[0].length; } + public int getRowCount() { return data.length;} + public Object getValueAt(int row, int col) + { + //System.err.println( "getValueAt row =" + row + " col =" + col ); + try { + if ( data[row][col] == "" ) + { + //System.err.println( "NOT EXISTS getValueAt row =" + row + " col =" + col ); + } + } + catch( Exception ex ) + { + return ""; + } + return data[row][col]; + } + + public String getColumnName(int col) { + return colNames.get( col ); + } + + /* + public int getColumnCount() { return 10; } + public int getRowCount() { return 10;} + public Object getValueAt(int row, int col) { return new Integer(row*col); } + */ +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.form b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.form new file mode 100644 index 0000000..38321f6 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.form @@ -0,0 +1,55 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ diff --git a/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.java b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.java new file mode 100644 index 0000000..f71dd17 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/PreviewImportWin.java @@ -0,0 +1,243 @@ +package com.moneydance.modules.features.mdcsvimporter; + +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE; +import static com.moneydance.modules.features.mdcsvimporter.formats.CustomReader.DATA_TYPE_IGNORE_REST; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.KeyStroke; + +/** + * + * @author stan + */ + + +public class PreviewImportWin extends javax.swing.JFrame { + + private TransactionReader transReader = null; + private CSVData csvData = null; + + /** + * Creates new form PreviewImportWin + */ + public PreviewImportWin() { + initComponents(); + } + + public void myInit( ImportDialog importDialog, TransactionReader transReaderArg, CSVData csvDataArg, CSVReader csvReader ) + { + System.err.println( "entered PreviewImportWin.myInit()" + "< ==============================" ); + transReader = transReaderArg; + csvData = csvDataArg; + boolean gotError = false; + + try { + if ( transReader.canParse( csvData ) ) + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file works having " + csvData.getData().length + " rows" ); + importDialog.btnProcess.setEnabled( true ); + System.err.println( "=============== at canparse WORKS for >" + transReader.getFormatName() + "< ===============" ); + } + else + { + this.setTitle( "For Reader: " + transReader.toString() + " - Parse file does not work!" ); + importDialog.btnProcess.setEnabled( false ); + System.err.println( "=============== at canparse NOT WORK for >" + transReader.getFormatName() + " at row,col " + + csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + "< ===============" ); + gotError = true; + } + + //csvData.parseIntoLines( transReader.getCustomReaderData().getFieldSeparatorChar() ); + System.err.println( "after parse row count =" + csvData.getData().length ); + System.err.println( "after parse col count =" + (csvData.getData())[0].length ); + + // Find and Insert User DataTypes as a Header row to show if they line up: + + int fieldIndex = 0; + int maxFieldIndex = transReader.getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + ArrayList headerDataTypesList = new ArrayList(); + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = transReader.getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + headerDataTypesList.add( dataTypeExpecting ); + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + transReader.getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + int cnt = x; + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + while ( x > 1 ) + { + headerDataTypesList.add( dataTypeExpecting + "-" + cnt ); + x--; + } + } + else + { + headerDataTypesList.add( dataTypeExpecting ); + } + } + previewImportTbl.setModel( new PreviewImportTblModel( headerDataTypesList, csvData.getData() ) ); + if ( gotError ) + { + //csvData.getCurrentLineIndex() + "," + csvData.getCurrentFieldIndex() + CustomTableCellRenderer customTableCellRenderer = new CustomTableCellRenderer(); + customTableCellRenderer.setForRowCol( csvData.getCurrentLineIndex(), csvData.getCurrentFieldIndex() ); + //previewImportTbl.getColumnModel().getColumn( csvData.getCurrentFieldIndexWithinBounds() ).setCellRenderer( customTableCellRenderer ); + previewImportTbl.setDefaultRenderer( Object.class, customTableCellRenderer ); + } + } + catch (Exception ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + //return false; + } + finally + { + try + { + csvReader.close(); + csvData = null; + transReader = null; + this.setSize( 800, 600 ); + this.setLocationRelativeTo( getRootPane() ); + this.setVisible( true ); + this.validate(); + this.addEscapeListener( this ); + } + catch( Exception fex ) + { + ; + } + } + } + + public static void addEscapeListener(final JFrame win) { + ActionListener escListener = new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //System.err.println( "previewImportWin formWindow dispose()" ); + win.dispose(); + } + }; + + win.getRootPane().registerKeyboardAction(escListener, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + PreviewImportWin dialog = new PreviewImportWin(); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + ArrayList header = new ArrayList(Arrays.asList( "H1", "H2", "H3" ) ); + String[][] data = { + {"User", "Password", "Age"}, + {"1", "2", "3"}, + {"10", "20", "30"}, + }; + + //dialog.myInit( null, null ); + dialog.previewImportTbl.setModel( new PreviewImportTblModel( header, data ) ); + dialog.setSize( 800, 600 ); + dialog.setVisible(true); + dialog.addEscapeListener( dialog ); + } + }); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + jScrollPane1 = new javax.swing.JScrollPane(); + previewImportTbl = new javax.swing.JTable(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + public void windowClosing(java.awt.event.WindowEvent evt) { + formWindowClosing(evt); + } + }); + getContentPane().setLayout(new java.awt.GridBagLayout()); + + previewImportTbl.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String [] { + "Title 1", "Title 2", "Title 3", "Title 4" + } + )); + jScrollPane1.setViewportView(previewImportTbl); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.ipadx = 456; + gridBagConstraints.ipady = 400; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(10, 10, 10, 10); + getContentPane().add(jScrollPane1, gridBagConstraints); + }// //GEN-END:initComponents + + private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing + try { + System.err.println( "previewImportWin formWindowClosing()" ); + } catch (Exception ex) { + Logger.getLogger(PreviewImportWin.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_formWindowClosing + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTable previewImportTbl; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/RegexReader.java b/src/com/moneydance/modules/features/mdcsvimporter/RegexReader.java new file mode 100644 index 0000000..d0200b2 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/RegexReader.java @@ -0,0 +1,373 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author miki + * modified by: Stan Towianski + */ +public class RegexReader extends CSVReader +{ + /** + * Carriage-Return + */ + private static final int CR = 13; + /** + * Line-Feed + */ + private static final int LF = 10; + /** + * Space + */ + private static final int SPACE = 32; + /** + * Tab + */ + private static final int TAB = 8; + /** + * Character used as a separator of individual fields. + */ + private int fieldSeparator = ','; + /** + * Character used to start and end quoted sequences. + */ + private int quoteCharacter = '"'; + /** + * Character used to mark comment lines. + */ + private int commentCharacter = '#'; + /** + * Character used to mark pragma lines. + */ + private int pragmaCharacter = '$'; + /** + * True if the fields values should be trimmed before return. Equivalent of returning + * nextField().trim(). + */ + private boolean trimFields = true; + /** + * True if empty lines should be skipped and not reported as data rows. + */ + private boolean skipEmptyLines = false; + /** + * Reference to the reader. + */ + private Reader reader; + private CustomReaderData customReaderData; + /** + * The last char read from the reader. Also it stores the next character to be parsed. + * <0 if end of file is reached. Code is currently written so that initializing + * this to LF is the proper way to start parsing. + */ + private int lastChar = LF; + /** + * Temporary buffer used to build field values before hey are returned. + */ + private StringBuilder builder = new StringBuilder(); + + private LineNumberReader lineReader; + private String rgLine = ""; + private int rgFieldCnt = 0; + + public RegexReader() + throws IOException + { + } + + /** + * Constructs a new CSV file reader. + * @param reader must be a valid reference to a reader providing CSV data to parse. + * @throws java.io.IOException + */ + public RegexReader( Reader reader, CustomReaderData customReaderData ) + throws IOException + { + if ( reader == null || !reader.ready() ) + { + throw new IllegalArgumentException( "Reader must be a valid object." ); + } + this.reader = reader; + this.customReaderData = customReaderData; + lineReader = new LineNumberReader( reader ); + } + + /** + * Closes the input reader and releases all object references. No other calls to this + * instance should be made. + * @throws java.io.IOException IOException might be thrown by referenced reader. See + * Reader.close(). + */ + public void close() + throws IOException + { + reader.close(); + reader = null; + lastChar = -1; + } + + /** + * Used to move to the next line in the CSV file. It must be called before the each + * line is processed, including before the very first line in the file. Any fields on + * the current line that have not been retrieved, will be skipped. + * @return true if the file contains another line. + * @throws java.io.IOException if data cannot be read. + */ + public boolean nextLine_HIDE() + throws IOException + { + while ( nextField() != null ) + { + } + + // skip EOL; possible combinations are CR, CR+LF, LF + if ( lastChar == CR ) + { + lastChar = reader.read(); + } + if ( lastChar == LF ) + { + lastChar = reader.read(); + } + + // skip whitespace at the beginning + if ( trimFields ) + { + while ( isWhitespace( lastChar ) && !isEof( lastChar ) ) + { + lastChar = reader.read(); + } + } + + // skip comment lines + if ( lastChar == commentCharacter ) + { + do + { + lastChar = reader.read(); + } while ( !isEof( lastChar ) && lastChar != CR && lastChar != LF ); + return nextLine(); + } + + // handle pragma lines + if ( lastChar == pragmaCharacter ) + { + throw new IOException( "Pragma lines (starting with " + pragmaCharacter + + ") are currently not supported. If you need to use this character surround " + + "the field with quotes." ); + } + + // skip empty lines if so requested + if ( skipEmptyLines && isEol( lastChar ) ) + { + return nextLine(); + } + + // end of file + if ( isEof( lastChar ) ) + { + return false; + } + return true; + } + + /** + * Retrieves next field on the current line. If the field value was quoted, the quotes + * are stripped. If the reader has been configured to trim fields, then all whitespaces + * at the beginning and end of the field are stripped before returning. + * @return field value or null if no more fields on the current line. + * @throws java.io.IOException if data cannot be read. + */ + public String nextField() + throws IOException + { + //Pattern and Matcher are used here, not String.matches(regexp), + //since String.matches(regexp) would repeatedly compile the same + //regular expression + //String pat42 = "([^,]*([,]|\\Z)).*"; + //String pat5 = "Check[ ]#(\\d*)[^,]*|([^,]*)([,]|\\Z).*"; + /* was used + String pat42 = "([^,]*([,]|\\Z)).*"; + String pat5 = "(?:Check[ ]#(\\d*)|([^,]*)([,]|\\Z)).*"; + + Pattern regexp = Pattern.compile( pat42 ); + Pattern regexp2 = Pattern.compile( pat5 ); + */ + + ArrayList matcherAl = new ArrayList(); + /* + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp2.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + matcherAl.add( regexp.matcher("") ); + Matcher matcher = regexp.matcher(""); + */ + for ( String patString : customReaderData.getRegexsList() ) + { + matcherAl.add( Pattern.compile( patString ).matcher("") ); + //System.err.println( "patString =" + patString + "=" ); + } + Matcher matcher = matcherAl.get( 0 ); + + String item = null; + + //System.err.println( "\nnextField() fieldSeparator =" + (char)fieldSeparator + "=" ); + +// if ( isEol( lastChar ) || isEof( lastChar ) ) +// { +// //System.err.println( "nextField() return null for Eol or Eof" ); +// return null; +// } + + if ( ! rgLine.isEmpty() ) + { + System.err.println( "\n----- left =" + rgLine + "= use regex =" + matcherAl.get( rgFieldCnt ).pattern() + "=" ); + matcher = (matcherAl.get( rgFieldCnt )); + matcher.reset( rgLine ); //reset the input + if ( matcher.matches() ) + { + //System.err.println("Num groups: " + matcher.groupCount()); + item = matcher.group(1) == null ? "" : matcher.group(1); + rgLine = rgLine.substring( item.length() ); + if ( item.endsWith( "," ) ) + item = item.substring( 0, item.length() - 1 ); + System.err.println( "rgFieldCnt =" + rgFieldCnt + " item >" + item + "< item2 >" + matcher.group(2) + "<" ); + } + else + { + System.err.println("Input does not match pattern."); + rgLine = ""; + return null; + } + rgFieldCnt++; + } + else + { + System.err.println( "No more fields left." ); + rgLine = ""; + return null; + } + + // TODO: skip separator + + if ( trimFields ) + { + System.err.println( "RegexReader return nextField trim =" + item.trim() + "=" ); + return item.trim(); + } + else + { + System.err.println( "RegexReader return nextField =" + item + "=" ); + return item; + } + } + + public boolean nextLine() + throws IOException + //public void regexParseIntoLines(String aFileName) + { + //Path path = Paths.get(aFileName); + try + //( + //BufferedReader reader = Files.newBufferedReader(path, ENCODING); + //LineNumberReader lineReader = new LineNumberReader( reader ); + //) + { + System.err.println( "entered RegexReader.nextLine()" ); + if ((rgLine = lineReader.readLine()) != null) + { + System.err.println( "\n---------- line =" + rgLine + "=" ); + rgFieldCnt = 0; + return true; + } + } + catch (IOException ex){ + ex.printStackTrace(); + } + return false; + } + + public void setFieldSeparator( int fieldSeparator ) + { + //System.err.println( "CSVReader.setFieldSeparator =" + (char)fieldSeparator + "=" ); + this.fieldSeparator = fieldSeparator; + } + + public int getFieldSeparator() + { + return fieldSeparator; + } + + public void setQuoteCharacter( int quoteCharacter ) + { + this.quoteCharacter = quoteCharacter; + } + + public int getQuoteCharacter() + { + return quoteCharacter; + } + + public void setCommentCharacter( int commentCharacter ) + { + this.commentCharacter = commentCharacter; + } + + public int getCommentCharacter() + { + return commentCharacter; + } + + public void setPragmaCharacter( int pragmaCharacter ) + { + this.pragmaCharacter = pragmaCharacter; + } + + public int getPragmaCharacter() + { + return pragmaCharacter; + } + + public void setTrimFields( boolean trimFields ) + { + this.trimFields = trimFields; + } + + public boolean getTrimFields() + { + return trimFields; + } + + public void setSkipEmptyLines( boolean skipEmptyLines ) + { + this.skipEmptyLines = skipEmptyLines; + } + + public boolean getSkipEmptyLines() + { + return skipEmptyLines; + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/SecureFileDeleter.java b/src/com/moneydance/modules/features/mdcsvimporter/SecureFileDeleter.java new file mode 100644 index 0000000..f0e1534 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/SecureFileDeleter.java @@ -0,0 +1,97 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Random; + +/** + * + * @author miki + */ +public class SecureFileDeleter +{ + private static final int CHUNK_SIZE = 65536; + + /** + * Securely deletes the specified file. This is done by overwriting the file three + * times, by 0xFF's, random values and 0's, and finally deleting the file. + * @param file File to delete. + * @throws java.io.IOException IOException is thrown if file does not exist, if it is a directory, + * cannot be written to or if any other IO erroroccurs. + */ + public static void delete( File file ) + throws IOException + { + if ( !file.exists() || !file.isFile() || !file.canWrite() ) + { + throw new IOException( "Unable to securely delete specified file." ); + } + + Random random = new Random(); + byte[] buffer = new byte[CHUNK_SIZE]; + + // fill file with 0xFF + for ( int i = 0; i < CHUNK_SIZE; ++i ) + { + buffer[i] = (byte) 0xFF; + } + long fileLength = file.length(); + OutputStream output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + // fill file with random values + fileLength = file.length(); + output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + random.nextBytes( buffer ); + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + // fill file with 0's + for ( int i = 0; i < CHUNK_SIZE; ++i ) + { + buffer[i] = (byte) 0; + } + fileLength = file.length(); + output = new FileOutputStream( file ); + while ( fileLength > 0 ) + { + int chunkSize = fileLength > CHUNK_SIZE ? CHUNK_SIZE : (int) fileLength; + random.nextBytes( buffer ); + output.write( buffer, 0, chunkSize ); + fileLength -= chunkSize; + } + output.close(); + + if ( !file.delete() ) + { + throw new IOException( "Failed to delete file." ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/Settings.java b/src/com/moneydance/modules/features/mdcsvimporter/Settings.java new file mode 100644 index 0000000..11f23ab --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/Settings.java @@ -0,0 +1,463 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public final class Settings +{ + static HashMap ReaderConfigsHM = null; + static HashMap ReaderHM = null; + static Properties currentProps = new Properties(); + static String emptyArrayProperty = "[,,,, , , , , , ]"; + // static String emptyRegexsArrayProperty = "[\u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F \u001F ]"; + //static String emptyRegexsArrayProperty = "[ a a a a a a a a a ]"; + public static File getFilename() + { + System.err.println( "os.name =" + System.getProperty( "os.name" ) + "=" ); + File moneydanceHome = null; + File moneydanceHome1 = null; + File moneydanceHome2 = null; + File moneydanceHome3 = null; + File moneydanceHome4 = null; + String missingHomeErrMsg = ""; + + if ( System.getProperty( "os.name" ).toLowerCase().startsWith( "mac" ) ) + { + moneydanceHome1 = new File( System.getProperty( "user.home" ) + "/Library/Application Support", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + { + moneydanceHome = moneydanceHome1; + } + else + { + moneydanceHome2 = new File( System.getProperty( "user.home" ) + "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome2 + "=" ); + if ( moneydanceHome2.exists() ) + { + moneydanceHome = moneydanceHome2; + } + else + { + moneydanceHome3 = new File( "/Library/Preferences", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome3 + "=" ); + if ( moneydanceHome3.exists() ) + { + moneydanceHome = moneydanceHome3; + } + else + { + moneydanceHome4 = new File( System.getProperty( "user.home" ) + "/Library", "Moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome4 + "=" ); + if ( moneydanceHome4.exists() ) + moneydanceHome = moneydanceHome4; + } // 3 + } // 2 + } // 1 + + // I am assuming at this point that these Mac folders do exist. + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = "\n\nI looked in these 4 places in this order: \n\n" + + moneydanceHome1 + "\n" + + moneydanceHome2 + "\n" + + moneydanceHome3 + "\n" + + moneydanceHome4 + "\n"; + } + } + else // windows + Linux : test for moneydance folder + { + moneydanceHome1 = new File( System.getProperty( "user.home" ), ".moneydance" ); + System.err.println( "try moneydanceHome folder =" + moneydanceHome1 + "=" ); + if ( moneydanceHome1.exists() ) + moneydanceHome = moneydanceHome1; + + if ( moneydanceHome == null ) + { + System.err.println( "Could not find so assuming moneydanceHome folder =" + moneydanceHome1 + "=" ); + moneydanceHome = moneydanceHome1; + missingHomeErrMsg = ""; //\n\nI looked in this place: \n\n" + //+ moneydanceHome + "\n"; + } + } + + // for all os's + if ( ! moneydanceHome.exists() ) + { + boolean ok = moneydanceHome.mkdirs(); + JOptionPane.showMessageDialog( null, "Importer could not find a Moneydance Home directory so I created one here: \n\n" + moneydanceHome + + missingHomeErrMsg + ); + if ( ! ok ) + { + JOptionPane.showMessageDialog( null, "*** Error creating Moneydance Home directory: \n\n" + moneydanceHome ); + } + } + moneydanceHome = new File( moneydanceHome, "mdcsvimporter.props" ); + + // all systems - moneydanceHome now includes properties file path + try { + if ( ! moneydanceHome.exists() ) + { + moneydanceHome.createNewFile(); + JOptionPane.showMessageDialog( null, "Importer could not find its properties files so I created one here: \n\n" + moneydanceHome + ); + } + } + catch (IOException ex) + { + Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex); + } + + return moneydanceHome; + } + + private static Properties load() + throws IOException + { + currentProps = new Properties(); + + InputStream is; + try + { + is = new FileInputStream( getFilename() ); + } + catch ( FileNotFoundException ex ) + { + return currentProps; // no file is normal condition to start with empty props object + } + try + { + currentProps.load( is ); + } + finally + { + is.close(); + } + return currentProps; + } + + private static void save( Properties props ) + throws IOException + { + OutputStream os = new FileOutputStream( getFilename() ); //, Charset.forName( "UTF-8" ) ); //(String) transReader.getCustomReaderData().getFileEncoding() ) ); + try + { + props.store( os, "MDCSVImporter - Moneydance CSV Importer" ); + } + finally + { + os.close(); + load(); + } + } + + public static String get( boolean loadProps, String name ) + { + try + { + if ( loadProps ) + { + load(); + } + return currentProps.getProperty( name ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + } + + public static String get( boolean loadProps, String name, String defaultValue ) + { + String retVal = get( loadProps, name ); + if ( retVal == null ) + { + return defaultValue; + } + return retVal; + } + + public static void set( String name, String value ) + { + try + { + Properties props = load(); + + setOnly( props, name, value ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void setOnly( Properties props, String name, String value ) + { + // skip if values match (I am sorry for not optimizing the condition, it is early morning...) + String oldValue = props.getProperty( name ); + if ( (oldValue != null && oldValue.equals( value )) || + (value != null && value.equals( oldValue )) ) + { + return; + } + + props.setProperty( name, value ); + } + + public static boolean getBoolean( boolean loadProps, String name ) + { + return getBoolean( loadProps, name, false ); + } + + public static boolean getBoolean( boolean loadProps, String name, boolean defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + if ( value.equalsIgnoreCase( "true" ) || value.equalsIgnoreCase( "yes" ) || + value.equalsIgnoreCase( "1" ) ) + { + return true; + } + else + { + return false; + } + } + + public static void setBoolean( String name, boolean value ) + { + set( name, value ? "true" : "false" ); + } + + public static void setYesNo( String name, boolean value ) + { + set( name, value ? "yes" : "no" ); + } + + public static int getInteger( boolean loadProps, String name ) + { + return getInteger( loadProps, name, 0 ); + } + + public static int getInteger( boolean loadProps, String name, int defaultValue ) + { + String value = get( loadProps, name ); + if ( value == null ) + { + return defaultValue; + } + + return Integer.parseInt( value ); + } + + public static void setInteger( String name, int value ) + { + set( name, Integer.toString( value ) ); + } + + public static HashMap createReaderConfigsHM() + { + ReaderConfigsHM = new HashMap(); + ReaderHM = new HashMap(); + + try + { + Properties props = load(); + + for ( Enumeration enu = props.propertyNames(); enu.hasMoreElements(); ) + { + String key = (String) enu.nextElement(); + System.out.println( "props key =" + key + "=" ); + if ( key.startsWith( "reader:" ) && key.endsWith( ".Name" ) ) + { + String readerName = key.replaceAll( "reader\\:(.*)\\..*", "reader:$1" ); + System.err.println( "readerName >" + readerName + "<" ); + + CustomReaderData customReaderData = new CustomReaderData(); + customReaderData.setReaderName( props.getProperty( readerName + ".Name" ) ); + customReaderData.setFieldSeparatorChar( getInteger( false, readerName + ".FieldSeparator", ',' ) ); + customReaderData.setDateFormatString( props.getProperty( readerName + ".DateFormatString" ) ); + customReaderData.setFileEncoding( props.getProperty( readerName + ".FileEncodingString" ) ); + + customReaderData.setHeaderLines( getInteger( false, readerName + ".HeaderLines", 0 ) ); + customReaderData.setFooterLines( getInteger( false, readerName + ".FooterLines", 0 ) ); + + customReaderData.setAmountCurrencyChar( getInteger( false, readerName + ".AmountCurrencyChar", '$' ) ); + customReaderData.setAmountDecimalSignChar( getInteger( false, readerName + ".AmountDecimalSignChar", '.' ) ); + customReaderData.setAmountGroupingSeparatorChar( getInteger( false, readerName + ".AmountGroupingSeparatorChar", ',' ) ); + customReaderData.setAmountFormat( props.getProperty( readerName + ".AmountFormat" ) ); + customReaderData.setImportReverseOrderFlg( getBoolean( false, readerName + ".ImportReverseOrderFlag", false ) ); + customReaderData.setUseRegexFlag(getBoolean( false, readerName + ".UseRegexFlag", false ) ); + customReaderData.setFilenameMatcher(props.getProperty( readerName + ".FilenameMatcher" ) ); + + //customReaderData.setRegexsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".RegexsList", emptyRegexsArrayProperty ).split( "[\\[\\]a]" ) ) ) ); + //customReaderData.setRegexsList( new ArrayList( 10 ) ); + customReaderData.setRegexsList( new ArrayList(Arrays.asList( "", "", "", "", "", "", "", "", "", "" ) ) ); + customReaderData.setDataTypesList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DataTypesList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + customReaderData.setEmptyFlagsList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".EmptyFlagsList", emptyArrayProperty ).split( "[\\[\\],]" ) ) ) ); + + int max = customReaderData.getDataTypesList().size(); + System.err.println( "props customReaderData.getRegexsList().size() =" + customReaderData.getRegexsList().size() + "= max =" + max ); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getRegexsList().set( c - 1, props.getProperty( readerName + ".RegexsList." + (c-1), "" ) ); + //customReaderData.getRegexsList().set( c - 1,customReaderData.getRegexsList().get( c ).trim() ); + customReaderData.getDataTypesList().set( c - 1,customReaderData.getDataTypesList().get( c ).trim() ); + customReaderData.getEmptyFlagsList().set( c - 1,customReaderData.getEmptyFlagsList().get( c ).trim() ); + } + + /* + if ( props.getProperty( readerName + ".DateFormatList" ) != null ) + { + customReaderData.setDateFormatList( new ArrayList(Arrays.asList( props.getProperty( readerName + ".DateFormatList" ).split( "[\\[\\],]" ) ) ) ); + } + else + { + customReaderData.setDateFormatList( new ArrayList() ); + } + max = customReaderData.getDateFormatList().size(); + for ( int c = 1; c < max; c++ ) + { + customReaderData.getDateFormatList().set( c - 1,customReaderData.getDateFormatList().get( c ).trim() ); + } + */ + System.err.println( "props readerName =" + customReaderData.getReaderName() + "=" ); + System.err.println( "props getFieldSeparatorChar() =" + customReaderData.getFieldSeparatorChar() + "=" ); + System.err.println( "props getFileEncoding() =" + customReaderData.getFileEncoding() + "=" ); + System.err.println( "props getDateFormatString() =" + customReaderData.getDateFormatString()+ "=" ); + System.err.println( "props getHeaderLines() =" + customReaderData.getHeaderLines() + "=" ); + System.err.println( "props getRegexsList() =" + customReaderData.getRegexsList() + "=" ); + System.err.println( "props getDataTypesList() =" + customReaderData.getDataTypesList() + "=" ); + System.err.println( "props getEmptyFlagsList() =" + customReaderData.getEmptyFlagsList() + "=" ); + + ReaderConfigsHM.put( props.getProperty( readerName + ".Name" ), customReaderData ); + + CustomReader customReader = new CustomReader( customReaderData ); + ReaderHM.put( props.getProperty( readerName + ".Name" ), customReader ); + + customReader.createSupportedDateFormats( customReaderData.getDateFormatString() ); + } + } + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + return null; + } + + return ReaderConfigsHM; + } + + public static HashMap getReaderHM() { + return ReaderHM; + } + + public static void setCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + setOnly( props, "reader:" + customReaderData.getReaderName() + ".Name", customReaderData.getReaderName() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".HeaderLines", Integer.toString( customReaderData.getHeaderLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FooterLines", Integer.toString( customReaderData.getFooterLines() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FieldSeparator", Integer.toString( customReaderData.getFieldSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FileEncodingString", customReaderData.getFileEncoding() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatString", customReaderData.getDateFormatString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList", customReaderData.getRegexsListEncoded() ); + for( int c = 0; c < 10; c++ ) + { + setOnly( props, "reader:" + customReaderData.getReaderName() + ".RegexsList." + c, customReaderData.getRegexsListEle( c ) ); + } + setOnly( props, "reader:" + customReaderData.getReaderName() + ".DataTypesList", customReaderData.getDataTypesList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList", customReaderData.getEmptyFlagsList().toString() ); + //setOnly( props, "reader:" + customReaderData.getReaderName() + ".DateFormatList", customReaderData.getDateFormatList().toString() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar", Integer.toString( customReaderData.getAmountCurrencyChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar", Integer.toString( customReaderData.getAmountDecimalSignChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar", Integer.toString( customReaderData.getAmountGroupingSeparatorChar() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".AmountFormat", customReaderData.getAmountFormat() ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag", Boolean.toString( customReaderData.getImportReverseOrderFlg() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".UseRegexFlag", Boolean.toString( customReaderData.getUseRegexFlag() ) ); + setOnly( props, "reader:" + customReaderData.getReaderName() + ".FilenameMatcher", customReaderData.getFilenameMatcher() ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public static void removeCustomReaderConfig( CustomReaderData customReaderData ) + { + try + { + Properties props = load(); + + props.remove( "reader:" + customReaderData.getReaderName() + ".Name" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".HeaderLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FieldSeparator" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatString" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".RegexsList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".DataTypesList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".EmptyFlagsList" ); + //props.remove( "reader:" + customReaderData.getReaderName() + ".DateFormatList" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".FooterLines" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountCurrencyChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountDecimalSignChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountGroupingSeparatorChar" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".AmountFormat" ); + props.remove( "reader:" + customReaderData.getReaderName() + ".ImportReverseOrderFlag" ); + + save( props ); + } + catch ( IOException ex ) + { + Logger.getLogger( Settings.class.getName() ).log( Level.SEVERE, null, ex ); + } + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/TransactionReader.java b/src/com/moneydance/modules/features/mdcsvimporter/TransactionReader.java new file mode 100644 index 0000000..d7255dd --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/TransactionReader.java @@ -0,0 +1,852 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.TransactionSet; +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.model.CurrencyType; +import com.moneydance.apps.md.model.AbstractTxn; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.apps.md.model.OnlineTxnList; +import com.moneydance.apps.md.model.ParentTxn; +import com.moneydance.apps.md.model.SplitTxn; + +import com.moneydance.apps.md.model.TxnSet; +import com.moneydance.apps.md.view.gui.MoneydanceGUI; +import com.moneydance.apps.md.view.gui.OnlineManager; +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public abstract class TransactionReader +{ + private boolean customReaderFlag = false; + private CustomReaderData customReaderData = null; + + protected static ImportDialog importDialog = null; + protected static CustomReaderDialog customReaderDialog = null; + protected static RootAccount rootAccount = null; + + protected CSVData csvData; + protected Account account; + protected String accountNameFromCSV;//for reading account from CSV file + protected String priorAccountNameFromCSV = "";//for efficiency only + protected OnlineTxnList transactionList; + protected TransactionSet txnSet; + protected CurrencyType currency; + protected HashSet tsetMatcherKey = new HashSet(); + protected HashSet tsetFITxnIdMatcherKey = new HashSet(); + //protected HashSet onlineMatcherKey = new HashSet(); + protected int defProtocolId = 999; // per Sean at MD + protected final static String DEFAULT_ENCODING = "UTF-8"; // "UTF-16LE"; "windows-1250"; Preselect this value in Encoding JComboBox. + //protected String fileEncoding = DEFAULT_ENCODING; + protected boolean isUsingCategorynameFlag = false; + + protected abstract boolean canParse( CSVData data ); + + protected abstract boolean parseNext() throws IOException; + +// protected abstract boolean parseNext(OnlineTxn txn) throws IOException; + + protected abstract boolean assignDataToTxn( OnlineTxn txn ) throws IOException; + + public abstract String getFormatName(); + + public abstract String[] getSupportedDateFormats(); + + public abstract void setSupportedDateFormats( String[] supportedDateFormats ); + + public abstract String getDateFormat(); + + public abstract void setDateFormat( String format ); + + //public abstract int getFieldSeparator(); + + //public abstract void setFieldSeparator( int xxx ); + + protected final void throwException( String message ) + throws IOException + { + throw new IOException( message ); + } + + public static void init( CustomReaderDialog customReaderDialogArg, ImportDialog importDialogArg, RootAccount rootAccountArg ) + { + customReaderDialog = customReaderDialogArg; + importDialog = importDialogArg; + rootAccount = rootAccountArg; + } + + protected final void setRootAccount( RootAccount rootAccount ) + { + this.rootAccount = rootAccount; + } + + public final String calcFITxnIdAbstract( AbstractTxn atxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( AbstractTxn ) -------------" ); + //System.err.println( "key.getDescription() =" + atxn.getDescription() + "= atxn.getFiTxnId( 1 ) =" + atxn.getFiTxnId( 1 ) + "=" ); + //System.err.println( "atxn.getFiTxnId( 1 ) [" + k + "] =" + atxn.getFiTxnId( 1 ) + "= atxn.getFiTxnId( 0 ) [" + k + "] =" + atxn.getFiTxnId( 0 ) + "=" ); + //tsetMatcherKey.add( atxn.getFiTxnId( 1 ) ); + + // Here I am manually recreating the FiTxnId that I set on imported txn's because I could not figure + // out how to simply read it. + + + //String tmp = atxn.getDateInt() + ":" + currency.format( atxn.getValue(), '.' ) + ":" + atxn.getDescription() + ":" + atxn.getCheckNumber(); + + // Create a pattern to match comments + //dave Pattern ckNumPat = Pattern.compile("^.*\\\"chknum\\\" = \\\"(.+?)\\\"\n.*$", Pattern.MULTILINE); + // I think I want to stick with (.*) instead of (.+) because I want to catch () either way. Stan + Pattern ckNumPat = Pattern.compile( "^.*\\\"chknum\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + Pattern amtPat = Pattern.compile( "^.*\\\"amt\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + String amt = null; + String origCheckNumber = null; + String desc = null; + + /* + + ol.orig-txn + { "dtinit-int" = "20110824" "name" = "whatever desc" "amt" = "-9824" "fitxnid" = "20110824:-98.24:whatever desc" "dtpstd-int" = "20110824" "dtavail-int" = "20110824" "invst.totalamt" = "-9824" "chknum" = "001234" "ptype" = "1" } + + */ + + String origtxn = atxn.getTag( "ol.orig-txn" ); + //String origCheckNumber = origtxn.replaceAll( ".*\\\"chknum\\\" = \\\"(.*?)\\\"\\\n.*", "$1" ); + + //System.out.println( "\norigtxn ="+origtxn + "=" ); + + // Run some matches + if ( origtxn != null ) + { + Matcher m = ckNumPat.matcher( origtxn ); + if ( m.find() ) + { + origCheckNumber = m.group( 1 ); + //System.out.println("Found orig check num ="+m.group( 1 ) + "=" ); + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + + m = amtPat.matcher( origtxn ); + if ( m.find() ) + { + long lamt = Long.valueOf( m.group( 1 ) ).longValue(); + amt = currency.format( lamt, '.' ); + //System.out.println("Found orig amt ="+m.group( 1 ) + "= formatted =" + amt ); + } + else + { + amt = currency.format( atxn.getValue(), '.' ); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("no orig check num so use getchecknum() ="+origCheckNumber + "=" ); + amt = currency.format( atxn.getValue(), '.' ); + } + + //long value = atxn.getParentTxn().getValue(); + + if ( atxn.getTag( "ol.orig-payee" ) == null ) + { + desc = atxn.getDescription(); + } + else + { + desc = atxn.getTag( "ol.orig-payee" ); + } + + // This new way compare using the ORIGINAL payee and memo fields so if the user changes them, it will still match. Stan + String tmp = atxn.getDateInt() + ":" + amt + + ":" + desc + + ":" + (origCheckNumber == null ? "" : origCheckNumber.replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (atxn.getTag( "ol.orig-memo" ) == null ? "" : atxn.getTag( "ol.orig-memo" )); + + //System.err.println( "calc abstract FITxnld >" + tmp + "<" ); + return tmp; + } + + + public final String calcFITxnId( OnlineTxn onlinetxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( onlinetxn ) -------------" ); + // txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + + String tmp = onlinetxn.getDateInitiatedInt() + ":" + currency.format( onlinetxn.getAmount(), '.' ) + + ":" + (onlinetxn.getName() == null ? "" : onlinetxn.getName() ) // used payeeName once + + ":" + (onlinetxn.getCheckNum() == null ? "" : onlinetxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (onlinetxn.getMemo() == null ? "" : onlinetxn.getMemo() ) + ; + + //System.err.println( "calc online FITxnld >" + tmp + "<" ); + return tmp; + } + + private final void makeSetOfExistingTxns( TxnSet tset ) + throws IOException + { + int k = 0; + for ( AbstractTxn atxn : tset ) + { + String tmp = calcFITxnIdAbstract( atxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + tsetMatcherKey.add( tmp ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( OnlineTxn.PROTO_TYPE_OFX ) ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( defProtocolId ) ); + + k++; + //if ( k > 9 ) + // break; + } + //System.err.println( "\n--------- end: make set of existing account transactions -------------" ); + } + + /* + ************************************************************************************************ + */ + public final void parse( Main main, CSVData csvDataArg, Account accountIn, RootAccount rootAccount ) + throws IOException + { + System.err.println("\n--------- entered TransactionReader().parse() -------------"); + + this.csvData = csvDataArg; + this.rootAccount = rootAccount; + this.txnSet = rootAccount.getTransactionSet(); + this.tsetMatcherKey = new HashSet(); + this.tsetFITxnIdMatcherKey = new HashSet(); + +// //begin testing +// //this is part of what would be needed to match account names +// //using regex or partial matching instead of exact and complete matching. +// HashMap accountMap = new HashMap(); +// Enumeration accountListEnum = rootAccount.getSubAccounts(); +// while (accountListEnum.hasMoreElements()) { +// Account a = (Account)accountListEnum.nextElement(); +// accountMap.put(a.getAccountName(), a); +// } +// //getAllAccountNames - is only path from root to present acct +// //end testing + + System.err.println("\n--------- beg: make set of existing account transactions -------------"); + //System.err.println( "number of trans list =" +this.txnSet.getTransactionsForAccount( account ).getSize() ); + System.err.println("size of txnSet.getAllTxns = " + this.txnSet.getAllTxns().getSize()); + // cannot get just for account because I am putting them into a temp/empty account ! + //Enumeration tenums = this.txnSet.getTransactionsForAccount( account ).getAllTxns(); + TxnSet tset = this.txnSet.getAllTxns(); + + //TODO: refactor this. + //Currently, if the CSV file contains transactions from different accounts + //with different currencies, we don't handle that. However, we could. + //By separating the parsing from the matching, we could easily handle it. + //For now, the account selected on the dialog will provide the currency + //for all accounts. + //Fixing this is a low priority because + // 1) not everyone has multiple accounts in a single file + // 2) most people with multiple accounts will have them in the same currency + //If someone needs multiple currencies and accounts in one file, + //it can be implemented as described above. + this.currency = accountIn.getCurrencyType(); + //TODO: after refacting, call this only after each line of CSV file has been processed + //TODO: parse CSV first, then iterate again to match FITxnId + makeSetOfExistingTxns( tset ); + + /* + while ( tenums.hasMoreElements() ) + { + AbstractTxn key = tenums.nextElement(); + System.err.println( "key.getDescription() =" + key.getDescription() + "= key.getFiTxnId( 0 )" + key.getFiTxnId( 0 ) + "=" ); + tsetMatcherKey.add( key.getFiTxnId( 0 ) ); + } + * + */ + + /* THIS DOES NOT SEEM TO HAVE ENTRIES SO i AM LEAVING IT OUT + int max = transactionList.getTxnCount(); + for ( k = 0; k < max; k++ ) // OnlineTxn onlinetxn : transactionList ) + { + OnlineTxn onlinetxn = transactionList.getTxn( k ); + String tmp = calcFITxnId( onlinetxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + onlineMatcherKey.add( tmp ); + + //if ( k > 9 ) + // break; + } + */ + System.err.println( "\n--------- end: make set of existing account online transactions -------------" ); + + //csvData.reset(); + if ( this instanceof CustomReader ) + { + csvData.parseIntoLines( customReaderData ); + } + else + { + csvData.parseIntoLines( null ); + } + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + csvData.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( csvData.nextLine() ) + { + fileLineCount ++; + if ( ! csvData.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + + csvData.reset(); + //----- Skip Header Lines ----- + System.err.println( "getHeaderCount() =" + getHeaderCount() ); + for ( int hdrCnt = getHeaderCount(); hdrCnt > 0; --hdrCnt ) + { + csvData.nextLine(); // skip the header + System.err.println( "skip header" ); + } + long begAtLine = csvData.getCurrentLineIndex() + 1; + + //testing + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + OnlineManager onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + +// this.account = account; +// this.transactionList = account.getDownloadedTxns(); + long totalProcessed = 0; + long totalAccepted = 0; + long totalRejected = 0; + long totalDuplicates = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + boolean accountMissingError = false; + +// csvData.printFile(); + System.err.println( "ImportReverseOrderFlg(): " + getCustomReaderData().getImportReverseOrderFlg() ); + if ( getCustomReaderData().getImportReverseOrderFlg() ) + { + csvData.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); + // csvData.printFile(); + } + + while ( csvData.nextLine() && totalProcessed < stopAtLine ) + { + accountNameFromCSV = ""; + totalProcessed++; + // System.out.println("calling parseNext..."); + + if ( parseNext() ) + { + if ( null == accountNameFromCSV || accountNameFromCSV.isEmpty() ) + { + System.out.println( "accountNameFromCSV is empty. Used selected acct." ); + this.account = accountIn; + } + else + { + this.account = rootAccount.getAccountByName( accountNameFromCSV ); + System.out.println( "accountNameFromCSV: " + accountNameFromCSV ); + if ( this.account == null ) + { + System.err.println( "ERROR: account is null" ); + //TODO: make new account? + if ( ! accountMissingError ) + { + JOptionPane.showMessageDialog(importDialog, "The account in the CSV file must \nalready exist in Money Dance. \nPlease create it first."); + } + accountMissingError = true; + totalRejected++; + continue; + } + System.out.println( "account.getAccountName(): " + this.account.getAccountName() ); + } + //TODO: per-account currency assignment is unfinished. + //it requires separating parsing logic from matching logic. 2011.11.25 ds + //this.currency = account.getCurrencyType(); + + + // if (null != this.transactionList && + // ! accountNameFromCSV.contentEquals(priorAccountNameFromCSV)) { + // priorAccountNameFromCSV = accountNameFromCSV; + this.transactionList = account.getDownloadedTxns();//TODO: move this out of loop + System.err.println( "tset.getSize() = " + tset.getSize() + " online txns.getSize() = " + transactionList.getTxnCount() ); + + // } + System.out.println("OnlineTxn txn = transactionList.newTxn();"); + OnlineTxn txn = transactionList.newTxn(); + assignDataToTxn( txn ); + txn.setProtocolType( OnlineTxn.PROTO_TYPE_OFX ); + + /* + if ( ! importDialog.isSelectedOnlineImportTypeRB() ) + { + // Flip signs for regular txn's + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + */ + System.err.println( "if (account.balanceIsNegated())" ); + if ( account.balanceIsNegated() ) + { + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + + //System.err.println( "call to calc fitxnid - should be online type" ); + String onlineMatchKey = calcFITxnId( txn ); + txn.setFITxnId( onlineMatchKey ); + + // ! onlineMatcherKey.contains( onlineMatchKey ) && + if ( ! tsetMatcherKey.contains( onlineMatchKey ) && + ! tsetFITxnIdMatcherKey.contains( onlineMatchKey ) + ) + { + System.err.println( "will add transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "= txn.getFIID() =" + txn.getFIID() + "=" ); + // + "\n or onlineMatchKey =" + onlineMatchKey + "=" ); + //System.err.println( "importDialog =" + importDialog + "=" ); + + /* NOTE: This is to convert the online txn to an regular txn. This would let me set categories and tags + * on incoming txn's, but it automatically sets the category to the default account one and I like it + * better using the onlineTxn where it prompts the user to select a category for imported txn's. Stan + */ + if ( importDialog.isSelectedOnlineImportTypeRB() ) + { + System.err.println( "add new onlineTxn" ); + transactionList.addNewTxn( txn ); + } + else + { + System.err.println( "add new parentTxn/splitTxn" ); + ParentTxn pTxn = onlineToParentTxn( account, rootAccount, txn ); + if ( pTxn != null ) + { + txnSet.addNewTxn( pTxn ); + } + } + totalAccepted ++; + // I don't know why, but for now this works here, but not below, after the main loop - Stan. Maybe because of using multiple account names? + System.err.println( "onlineMgr.processDownloadedTxns for account :" + account.getAccountName() ); + onlineMgr.processDownloadedTxns( account ); + } + else + { + System.err.println( "will NOT add Duplicate transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "=" ); + totalDuplicates ++; + } + } // parseNext() + else + { + // need to fixxx that it counts blank lines which it skips, as rejecteds + csvData.printCurrentLine(); + totalRejected++; + } + } // end while() + + JOptionPane.showMessageDialog( importDialog, "Total Records Process: " + totalProcessed + + "\nRecords Imported: " + totalAccepted + + "\nDuplicates Skipped: " + totalDuplicates + + "\nRejected Records: " + totalRejected + ); + + + /** NOTE: This is what I would like to do but I do not understand enough about this + * transactionList and why you create a newTxn() and then later call addNewTxn(). + * newTxn seems to be some kind of 'service' as opposed to a regular object??? Stan + */ + /* + int ans = JOptionPane.showConfirmDialog( importDialog, "Total Records Processed: " + totalProcessed + + "\nNew Records: " + totalAccepted + + "\nDuplicate Records: " + totalDuplicates + + "\nRejected Records: " + totalRejected + + "\n\nDo you want to import the New records ?" + , "Results", JOptionPane.YES_NO_OPTION ); + System.err.println( "ans =" + ans + "= JOptionPane.YES_OPTION =" + JOptionPane.YES_OPTION + "= JOptionPane.NO_OPTION =" + JOptionPane.NO_OPTION + "=" ); + if ( ans == JOptionPane.YES_OPTION ) + { + + OnlineTxnList transactionListCurrent = account.getDownloadedTxns(); + int max = transactionList.getTxnCount(); + System.err.println( "getTxnCount()/max =" + max + "=" ); + + for ( int j = 0; j < max; j ++ ) + { + System.err.println( "transactionList.getTxn( " + j + " ) =" + transactionList.getTxn( j ) + "=" ); + transactionListCurrent.addNewTxn( transactionList.getTxn( j ) ); + } + + + JOptionPane.showMessageDialog( importDialog, totalAccepted + " records were added" ); + } + else + { + JOptionPane.showMessageDialog( importDialog, "No records were added" ); + } + */ + + /* + int max = transactionList.getTxnCount(); + + for ( int j = 0; j < max; j ++ ) + { + transactionList.removeTxn( j ); + } + * + */ + } + + /* + * Note: Create a ParentTxn from a filled out OnlineTxn + */ + // @ Override + protected ParentTxn onlineToParentTxn( Account account, RootAccount rootAccount, OnlineTxn oTxn ) + throws IOException + { + Account category = null; + + String ckNum = oTxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ); + + // Don't know why I have to do this but I had to to make Online and Regular transactions use the same sign. + // actually I noticed that the 'Type of Account' determines the sign of an amount also. + // Bank accounts input as: Payment, Deposit + // Charge accounts input as: Charge, Payment and are reversed sign ! + // I am not going to worry about that at this point. It doesn't really matter. Just define your reader to compensate. + oTxn.setAmount( - oTxn.getAmount() ); + oTxn.setTotalAmount( - oTxn.getTotalAmount() ); + + ParentTxn pTxn = new ParentTxn( oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt() + , ckNum, account, oTxn.getName(), oTxn.getMemo() + , -1, AbstractTxn.STATUS_UNRECONCILED ); + try { + System.err.println( "find category for oTxn.getSubAccountTo() =" + oTxn.getSubAccountTo() + "=" ); + category = getAccount( account, oTxn.getSubAccountTo(), com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct( account ).getAccountName() //rr.getString("default_category"), + , oTxn.getAmount() <= 0 ? Account.ACCOUNT_TYPE_EXPENSE : Account.ACCOUNT_TYPE_INCOME ); + System.err.println( "found category =" + category + "=" ); + + } catch (Exception ex) { + Logger.getLogger(TransactionReader.class.getName()).log(Level.SEVERE, null, ex); + return null; // skip this transaction - do not add + } + + SplitTxn sptxn = new SplitTxn( pTxn, oTxn.getAmount(), oTxn.getAmount(), 1.0 + , category //com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct(account) /* category */ + , pTxn.getDescription(), -1, AbstractTxn.STATUS_UNRECONCILED ); + + sptxn.setIsNew( true ); + pTxn.addSplit( sptxn ); + + pTxn.setIsNew( true ); + + pTxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + sptxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + + return pTxn; + } + + public void setCustomReaderDialog( CustomReaderDialog customReaderDialog ) + { + System.err.println( "custreader set custreaderdialog" ); + this.customReaderDialog = customReaderDialog; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + if ( this.customReaderDialog == null ) + return 0; + else + return this.customReaderDialog.getNumberOfCustomReaderFieldsUsed(); + } + + public static TransactionReader[] getCompatibleReaders( boolean getAllReadersList, File selectedFile, ImportDialog importDialogArg, RootAccount rootAccount ) + { + ArrayList formats = new ArrayList(); +// moving importDialog = importDialogArg; + + System.err.println( "getCompatibleReaders() call cust read canParse()" ); + CSVReader csvReader = null; + + for ( String key : Settings.getReaderHM().keySet() ) + { + TransactionReader transactionReader = Settings.getReaderHM().get( key ); + System.err.println( "\n================ at canparse for transReader >" + key + "< ===============" ); + + try + { + System.err.println( "using fileEncoding >" + transactionReader.getCustomReaderData().getFileEncoding() + "< ===============" ); + if ( transactionReader.getCustomReaderData().getUseRegexFlag() ) + { + System.err.println( "\n================ Regex Reader" ); + csvReader = new RegexReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + else + { + System.err.println( "\n================ Csv Reader" ); + csvReader = new CSVReader( new InputStreamReader( new FileInputStream( selectedFile ), Charset.forName( transactionReader.getCustomReaderData().getFileEncoding() ) ), transactionReader.getCustomReaderData() ); + } + CSVData csvData = new CSVData( csvReader ); + + transactionReader.setRootAccount( rootAccount ); + if ( getAllReadersList ) + { + System.err.println( "=============== add all readers for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else if ( transactionReader.canParse( csvData ) ) + { + System.err.println( "=============== at canparse WORKS for >" + key + "< ===============" ); + formats.add( transactionReader ); + } + else + { + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + } + } + catch ( Throwable x ) + { + System.err.println( "at canparse error reading file !" ); + System.err.println( "=============== at canparse NOT WORK for >" + key + "< ===============" ); + System.err.println( "File Error: " ); + x.printStackTrace(); + } + finally + { + try + { + csvReader.close(); + } + catch( Exception fex ) + { + ; + } + } + } + + /* + if ( customerReaderName != null && ! customerReaderName.equals( "" ) ) +s { + + System.err.println( "at canparse getFieldSeparator() =" + (char)data.getReader().getFieldSeparator() + "=" ); + + //data.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + +//s System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + + customReader.setDateFormat( importDialog.comboDateFormatGetItem() ); + System.err.println( "at canparse importDialog.comboDateFormatGetItem() after set =" + importDialog.comboDateFormatGetItem() + "=" ); + + if ( customReader.canParse( data ) ) + { + formats.add( customReader ); + } + } + + if ( citiBankCanadaReader.canParse( data ) ) + { + formats.add( citiBankCanadaReader ); + } + + if ( ingNetherlandsReader.canParse( data ) ) + { + formats.add( ingNetherlandsReader ); + } + + if ( simpleCreditDebitReader.canParse( data ) ) + { + formats.add( simpleCreditDebitReader ); + } + + if ( wellsFargoReader.canParse( data ) ) + { + formats.add( wellsFargoReader ); + } + */ + + TransactionReader[] retVal = new TransactionReader[formats.size()]; + formats.toArray( retVal ); + return retVal; + } + + @Override + public String toString() + { + return getFormatName(); + } + + //protected abstract boolean haveHeader(); + protected abstract int getHeaderCount(); + + /* + protected String convertParensToMinusSign( String amt ) + { + return amt.replaceAll( "\(.*\)", "-\$1" ); + } + */ + + public boolean isCustomReaderFlag() { + return customReaderFlag; + } + + public void setCustomReaderFlag(boolean customReaderFlag) { + this.customReaderFlag = customReaderFlag; + } + + public CustomReaderData getCustomReaderData() { + return customReaderData; + } + + public void setCustomReaderData(CustomReaderData customReaderData) { + this.customReaderData = customReaderData; + } + + public boolean isUsingCategorynameFlag() { + return isUsingCategorynameFlag; + } + + public void setUsingCategorynameFlag(boolean xx) { + this.isUsingCategorynameFlag = xx; + //System.err.println( "set isUsingCategorynameFlag to =" + isUsingCategorynameFlag + "=" ); + } + + /**************************************************************************************/ + + /** Find and return the ACCOUNT field in the appropriate format. */ + private final Account getAccount( Account account, String categoryName, String defaultAccount, + int defaultAcctType ) + throws Exception + { + //String acctStr = getField(fieldValues, 1 /*ACCOUNT*/, null); + if ( categoryName == null ) return addNewAccount( defaultAccount, account.getCurrencyType(), + rootAccount, "", defaultAcctType, true, -1 ); + //acctStr = acctStr.trim(); + return addNewAccount( categoryName, account.getCurrencyType(), rootAccount, "", + defaultAcctType, true, -1 ); + } + + /************************************************** + * Copied from Text File Importer code with permission from Reilly Technologies, L.L.C. + * I unfortunately do not understand what this code does. + **************************************************/ + + private Account addNewAccount( String accountName, CurrencyType currencyType, + Account parentAccount, String description, + int accountType, boolean lenientMatch, + int currAccountId) + throws Exception + { + if(accountName.indexOf(':')==0 && + parentAccount.getAccountType()==Account.ACCOUNT_TYPE_ROOT) { + accountName = accountName.substring(1); + } + + int colIndex = accountName.indexOf(':'); + String restOfAcctName; + String thisAcctName; + if(colIndex>=0) { + restOfAcctName = accountName.substring(colIndex+1); + thisAcctName = accountName.substring(0,colIndex); + } else { + restOfAcctName = null; + thisAcctName = accountName; + } + + Account newAccount = null; + for(int i=0; i. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.TransactionSet; +import com.moneydance.apps.md.model.Account; +import com.moneydance.apps.md.model.RootAccount; +import com.moneydance.apps.md.model.CurrencyType; +import com.moneydance.apps.md.model.AbstractTxn; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.apps.md.model.OnlineTxnList; +import com.moneydance.apps.md.model.ParentTxn; +import com.moneydance.apps.md.model.SplitTxn; + +import com.moneydance.apps.md.model.TxnSet; +import com.moneydance.modules.features.mdcsvimporter.formats.CustomReader; +import com.moneydance.util.StreamTable; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.JOptionPane; + +/** + * + * @author miki and Stan Towianski + */ +public abstract class TransactionReader +{ + private boolean customReaderFlag = false; + private CustomReaderData customReaderData = null; + + protected static ImportDialog importDialog = null; + protected static CustomReaderDialog customReaderDialog = null; + + protected CSVData csvData; + protected Account account; + protected String accountNameFromCSV;//for reading account from CSV file + protected String priorAccountNameFromCSV = "";//for efficiency only + protected OnlineTxnList transactionList; + protected TransactionSet txnSet; + protected CurrencyType currency; + protected HashSet tsetMatcherKey = new HashSet(); + protected HashSet tsetFITxnIdMatcherKey = new HashSet(); + //protected HashSet onlineMatcherKey = new HashSet(); + protected int defProtocolId = 999; // per Sean at MD + + protected abstract boolean canParse( CSVData data ); + + protected abstract boolean parseNext() throws IOException; + +// protected abstract boolean parseNext(OnlineTxn txn) throws IOException; + + protected abstract boolean assignDataToTxn( OnlineTxn txn ) throws IOException; + + public abstract String getFormatName(); + + public abstract String[] getSupportedDateFormats(); + + public abstract void setSupportedDateFormats( String[] supportedDateFormats ); + + public abstract String getDateFormat(); + + public abstract void setDateFormat( String format ); + + //public abstract int getFieldSeparator(); + + //public abstract void setFieldSeparator( int xxx ); + + protected final void throwException( String message ) + throws IOException + { + throw new IOException( message ); + } + + public final String calcFITxnIdAbstract( AbstractTxn atxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( AbstractTxn ) -------------" ); + //System.err.println( "key.getDescription() =" + atxn.getDescription() + "= atxn.getFiTxnId( 1 ) =" + atxn.getFiTxnId( 1 ) + "=" ); + //System.err.println( "atxn.getFiTxnId( 1 ) [" + k + "] =" + atxn.getFiTxnId( 1 ) + "= atxn.getFiTxnId( 0 ) [" + k + "] =" + atxn.getFiTxnId( 0 ) + "=" ); + //tsetMatcherKey.add( atxn.getFiTxnId( 1 ) ); + + // Here I am manually recreating the FiTxnId that I set on imported txn's because I could not figure + // out how to simply read it. + + + //String tmp = atxn.getDateInt() + ":" + currency.format( atxn.getValue(), '.' ) + ":" + atxn.getDescription() + ":" + atxn.getCheckNumber(); + + // Create a pattern to match comments + //dave Pattern ckNumPat = Pattern.compile("^.*\\\"chknum\\\" = \\\"(.+?)\\\"\n.*$", Pattern.MULTILINE); + Pattern ckNumPat = Pattern.compile( "^.*\\\"chknum\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + Pattern amtPat = Pattern.compile( "^.*\\\"amt\\\" = \\\"(.*?)\\\"\n.*$", Pattern.MULTILINE ); + String amt = null; + String origCheckNumber = null; + String desc = null; + + /* + + ol.orig-txn + { "dtinit-int" = "20110824" "name" = "whatever desc" "amt" = "-9824" "fitxnid" = "20110824:-98.24:whatever desc" "dtpstd-int" = "20110824" "dtavail-int" = "20110824" "invst.totalamt" = "-9824" "chknum" = "001234" "ptype" = "1" } + + */ + + String origtxn = atxn.getTag( "ol.orig-txn" ); + //String origCheckNumber = origtxn.replaceAll( ".*\\\"chknum\\\" = \\\"(.*?)\\\"\\\n.*", "$1" ); + + //System.out.println( "\norigtxn ="+origtxn + "=" ); + + // Run some matches + if ( origtxn != null ) + { + Matcher m = ckNumPat.matcher( origtxn ); + if ( m.find() ) + { + origCheckNumber = m.group( 1 ); + //System.out.println("Found orig check num ="+m.group( 1 ) + "=" ); + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + + m = amtPat.matcher( origtxn ); + if ( m.find() ) + { + long lamt = Long.valueOf( m.group( 1 ) ).longValue(); + amt = currency.format( lamt, '.' ); + //System.out.println("Found orig amt ="+m.group( 1 ) + "= formatted =" + amt ); + } + else + { + amt = currency.format( atxn.getValue(), '.' ); + //System.out.println("have orig-txn but no check num so use getchecknum() ="+origCheckNumber + "=" ); + } + } + else + { + origCheckNumber = atxn.getCheckNumber(); + //System.out.println("no orig check num so use getchecknum() ="+origCheckNumber + "=" ); + amt = currency.format( atxn.getValue(), '.' ); + } + + //long value = atxn.getParentTxn().getValue(); + + if ( atxn.getTag( "ol.orig-payee" ) == null ) + { + desc = atxn.getDescription(); + } + else + { + desc = atxn.getTag( "ol.orig-payee" ); + } + + // This new way compare using the ORIGINAL payee and memo fields so if the user changes them, it will still match. Stan + String tmp = atxn.getDateInt() + ":" + amt + + ":" + desc + + ":" + (origCheckNumber == null ? "" : origCheckNumber.replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (atxn.getTag( "ol.orig-memo" ) == null ? "" : atxn.getTag( "ol.orig-memo" )); + + //System.err.println( "calc abstract FITxnld >" + tmp + "<" ); + return tmp; + } + + + public final String calcFITxnId( OnlineTxn onlinetxn ) + throws IOException + { + //System.err.println( "\n--------- entered TransactionReader().calcFITxnId( onlinetxn ) -------------" ); + // txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + + String tmp = onlinetxn.getDateInitiatedInt() + ":" + currency.format( onlinetxn.getAmount(), '.' ) + + ":" + (onlinetxn.getName() == null ? "" : onlinetxn.getName() ) // used payeeName once + + ":" + (onlinetxn.getCheckNum() == null ? "" : onlinetxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ) ) // strip leading 0's + + ":" + (onlinetxn.getMemo() == null ? "" : onlinetxn.getMemo() ) + ; + + //System.err.println( "calc online FITxnld >" + tmp + "<" ); + return tmp; + } + + private final void makeSetOfExistingTxns(TxnSet tset) throws IOException + { + int k = 0; + for ( AbstractTxn atxn : tset ) + { + String tmp = calcFITxnIdAbstract( atxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + tsetMatcherKey.add( tmp ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( OnlineTxn.PROTO_TYPE_OFX ) ); + tsetFITxnIdMatcherKey.add( atxn.getFiTxnId( defProtocolId ) ); + + k++; + //if ( k > 9 ) + // break; + } + System.err.println( "\n--------- end: make set of existing account transactions -------------" ); + } + + long totalAccepted = 0; + + public final void parse(Main main, CSVData csvDataArg, Account accountIn, RootAccount rootAccount) + throws IOException { + System.err.println("\n--------- entered TransactionReader().parse() -------------"); + + this.txnSet = rootAccount.getTransactionSet(); + +// //begin testing +// //this is part of what would be needed to match account names +// //using regex or partial matching instead of exact and complete matching. +// HashMap accountMap = new HashMap(); +// Enumeration accountListEnum = rootAccount.getSubAccounts(); +// while (accountListEnum.hasMoreElements()) { +// Account a = (Account)accountListEnum.nextElement(); +// accountMap.put(a.getAccountName(), a); +// } +// //getAllAccountNames - is only path from root to present acct +// //end testing + + System.err.println("\n--------- beg: make set of existing account transactions -------------"); + //System.err.println( "number of trans list =" +this.txnSet.getTransactionsForAccount( account ).getSize() ); + System.err.println("size of txnSet.getAllTxns = " + this.txnSet.getAllTxns().getSize()); + // cannot get just for account because I am putting them into a temp/empty account ! + //Enumeration tenums = this.txnSet.getTransactionsForAccount( account ).getAllTxns(); + TxnSet tset = this.txnSet.getAllTxns(); + + //TODO: refactor this. + //Currently, if the CSV file contains transactions from different accounts + //with different currencies, we don't handle that. However, we could. + //By separating the parsing from the matching, we could easily handle it. + //For now, the account selected on the dialog will provide the currency + //for all accounts. + //Fixing this is a low priority because + // 1) not everyone has multiple accounts in a single file + // 2) most people with multiple accounts will have them in the same currency + //If someone needs multiple currencies and accounts in one file, + //it can be implemented as described above. + this.currency = accountIn.getCurrencyType(); + //TODO: after refacting, call this only after each line of CSV file has been processed + //TODO: parse CSV first, then iterate again to match FITxnId + makeSetOfExistingTxns(tset); + + /* + while ( tenums.hasMoreElements() ) + { + AbstractTxn key = tenums.nextElement(); + System.err.println( "key.getDescription() =" + key.getDescription() + "= key.getFiTxnId( 0 )" + key.getFiTxnId( 0 ) + "=" ); + tsetMatcherKey.add( key.getFiTxnId( 0 ) ); + } + * + */ + + /* THIS DOES NOT SEEM TO HAVE ENTRIES SO i AM LEAVING IT OUT + int max = transactionList.getTxnCount(); + for ( k = 0; k < max; k++ ) // OnlineTxn onlinetxn : transactionList ) + { + OnlineTxn onlinetxn = transactionList.getTxn( k ); + String tmp = calcFITxnId( onlinetxn ); + + //System.err.println( "tmp string [" + k + "] =" + tmp + "=" ); + onlineMatcherKey.add( tmp ); + + //if ( k > 9 ) + // break; + } + System.err.println( "\n--------- end: make set of existing account online transactions -------------" ); + */ + + this.csvData = csvDataArg; + //csvData.reset(); + if ( this instanceof CustomReader ) + { + csvData.parseIntoLines( customReaderData.getFieldSeparatorChar() ); + } + else + { + csvData.parseIntoLines( 0 ); + } + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + //----- Skip Header Lines ----- + //TODO: refactor so that CustomReader uses same logic as other readers (see below). + //2011.11.25 ds + if ( this instanceof CustomReader ) + { +// int skipHeaderLines = customReaderDialog.getHeaderLines(); + int skipHeaderLines = getCustomReaderData().getHeaderLines(); + for ( int i = 0; i < skipHeaderLines; i++ ) + { + System.err.println( "skip header for customReader" ); + csvData.nextLine(); + } + } + else + { + for (int hdrCnt = getHeaderCount(); hdrCnt > 0; --hdrCnt) + { + csvData.nextLine(); // skip the header + System.err.println("skip header"); + } + } + + //testing + com.moneydance.apps.md.controller.Main mainApp = + (com.moneydance.apps.md.controller.Main) main.getMainContext(); + OnlineManager onlineMgr = new OnlineManager( (MoneydanceGUI) mainApp.getUI() ); + +// this.account = account; +// this.transactionList = account.getDownloadedTxns(); + this.tsetMatcherKey = new HashSet(); + this.tsetFITxnIdMatcherKey = new HashSet(); + long totalProcessed = 0; + totalAccepted = 0; + long totalRejected = 0; + long totalDuplicates = 0; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + boolean accountMissingError = false; + + while ( csvData.nextLine() ) + { + accountNameFromCSV = ""; + totalProcessed++; +// System.out.println("calling parseNext..."); + if (parseNext()) { + if (null == accountNameFromCSV || accountNameFromCSV.isEmpty()) { + System.out.println("accountNameFromCSV is empty. Used selected acct."); + this.account = accountIn; + } else { + this.account = rootAccount.getAccountByName(accountNameFromCSV); + System.out.println("accountNameFromCSV: " + accountNameFromCSV); + if (this.account == null) { + System.err.println("ERROR: account is null"); + //TODO: make new account? + if (!accountMissingError) { + JOptionPane.showMessageDialog(importDialog, "The account in the CSV file must \nalready exist in Money Dance. \nPlease create it first."); + } + accountMissingError = true; + totalRejected++; + continue; + } + System.out.println("account.getAccountName(): " + this.account.getAccountName()); + } + //TODO: per-account currency assignment is unfinished. + //it requires separating parsing logic from matching logic. 2011.11.25 ds + //this.currency = account.getCurrencyType(); + + +// if (null != this.transactionList && +// !accountNameFromCSV.contentEquals(priorAccountNameFromCSV)) { +// priorAccountNameFromCSV = accountNameFromCSV; + this.transactionList = account.getDownloadedTxns();//TODO: move this out of loop + System.err.println("tset.getSize() = " + tset.getSize() + " online txns.getSize() = " + transactionList.getTxnCount()); + +// } + System.out.println("OnlineTxn txn = transactionList.newTxn();"); + OnlineTxn txn = transactionList.newTxn(); + assignDataToTxn(txn); + txn.setProtocolType(OnlineTxn.PROTO_TYPE_OFX); + + /* + if ( ! importDialog.isSelectedOnlineImportTypeRB() ) + { + // Flip signs for regular txn's + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + */ + System.err.println("if (account.balanceIsNegated())"); + if ( account.balanceIsNegated() ) + { + txn.setAmount( -txn.getAmount() ); + txn.setTotalAmount( -txn.getAmount() ); + } + + //System.err.println( "call to calc fitxnid - should be online type" ); + String onlineMatchKey = calcFITxnId( txn ); + txn.setFITxnId( onlineMatchKey ); + + // ! onlineMatcherKey.contains( onlineMatchKey ) && + if ( ! tsetMatcherKey.contains( onlineMatchKey ) && + ! tsetFITxnIdMatcherKey.contains( onlineMatchKey ) + ) + { + System.err.println( "will add transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "= txn.getFIID() =" + txn.getFIID() + "=" ); + // + "\n or onlineMatchKey =" + onlineMatchKey + "=" ); + //System.err.println( "importDialog =" + importDialog + "=" ); + + /* NOTE: This is to convert the online txn to an regular txn. This would let me set categories and tags + * on incoming txn's, but it automatically sets the category to the default account one and I like it + * better using the onlineTxn where it prompts the user to select a category for imported txn's. Stan + */ + if ( importDialog.isSelectedOnlineImportTypeRB() ) + { + System.err.println( "add new onlineTxn" ); + transactionList.addNewTxn( txn ); + } + else + { + System.err.println( "add new parentTxn/splitTxn" ); + ParentTxn pTxn = onlineToParentTxn( account, rootAccount, txn ); + txnSet.addNewTxn( pTxn ); + } + totalAccepted ++; + System.err.println("onlineMgr.processDownloadedTxns:" + account.getAccountName()); + onlineMgr.processDownloadedTxns( account ); + } + else + { + System.err.println( "will NOT add Duplicate transaction with txn.getFITxnId( ) =" + txn.getFITxnId( ) + "=" ); + totalDuplicates ++; + } + } + else + { + csvData.printCurrentLine(); + totalRejected++; + } + } + + JOptionPane.showMessageDialog( importDialog, "Total Records Process: " + totalProcessed + + "\nRecords Imported: " + totalAccepted + + "\nDuplicates Skipped: " + totalDuplicates + + "\nRejected Records: " + totalRejected + ); + + + /** NOTE: This is what I would like to do but I do not understand enough about this + * transactionList and why you create a newTxn() and then later call addNewTxn(). + * newTxn seems to be some kind of 'service' as opposed to a regular object??? Stan + */ + /* + int ans = JOptionPane.showConfirmDialog( importDialog, "Total Records Processed: " + totalProcessed + + "\nNew Records: " + totalAccepted + + "\nDuplicate Records: " + totalDuplicates + + "\nRejected Records: " + totalRejected + + "\n\nDo you want to import the New records ?" + , "Results", JOptionPane.YES_NO_OPTION ); + System.err.println( "ans =" + ans + "= JOptionPane.YES_OPTION =" + JOptionPane.YES_OPTION + "= JOptionPane.NO_OPTION =" + JOptionPane.NO_OPTION + "=" ); + if ( ans == JOptionPane.YES_OPTION ) + { + + OnlineTxnList transactionListCurrent = account.getDownloadedTxns(); + int max = transactionList.getTxnCount(); + System.err.println( "getTxnCount()/max =" + max + "=" ); + + for ( int j = 0; j < max; j ++ ) + { + System.err.println( "transactionList.getTxn( " + j + " ) =" + transactionList.getTxn( j ) + "=" ); + transactionListCurrent.addNewTxn( transactionList.getTxn( j ) ); + } + + + JOptionPane.showMessageDialog( importDialog, totalAccepted + " records were added" ); + } + else + { + JOptionPane.showMessageDialog( importDialog, "No records were added" ); + } + */ + + /* + int max = transactionList.getTxnCount(); + + for ( int j = 0; j < max; j ++ ) + { + transactionList.removeTxn( j ); + } + * + */ + } + + /* + * Note: Create a ParentTxn from a filled out OnlineTxn + */ + // @ Override + protected ParentTxn onlineToParentTxn( Account account, RootAccount rootAccount, OnlineTxn oTxn ) + throws IOException + { + Account category = null; + + String ckNum = oTxn.getCheckNum().replaceAll( "^0*(.*)", "$1" ); + + ParentTxn pTxn = new ParentTxn( oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt(), oTxn.getDateInitiatedInt() + , ckNum, account, oTxn.getName(), oTxn.getMemo() + , -1, AbstractTxn.STATUS_UNRECONCILED ); + + SplitTxn sptxn = new SplitTxn( pTxn, oTxn.getAmount(), oTxn.getAmount(), 1.0 + , com.moneydance.apps.md.model.AccountUtil.getDefaultCategoryForAcct(account) /* category */ + , pTxn.getDescription(), -1, AbstractTxn.STATUS_UNRECONCILED ); + + sptxn.setIsNew( true ); + pTxn.addSplit( sptxn ); + + pTxn.setIsNew( true ); + + pTxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + sptxn.setFiTxnId( defProtocolId, oTxn.getFITxnId( ) ); + + return pTxn; + } + + public void setCustomReaderDialog( CustomReaderDialog customReaderDialog ) + { + System.err.println( "custreader set custreaderdialog" ); + this.customReaderDialog = customReaderDialog; + } + + public int getNumberOfCustomReaderFieldsUsed() + { + if ( this.customReaderDialog == null ) + return 0; + else + return this.customReaderDialog.getNumberOfCustomReaderFieldsUsed(); + } + + public static TransactionReader[] getCompatibleReaders( File selectedFile, ImportDialog importDialogArg ) + { + ArrayList formats = new ArrayList(); + importDialog = importDialogArg; + + System.err.println( "getCompatibleReaders() call cust read canParse()" ); + + for ( String key : Settings.getReaderHM().keySet() ) + { + TransactionReader transactionReader = Settings.getReaderHM().get( key ); + System.err.println( "at canparse for transReader =" + key + "=" ); + + try + { + CSVReader csvReader = new CSVReader( new FileReader( selectedFile ) ); + CSVData csvData = new CSVData( csvReader ); + + if ( transactionReader.canParse( csvData ) ) + { + System.err.println( "------- at canparse WORKS for =" + key + "=" ); + formats.add( transactionReader ); + } + else + { + System.err.println( "------- at canparse not work for =" + key + "=" ); + } + csvReader.close(); + } + catch ( Throwable x ) + { + System.err.println( "at canparse error reading file !" ); + } + } + + /* + if ( customerReaderName != null && ! customerReaderName.equals( "" ) ) + { + + System.err.println( "at canparse getFieldSeparator() =" + (char)data.getReader().getFieldSeparator() + "=" ); + + //data.getReader().setFieldSeparator( customReaderDialog.getFieldSeparatorChar() ); + //System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + +//s System.err.println( "at canparse getFieldSeparator() after set =" + (char)data.getReader().getFieldSeparator() + "=" ); + + customReader.setDateFormat( importDialog.comboDateFormatGetItem() ); + System.err.println( "at canparse importDialog.comboDateFormatGetItem() after set =" + importDialog.comboDateFormatGetItem() + "=" ); + + if ( customReader.canParse( data ) ) + { + formats.add( customReader ); + } + } + + if ( citiBankCanadaReader.canParse( data ) ) + { + formats.add( citiBankCanadaReader ); + } + + if ( ingNetherlandsReader.canParse( data ) ) + { + formats.add( ingNetherlandsReader ); + } + + if ( simpleCreditDebitReader.canParse( data ) ) + { + formats.add( simpleCreditDebitReader ); + } + + if ( wellsFargoReader.canParse( data ) ) + { + formats.add( wellsFargoReader ); + } + */ + + TransactionReader[] retVal = new TransactionReader[formats.size()]; + formats.toArray( retVal ); + return retVal; + } + + @Override + public String toString() + { + return getFormatName(); + } + + //protected abstract boolean haveHeader(); + protected abstract int getHeaderCount(); + + /* + protected String convertParensToMinusSign( String amt ) + { + return amt.replaceAll( "\(.*\)", "-\$1" ); + } + */ + + public boolean isCustomReaderFlag() { + return customReaderFlag; + } + + public void setCustomReaderFlag(boolean customReaderFlag) { + this.customReaderFlag = customReaderFlag; + } + + public CustomReaderData getCustomReaderData() { + return customReaderData; + } + + public void setCustomReaderData(CustomReaderData customReaderData) { + this.customReaderData = customReaderData; + } + +} + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/all-wcprops b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/all-wcprops new file mode 100644 index 0000000..f43b426 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 80 +/svn/!svn/ver/35/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats +END +INGNetherlandsReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE +END +YodleeReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 103 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE +END +SimpleCreditDebitReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 114 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE +END +BbvaCompassBankReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 112 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE +END +CitiBankCanadaReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 111 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE +END +CustomReader.java +K 25 +svn:wc:ra_dav:version-url +V 98 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/CustomReader.java +END +WellsFargoReader.java-HIDE +K 25 +svn:wc:ra_dav:version-url +V 107 +/svn/!svn/ver/97/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/entries b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/entries new file mode 100644 index 0000000..8ad04ff --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/entries @@ -0,0 +1,410 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/src/com/moneydance/modules/features/mdcsvimporter/formats +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T23:40:41.147656Z +35 +Jovanovic.Milutin + + + + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +BbvaCompassBankReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +BbvaCompassBankReader.java-HIDE +file +97 + + + +2011-11-25T22:07:53.000000Z +5898f39b41c50154e1d392581c3f4277 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +6550 + +CitiBankCanadaReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +CitiBankCanadaReader.java-HIDE +file +97 + + + +2012-01-11T05:19:42.000000Z +0e09ad75a47ba70ed16f86e96b746e1c +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +4745 + +CustomReader.java +file +97 + + + +2014-12-29T23:18:52.604000Z +95b2cd7a8c2f6e1fc10e4ed186a42995 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com +has-props + + + + + + + + + + + + + + + + + + + + +37757 + +INGNetherlandsReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +INGNetherlandsReader.java-HIDE +file +97 + + + +2012-01-11T05:20:19.000000Z +c6ddc36880e3cbbbdeb9d190d0bfe405 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +5948 + +SimpleCreditDebitReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +SimpleCreditDebitReader.java-HIDE +file +97 + + + +2012-01-11T05:20:47.000000Z +1a47aac4854182d5357d0c863602a89d +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +5799 + +WellsFargoReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +WellsFargoReader.java-HIDE +file +97 + + + +2012-01-11T05:21:00.000000Z +8b96c62465beec8d41fc3eb5ee2bdaed +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +4797 + +YodleeReader.java +file +97 + + + + + + + + + + + + + + + + + + + +deleted + +YodleeReader.java-HIDE +file +97 + + + +2011-11-26T23:48:56.000000Z +855c35db1116ca2727b21819573fe1d0 +2014-12-31T18:41:56.724592Z +97 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +8516 + diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/prop-base/CustomReader.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/prop-base/CustomReader.java.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/prop-base/CustomReader.java.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java-HIDE.svn-base new file mode 100644 index 0000000..b709611 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java-HIDE.svn-base @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class BbvaCompassBankReader + extends TransactionReader { + + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CHECKNUM = "check #"; + private static final String CREDIT = "credit (+)"; + private static final String DEBIT = "debit (-)"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String checknum; + private String debit; + private String credit; + private static final int headerRows = 5; + + @Override + public boolean canParse(CSVData data) { +// System.out.println("enter BbvaCompassBankReader.canParse"); + try { + data.parseIntoLines(0); + } catch (IOException ex) { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + for (int i = 0; i < headerRows -1; i++) { + data.nextLine(); + if (null == data) { + continue; + } + //this next statement raises an exception - don't use it + //System.out.println("BbvaReader:skip: " + data.printCurrentLine()); + } + + boolean retVal = data.nextLine() + && data.nextField() && DATE.equalsIgnoreCase(data.getField()) + && data.nextField() && DESCRIPTION.equalsIgnoreCase(data.getField()) + && data.nextField() && CHECKNUM.equalsIgnoreCase(data.getField()) + && data.nextField() && DEBIT.equalsIgnoreCase(data.getField()) + && data.nextField() && CREDIT.equalsIgnoreCase(data.getField()) + && !data.nextField(); + + // find guessable date formats + if (retVal) { + DateGuesser guesser = new DateGuesser(); + while (data.nextLine()) { + if (data.nextField()) { + guesser.checkDateString(data.getField()); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if (dateFormatString == null + || !find(compatibleDateFormats, dateFormatString)) { + setDateFormat(guesser.getBestFormat()); + } + } + System.out.println("BbvaCompassBankReader.dateFormat = " + getDateFormat()); + System.out.println("BbvaCompassBankReader.canParse = " + String.valueOf(retVal)); + return retVal; + } + + @Override + public String getFormatName() { + return "BBVA Compass Bank NA"; + } + + @Override + protected boolean parseNext() throws IOException { + System.out.println("enter BbvaCompassBankReader parseNext"); + csvData.nextField(); + dateString = csvData.getField(); + if (dateString == null || dateString.length() == 0) { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + checknum = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + if (credit == null && debit == null) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are null."); + throwException("Invalid line"); + } + + if (credit.length() == 0 && debit.length() == 0) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are empty."); + throwException("Credit and debit fields are both empty."); + } + System.out.println("exit BbvaCompassBankReader parseNext"); + return true; + } + + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + System.out.println("enter BbvaCompassBankReader assignDataToTxn"); + long amount = 0; + try { + double amountDouble; + if (credit.length() > 0) { + System.out.println("credit = " + String.valueOf(credit)); + amountDouble = StringUtils.parseDoubleWithException(credit, '.'); + } else { + System.out.println("credit.length() <= 0"); + amountDouble = -StringUtils.parseDoubleWithException(debit, '.'); + } + System.out.println("amountDouble = " + String.valueOf(amountDouble)); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + + int date = dateFormat.parseInt(dateString); + + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setMemo(description); + txn.setCheckNum(checknum); + // MOVED to TransactionReader so everyone creates it the same way. + //txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + //for temp testing. TODO: remove next line after testing. 2011.11.25 ds + txn.setRefNum(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + System.out.println("exit BbvaCompassBankReader assignDataToTxn"); + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() { + return dateFormatString; + } + + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + if (!format.equals(dateFormatString)) { + dateFormat = new CustomDateFormat(format); + dateFormatString = format; + } + } + + private static boolean find(String[] compatibleDateFormats, String dateFormatString) { + if (dateFormatString == null) { + return false; + } + + for (String s : compatibleDateFormats) { + if (dateFormatString.equals(dateFormatString)) { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() { + return headerRows; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java.netbeans-base new file mode 100644 index 0000000..b709611 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/BbvaCompassBankReader.java.netbeans-base @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class BbvaCompassBankReader + extends TransactionReader { + + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CHECKNUM = "check #"; + private static final String CREDIT = "credit (+)"; + private static final String DEBIT = "debit (-)"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String checknum; + private String debit; + private String credit; + private static final int headerRows = 5; + + @Override + public boolean canParse(CSVData data) { +// System.out.println("enter BbvaCompassBankReader.canParse"); + try { + data.parseIntoLines(0); + } catch (IOException ex) { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + for (int i = 0; i < headerRows -1; i++) { + data.nextLine(); + if (null == data) { + continue; + } + //this next statement raises an exception - don't use it + //System.out.println("BbvaReader:skip: " + data.printCurrentLine()); + } + + boolean retVal = data.nextLine() + && data.nextField() && DATE.equalsIgnoreCase(data.getField()) + && data.nextField() && DESCRIPTION.equalsIgnoreCase(data.getField()) + && data.nextField() && CHECKNUM.equalsIgnoreCase(data.getField()) + && data.nextField() && DEBIT.equalsIgnoreCase(data.getField()) + && data.nextField() && CREDIT.equalsIgnoreCase(data.getField()) + && !data.nextField(); + + // find guessable date formats + if (retVal) { + DateGuesser guesser = new DateGuesser(); + while (data.nextLine()) { + if (data.nextField()) { + guesser.checkDateString(data.getField()); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if (dateFormatString == null + || !find(compatibleDateFormats, dateFormatString)) { + setDateFormat(guesser.getBestFormat()); + } + } + System.out.println("BbvaCompassBankReader.dateFormat = " + getDateFormat()); + System.out.println("BbvaCompassBankReader.canParse = " + String.valueOf(retVal)); + return retVal; + } + + @Override + public String getFormatName() { + return "BBVA Compass Bank NA"; + } + + @Override + protected boolean parseNext() throws IOException { + System.out.println("enter BbvaCompassBankReader parseNext"); + csvData.nextField(); + dateString = csvData.getField(); + if (dateString == null || dateString.length() == 0) { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + checknum = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + if (credit == null && debit == null) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are null."); + throwException("Invalid line"); + } + + if (credit.length() == 0 && debit.length() == 0) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are empty."); + throwException("Credit and debit fields are both empty."); + } + System.out.println("exit BbvaCompassBankReader parseNext"); + return true; + } + + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + System.out.println("enter BbvaCompassBankReader assignDataToTxn"); + long amount = 0; + try { + double amountDouble; + if (credit.length() > 0) { + System.out.println("credit = " + String.valueOf(credit)); + amountDouble = StringUtils.parseDoubleWithException(credit, '.'); + } else { + System.out.println("credit.length() <= 0"); + amountDouble = -StringUtils.parseDoubleWithException(debit, '.'); + } + System.out.println("amountDouble = " + String.valueOf(amountDouble)); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + + int date = dateFormat.parseInt(dateString); + + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setMemo(description); + txn.setCheckNum(checknum); + // MOVED to TransactionReader so everyone creates it the same way. + //txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + //for temp testing. TODO: remove next line after testing. 2011.11.25 ds + txn.setRefNum(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + System.out.println("exit BbvaCompassBankReader assignDataToTxn"); + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() { + return dateFormatString; + } + + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + if (!format.equals(dateFormatString)) { + dateFormat = new CustomDateFormat(format); + dateFormatString = format; + } + } + + private static boolean find(String[] compatibleDateFormats, String dateFormatString) { + if (dateFormatString == null) { + return false; + } + + for (String s : compatibleDateFormats) { + if (dateFormatString.equals(dateFormatString)) { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() { + return headerRows; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java-HIDE.svn-base new file mode 100644 index 0000000..4223077 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java-HIDE.svn-base @@ -0,0 +1,159 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class CitiBankCanadaReader + extends TransactionReader +{ + private static final String TRANSACTION_DATE = "transaction date"; + private static final String POSTING_DATE = "posting date"; + private static final String DESCRIPTION = "description"; + private static final String AMOUNT = "amount"; + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String description; +// private long amount; +// private int transactionDate; + private String transactionDateString; +// private int postingDate; + private String postingDateString; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && TRANSACTION_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && POSTING_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && AMOUNT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "CitiBank Canada"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + transactionDateString = csvData.getField(); + if ( transactionDateString.equalsIgnoreCase( "Date downloaded:" ) ) + { // skip the footer line + return false; + } + + csvData.nextField(); + postingDateString = csvData.getField(); + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + amountString = csvData.getField(); + if ( amountString == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int transactionDate = dateFormat.parseInt( transactionDateString ); + int postingDate = dateFormat.parseInt( postingDateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( postingDate + ":" + amountString + ":" + description ); + txn.setDatePostedInt( postingDate ); + txn.setDateInitiatedInt( transactionDate ); + txn.setDateAvailableInt( postingDate ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java.netbeans-base new file mode 100644 index 0000000..4223077 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CitiBankCanadaReader.java.netbeans-base @@ -0,0 +1,159 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class CitiBankCanadaReader + extends TransactionReader +{ + private static final String TRANSACTION_DATE = "transaction date"; + private static final String POSTING_DATE = "posting date"; + private static final String DESCRIPTION = "description"; + private static final String AMOUNT = "amount"; + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String description; +// private long amount; +// private int transactionDate; + private String transactionDateString; +// private int postingDate; + private String postingDateString; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && TRANSACTION_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && POSTING_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && AMOUNT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "CitiBank Canada"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + transactionDateString = csvData.getField(); + if ( transactionDateString.equalsIgnoreCase( "Date downloaded:" ) ) + { // skip the footer line + return false; + } + + csvData.nextField(); + postingDateString = csvData.getField(); + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + amountString = csvData.getField(); + if ( amountString == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int transactionDate = dateFormat.parseInt( transactionDateString ); + int postingDate = dateFormat.parseInt( postingDateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( postingDate + ":" + amountString + ":" + description ); + txn.setDatePostedInt( postingDate ); + txn.setDateInitiatedInt( transactionDate ); + txn.setDateAvailableInt( postingDate ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.netbeans-base new file mode 100644 index 0000000..49399f9 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.netbeans-base @@ -0,0 +1,885 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.CustomReaderData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +/** + * + * @author Stan Towianski August 2011 + */ +public class CustomReader extends TransactionReader +{ + public static final String DATA_TYPE_BLANK = ""; + public static final String DATA_TYPE_IGNORE = "ignore"; + public static final String DATA_TYPE_IGNORE_REST = "ignore rest"; + public static final String DATA_TYPE_PAYMENT = "-Payment-"; + public static final String DATA_TYPE_DEPOSIT = "-Deposit-"; + public static final String DATA_TYPE_DATE = "date"; + public static final String DATA_TYPE_DATE_AVAILABLE = "date available"; + public static final String DATA_TYPE_DATE_INITIATED = "date initiated"; + public static final String DATA_TYPE_DATE_POSTED = "date posted"; + public static final String DATA_TYPE_DATE_PURCHASED = "date purchased"; + public static final String DATA_TYPE_CHECK_NUMBER = "check number"; + public static final String DATA_TYPE_DESCRIPTION = "description"; + public static final String DATA_TYPE_MEMO = "memo"; + public static final String DATA_TYPE_ACCOUNT_NAME = "account name"; + public static final String DATA_TYPE_CATEGORY_NAME = "category name"; + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + + private String dateFormatStringSelected = DATE_FORMAT_US; + + private static String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT_US + , DATE_FORMAT_EU + , DATE_FORMAT_JP + , DATE_FORMAT_INTN + }; + + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT_US ); + //private CustomDateFormat dateFormat; + + //private String[] compatibleDateFormats; + private String dateFormatString; + + private long amount = 0; + private int date = 0; + private int dateAvailable = 0; + private int dateInitiated = 0; + private int datePosted = 0; + private int datePurchased = 0; + private String description = ""; + private String checkNumber = ""; + private String phoneString; + private String memo; + private String accountName; + private String categoryName; + + public CustomReader( CustomReaderData customReaderData ) + { + setCustomReaderData( customReaderData ); + setCustomReaderFlag( true ); + } + + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + System.err.println( "\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------" ); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat( dateFormatArg ); + } + + @Override + public boolean canParse( CSVData data ) + { + System.err.println( "--------- entered customerReader().canParse() as type =" + getFormatName() + "= -------------" ); + try { + data.parseIntoLines( getCustomReaderData() ); + } + catch (IOException ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + //if ( data.getReader() == null ) + // System.err.println( "data.getReader() == null" ); + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( getCustomReaderData().getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + data.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( data.nextLine() ) + { + fileLineCount ++; + if ( ! data.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + data.reset(); + int skipHeaderLines = getHeaderCount(); + System.err.println( "skip any Header Lines =" + skipHeaderLines ); + for ( int i = 0; i < skipHeaderLines; i++ ) + { + System.err.println( "skip header line" ); + data.nextLine(); + } + long begAtLine = data.getCurrentLineIndex() + 1; + + boolean retVal = true; + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = getCustomReaderData().getDateFormatString().toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat, Locale.ENGLISH ); + sdf.setLenient( false ); + + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "->" + jDateFormat + "<-" ); + + long totalProcessed = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + +// data.printFile(); +// data.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); +// data.printFile(); + + while ( retVal && data.nextLine() && totalProcessed < stopAtLine ) + { + totalProcessed++; + System.err.println( "------- next line ---------------" ); + if ( ! data.hasZeroFields() ) + { + continue; // skip empty lines + } + + if ( ! data.hasEnoughFieldsPerCurrentLine( maxFieldIndex - 1 ) ) + { + System.err.println( "Have too few fields. Needed >= " + ( maxFieldIndex - 2 ) ); + data.printCurrentLine(); + retVal = false; + } + + int fieldIndex = 0; + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + for ( ; retVal && fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + data.nextField(); +// if ( ! data.nextField() ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but have no data left." ); +// retVal = false; +// break; +// } + String fieldString = data.getField(); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + data.nextField(); + fieldString = data.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( DATA_TYPE_BLANK ) ) ) + { + if ( ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + retVal = false; + break; + } + else + { + System.err.println( "ok to skip this blank field" ); + continue; + } + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) + ) + { + System.err.println( "date >" + fieldString + "<" ); + + /* + // find guessable date formats + // if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + guesser.checkDateString( fieldString ); + + //compatibleDateFormats = guesser.getPossibleFormats(); + SUPPORTED_DATE_FORMATS = guesser.getPossibleFormats(); + importDialog.popComboDateFormatList( SUPPORTED_DATE_FORMATS ); + if ( dateFormatStringSelected == null || + ! findDateFormat( SUPPORTED_DATE_FORMATS, dateFormatStringSelected ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + */ + /**/ +// if ( dateFormat.parseInt( fieldString ) != dateFormat.parseInt( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + System.err.println( "fieldString =" + fieldString + "= date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + try { + sdf.parse( fieldString ); // This seems to catch jan 32 -> feb 01 which I do not want to allow. + + // won't work when fieldString is 3/5/2012 because it will compare incorrectly to created 03/05/2012 and don't know how to fix that! ! +// if ( ! sdf.fieldString.equals( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + } + catch (ParseException e) { + System.err.println( "canParse() parseException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + catch (IllegalArgumentException e) { + System.err.println( "canParse() IllegalArgumentException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + + /**/ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) // was only amount before + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "[^0-9]*(.*)", "$1" ); // strip leading non-digits + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + //StringUtils.parseDoubleWithException( fieldString, '.' ); + String tmp = fieldString.replace( '$', '0' ); + //System.err.println( "check modified amountString 1 >" + tmp + "<" ); + tmp = tmp.replace( '-', '0' ); + //System.err.println( "check modified amountString 2 >" + tmp + "<" ); + tmp = tmp.replaceAll( " ", "" ); + //System.err.println( "check modified amountString 3 >" + tmp + "<" ); + tmp = tmp.replaceAll( ",", "" ); + //System.err.println( "check modified amountString 4 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\.", "" ); + //System.err.println( "check modified amountString 5 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\d", "" ); + System.err.println( "check modified amountString 6 >" + tmp + "<" ); + //Number number = NumberFormat.getNumberInstance().parse( tmp ); + if ( tmp.equals( "" ) ) //number instanceof Double || number instanceof Long ) + { + System.err.println( "ok number" ); + ; + } + else + { + retVal = false; + break; + } + } + catch ( Exception x ) + { + retVal = false; + break; + } + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO) ) + { + System.err.println( "memo >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// retVal = false; +// break; + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + setUsingCategorynameFlag( true ); + +// if ( rootAccount.getAccountByName( categoryName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// retVal = false; +//// break; +// } + //this.categoryNameFromCSV = categoryName; + } + } // end for + } + + System.err.println( "canParse will return =" + retVal ); + return retVal; + } + + @Override + public String getFormatName() + { + return getCustomReaderData().getReaderName(); + } + + /* + * Note: This really parses a whole line at a time. + */ + @Override + protected boolean parseNext() throws IOException + { + amount = 0; + date = 0; + dateAvailable = 0; + dateInitiated = 0; + datePosted = 0; + datePurchased = 0; + description = ""; + checkNumber = ""; + phoneString = ""; + memo = ""; + accountName = ""; + + int fieldIndex = 0; + int amountDecimalSignChar = getCustomReaderData().getAmountDecimalSignChar(); + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "=" ); + + System.err.println( "----------------------" ); + if ( ! csvData.hasZeroFields() ) + { + System.err.println( "skip empty line" ); + return false; // skip empty lines + } + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= EmptyFlagsList = " + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + "=" ); + + csvData.nextField(); + String fieldString = csvData.getField(); + System.err.println( "fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + csvData.nextField(); + fieldString = csvData.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( "" ) ) + && ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + .equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) ) + { + System.err.println( "date >" + fieldString + "<" ); + + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + date = dateFormat.parseInt( fieldString ); + // I thought the format was giving incorrect dates for 2/5/2011 so I started doing my own thing. I later + // found out the method I am calling uses an MD method which is working, and my new stuff was not so I left it out. Stan +// Date gotDate = parseDateToInt( fieldString, getCustomReaderData().getDateFormatString() ); // part of my new stuff not being used. +// date = getIntDate( gotDate ); +// System.err.println( "new date int =" + getIntDate( gotDate ) + "= new date formatted >" + giveFormattedDate( gotDate, getCustomReaderData().getDateFormatString() ) + "<" ); + +// txn.setDatePostedInt( date ); +// txn.setDateInitiatedInt( date ); +// txn.setDateAvailableInt( date ); + /* + if ( !date.equals( dateFormat.format( dateFormat.parseInt( csvData.getField() ) ) ) ) + { + retVal = false; + break; + } + */ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) ) + { + System.err.println( "dateAvailable >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateAvailable = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED) ) + { + System.err.println( "dateInitiated >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateInitiated = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) ) + { + System.err.println( "datePosted >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePosted = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) ) + { + System.err.println( "datePurchased >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePurchased = dateFormat.parseInt( fieldString ); + } + else if ( ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + && + ! ( fieldString == null || fieldString.equals( "" ) ) ) + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + fieldString = StringUtils.stripNonNumbers( fieldString, (char)amountDecimalSignChar ); + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + double amountDouble = StringUtils.parseDoubleWithException( fieldString, (char)amountDecimalSignChar ); + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) ) + { + amount += currency.getLongValue( amountDouble ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + { + System.err.println( "flip sign for deposit" ); + amount -= currency.getLongValue( amountDouble ); + } + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } +// txn.setAmount( amount ); +// txn.setTotalAmount( amount ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CHECK_NUMBER ) ) + { + //origCheckNumber = fieldString; + /* changed matching to use original check number which contained leading 0's so go back to using that. Stan + if ( fieldString != null ) + { + // NOTE: I had to do this because I could set ck # = 004567 but get() returns 4567 so matching would not work. Stan + fieldString = fieldString.replaceAll( "^0*(.*)", "$1" ); + } + */ + System.err.println( "check number >" + fieldString + "<" ); + checkNumber = fieldString; +// txn.setCheckNum( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); +// txn.setName( fieldString ); + description = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO ) ) + { + System.err.println( "memo >" + fieldString + "<" ); + memo = fieldString; +// txn.setMemo( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag in phone field >" + fieldString + "<" ); + // storing it into phone field for now since onlinetxn cannot handle tags. A kludge for now. Stan +// txn.setPhone( fieldString ); + phoneString = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); + return false; // skip this line + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + +// if ( rootAccount.getAccountByName( accountName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// return false; // skip this line +// } +// this.accountNameFromCSV = accountName; + } + } // end for + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); +// System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); + + return true; + } + + public Date parseDateToInt( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse(dateStr); + System.err.println( "parseDateToInt() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return ddd; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return ddd; + } + return ddd; + } + + public String convertMmmFormattedDate( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse( dateStr ); + System.err.println( "convertMmmFormattedDate() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + + jDateFormat = jDateFormat.replace( "MMM", "MM" ); // convert MMM Jan to MM number 1 + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return dateStr; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return dateStr; + } + return sdf.format( ddd ); + } + + public int getIntDate( Date gotDate ) + { + Calendar cal = Calendar.getInstance(); + cal.setTime(gotDate); + return (cal.get( Calendar.YEAR ) * 10000) + (cal.get( Calendar.MONTH ) * 100) + cal.get( Calendar.DAY_OF_MONTH ); + } + + public String giveFormattedDate( Date ddd, String format ) + { + StringBuffer sss = new StringBuffer(); + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + if ( ddd == null ) + return ""; + + //StringBuffer buf = sdf.format( ddd ); + return sdf.format( ddd ); + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + + // --- set a default date to be used if particular dates are not set ---s + if ( date == 0 ) + { + if ( dateInitiated != 0 ) + { + date = dateInitiated; + } + else if ( datePurchased != 0 ) + { + date = datePurchased; + } + else if ( datePosted != 0 ) + { + date = datePosted; + } + else if ( dateAvailable != 0 ) + { + date = dateAvailable; + } + else + { + System.err.println( "*** Error: No Date field is set !" ); + throwException( "*** Error: No Date field is set !" ); + } + } + + if ( dateAvailable != 0 ) + { + txn.setDateAvailableInt( dateAvailable ); + } + else + { + txn.setDateAvailableInt( date ); + } + + if ( dateInitiated != 0 ) + { + txn.setDateInitiatedInt( dateInitiated ); + } + else + { + txn.setDateInitiatedInt( date ); + } + + if ( datePosted != 0 ) + { + txn.setDatePostedInt( datePosted ); + } + else + { + txn.setDatePostedInt( date ); + } + + if ( datePurchased != 0 ) + { + txn.setDatePurchasedInt( datePurchased ); + } + else + { + txn.setDatePurchasedInt( date ); + } + +// System.err.println( "date >" + date + "<" ); +// System.err.println( "date >" + txn.getDateAvailableInt() + "<" ); +// System.err.println( "date >" + txn.getDateInitiatedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePostedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePurchasedInt() + "<" ); + + txn.setCheckNum( checkNumber ); + txn.setName( description ); + txn.setMemo( memo ); + txn.setPhone( phoneString ); + txn.setSubAccountTo( categoryName ); // Hopefully this is ok to use as I do not know the MD api. + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) +// + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + //System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + // + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); +//(date == 0 ? datePurchased : date) + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public String getDateFormat() + { + System.err.println( "customReader getDateFormat() >" + dateFormatStringSelected + "<" ); + return dateFormatStringSelected; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + System.err.println( "setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "=" ); + if ( ! format.equals( dateFormatStringSelected ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatStringSelected = format; + } + + /* + dateFormatStringSelected = getCustomReaderData().getDateFormatString(); + System.err.println( "customReader setDateFormat() =" + dateFormatStringSelected + "<" ); + System.err.println( "customReader customReaderDialog.getDateFormatSelected() >" + getCustomReaderData().getDateFormatString() + "<" ); + dateFormat = new CustomDateFormat( getCustomReaderData().getDateFormatString() ); + */ + + /* + if ( !DATE_FORMAT_US.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + * + */ + } + + private static boolean findDateFormat( String[] compatibleDateFormats, String dateFormatStringArg ) + { + if ( dateFormatStringArg == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( s.equals( dateFormatStringArg ) ) + { + return true; + } + } + + return false; + } + +// @Override +// public void setFieldSeparatorChar( int xxx) { +// fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); +// } +// +// @Override +// public int getFieldSeparatorChar() { +// return fieldSeparator; +// } + + + @Override + protected int getHeaderCount() + { + return getCustomReaderData().getHeaderLines(); + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.svn-base new file mode 100644 index 0000000..49399f9 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/CustomReader.java.svn-base @@ -0,0 +1,885 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.CustomReaderData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +/** + * + * @author Stan Towianski August 2011 + */ +public class CustomReader extends TransactionReader +{ + public static final String DATA_TYPE_BLANK = ""; + public static final String DATA_TYPE_IGNORE = "ignore"; + public static final String DATA_TYPE_IGNORE_REST = "ignore rest"; + public static final String DATA_TYPE_PAYMENT = "-Payment-"; + public static final String DATA_TYPE_DEPOSIT = "-Deposit-"; + public static final String DATA_TYPE_DATE = "date"; + public static final String DATA_TYPE_DATE_AVAILABLE = "date available"; + public static final String DATA_TYPE_DATE_INITIATED = "date initiated"; + public static final String DATA_TYPE_DATE_POSTED = "date posted"; + public static final String DATA_TYPE_DATE_PURCHASED = "date purchased"; + public static final String DATA_TYPE_CHECK_NUMBER = "check number"; + public static final String DATA_TYPE_DESCRIPTION = "description"; + public static final String DATA_TYPE_MEMO = "memo"; + public static final String DATA_TYPE_ACCOUNT_NAME = "account name"; + public static final String DATA_TYPE_CATEGORY_NAME = "category name"; + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + + private String dateFormatStringSelected = DATE_FORMAT_US; + + private static String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT_US + , DATE_FORMAT_EU + , DATE_FORMAT_JP + , DATE_FORMAT_INTN + }; + + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT_US ); + //private CustomDateFormat dateFormat; + + //private String[] compatibleDateFormats; + private String dateFormatString; + + private long amount = 0; + private int date = 0; + private int dateAvailable = 0; + private int dateInitiated = 0; + private int datePosted = 0; + private int datePurchased = 0; + private String description = ""; + private String checkNumber = ""; + private String phoneString; + private String memo; + private String accountName; + private String categoryName; + + public CustomReader( CustomReaderData customReaderData ) + { + setCustomReaderData( customReaderData ); + setCustomReaderFlag( true ); + } + + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + System.err.println( "\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------" ); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat( dateFormatArg ); + } + + @Override + public boolean canParse( CSVData data ) + { + System.err.println( "--------- entered customerReader().canParse() as type =" + getFormatName() + "= -------------" ); + try { + data.parseIntoLines( getCustomReaderData() ); + } + catch (IOException ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + //if ( data.getReader() == null ) + // System.err.println( "data.getReader() == null" ); + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( getCustomReaderData().getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + data.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( data.nextLine() ) + { + fileLineCount ++; + if ( ! data.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + data.reset(); + int skipHeaderLines = getHeaderCount(); + System.err.println( "skip any Header Lines =" + skipHeaderLines ); + for ( int i = 0; i < skipHeaderLines; i++ ) + { + System.err.println( "skip header line" ); + data.nextLine(); + } + long begAtLine = data.getCurrentLineIndex() + 1; + + boolean retVal = true; + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = getCustomReaderData().getDateFormatString().toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat, Locale.ENGLISH ); + sdf.setLenient( false ); + + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "->" + jDateFormat + "<-" ); + + long totalProcessed = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + +// data.printFile(); +// data.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); +// data.printFile(); + + while ( retVal && data.nextLine() && totalProcessed < stopAtLine ) + { + totalProcessed++; + System.err.println( "------- next line ---------------" ); + if ( ! data.hasZeroFields() ) + { + continue; // skip empty lines + } + + if ( ! data.hasEnoughFieldsPerCurrentLine( maxFieldIndex - 1 ) ) + { + System.err.println( "Have too few fields. Needed >= " + ( maxFieldIndex - 2 ) ); + data.printCurrentLine(); + retVal = false; + } + + int fieldIndex = 0; + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + for ( ; retVal && fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + data.nextField(); +// if ( ! data.nextField() ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but have no data left." ); +// retVal = false; +// break; +// } + String fieldString = data.getField(); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + data.nextField(); + fieldString = data.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( DATA_TYPE_BLANK ) ) ) + { + if ( ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + retVal = false; + break; + } + else + { + System.err.println( "ok to skip this blank field" ); + continue; + } + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) + ) + { + System.err.println( "date >" + fieldString + "<" ); + + /* + // find guessable date formats + // if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + guesser.checkDateString( fieldString ); + + //compatibleDateFormats = guesser.getPossibleFormats(); + SUPPORTED_DATE_FORMATS = guesser.getPossibleFormats(); + importDialog.popComboDateFormatList( SUPPORTED_DATE_FORMATS ); + if ( dateFormatStringSelected == null || + ! findDateFormat( SUPPORTED_DATE_FORMATS, dateFormatStringSelected ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + */ + /**/ +// if ( dateFormat.parseInt( fieldString ) != dateFormat.parseInt( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + System.err.println( "fieldString =" + fieldString + "= date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + try { + sdf.parse( fieldString ); // This seems to catch jan 32 -> feb 01 which I do not want to allow. + + // won't work when fieldString is 3/5/2012 because it will compare incorrectly to created 03/05/2012 and don't know how to fix that! ! +// if ( ! sdf.fieldString.equals( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + } + catch (ParseException e) { + System.err.println( "canParse() parseException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + catch (IllegalArgumentException e) { + System.err.println( "canParse() IllegalArgumentException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + + /**/ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) // was only amount before + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "[^0-9]*(.*)", "$1" ); // strip leading non-digits + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + //StringUtils.parseDoubleWithException( fieldString, '.' ); + String tmp = fieldString.replace( '$', '0' ); + //System.err.println( "check modified amountString 1 >" + tmp + "<" ); + tmp = tmp.replace( '-', '0' ); + //System.err.println( "check modified amountString 2 >" + tmp + "<" ); + tmp = tmp.replaceAll( " ", "" ); + //System.err.println( "check modified amountString 3 >" + tmp + "<" ); + tmp = tmp.replaceAll( ",", "" ); + //System.err.println( "check modified amountString 4 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\.", "" ); + //System.err.println( "check modified amountString 5 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\d", "" ); + System.err.println( "check modified amountString 6 >" + tmp + "<" ); + //Number number = NumberFormat.getNumberInstance().parse( tmp ); + if ( tmp.equals( "" ) ) //number instanceof Double || number instanceof Long ) + { + System.err.println( "ok number" ); + ; + } + else + { + retVal = false; + break; + } + } + catch ( Exception x ) + { + retVal = false; + break; + } + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO) ) + { + System.err.println( "memo >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// retVal = false; +// break; + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + setUsingCategorynameFlag( true ); + +// if ( rootAccount.getAccountByName( categoryName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// retVal = false; +//// break; +// } + //this.categoryNameFromCSV = categoryName; + } + } // end for + } + + System.err.println( "canParse will return =" + retVal ); + return retVal; + } + + @Override + public String getFormatName() + { + return getCustomReaderData().getReaderName(); + } + + /* + * Note: This really parses a whole line at a time. + */ + @Override + protected boolean parseNext() throws IOException + { + amount = 0; + date = 0; + dateAvailable = 0; + dateInitiated = 0; + datePosted = 0; + datePurchased = 0; + description = ""; + checkNumber = ""; + phoneString = ""; + memo = ""; + accountName = ""; + + int fieldIndex = 0; + int amountDecimalSignChar = getCustomReaderData().getAmountDecimalSignChar(); + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "=" ); + + System.err.println( "----------------------" ); + if ( ! csvData.hasZeroFields() ) + { + System.err.println( "skip empty line" ); + return false; // skip empty lines + } + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= EmptyFlagsList = " + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + "=" ); + + csvData.nextField(); + String fieldString = csvData.getField(); + System.err.println( "fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + csvData.nextField(); + fieldString = csvData.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( "" ) ) + && ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + .equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) ) + { + System.err.println( "date >" + fieldString + "<" ); + + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + date = dateFormat.parseInt( fieldString ); + // I thought the format was giving incorrect dates for 2/5/2011 so I started doing my own thing. I later + // found out the method I am calling uses an MD method which is working, and my new stuff was not so I left it out. Stan +// Date gotDate = parseDateToInt( fieldString, getCustomReaderData().getDateFormatString() ); // part of my new stuff not being used. +// date = getIntDate( gotDate ); +// System.err.println( "new date int =" + getIntDate( gotDate ) + "= new date formatted >" + giveFormattedDate( gotDate, getCustomReaderData().getDateFormatString() ) + "<" ); + +// txn.setDatePostedInt( date ); +// txn.setDateInitiatedInt( date ); +// txn.setDateAvailableInt( date ); + /* + if ( !date.equals( dateFormat.format( dateFormat.parseInt( csvData.getField() ) ) ) ) + { + retVal = false; + break; + } + */ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) ) + { + System.err.println( "dateAvailable >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateAvailable = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED) ) + { + System.err.println( "dateInitiated >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateInitiated = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) ) + { + System.err.println( "datePosted >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePosted = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) ) + { + System.err.println( "datePurchased >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePurchased = dateFormat.parseInt( fieldString ); + } + else if ( ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + && + ! ( fieldString == null || fieldString.equals( "" ) ) ) + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + fieldString = StringUtils.stripNonNumbers( fieldString, (char)amountDecimalSignChar ); + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + double amountDouble = StringUtils.parseDoubleWithException( fieldString, (char)amountDecimalSignChar ); + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) ) + { + amount += currency.getLongValue( amountDouble ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + { + System.err.println( "flip sign for deposit" ); + amount -= currency.getLongValue( amountDouble ); + } + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } +// txn.setAmount( amount ); +// txn.setTotalAmount( amount ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CHECK_NUMBER ) ) + { + //origCheckNumber = fieldString; + /* changed matching to use original check number which contained leading 0's so go back to using that. Stan + if ( fieldString != null ) + { + // NOTE: I had to do this because I could set ck # = 004567 but get() returns 4567 so matching would not work. Stan + fieldString = fieldString.replaceAll( "^0*(.*)", "$1" ); + } + */ + System.err.println( "check number >" + fieldString + "<" ); + checkNumber = fieldString; +// txn.setCheckNum( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); +// txn.setName( fieldString ); + description = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO ) ) + { + System.err.println( "memo >" + fieldString + "<" ); + memo = fieldString; +// txn.setMemo( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag in phone field >" + fieldString + "<" ); + // storing it into phone field for now since onlinetxn cannot handle tags. A kludge for now. Stan +// txn.setPhone( fieldString ); + phoneString = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); + return false; // skip this line + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + +// if ( rootAccount.getAccountByName( accountName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// return false; // skip this line +// } +// this.accountNameFromCSV = accountName; + } + } // end for + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); +// System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); + + return true; + } + + public Date parseDateToInt( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse(dateStr); + System.err.println( "parseDateToInt() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return ddd; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return ddd; + } + return ddd; + } + + public String convertMmmFormattedDate( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse( dateStr ); + System.err.println( "convertMmmFormattedDate() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + + jDateFormat = jDateFormat.replace( "MMM", "MM" ); // convert MMM Jan to MM number 1 + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return dateStr; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return dateStr; + } + return sdf.format( ddd ); + } + + public int getIntDate( Date gotDate ) + { + Calendar cal = Calendar.getInstance(); + cal.setTime(gotDate); + return (cal.get( Calendar.YEAR ) * 10000) + (cal.get( Calendar.MONTH ) * 100) + cal.get( Calendar.DAY_OF_MONTH ); + } + + public String giveFormattedDate( Date ddd, String format ) + { + StringBuffer sss = new StringBuffer(); + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + if ( ddd == null ) + return ""; + + //StringBuffer buf = sdf.format( ddd ); + return sdf.format( ddd ); + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + + // --- set a default date to be used if particular dates are not set ---s + if ( date == 0 ) + { + if ( dateInitiated != 0 ) + { + date = dateInitiated; + } + else if ( datePurchased != 0 ) + { + date = datePurchased; + } + else if ( datePosted != 0 ) + { + date = datePosted; + } + else if ( dateAvailable != 0 ) + { + date = dateAvailable; + } + else + { + System.err.println( "*** Error: No Date field is set !" ); + throwException( "*** Error: No Date field is set !" ); + } + } + + if ( dateAvailable != 0 ) + { + txn.setDateAvailableInt( dateAvailable ); + } + else + { + txn.setDateAvailableInt( date ); + } + + if ( dateInitiated != 0 ) + { + txn.setDateInitiatedInt( dateInitiated ); + } + else + { + txn.setDateInitiatedInt( date ); + } + + if ( datePosted != 0 ) + { + txn.setDatePostedInt( datePosted ); + } + else + { + txn.setDatePostedInt( date ); + } + + if ( datePurchased != 0 ) + { + txn.setDatePurchasedInt( datePurchased ); + } + else + { + txn.setDatePurchasedInt( date ); + } + +// System.err.println( "date >" + date + "<" ); +// System.err.println( "date >" + txn.getDateAvailableInt() + "<" ); +// System.err.println( "date >" + txn.getDateInitiatedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePostedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePurchasedInt() + "<" ); + + txn.setCheckNum( checkNumber ); + txn.setName( description ); + txn.setMemo( memo ); + txn.setPhone( phoneString ); + txn.setSubAccountTo( categoryName ); // Hopefully this is ok to use as I do not know the MD api. + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) +// + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + //System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + // + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); +//(date == 0 ? datePurchased : date) + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public String getDateFormat() + { + System.err.println( "customReader getDateFormat() >" + dateFormatStringSelected + "<" ); + return dateFormatStringSelected; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + System.err.println( "setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "=" ); + if ( ! format.equals( dateFormatStringSelected ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatStringSelected = format; + } + + /* + dateFormatStringSelected = getCustomReaderData().getDateFormatString(); + System.err.println( "customReader setDateFormat() =" + dateFormatStringSelected + "<" ); + System.err.println( "customReader customReaderDialog.getDateFormatSelected() >" + getCustomReaderData().getDateFormatString() + "<" ); + dateFormat = new CustomDateFormat( getCustomReaderData().getDateFormatString() ); + */ + + /* + if ( !DATE_FORMAT_US.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + * + */ + } + + private static boolean findDateFormat( String[] compatibleDateFormats, String dateFormatStringArg ) + { + if ( dateFormatStringArg == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( s.equals( dateFormatStringArg ) ) + { + return true; + } + } + + return false; + } + +// @Override +// public void setFieldSeparatorChar( int xxx) { +// fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); +// } +// +// @Override +// public int getFieldSeparatorChar() { +// return fieldSeparator; +// } + + + @Override + protected int getHeaderCount() + { + return getCustomReaderData().getHeaderLines(); + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/INGNetherlandsReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/INGNetherlandsReader.java-HIDE.svn-base new file mode 100644 index 0000000..61dea62 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/INGNetherlandsReader.java-HIDE.svn-base @@ -0,0 +1,198 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class INGNetherlandsReader + extends TransactionReader +{ + private static final String DATUM = "datum"; + private static final String NAAM_OMSCHRIJVING = "naam / omschrijving"; + private static final String REKENING = "rekening"; + private static final String TEGENREKENING = "tegenrekening"; + private static final String CODE = "code"; + private static final String AF_BIJ = "af bij"; + private static final String BEDRAG_EUR = "bedrag (eur)"; + private static final String MUTATIESORT = "mutatiesoort"; + private static final String MEDEDELINGEN = "mededelingen"; + private static final String DATE_FORMAT = "D-M-YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String mededelingen; + private String code; + private String datum; + private String bedrag; + private String naam; + private String rekening; + private String tegenrekening; + private String mutatiesort; + private String af_bij; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && DATUM.equals( data.getField().toLowerCase() ) && + data.nextField() && NAAM_OMSCHRIJVING.equals( data.getField().toLowerCase() ) && + data.nextField() && REKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && TEGENREKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && CODE.equals( data.getField().toLowerCase() ) && + data.nextField() && AF_BIJ.equals( data.getField().toLowerCase() ) && + data.nextField() && BEDRAG_EUR.equals( data.getField().toLowerCase() ) && + data.nextField() && MUTATIESORT.equals( data.getField().toLowerCase() ) && + data.nextField() && MEDEDELINGEN.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "ING The Netherlands"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + datum = csvData.getField(); + + csvData.nextField(); + naam = csvData.getField(); + + csvData.nextField(); + rekening = csvData.getField(); + + csvData.nextField(); + tegenrekening = csvData.getField(); + + csvData.nextField(); + code = csvData.getField(); + + csvData.nextField(); + af_bij = csvData.getField(); + + csvData.nextField(); + bedrag = csvData.getField(); + + csvData.nextField(); + mutatiesort = csvData.getField(); + + csvData.nextField(); + mededelingen = csvData.getField(); + if ( mededelingen == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( bedrag, ',' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + if ( af_bij.equalsIgnoreCase( "af" ) ) + { + amount = -amount; + } + else if ( af_bij.equalsIgnoreCase( "bij" ) ) + { + } + else + { + throwException( "Value of Af/Bij field must be 'Af' or 'Bij'." ); + } + + int date = dateFormat.parseInt( datum ); + + Integer hashCode = naam.hashCode() ^ rekening.hashCode() ^ + tegenrekening.hashCode() ^ code.hashCode() ^ af_bij.hashCode() ^ + mutatiesort.hashCode() ^ mededelingen.hashCode(); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( mededelingen ); + txn.setFITxnId( datum + ":" + bedrag + ":" + hashCode.toString() ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + txn.setPayeeName( naam ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java-HIDE.svn-base new file mode 100644 index 0000000..9bef54d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java-HIDE.svn-base @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class SimpleCreditDebitReader + extends TransactionReader +{ + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CREDIT = "credit"; + private static final String DEBIT = "debit"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String debit; + private String credit; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = data.nextLine() && + data.nextField() && DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && CREDIT.equals( data.getField().toLowerCase() ) && + data.nextField() && DEBIT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + + // find guessable date formats + if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + while ( data.nextLine() ) + { + if ( data.nextField() ) + { + guesser.checkDateString( data.getField() ); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if ( dateFormatString == null || + !find( compatibleDateFormats, dateFormatString ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Simple Date/Description/Credit/Debit"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + if ( credit == null && debit == null ) + { + throwException( "Invalid line." ); + } + + if ( credit.length() == 0 && debit.length() == 0 ) + { + throwException( "Credit and debit fields are both empty." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + if ( credit.length() > 0 ) + { + amountDouble = StringUtils.parseDoubleWithException( credit, '.' ); + } + else + { + amountDouble = -StringUtils.parseDoubleWithException( debit, '.' ); + } + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int date = dateFormat.parseInt( dateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + @Override + public String[] getSupportedDateFormats() + { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() + { + return dateFormatString; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + if ( !format.equals( dateFormatString ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatString = format; + } + } + + private static boolean find( String[] compatibleDateFormats, String dateFormatString ) + { + if ( dateFormatString == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( dateFormatString.equals( dateFormatString ) ) + { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java.netbeans-base new file mode 100644 index 0000000..9bef54d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/SimpleCreditDebitReader.java.netbeans-base @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class SimpleCreditDebitReader + extends TransactionReader +{ + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CREDIT = "credit"; + private static final String DEBIT = "debit"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String debit; + private String credit; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = data.nextLine() && + data.nextField() && DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && CREDIT.equals( data.getField().toLowerCase() ) && + data.nextField() && DEBIT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + + // find guessable date formats + if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + while ( data.nextLine() ) + { + if ( data.nextField() ) + { + guesser.checkDateString( data.getField() ); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if ( dateFormatString == null || + !find( compatibleDateFormats, dateFormatString ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Simple Date/Description/Credit/Debit"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + if ( credit == null && debit == null ) + { + throwException( "Invalid line." ); + } + + if ( credit.length() == 0 && debit.length() == 0 ) + { + throwException( "Credit and debit fields are both empty." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + if ( credit.length() > 0 ) + { + amountDouble = StringUtils.parseDoubleWithException( credit, '.' ); + } + else + { + amountDouble = -StringUtils.parseDoubleWithException( debit, '.' ); + } + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int date = dateFormat.parseInt( dateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + @Override + public String[] getSupportedDateFormats() + { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() + { + return dateFormatString; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + if ( !format.equals( dateFormatString ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatString = format; + } + } + + private static boolean find( String[] compatibleDateFormats, String dateFormatString ) + { + if ( dateFormatString == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( dateFormatString.equals( dateFormatString ) ) + { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java-HIDE.svn-base new file mode 100644 index 0000000..1304899 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java-HIDE.svn-base @@ -0,0 +1,191 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class WellsFargoReader + extends TransactionReader +{ + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT + }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String dateString; + private String description; +// private long amount; + private int date; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = true; + + while ( retVal && data.nextLine() ) + { + if ( !data.nextField() ) + { + continue; // skip empty lines + } + String dateTest = data.getField(); + if ( !dateTest.equals( dateFormat.format( dateFormat.parseInt( data.getField() ) ) ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() ) + { + retVal = false; + break; + } + try + { + StringUtils.parseDoubleWithException( data.getField(), '.' ); + } + catch ( Exception x ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.getField().equals( "*" ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.nextField() || data.nextField() ) + { + retVal = false; + break; + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Wells Fargo"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // skip empty lines + return false; + } + + csvData.nextField(); + amountString = csvData.getField(); + + csvData.nextField(); // skip '*' + + csvData.nextField(); // skip unknown number + + csvData.nextField(); + description = csvData.getField(); + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + date = dateFormat.parseInt( dateString ); + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java.netbeans-base new file mode 100644 index 0000000..1304899 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/WellsFargoReader.java.netbeans-base @@ -0,0 +1,191 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class WellsFargoReader + extends TransactionReader +{ + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT + }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String dateString; + private String description; +// private long amount; + private int date; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = true; + + while ( retVal && data.nextLine() ) + { + if ( !data.nextField() ) + { + continue; // skip empty lines + } + String dateTest = data.getField(); + if ( !dateTest.equals( dateFormat.format( dateFormat.parseInt( data.getField() ) ) ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() ) + { + retVal = false; + break; + } + try + { + StringUtils.parseDoubleWithException( data.getField(), '.' ); + } + catch ( Exception x ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.getField().equals( "*" ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.nextField() || data.nextField() ) + { + retVal = false; + break; + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Wells Fargo"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // skip empty lines + return false; + } + + csvData.nextField(); + amountString = csvData.getField(); + + csvData.nextField(); // skip '*' + + csvData.nextField(); // skip unknown number + + csvData.nextField(); + description = csvData.getField(); + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + date = dateFormat.parseInt( dateString ); + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java-HIDE.svn-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java-HIDE.svn-base new file mode 100644 index 0000000..8fccf92 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java-HIDE.svn-base @@ -0,0 +1,276 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + + */ +public class YodleeReader + extends TransactionReader { + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + private String dateFormatStringSelected = DATE_FORMAT_INTN; + private static String[] SUPPORTED_DATE_FORMATS = { + DATE_FORMAT_US, DATE_FORMAT_EU, DATE_FORMAT_JP, DATE_FORMAT_INTN + }; + private CustomDateFormat dateFormat = new CustomDateFormat(DATE_FORMAT_INTN); + private String dateFormatString; + private String status; + private String description; + private String splitType; + private String category; + private String currencyString; + private String amountString; + private long amount; + private String userDescription; + private String memo; + private String classification; + private int date; + private static final String STATUS = "status"; + private static final String DATE = "date"; + private static final String DESCRIPTION = "original description"; + private static final String SPLIT = "split type"; + private static final String CATEGORY = "category"; + private static final String CURRENCY = "currency"; + private static final String AMOUNT = "amount"; + private static final String USER_DESCRIPTION = "user description"; + private static final String MEMO = "memo"; + private static final String CLASSIFICATION = "classification"; + private static final String ACCOUNT = "account name"; + + @Override + public boolean canParse(CSVData data) { + try { + data.parseIntoLines(0); + } catch (IOException ex) { + return false; + } + + boolean retVal = data.nextLine() + && data.nextField() && STATUS.equals(data.getField().toLowerCase()) + && data.nextField() && DATE.equals(data.getField().toLowerCase()) + && data.nextField() && DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && SPLIT.equals(data.getField().toLowerCase()) + && data.nextField() && CATEGORY.equals(data.getField().toLowerCase()) + && data.nextField() && CURRENCY.equals(data.getField().toLowerCase()) + && data.nextField() && AMOUNT.equals(data.getField().toLowerCase()) + && data.nextField() && USER_DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && MEMO.equals(data.getField().toLowerCase()) + && data.nextField() && CLASSIFICATION.equals(data.getField().toLowerCase()) + && data.nextField() && ACCOUNT.equals(data.getField().toLowerCase()) + && !data.nextField(); + + System.out.println( "can parse Yodlee format =" + String.valueOf(retVal) + "=" ); + return retVal; + } + + @Override + public String getFormatName() { + return "Yodlee"; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + * + */ + @Override + protected boolean parseNext() throws IOException { + + csvData.nextField(); + status = csvData.getField(); +// System.out.println("status: " + status); + +// System.out.println("getting Yodlee dateString..."); + csvData.nextField(); + String dateString = csvData.getField(); + if (dateString == null || dateString.isEmpty()) { + // skip lines without valid dates (or empty) + return false; + } +// System.out.println("dateString: " + dateString); + + csvData.nextField(); + description = csvData.getField(); +// System.out.println("description: " + description); + + csvData.nextField(); + splitType = csvData.getField(); +// System.out.println("splitType: " + splitType); + + csvData.nextField(); + category = csvData.getField();//NOTE: don't set in Txn object! +// System.out.println("category: " + category); + + csvData.nextField(); + currencyString = csvData.getField();//NOTE: not used +// System.out.println("currencyString: " + currencyString); + + csvData.nextField(); + amountString = csvData.getField().trim(); +// System.out.println("amountString: " + amountString); + + csvData.nextField(); + userDescription = csvData.getField(); +// System.out.println("userDescription: " + userDescription); + + csvData.nextField(); + memo = csvData.getField(); +// System.out.println("memo: " + memo); + + csvData.nextField(); + classification = csvData.getField(); +// System.out.println("classification: " + classification); + + csvData.nextField(); + this.accountNameFromCSV = csvData.getField(); +// System.out.println("accountNameFromCSV: " + accountNameFromCSV); + +// System.out.println( "parsing Yodlee amount..."); +// amount = 0; +// try { +// double amountDouble; +// amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); +// System.out.println( "after parseDoubleWithException..."); +// amount = currency.getLongValue(amountDouble); +// } catch (Exception x) { +// throwException("Invalid amount."); +// } +// System.out.println( "parsing Yodlee date..."); + date = dateFormat.parseInt(dateString); + +// System.out.println( "parsed Yodlee txn on " + dateString + " for " + accountNameFromCSV); + return true; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + x Category + x Currency + * Amount + * User Description + * Memo + x Classification (Tag) + ^ Account Name + * + */ + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + amount = 0; + try { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); + System.out.println( "after parseDoubleWithException..."); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + txn.setMemo(memo); + txn.setRefNum(status + ":" + splitType + ":" + userDescription); + //TODO: classification (e.g., business or personal) + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats(String dateFormatArg) { + System.err.println("\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------"); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat(dateFormatArg); + } + + @Override + public String getDateFormat() { + return DATE_FORMAT_INTN; + } + +// @Override +// public void setDateFormat(String format) { +// if (!DATE_FORMAT.equals(format)) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// } + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + System.err.println("setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "="); + if (!format.equals(dateFormatStringSelected)) { + dateFormat = new CustomDateFormat(format); + dateFormatStringSelected = format; + } + + } + + @Override + protected int getHeaderCount() { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java.netbeans-base b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java.netbeans-base new file mode 100644 index 0000000..8fccf92 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/.svn/text-base/YodleeReader.java.netbeans-base @@ -0,0 +1,276 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + + */ +public class YodleeReader + extends TransactionReader { + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + private String dateFormatStringSelected = DATE_FORMAT_INTN; + private static String[] SUPPORTED_DATE_FORMATS = { + DATE_FORMAT_US, DATE_FORMAT_EU, DATE_FORMAT_JP, DATE_FORMAT_INTN + }; + private CustomDateFormat dateFormat = new CustomDateFormat(DATE_FORMAT_INTN); + private String dateFormatString; + private String status; + private String description; + private String splitType; + private String category; + private String currencyString; + private String amountString; + private long amount; + private String userDescription; + private String memo; + private String classification; + private int date; + private static final String STATUS = "status"; + private static final String DATE = "date"; + private static final String DESCRIPTION = "original description"; + private static final String SPLIT = "split type"; + private static final String CATEGORY = "category"; + private static final String CURRENCY = "currency"; + private static final String AMOUNT = "amount"; + private static final String USER_DESCRIPTION = "user description"; + private static final String MEMO = "memo"; + private static final String CLASSIFICATION = "classification"; + private static final String ACCOUNT = "account name"; + + @Override + public boolean canParse(CSVData data) { + try { + data.parseIntoLines(0); + } catch (IOException ex) { + return false; + } + + boolean retVal = data.nextLine() + && data.nextField() && STATUS.equals(data.getField().toLowerCase()) + && data.nextField() && DATE.equals(data.getField().toLowerCase()) + && data.nextField() && DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && SPLIT.equals(data.getField().toLowerCase()) + && data.nextField() && CATEGORY.equals(data.getField().toLowerCase()) + && data.nextField() && CURRENCY.equals(data.getField().toLowerCase()) + && data.nextField() && AMOUNT.equals(data.getField().toLowerCase()) + && data.nextField() && USER_DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && MEMO.equals(data.getField().toLowerCase()) + && data.nextField() && CLASSIFICATION.equals(data.getField().toLowerCase()) + && data.nextField() && ACCOUNT.equals(data.getField().toLowerCase()) + && !data.nextField(); + + System.out.println( "can parse Yodlee format =" + String.valueOf(retVal) + "=" ); + return retVal; + } + + @Override + public String getFormatName() { + return "Yodlee"; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + * + */ + @Override + protected boolean parseNext() throws IOException { + + csvData.nextField(); + status = csvData.getField(); +// System.out.println("status: " + status); + +// System.out.println("getting Yodlee dateString..."); + csvData.nextField(); + String dateString = csvData.getField(); + if (dateString == null || dateString.isEmpty()) { + // skip lines without valid dates (or empty) + return false; + } +// System.out.println("dateString: " + dateString); + + csvData.nextField(); + description = csvData.getField(); +// System.out.println("description: " + description); + + csvData.nextField(); + splitType = csvData.getField(); +// System.out.println("splitType: " + splitType); + + csvData.nextField(); + category = csvData.getField();//NOTE: don't set in Txn object! +// System.out.println("category: " + category); + + csvData.nextField(); + currencyString = csvData.getField();//NOTE: not used +// System.out.println("currencyString: " + currencyString); + + csvData.nextField(); + amountString = csvData.getField().trim(); +// System.out.println("amountString: " + amountString); + + csvData.nextField(); + userDescription = csvData.getField(); +// System.out.println("userDescription: " + userDescription); + + csvData.nextField(); + memo = csvData.getField(); +// System.out.println("memo: " + memo); + + csvData.nextField(); + classification = csvData.getField(); +// System.out.println("classification: " + classification); + + csvData.nextField(); + this.accountNameFromCSV = csvData.getField(); +// System.out.println("accountNameFromCSV: " + accountNameFromCSV); + +// System.out.println( "parsing Yodlee amount..."); +// amount = 0; +// try { +// double amountDouble; +// amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); +// System.out.println( "after parseDoubleWithException..."); +// amount = currency.getLongValue(amountDouble); +// } catch (Exception x) { +// throwException("Invalid amount."); +// } +// System.out.println( "parsing Yodlee date..."); + date = dateFormat.parseInt(dateString); + +// System.out.println( "parsed Yodlee txn on " + dateString + " for " + accountNameFromCSV); + return true; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + x Category + x Currency + * Amount + * User Description + * Memo + x Classification (Tag) + ^ Account Name + * + */ + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + amount = 0; + try { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); + System.out.println( "after parseDoubleWithException..."); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + txn.setMemo(memo); + txn.setRefNum(status + ":" + splitType + ":" + userDescription); + //TODO: classification (e.g., business or personal) + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats(String dateFormatArg) { + System.err.println("\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------"); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat(dateFormatArg); + } + + @Override + public String getDateFormat() { + return DATE_FORMAT_INTN; + } + +// @Override +// public void setDateFormat(String format) { +// if (!DATE_FORMAT.equals(format)) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// } + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + System.err.println("setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "="); + if (!format.equals(dateFormatStringSelected)) { + dateFormat = new CustomDateFormat(format); + dateFormatStringSelected = format; + } + + } + + @Override + protected int getHeaderCount() { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE new file mode 100644 index 0000000..b709611 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/BbvaCompassBankReader.java-HIDE @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class BbvaCompassBankReader + extends TransactionReader { + + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CHECKNUM = "check #"; + private static final String CREDIT = "credit (+)"; + private static final String DEBIT = "debit (-)"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String checknum; + private String debit; + private String credit; + private static final int headerRows = 5; + + @Override + public boolean canParse(CSVData data) { +// System.out.println("enter BbvaCompassBankReader.canParse"); + try { + data.parseIntoLines(0); + } catch (IOException ex) { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + for (int i = 0; i < headerRows -1; i++) { + data.nextLine(); + if (null == data) { + continue; + } + //this next statement raises an exception - don't use it + //System.out.println("BbvaReader:skip: " + data.printCurrentLine()); + } + + boolean retVal = data.nextLine() + && data.nextField() && DATE.equalsIgnoreCase(data.getField()) + && data.nextField() && DESCRIPTION.equalsIgnoreCase(data.getField()) + && data.nextField() && CHECKNUM.equalsIgnoreCase(data.getField()) + && data.nextField() && DEBIT.equalsIgnoreCase(data.getField()) + && data.nextField() && CREDIT.equalsIgnoreCase(data.getField()) + && !data.nextField(); + + // find guessable date formats + if (retVal) { + DateGuesser guesser = new DateGuesser(); + while (data.nextLine()) { + if (data.nextField()) { + guesser.checkDateString(data.getField()); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if (dateFormatString == null + || !find(compatibleDateFormats, dateFormatString)) { + setDateFormat(guesser.getBestFormat()); + } + } + System.out.println("BbvaCompassBankReader.dateFormat = " + getDateFormat()); + System.out.println("BbvaCompassBankReader.canParse = " + String.valueOf(retVal)); + return retVal; + } + + @Override + public String getFormatName() { + return "BBVA Compass Bank NA"; + } + + @Override + protected boolean parseNext() throws IOException { + System.out.println("enter BbvaCompassBankReader parseNext"); + csvData.nextField(); + dateString = csvData.getField(); + if (dateString == null || dateString.length() == 0) { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + checknum = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + if (credit == null && debit == null) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are null."); + throwException("Invalid line"); + } + + if (credit.length() == 0 && debit.length() == 0) { + System.out.println("BbvaCompassBankReader Invalid line-debit and credit are empty."); + throwException("Credit and debit fields are both empty."); + } + System.out.println("exit BbvaCompassBankReader parseNext"); + return true; + } + + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + System.out.println("enter BbvaCompassBankReader assignDataToTxn"); + long amount = 0; + try { + double amountDouble; + if (credit.length() > 0) { + System.out.println("credit = " + String.valueOf(credit)); + amountDouble = StringUtils.parseDoubleWithException(credit, '.'); + } else { + System.out.println("credit.length() <= 0"); + amountDouble = -StringUtils.parseDoubleWithException(debit, '.'); + } + System.out.println("amountDouble = " + String.valueOf(amountDouble)); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + + int date = dateFormat.parseInt(dateString); + + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setMemo(description); + txn.setCheckNum(checknum); + // MOVED to TransactionReader so everyone creates it the same way. + //txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + //for temp testing. TODO: remove next line after testing. 2011.11.25 ds + txn.setRefNum(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + System.out.println("exit BbvaCompassBankReader assignDataToTxn"); + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() { + return dateFormatString; + } + + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + if (!format.equals(dateFormatString)) { + dateFormat = new CustomDateFormat(format); + dateFormatString = format; + } + } + + private static boolean find(String[] compatibleDateFormats, String dateFormatString) { + if (dateFormatString == null) { + return false; + } + + for (String s : compatibleDateFormats) { + if (dateFormatString.equals(dateFormatString)) { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() { + return headerRows; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE new file mode 100644 index 0000000..4223077 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/CitiBankCanadaReader.java-HIDE @@ -0,0 +1,159 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class CitiBankCanadaReader + extends TransactionReader +{ + private static final String TRANSACTION_DATE = "transaction date"; + private static final String POSTING_DATE = "posting date"; + private static final String DESCRIPTION = "description"; + private static final String AMOUNT = "amount"; + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String description; +// private long amount; +// private int transactionDate; + private String transactionDateString; +// private int postingDate; + private String postingDateString; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && TRANSACTION_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && POSTING_DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && AMOUNT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "CitiBank Canada"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + transactionDateString = csvData.getField(); + if ( transactionDateString.equalsIgnoreCase( "Date downloaded:" ) ) + { // skip the footer line + return false; + } + + csvData.nextField(); + postingDateString = csvData.getField(); + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + amountString = csvData.getField(); + if ( amountString == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int transactionDate = dateFormat.parseInt( transactionDateString ); + int postingDate = dateFormat.parseInt( postingDateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( postingDate + ":" + amountString + ":" + description ); + txn.setDatePostedInt( postingDate ); + txn.setDateInitiatedInt( transactionDate ); + txn.setDateAvailableInt( postingDate ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/CustomReader.java b/src/com/moneydance/modules/features/mdcsvimporter/formats/CustomReader.java new file mode 100644 index 0000000..49399f9 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/CustomReader.java @@ -0,0 +1,885 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.CustomReaderData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +/** + * + * @author Stan Towianski August 2011 + */ +public class CustomReader extends TransactionReader +{ + public static final String DATA_TYPE_BLANK = ""; + public static final String DATA_TYPE_IGNORE = "ignore"; + public static final String DATA_TYPE_IGNORE_REST = "ignore rest"; + public static final String DATA_TYPE_PAYMENT = "-Payment-"; + public static final String DATA_TYPE_DEPOSIT = "-Deposit-"; + public static final String DATA_TYPE_DATE = "date"; + public static final String DATA_TYPE_DATE_AVAILABLE = "date available"; + public static final String DATA_TYPE_DATE_INITIATED = "date initiated"; + public static final String DATA_TYPE_DATE_POSTED = "date posted"; + public static final String DATA_TYPE_DATE_PURCHASED = "date purchased"; + public static final String DATA_TYPE_CHECK_NUMBER = "check number"; + public static final String DATA_TYPE_DESCRIPTION = "description"; + public static final String DATA_TYPE_MEMO = "memo"; + public static final String DATA_TYPE_ACCOUNT_NAME = "account name"; + public static final String DATA_TYPE_CATEGORY_NAME = "category name"; + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + + private String dateFormatStringSelected = DATE_FORMAT_US; + + private static String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT_US + , DATE_FORMAT_EU + , DATE_FORMAT_JP + , DATE_FORMAT_INTN + }; + + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT_US ); + //private CustomDateFormat dateFormat; + + //private String[] compatibleDateFormats; + private String dateFormatString; + + private long amount = 0; + private int date = 0; + private int dateAvailable = 0; + private int dateInitiated = 0; + private int datePosted = 0; + private int datePurchased = 0; + private String description = ""; + private String checkNumber = ""; + private String phoneString; + private String memo; + private String accountName; + private String categoryName; + + public CustomReader( CustomReaderData customReaderData ) + { + setCustomReaderData( customReaderData ); + setCustomReaderFlag( true ); + } + + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats( String dateFormatArg ) + { + System.err.println( "\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------" ); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat( dateFormatArg ); + } + + @Override + public boolean canParse( CSVData data ) + { + System.err.println( "--------- entered customerReader().canParse() as type =" + getFormatName() + "= -------------" ); + try { + data.parseIntoLines( getCustomReaderData() ); + } + catch (IOException ex) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + //if ( data.getReader() == null ) + // System.err.println( "data.getReader() == null" ); + + //System.err.println( "at parse getFieldSeparator() =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + //csvData.getReader().setFieldSeparator( getCustomReaderData().getFieldSeparatorChar() ); + //System.err.println( "at parse getFieldSeparator() after set =" + (char)csvData.getReader().getFieldSeparator() + "=" ); + + data.reset(); + long fileLineCount = 0; + long endingBlankLines = 0; + //----- Count File Lines to know where Footer starts ----- + while ( data.nextLine() ) + { + fileLineCount ++; + if ( ! data.hasZeroFields() ) + { + endingBlankLines ++; + System.err.println( "endingBlankLines =" + endingBlankLines ); + } + else + { + endingBlankLines = 0; + } + } + System.err.println( "fileLineCount =" + fileLineCount ); + + data.reset(); + int skipHeaderLines = getHeaderCount(); + System.err.println( "skip any Header Lines =" + skipHeaderLines ); + for ( int i = 0; i < skipHeaderLines; i++ ) + { + System.err.println( "skip header line" ); + data.nextLine(); + } + long begAtLine = data.getCurrentLineIndex() + 1; + + boolean retVal = true; + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = getCustomReaderData().getDateFormatString().toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat, Locale.ENGLISH ); + sdf.setLenient( false ); + + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "->" + jDateFormat + "<-" ); + + long totalProcessed = 0; + long stopAtLine = fileLineCount - getHeaderCount() - getCustomReaderData().getFooterLines() - endingBlankLines; +// priorAccountNameFromCSV = ""; +// System.out.println("calling while (csvData.nextLine())..."); + +// data.printFile(); +// data.reverseListRangeOrder( begAtLine, stopAtLine - 1 ); +// data.printFile(); + + while ( retVal && data.nextLine() && totalProcessed < stopAtLine ) + { + totalProcessed++; + System.err.println( "------- next line ---------------" ); + if ( ! data.hasZeroFields() ) + { + continue; // skip empty lines + } + + if ( ! data.hasEnoughFieldsPerCurrentLine( maxFieldIndex - 1 ) ) + { + System.err.println( "Have too few fields. Needed >= " + ( maxFieldIndex - 2 ) ); + data.printCurrentLine(); + retVal = false; + } + + int fieldIndex = 0; + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + for ( ; retVal && fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= fieldIndex = " + fieldIndex ); + + data.nextField(); +// if ( ! data.nextField() ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but have no data left." ); +// retVal = false; +// break; +// } + String fieldString = data.getField(); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + data.nextField(); + fieldString = data.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( DATA_TYPE_BLANK ) ) ) + { + if ( ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + retVal = false; + break; + } + else + { + System.err.println( "ok to skip this blank field" ); + continue; + } + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) + ) + { + System.err.println( "date >" + fieldString + "<" ); + + /* + // find guessable date formats + // if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + guesser.checkDateString( fieldString ); + + //compatibleDateFormats = guesser.getPossibleFormats(); + SUPPORTED_DATE_FORMATS = guesser.getPossibleFormats(); + importDialog.popComboDateFormatList( SUPPORTED_DATE_FORMATS ); + if ( dateFormatStringSelected == null || + ! findDateFormat( SUPPORTED_DATE_FORMATS, dateFormatStringSelected ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + */ + /**/ +// if ( dateFormat.parseInt( fieldString ) != dateFormat.parseInt( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + System.err.println( "fieldString =" + fieldString + "= date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + try { + sdf.parse( fieldString ); // This seems to catch jan 32 -> feb 01 which I do not want to allow. + + // won't work when fieldString is 3/5/2012 because it will compare incorrectly to created 03/05/2012 and don't know how to fix that! ! +// if ( ! sdf.fieldString.equals( dateFormat.format( dateFormat.parseInt( fieldString ) ) ) ) +// { +// retVal = false; +// break; +// } + } + catch (ParseException e) { + System.err.println( "canParse() parseException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + catch (IllegalArgumentException e) { + System.err.println( "canParse() IllegalArgumentException: " + sdf.toString() + "<" ); + retVal = false; + break; + } + + /**/ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) // was only amount before + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "[^0-9]*(.*)", "$1" ); // strip leading non-digits + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + //StringUtils.parseDoubleWithException( fieldString, '.' ); + String tmp = fieldString.replace( '$', '0' ); + //System.err.println( "check modified amountString 1 >" + tmp + "<" ); + tmp = tmp.replace( '-', '0' ); + //System.err.println( "check modified amountString 2 >" + tmp + "<" ); + tmp = tmp.replaceAll( " ", "" ); + //System.err.println( "check modified amountString 3 >" + tmp + "<" ); + tmp = tmp.replaceAll( ",", "" ); + //System.err.println( "check modified amountString 4 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\.", "" ); + //System.err.println( "check modified amountString 5 >" + tmp + "<" ); + tmp = tmp.replaceAll( "\\d", "" ); + System.err.println( "check modified amountString 6 >" + tmp + "<" ); + //Number number = NumberFormat.getNumberInstance().parse( tmp ); + if ( tmp.equals( "" ) ) //number instanceof Double || number instanceof Long ) + { + System.err.println( "ok number" ); + ; + } + else + { + retVal = false; + break; + } + } + catch ( Exception x ) + { + retVal = false; + break; + } + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO) ) + { + System.err.println( "memo >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag >" + fieldString + "<" ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// retVal = false; +// break; + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + setUsingCategorynameFlag( true ); + +// if ( rootAccount.getAccountByName( categoryName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// retVal = false; +//// break; +// } + //this.categoryNameFromCSV = categoryName; + } + } // end for + } + + System.err.println( "canParse will return =" + retVal ); + return retVal; + } + + @Override + public String getFormatName() + { + return getCustomReaderData().getReaderName(); + } + + /* + * Note: This really parses a whole line at a time. + */ + @Override + protected boolean parseNext() throws IOException + { + amount = 0; + date = 0; + dateAvailable = 0; + dateInitiated = 0; + datePosted = 0; + datePurchased = 0; + description = ""; + checkNumber = ""; + phoneString = ""; + memo = ""; + accountName = ""; + + int fieldIndex = 0; + int amountDecimalSignChar = getCustomReaderData().getAmountDecimalSignChar(); + int maxFieldIndex = getCustomReaderData().getNumberOfCustomReaderFieldsUsed(); + System.err.println( "maxFieldIndex =" + maxFieldIndex ); + + setDateFormat( getCustomReaderData().getDateFormatString() ); + System.err.println( "using dateFormat string =" + getCustomReaderData().getDateFormatString() + "=" ); + + System.err.println( "----------------------" ); + if ( ! csvData.hasZeroFields() ) + { + System.err.println( "skip empty line" ); + return false; // skip empty lines + } + + for ( ; fieldIndex < maxFieldIndex; fieldIndex ++ ) + { + String dataTypeExpecting = getCustomReaderData().getDataTypesList().get( fieldIndex ); + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= EmptyFlagsList = " + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + "=" ); + + csvData.nextField(); + String fieldString = csvData.getField(); + System.err.println( "fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE_REST ) ) + { + break; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_IGNORE ) ) + { + int x = 1; + try + { + x = Integer.parseInt( getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() ); + System.err.println( "ignore " + x + " lines" ); + } + catch ( Exception ex ) + { + System.err.println( "ignore 1 line by erro on field =" + getCustomReaderData().getEmptyFlagsList().get( fieldIndex ).trim() + "=" ); + } + while ( x > 1 ) + { + csvData.nextField(); + fieldString = csvData.getField(); + System.err.println( "ignore fieldString =" + fieldString + "= fieldIndex = " + fieldIndex ); + //fieldIndex ++; NO - just skip data not field data type index + x--; + } + continue; + } + else if ( ( fieldString == null || fieldString.equals( "" ) ) + && ! getCustomReaderData().getEmptyFlagsList().get( fieldIndex ) + .equals( "Can Be Blank" ) ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but got no value =" + fieldString + "= and STOP ON ERROR" ); + } + + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE ) ) + { + System.err.println( "date >" + fieldString + "<" ); + + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + date = dateFormat.parseInt( fieldString ); + // I thought the format was giving incorrect dates for 2/5/2011 so I started doing my own thing. I later + // found out the method I am calling uses an MD method which is working, and my new stuff was not so I left it out. Stan +// Date gotDate = parseDateToInt( fieldString, getCustomReaderData().getDateFormatString() ); // part of my new stuff not being used. +// date = getIntDate( gotDate ); +// System.err.println( "new date int =" + getIntDate( gotDate ) + "= new date formatted >" + giveFormattedDate( gotDate, getCustomReaderData().getDateFormatString() ) + "<" ); + +// txn.setDatePostedInt( date ); +// txn.setDateInitiatedInt( date ); +// txn.setDateAvailableInt( date ); + /* + if ( !date.equals( dateFormat.format( dateFormat.parseInt( csvData.getField() ) ) ) ) + { + retVal = false; + break; + } + */ + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_AVAILABLE ) ) + { + System.err.println( "dateAvailable >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateAvailable = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_INITIATED) ) + { + System.err.println( "dateInitiated >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + dateInitiated = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_POSTED ) ) + { + System.err.println( "datePosted >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePosted = dateFormat.parseInt( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DATE_PURCHASED ) ) + { + System.err.println( "datePurchased >" + fieldString + "<" ); + fieldString = convertMmmFormattedDate( fieldString, getCustomReaderData().getDateFormatString() ); + System.err.println( "MMM date str =" + fieldString + "= date int =" + dateFormat.parseInt( fieldString ) + "= old date formatted >" + dateFormat.format( dateFormat.parseInt( fieldString ) ) + "<" ); + + datePurchased = dateFormat.parseInt( fieldString ); + } + else if ( ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) + || dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + && + ! ( fieldString == null || fieldString.equals( "" ) ) ) + { + System.err.println( "amountString >" + fieldString + "<" ); + fieldString = fieldString.replaceAll( "\\((.*)\\)", "-$1" ); + fieldString = StringUtils.stripNonNumbers( fieldString, (char)amountDecimalSignChar ); + System.err.println( "amountString >" + fieldString + "<" ); + + try + { + double amountDouble = StringUtils.parseDoubleWithException( fieldString, (char)amountDecimalSignChar ); + if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_PAYMENT ) ) + { + amount += currency.getLongValue( amountDouble ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DEPOSIT ) ) + { + System.err.println( "flip sign for deposit" ); + amount -= currency.getLongValue( amountDouble ); + } + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } +// txn.setAmount( amount ); +// txn.setTotalAmount( amount ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CHECK_NUMBER ) ) + { + //origCheckNumber = fieldString; + /* changed matching to use original check number which contained leading 0's so go back to using that. Stan + if ( fieldString != null ) + { + // NOTE: I had to do this because I could set ck # = 004567 but get() returns 4567 so matching would not work. Stan + fieldString = fieldString.replaceAll( "^0*(.*)", "$1" ); + } + */ + System.err.println( "check number >" + fieldString + "<" ); + checkNumber = fieldString; +// txn.setCheckNum( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_DESCRIPTION ) ) + { + System.err.println( "description >" + fieldString + "<" ); +// txn.setName( fieldString ); + description = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_MEMO ) ) + { + System.err.println( "memo >" + fieldString + "<" ); + memo = fieldString; +// txn.setMemo( fieldString ); + } + else if ( dataTypeExpecting.equalsIgnoreCase( "tag" ) ) + { + System.err.println( "tag in phone field >" + fieldString + "<" ); + // storing it into phone field for now since onlinetxn cannot handle tags. A kludge for now. Stan +// txn.setPhone( fieldString ); + phoneString = fieldString; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_ACCOUNT_NAME ) ) + { + System.err.println( "accountName >" + fieldString + "<" ); + accountName = fieldString; + + if ( rootAccount.getAccountByName( accountName ) == null ) + { + System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); + return false; // skip this line + } + this.accountNameFromCSV = accountName; + } + else if ( dataTypeExpecting.equalsIgnoreCase( DATA_TYPE_CATEGORY_NAME ) ) + { + System.err.println( "categoryName >" + fieldString + "<" ); + categoryName = fieldString; + +// if ( rootAccount.getAccountByName( accountName ) == null ) +// { +// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= will not import it." ); +//// System.err.println( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +//// throwException( "dataTypeExpecting =" + dataTypeExpecting + "= but that account does not exist =" + fieldString + "= and STOP ON ERROR" ); +// return false; // skip this line +// } +// this.accountNameFromCSV = accountName; + } + } // end for + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); +// System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); + + return true; + } + + public Date parseDateToInt( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse(dateStr); + System.err.println( "parseDateToInt() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return ddd; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return ddd; + } + return ddd; + } + + public String convertMmmFormattedDate( String dateStr, String format ) + { + Date ddd = null; + SimpleDateFormat sdf = null; + + try { + // convert to validate with Java date formatting d,y, and M. case matters. + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + ddd = sdf.parse( dateStr ); + System.err.println( "convertMmmFormattedDate() from format =" + format + "= and date in string =" + dateStr + "= got Date =" + ddd.toString() + "=" ); + + jDateFormat = jDateFormat.replace( "MMM", "MM" ); // convert MMM Jan to MM number 1 + sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + } + catch (ParseException e) { + System.err.println( "parseDateToInt() parseException =" + sdf.toString() + "=" ); + return dateStr; + } + catch (IllegalArgumentException e) { + System.err.println( "parseDateToInt() IllegalArgumentException =" + sdf.toString() + "=" ); + return dateStr; + } + return sdf.format( ddd ); + } + + public int getIntDate( Date gotDate ) + { + Calendar cal = Calendar.getInstance(); + cal.setTime(gotDate); + return (cal.get( Calendar.YEAR ) * 10000) + (cal.get( Calendar.MONTH ) * 100) + cal.get( Calendar.DAY_OF_MONTH ); + } + + public String giveFormattedDate( Date ddd, String format ) + { + StringBuffer sss = new StringBuffer(); + String jDateFormat = format.toLowerCase(); + jDateFormat = jDateFormat.replace( 'm', 'M' ); + SimpleDateFormat sdf = new SimpleDateFormat( jDateFormat ); + sdf.setLenient( false ); + + if ( ddd == null ) + return ""; + + //StringBuffer buf = sdf.format( ddd ); + return sdf.format( ddd ); + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + + // --- set a default date to be used if particular dates are not set ---s + if ( date == 0 ) + { + if ( dateInitiated != 0 ) + { + date = dateInitiated; + } + else if ( datePurchased != 0 ) + { + date = datePurchased; + } + else if ( datePosted != 0 ) + { + date = datePosted; + } + else if ( dateAvailable != 0 ) + { + date = dateAvailable; + } + else + { + System.err.println( "*** Error: No Date field is set !" ); + throwException( "*** Error: No Date field is set !" ); + } + } + + if ( dateAvailable != 0 ) + { + txn.setDateAvailableInt( dateAvailable ); + } + else + { + txn.setDateAvailableInt( date ); + } + + if ( dateInitiated != 0 ) + { + txn.setDateInitiatedInt( dateInitiated ); + } + else + { + txn.setDateInitiatedInt( date ); + } + + if ( datePosted != 0 ) + { + txn.setDatePostedInt( datePosted ); + } + else + { + txn.setDatePostedInt( date ); + } + + if ( datePurchased != 0 ) + { + txn.setDatePurchasedInt( datePurchased ); + } + else + { + txn.setDatePurchasedInt( date ); + } + +// System.err.println( "date >" + date + "<" ); +// System.err.println( "date >" + txn.getDateAvailableInt() + "<" ); +// System.err.println( "date >" + txn.getDateInitiatedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePostedInt() + "<" ); +// System.err.println( "date >" + txn.getDatePurchasedInt() + "<" ); + + txn.setCheckNum( checkNumber ); + txn.setName( description ); + txn.setMemo( memo ); + txn.setPhone( phoneString ); + txn.setSubAccountTo( categoryName ); // Hopefully this is ok to use as I do not know the MD api. + + // MOVED to TransactionReader so everyone creates it the same way. +// txn.setFITxnId( date + ":" + currency.format( amount, '.' ) +// + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() ); + //System.err.println( "FITxnld >" + date + ":" + currency.format( amount, '.' ) + // + ":" + description + ":" + txn.getCheckNum() + ":" + txn.getMemo() + "<" ); +//(date == 0 ? datePurchased : date) + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public String getDateFormat() + { + System.err.println( "customReader getDateFormat() >" + dateFormatStringSelected + "<" ); + return dateFormatStringSelected; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + System.err.println( "setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "=" ); + if ( ! format.equals( dateFormatStringSelected ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatStringSelected = format; + } + + /* + dateFormatStringSelected = getCustomReaderData().getDateFormatString(); + System.err.println( "customReader setDateFormat() =" + dateFormatStringSelected + "<" ); + System.err.println( "customReader customReaderDialog.getDateFormatSelected() >" + getCustomReaderData().getDateFormatString() + "<" ); + dateFormat = new CustomDateFormat( getCustomReaderData().getDateFormatString() ); + */ + + /* + if ( !DATE_FORMAT_US.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + * + */ + } + + private static boolean findDateFormat( String[] compatibleDateFormats, String dateFormatStringArg ) + { + if ( dateFormatStringArg == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( s.equals( dateFormatStringArg ) ) + { + return true; + } + } + + return false; + } + +// @Override +// public void setFieldSeparatorChar( int xxx) { +// fieldSeparatorChar.setText( String.valueOf( Character.toString( (char) xxx ) ) ); +// } +// +// @Override +// public int getFieldSeparatorChar() { +// return fieldSeparator; +// } + + + @Override + protected int getHeaderCount() + { + return getCustomReaderData().getHeaderLines(); + } + +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE new file mode 100644 index 0000000..61dea62 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/INGNetherlandsReader.java-HIDE @@ -0,0 +1,198 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +public class INGNetherlandsReader + extends TransactionReader +{ + private static final String DATUM = "datum"; + private static final String NAAM_OMSCHRIJVING = "naam / omschrijving"; + private static final String REKENING = "rekening"; + private static final String TEGENREKENING = "tegenrekening"; + private static final String CODE = "code"; + private static final String AF_BIJ = "af bij"; + private static final String BEDRAG_EUR = "bedrag (eur)"; + private static final String MUTATIESORT = "mutatiesoort"; + private static final String MEDEDELINGEN = "mededelingen"; + private static final String DATE_FORMAT = "D-M-YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = { DATE_FORMAT }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String mededelingen; + private String code; + private String datum; + private String bedrag; + private String naam; + private String rekening; + private String tegenrekening; + private String mutatiesort; + private String af_bij; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + return data.nextLine() && + data.nextField() && DATUM.equals( data.getField().toLowerCase() ) && + data.nextField() && NAAM_OMSCHRIJVING.equals( data.getField().toLowerCase() ) && + data.nextField() && REKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && TEGENREKENING.equals( data.getField().toLowerCase() ) && + data.nextField() && CODE.equals( data.getField().toLowerCase() ) && + data.nextField() && AF_BIJ.equals( data.getField().toLowerCase() ) && + data.nextField() && BEDRAG_EUR.equals( data.getField().toLowerCase() ) && + data.nextField() && MUTATIESORT.equals( data.getField().toLowerCase() ) && + data.nextField() && MEDEDELINGEN.equals( data.getField().toLowerCase() ) && + !data.nextField(); + } + + @Override + public String getFormatName() + { + return "ING The Netherlands"; + } + + @Override + protected boolean parseNext() + throws IOException + { + if ( !csvData.nextField() ) + { // empty line + return false; + } + datum = csvData.getField(); + + csvData.nextField(); + naam = csvData.getField(); + + csvData.nextField(); + rekening = csvData.getField(); + + csvData.nextField(); + tegenrekening = csvData.getField(); + + csvData.nextField(); + code = csvData.getField(); + + csvData.nextField(); + af_bij = csvData.getField(); + + csvData.nextField(); + bedrag = csvData.getField(); + + csvData.nextField(); + mutatiesort = csvData.getField(); + + csvData.nextField(); + mededelingen = csvData.getField(); + if ( mededelingen == null ) + { + throwException( "Invalid line." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble = StringUtils.parseDoubleWithException( bedrag, ',' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + if ( af_bij.equalsIgnoreCase( "af" ) ) + { + amount = -amount; + } + else if ( af_bij.equalsIgnoreCase( "bij" ) ) + { + } + else + { + throwException( "Value of Af/Bij field must be 'Af' or 'Bij'." ); + } + + int date = dateFormat.parseInt( datum ); + + Integer hashCode = naam.hashCode() ^ rekening.hashCode() ^ + tegenrekening.hashCode() ^ code.hashCode() ^ af_bij.hashCode() ^ + mutatiesort.hashCode() ^ mededelingen.hashCode(); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( mededelingen ); + txn.setFITxnId( datum + ":" + bedrag + ":" + hashCode.toString() ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + txn.setPayeeName( naam ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE new file mode 100644 index 0000000..9bef54d --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/SimpleCreditDebitReader.java-HIDE @@ -0,0 +1,215 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class SimpleCreditDebitReader + extends TransactionReader +{ + private static final String DATE = "date"; + private static final String DESCRIPTION = "description"; + private static final String CREDIT = "credit"; + private static final String DEBIT = "debit"; + private CustomDateFormat dateFormat; + private String[] compatibleDateFormats; + private String dateFormatString; + private String dateString; + private String description; + private String debit; + private String credit; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = data.nextLine() && + data.nextField() && DATE.equals( data.getField().toLowerCase() ) && + data.nextField() && DESCRIPTION.equals( data.getField().toLowerCase() ) && + data.nextField() && CREDIT.equals( data.getField().toLowerCase() ) && + data.nextField() && DEBIT.equals( data.getField().toLowerCase() ) && + !data.nextField(); + + // find guessable date formats + if ( retVal ) + { + DateGuesser guesser = new DateGuesser(); + while ( data.nextLine() ) + { + if ( data.nextField() ) + { + guesser.checkDateString( data.getField() ); + } + } + + compatibleDateFormats = guesser.getPossibleFormats(); + if ( dateFormatString == null || + !find( compatibleDateFormats, dateFormatString ) ) + { + setDateFormat( guesser.getBestFormat() ); + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Simple Date/Description/Credit/Debit"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // empty line + return false; + } + + csvData.nextField(); + description = csvData.getField(); + + csvData.nextField(); + credit = csvData.getField(); + + csvData.nextField(); + debit = csvData.getField(); + if ( credit == null && debit == null ) + { + throwException( "Invalid line." ); + } + + if ( credit.length() == 0 && debit.length() == 0 ) + { + throwException( "Credit and debit fields are both empty." ); + } + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + if ( credit.length() > 0 ) + { + amountDouble = StringUtils.parseDoubleWithException( credit, '.' ); + } + else + { + amountDouble = -StringUtils.parseDoubleWithException( debit, '.' ); + } + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + int date = dateFormat.parseInt( dateString ); + + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + @Override + public String[] getSupportedDateFormats() + { + return compatibleDateFormats; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + compatibleDateFormats = supportedDateFormats; + } + + @Override + public String getDateFormat() + { + return dateFormatString; + } + + @Override + public void setDateFormat( String format ) + { + if ( format == null ) + { + return; + } + + if ( !format.equals( dateFormatString ) ) + { + dateFormat = new CustomDateFormat( format ); + dateFormatString = format; + } + } + + private static boolean find( String[] compatibleDateFormats, String dateFormatString ) + { + if ( dateFormatString == null ) + { + return false; + } + + for ( String s : compatibleDateFormats ) + { + if ( dateFormatString.equals( dateFormatString ) ) + { + return true; + } + } + + return false; + } + + @Override + protected int getHeaderCount() + { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE new file mode 100644 index 0000000..1304899 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/WellsFargoReader.java-HIDE @@ -0,0 +1,191 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/** + * + * @author miki + */ +public class WellsFargoReader + extends TransactionReader +{ + private static final String DATE_FORMAT = "MM/DD/YYYY"; + private static final String[] SUPPORTED_DATE_FORMATS = + { + DATE_FORMAT + }; + private CustomDateFormat dateFormat = new CustomDateFormat( DATE_FORMAT ); + private String amountString; + private String dateString; + private String description; +// private long amount; + private int date; + + @Override + public boolean canParse( CSVData data ) + { + //data.reset(); + try { + data.parseIntoLines( 0 ); + } + catch ( IOException ex ) + { + //Logger.getLogger(CustomReader.class.getName()).log(Level.SEVERE, null, ex); + return false; + } + + boolean retVal = true; + + while ( retVal && data.nextLine() ) + { + if ( !data.nextField() ) + { + continue; // skip empty lines + } + String dateTest = data.getField(); + if ( !dateTest.equals( dateFormat.format( dateFormat.parseInt( data.getField() ) ) ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() ) + { + retVal = false; + break; + } + try + { + StringUtils.parseDoubleWithException( data.getField(), '.' ); + } + catch ( Exception x ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.getField().equals( "*" ) ) + { + retVal = false; + break; + } + + if ( !data.nextField() || !data.nextField() || data.nextField() ) + { + retVal = false; + break; + } + } + + return retVal; + } + + @Override + public String getFormatName() + { + return "Wells Fargo"; + } + + @Override + protected boolean parseNext() + throws IOException + { + csvData.nextField(); + dateString = csvData.getField(); + if ( dateString == null || dateString.length() == 0 ) + { // skip empty lines + return false; + } + + csvData.nextField(); + amountString = csvData.getField(); + + csvData.nextField(); // skip '*' + + csvData.nextField(); // skip unknown number + + csvData.nextField(); + description = csvData.getField(); + + return true; + } + + @Override + protected boolean assignDataToTxn( OnlineTxn txn ) throws IOException + { + long amount = 0; + try + { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException( amountString, '.' ); + amount = currency.getLongValue( amountDouble ); + } + catch ( Exception x ) + { + throwException( "Invalid amount." ); + } + + date = dateFormat.parseInt( dateString ); + txn.setAmount( amount ); + txn.setTotalAmount( amount ); + txn.setMemo( description ); + txn.setFITxnId( date + ":" + currency.format( amount, '.' ) + ":" + description ); + txn.setDatePostedInt( date ); + txn.setDateInitiatedInt( date ); + txn.setDateAvailableInt( date ); + + return true; + } + + @Override + public String[] getSupportedDateFormats() + { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats( String[] supportedDateFormats ) + { + ; + } + + @Override + public String getDateFormat() + { + return DATE_FORMAT; + } + + @Override + public void setDateFormat( String format ) + { + if ( !DATE_FORMAT.equals( format ) ) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + @Override + protected int getHeaderCount() + { + return 0; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE b/src/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE new file mode 100644 index 0000000..8fccf92 --- /dev/null +++ b/src/com/moneydance/modules/features/mdcsvimporter/formats/YodleeReader.java-HIDE @@ -0,0 +1,276 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.moneydance.modules.features.mdcsvimporter.formats; + +import com.moneydance.apps.md.model.OnlineTxn; +import com.moneydance.modules.features.mdcsvimporter.CSVData; +import com.moneydance.modules.features.mdcsvimporter.TransactionReader; +import com.moneydance.util.CustomDateFormat; +import com.moneydance.util.StringUtils; +import java.io.IOException; + +/* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + + */ +public class YodleeReader + extends TransactionReader { + + private static final String DATE_FORMAT_US = "MM/DD/YYYY"; + private static final String DATE_FORMAT_EU = "DD/MM/YY"; + private static final String DATE_FORMAT_JP = "YY/MM/DD"; + private static final String DATE_FORMAT_INTN = "YYYY-MM-DD"; + private String dateFormatStringSelected = DATE_FORMAT_INTN; + private static String[] SUPPORTED_DATE_FORMATS = { + DATE_FORMAT_US, DATE_FORMAT_EU, DATE_FORMAT_JP, DATE_FORMAT_INTN + }; + private CustomDateFormat dateFormat = new CustomDateFormat(DATE_FORMAT_INTN); + private String dateFormatString; + private String status; + private String description; + private String splitType; + private String category; + private String currencyString; + private String amountString; + private long amount; + private String userDescription; + private String memo; + private String classification; + private int date; + private static final String STATUS = "status"; + private static final String DATE = "date"; + private static final String DESCRIPTION = "original description"; + private static final String SPLIT = "split type"; + private static final String CATEGORY = "category"; + private static final String CURRENCY = "currency"; + private static final String AMOUNT = "amount"; + private static final String USER_DESCRIPTION = "user description"; + private static final String MEMO = "memo"; + private static final String CLASSIFICATION = "classification"; + private static final String ACCOUNT = "account name"; + + @Override + public boolean canParse(CSVData data) { + try { + data.parseIntoLines(0); + } catch (IOException ex) { + return false; + } + + boolean retVal = data.nextLine() + && data.nextField() && STATUS.equals(data.getField().toLowerCase()) + && data.nextField() && DATE.equals(data.getField().toLowerCase()) + && data.nextField() && DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && SPLIT.equals(data.getField().toLowerCase()) + && data.nextField() && CATEGORY.equals(data.getField().toLowerCase()) + && data.nextField() && CURRENCY.equals(data.getField().toLowerCase()) + && data.nextField() && AMOUNT.equals(data.getField().toLowerCase()) + && data.nextField() && USER_DESCRIPTION.equals(data.getField().toLowerCase()) + && data.nextField() && MEMO.equals(data.getField().toLowerCase()) + && data.nextField() && CLASSIFICATION.equals(data.getField().toLowerCase()) + && data.nextField() && ACCOUNT.equals(data.getField().toLowerCase()) + && !data.nextField(); + + System.out.println( "can parse Yodlee format =" + String.valueOf(retVal) + "=" ); + return retVal; + } + + @Override + public String getFormatName() { + return "Yodlee"; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + * Category + * Currency + * Amount + * User Description + * Memo + * Classification (Tag) + * Account Name + * + */ + @Override + protected boolean parseNext() throws IOException { + + csvData.nextField(); + status = csvData.getField(); +// System.out.println("status: " + status); + +// System.out.println("getting Yodlee dateString..."); + csvData.nextField(); + String dateString = csvData.getField(); + if (dateString == null || dateString.isEmpty()) { + // skip lines without valid dates (or empty) + return false; + } +// System.out.println("dateString: " + dateString); + + csvData.nextField(); + description = csvData.getField(); +// System.out.println("description: " + description); + + csvData.nextField(); + splitType = csvData.getField(); +// System.out.println("splitType: " + splitType); + + csvData.nextField(); + category = csvData.getField();//NOTE: don't set in Txn object! +// System.out.println("category: " + category); + + csvData.nextField(); + currencyString = csvData.getField();//NOTE: not used +// System.out.println("currencyString: " + currencyString); + + csvData.nextField(); + amountString = csvData.getField().trim(); +// System.out.println("amountString: " + amountString); + + csvData.nextField(); + userDescription = csvData.getField(); +// System.out.println("userDescription: " + userDescription); + + csvData.nextField(); + memo = csvData.getField(); +// System.out.println("memo: " + memo); + + csvData.nextField(); + classification = csvData.getField(); +// System.out.println("classification: " + classification); + + csvData.nextField(); + this.accountNameFromCSV = csvData.getField(); +// System.out.println("accountNameFromCSV: " + accountNameFromCSV); + +// System.out.println( "parsing Yodlee amount..."); +// amount = 0; +// try { +// double amountDouble; +// amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); +// System.out.println( "after parseDoubleWithException..."); +// amount = currency.getLongValue(amountDouble); +// } catch (Exception x) { +// throwException("Invalid amount."); +// } +// System.out.println( "parsing Yodlee date..."); + date = dateFormat.parseInt(dateString); + +// System.out.println( "parsed Yodlee txn on " + dateString + " for " + accountNameFromCSV); + return true; + } + + /* + * + * Status (e.g., posted) + * Date (YYYY-MM-DD) + * Original Description (Payee) + * Split Type + x Category + x Currency + * Amount + * User Description + * Memo + x Classification (Tag) + ^ Account Name + * + */ + @Override + protected boolean assignDataToTxn(OnlineTxn txn) throws IOException { + amount = 0; + try { + double amountDouble; + amountDouble = StringUtils.parseDoubleWithException(amountString, '.'); + System.out.println( "after parseDoubleWithException..."); + amount = currency.getLongValue(amountDouble); + } catch (Exception x) { + throwException("Invalid amount."); + } + txn.setAmount(amount); + txn.setTotalAmount(amount); + txn.setPayeeName(description); + txn.setFITxnId(date + ":" + currency.format(amount, '.') + ":" + description); + txn.setDatePostedInt(date); + txn.setDateInitiatedInt(date); + txn.setDateAvailableInt(date); + txn.setMemo(memo); + txn.setRefNum(status + ":" + splitType + ":" + userDescription); + //TODO: classification (e.g., business or personal) + return true; + } + + @Override + public String[] getSupportedDateFormats() { + return SUPPORTED_DATE_FORMATS; + } + + @Override + public void setSupportedDateFormats(String[] supportedDateFormats) { + SUPPORTED_DATE_FORMATS = supportedDateFormats; + } + + public void createSupportedDateFormats(String dateFormatArg) { + System.err.println("\n--------- entered createSupportedDateFormats() dateFormatArg =" + dateFormatArg + "= -------------"); + String[] tmp = new String[1]; + tmp[0] = dateFormatArg; + SUPPORTED_DATE_FORMATS = tmp; + setDateFormat(dateFormatArg); + } + + @Override + public String getDateFormat() { + return DATE_FORMAT_INTN; + } + +// @Override +// public void setDateFormat(String format) { +// if (!DATE_FORMAT.equals(format)) { +// throw new UnsupportedOperationException("Not supported yet."); +// } +// } + @Override + public void setDateFormat(String format) { + if (format == null) { + return; + } + + System.err.println("setDateFormat() format =" + format + "= dateFormatString =" + dateFormatString + "="); + if (!format.equals(dateFormatStringSelected)) { + dateFormat = new CustomDateFormat(format); + dateFormatStringSelected = format; + } + + } + + @Override + protected int getHeaderCount() { + return 1; + } +} diff --git a/src/com/moneydance/modules/features/mdcsvimporter/import.png b/src/com/moneydance/modules/features/mdcsvimporter/import.png new file mode 100644 index 0000000..9614140 Binary files /dev/null and b/src/com/moneydance/modules/features/mdcsvimporter/import.png differ diff --git a/test/.svn/all-wcprops b/test/.svn/all-wcprops new file mode 100644 index 0000000..8909c08 --- /dev/null +++ b/test/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 27 +/svn/!svn/ver/30/trunk/test +END diff --git a/test/.svn/entries b/test/.svn/entries new file mode 100644 index 0000000..7df559d --- /dev/null +++ b/test/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +com +dir + diff --git a/test/com/.svn/all-wcprops b/test/com/.svn/all-wcprops new file mode 100644 index 0000000..fce4ace --- /dev/null +++ b/test/com/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 31 +/svn/!svn/ver/30/trunk/test/com +END diff --git a/test/com/.svn/entries b/test/com/.svn/entries new file mode 100644 index 0000000..3a7fda6 --- /dev/null +++ b/test/com/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +moneydance +dir + diff --git a/test/com/moneydance/.svn/all-wcprops b/test/com/moneydance/.svn/all-wcprops new file mode 100644 index 0000000..cc23a77 --- /dev/null +++ b/test/com/moneydance/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/!svn/ver/30/trunk/test/com/moneydance +END diff --git a/test/com/moneydance/.svn/entries b/test/com/moneydance/.svn/entries new file mode 100644 index 0000000..a5717ec --- /dev/null +++ b/test/com/moneydance/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com/moneydance +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +modules +dir + diff --git a/test/com/moneydance/modules/.svn/all-wcprops b/test/com/moneydance/modules/.svn/all-wcprops new file mode 100644 index 0000000..171b3a8 --- /dev/null +++ b/test/com/moneydance/modules/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/30/trunk/test/com/moneydance/modules +END diff --git a/test/com/moneydance/modules/.svn/entries b/test/com/moneydance/modules/.svn/entries new file mode 100644 index 0000000..ab5933c --- /dev/null +++ b/test/com/moneydance/modules/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com/moneydance/modules +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +features +dir + diff --git a/test/com/moneydance/modules/features/.svn/all-wcprops b/test/com/moneydance/modules/features/.svn/all-wcprops new file mode 100644 index 0000000..9298ced --- /dev/null +++ b/test/com/moneydance/modules/features/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 59 +/svn/!svn/ver/30/trunk/test/com/moneydance/modules/features +END diff --git a/test/com/moneydance/modules/features/.svn/entries b/test/com/moneydance/modules/features/.svn/entries new file mode 100644 index 0000000..894e6e3 --- /dev/null +++ b/test/com/moneydance/modules/features/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com/moneydance/modules/features +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +csvimporter +dir + +mdcsvimporter +dir + diff --git a/test/com/moneydance/modules/features/csvimporter/.svn/all-wcprops b/test/com/moneydance/modules/features/csvimporter/.svn/all-wcprops new file mode 100644 index 0000000..5b74a84 --- /dev/null +++ b/test/com/moneydance/modules/features/csvimporter/.svn/all-wcprops @@ -0,0 +1,5 @@ +K 25 +svn:wc:ra_dav:version-url +V 70 +/svn/!svn/ver/5/trunk/test/com/moneydance/modules/features/csvimporter +END diff --git a/test/com/moneydance/modules/features/csvimporter/.svn/entries b/test/com/moneydance/modules/features/csvimporter/.svn/entries new file mode 100644 index 0000000..1f029e6 --- /dev/null +++ b/test/com/moneydance/modules/features/csvimporter/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com/moneydance/modules/features/csvimporter +https://mdcsvimporter.googlecode.com/svn + + + +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops b/test/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops new file mode 100644 index 0000000..635ae1e --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/all-wcprops @@ -0,0 +1,47 @@ +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/30/trunk/test/com/moneydance/modules/features/mdcsvimporter +END +CustomReaderDialogTest.java +K 25 +svn:wc:ra_dav:version-url +V 101 +/svn/!svn/ver/96/trunk/test/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialogTest.java +END +CSVReaderTest.java +K 25 +svn:wc:ra_dav:version-url +V 92 +/svn/!svn/ver/96/trunk/test/com/moneydance/modules/features/mdcsvimporter/CSVReaderTest.java +END +MainTest.java +K 25 +svn:wc:ra_dav:version-url +V 87 +/svn/!svn/ver/96/trunk/test/com/moneydance/modules/features/mdcsvimporter/MainTest.java +END +aa-test.csv +K 25 +svn:wc:ra_dav:version-url +V 85 +/svn/!svn/ver/69/trunk/test/com/moneydance/modules/features/mdcsvimporter/aa-test.csv +END +DateGuesserTest.java +K 25 +svn:wc:ra_dav:version-url +V 94 +/svn/!svn/ver/96/trunk/test/com/moneydance/modules/features/mdcsvimporter/DateGuesserTest.java +END +dateGuesser.csv +K 25 +svn:wc:ra_dav:version-url +V 88 +/svn/!svn/ver/5/trunk/test/com/moneydance/modules/features/mdcsvimporter/dateGuesser.csv +END +CSVDataTest.java +K 25 +svn:wc:ra_dav:version-url +V 90 +/svn/!svn/ver/96/trunk/test/com/moneydance/modules/features/mdcsvimporter/CSVDataTest.java +END diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/entries b/test/com/moneydance/modules/features/mdcsvimporter/.svn/entries new file mode 100644 index 0000000..70eb6e1 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/entries @@ -0,0 +1,266 @@ +10 + +dir +63 +https://mdcsvimporter.googlecode.com/svn/trunk/test/com/moneydance/modules/features/mdcsvimporter +https://mdcsvimporter.googlecode.com/svn + + + +2010-04-08T19:39:15.220338Z +30 +Jovanovic.Milutin + + +svn:special svn:externals svn:needs-lock + + + + + + + + + + + +2ef8ec78-0d1d-11de-a6e9-d320b29efae0 + +CSVDataTest.java +file +96 + + + +2014-11-24T13:58:56.512000Z +ae584aa73dd6b340ca3ea8c0f500cd31 +2014-11-24T14:01:24.546578Z +96 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +2482 + +CSVReaderTest.java +file +96 + + + +2014-11-24T13:59:16.554000Z +9130198aed374c82f8d92f8a6b57f4d3 +2014-11-24T14:01:24.546578Z +96 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +1995 + +CustomReaderDialogTest.java +file +96 + + + +2014-11-24T13:59:25.373000Z +af13e0e35f52da7b1a8a96dee0cf7ff3 +2014-11-24T14:01:24.546578Z +96 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +3036 + +DateGuesserTest.java +file +96 + + + +2014-11-24T13:59:39.540000Z +fe752b24192dcdf93dfb92d611364265 +2014-11-24T14:01:24.546578Z +96 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +1631 + +MainTest.java +file +96 + + + +2014-11-24T13:59:58.822000Z +45c396cc68ec857a75a9f4fcf45a599d +2014-11-24T14:01:24.546578Z +96 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +4245 + +aa-test.csv +file +69 + + + +2011-10-31T20:22:45.000000Z +f293cf3b128b79fabd904a9a87af6bd6 +2011-11-03T03:58:32.452334Z +69 +stashu.pub@gmail.com + + + + + + + + + + + + + + + + + + + + + +310 + +dateGuesser.csv +file + + + + +2011-10-03T21:48:08.000000Z +011dc441d63c756a14d54bd4873a7c42 +2009-03-10T18:37:22.954352Z +5 +Jovanovic.Milutin + + + + + + + + + + + + + + + + + + + + + +3029 + diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.netbeans-base new file mode 100644 index 0000000..cf2973b --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.netbeans-base @@ -0,0 +1,104 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVDataTest +{ + public CSVDataTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader csvReader = new CSVReader( data ); + CSVData csvData = new CSVData( csvReader ); + + csvData.parseIntoLines( ',' ); + + System.out.println( "finished transReader.parse" ); + + doTest1( csvData ); + csvReader.close(); + } + + private void doTest1( CSVData reader ) + throws IOException + { + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 1" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 2" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 11" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 12" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 21" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 22" ); + assertFalse( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertFalse( reader.nextField() ); + + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.svn-base new file mode 100644 index 0000000..cf2973b --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVDataTest.java.svn-base @@ -0,0 +1,104 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVDataTest +{ + public CSVDataTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader csvReader = new CSVReader( data ); + CSVData csvData = new CSVData( csvReader ); + + csvData.parseIntoLines( ',' ); + + System.out.println( "finished transReader.parse" ); + + doTest1( csvData ); + csvReader.close(); + } + + private void doTest1( CSVData reader ) + throws IOException + { + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 1" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 2" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 11" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 12" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 21" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 22" ); + assertFalse( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertFalse( reader.nextField() ); + + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.netbeans-base new file mode 100644 index 0000000..ee875a1 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.netbeans-base @@ -0,0 +1,87 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVReaderTest +{ + public CSVReaderTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader cvsReader = new CSVReader( data ); + doTest1( cvsReader ); + } + + private void doTest1( CSVReader reader ) + throws IOException + { + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "Column 1" ); + assertEquals( reader.nextField(), "Column 2" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 11" ); + assertEquals( reader.nextField(), "value 12" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 21" ); + assertEquals( reader.nextField(), "value 22" ); + assertNull( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertNull( reader.nextField() ); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.svn-base new file mode 100644 index 0000000..ee875a1 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CSVReaderTest.java.svn-base @@ -0,0 +1,87 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVReaderTest +{ + public CSVReaderTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader cvsReader = new CSVReader( data ); + doTest1( cvsReader ); + } + + private void doTest1( CSVReader reader ) + throws IOException + { + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "Column 1" ); + assertEquals( reader.nextField(), "Column 2" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 11" ); + assertEquals( reader.nextField(), "value 12" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 21" ); + assertEquals( reader.nextField(), "value 22" ); + assertNull( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertNull( reader.nextField() ); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.netbeans-base new file mode 100644 index 0000000..e22b184 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.netbeans-base @@ -0,0 +1,124 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class CustomReaderDialogTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public CustomReaderDialogTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { +// main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ + @Ignore + public void expectDateProblem() + throws IOException + { + URL url = MainTest.class.getResource( "aa-test.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + //String testUri = ImportDialog.RUN_ARGS_FILE + "=./aa-test.csv" + + "&fileformat=eu date test" + + "&importaccount=IMPORT BANK" + + "&importtype=online&JUNITFLAG2" + ; + + main1.invoke( testUri ); + + } + +// @Test + @Ignore + public void dummySoItHasOneTest() + { + + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.svn-base new file mode 100644 index 0000000..e22b184 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/CustomReaderDialogTest.java.svn-base @@ -0,0 +1,124 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class CustomReaderDialogTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public CustomReaderDialogTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { +// main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ + @Ignore + public void expectDateProblem() + throws IOException + { + URL url = MainTest.class.getResource( "aa-test.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + //String testUri = ImportDialog.RUN_ARGS_FILE + "=./aa-test.csv" + + "&fileformat=eu date test" + + "&importaccount=IMPORT BANK" + + "&importtype=online&JUNITFLAG2" + ; + + main1.invoke( testUri ); + + } + +// @Test + @Ignore + public void dummySoItHasOneTest() + { + + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.netbeans-base new file mode 100644 index 0000000..4461eb6 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.netbeans-base @@ -0,0 +1,80 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.CSVReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class DateGuesserTest +{ + public DateGuesserTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test of class DateGuesser. + */ +// @Test + @Ignore + public void testCheckDateString() + throws IOException + { + Reader file = new InputStreamReader( + DateGuesserTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + CSVReader reader = new CSVReader( file ); + DateGuesser guesser = new DateGuesser(); + + while ( reader.nextLine() ) { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) { + guesser.checkDateString( s ); + } + } + + guesser.getBestFormatProbability(); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.svn-base new file mode 100644 index 0000000..4461eb6 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/DateGuesserTest.java.svn-base @@ -0,0 +1,80 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.CSVReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class DateGuesserTest +{ + public DateGuesserTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test of class DateGuesser. + */ +// @Test + @Ignore + public void testCheckDateString() + throws IOException + { + Reader file = new InputStreamReader( + DateGuesserTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + CSVReader reader = new CSVReader( file ); + DateGuesser guesser = new DateGuesser(); + + while ( reader.nextLine() ) { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) { + guesser.checkDateString( s ); + } + } + + guesser.getBestFormatProbability(); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.netbeans-base new file mode 100644 index 0000000..a1fec2a --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.netbeans-base @@ -0,0 +1,153 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class MainTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public MainTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ +// @Test + @Ignore + public void expectInvalidFileAndImportaccount() + throws IOException + { + String testUri = ImportDialog.RUN_ARGS_FILE + "=/zzz111222qqq.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILE ); + assertEquals( (Integer) main1.getErrCodeList().get( 1 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + } + + @Ignore + public void expectInvalidFileformat() + throws IOException + { +// Reader file = new InputStreamReader( +// MainTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + + URL url = MainTest.class.getResource( "dateGuesser.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + + "&fileformat=Discover Card" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + } + +// @Test + @Ignore + public void expectMissingFileArg() + throws IOException + { + String testUri = "importaccount=1232zxzcx" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.svn-base new file mode 100644 index 0000000..a1fec2a --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/MainTest.java.svn-base @@ -0,0 +1,153 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class MainTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public MainTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ +// @Test + @Ignore + public void expectInvalidFileAndImportaccount() + throws IOException + { + String testUri = ImportDialog.RUN_ARGS_FILE + "=/zzz111222qqq.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILE ); + assertEquals( (Integer) main1.getErrCodeList().get( 1 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + } + + @Ignore + public void expectInvalidFileformat() + throws IOException + { +// Reader file = new InputStreamReader( +// MainTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + + URL url = MainTest.class.getResource( "dateGuesser.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + + "&fileformat=Discover Card" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + } + +// @Test + @Ignore + public void expectMissingFileArg() + throws IOException + { + String testUri = "importaccount=1232zxzcx" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.netbeans-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.netbeans-base new file mode 100644 index 0000000..f18b4fe --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.netbeans-base @@ -0,0 +1,5 @@ +"Dato";"Tekst";"Beløb";"Saldo";"Status";"Afstemt" +"30.08.2011";"Valutahandel";"6,819.74";"6,819.74";"Udført";"Nej" +"30.08.2011";"Kontantvaluta";"-35.00";"6,784.74";"Udført";"Nej" +"05.09.2011";"Udbetaling";"-5.000.00";"1,784.74";"Udført";"Nej" +"13.09.2011";"Panidraetdk";"-100.00";"1,684.74";"Udført";"Nej" \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.svn-base new file mode 100644 index 0000000..f18b4fe --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/aa-test.csv.svn-base @@ -0,0 +1,5 @@ +"Dato";"Tekst";"Beløb";"Saldo";"Status";"Afstemt" +"30.08.2011";"Valutahandel";"6,819.74";"6,819.74";"Udført";"Nej" +"30.08.2011";"Kontantvaluta";"-35.00";"6,784.74";"Udført";"Nej" +"05.09.2011";"Udbetaling";"-5.000.00";"1,784.74";"Udført";"Nej" +"13.09.2011";"Panidraetdk";"-100.00";"1,684.74";"Udført";"Nej" \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/dateGuesser.csv.svn-base b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/dateGuesser.csv.svn-base new file mode 100644 index 0000000..688ce29 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/.svn/text-base/dateGuesser.csv.svn-base @@ -0,0 +1,52 @@ +Transaction Date,Posting Date,Description,Amount +"02/02/2009","02/02/2009","Transaction Description","-5,082.82" +"01/15/2009","01/16/2009","Transaction Description","30.00" +"01/15/2009","01/16/2009","Transaction Description","84.53" +"01/16/2009","01/20/2009","Transaction Description","24.00" +"01/16/2009","01/19/2009","Transaction Description","19.81" +"01/17/2009","01/19/2009","Transaction Description","195.00" +"01/17/2009","01/19/2009","Transaction Description","31.34" +"01/17/2009","01/19/2009","Transaction Description","63.53" +"01/17/2009","01/19/2009","Transaction Description","11.30" +"01/20/2009","01/27/2009","Transaction Description","32.00" +"01/20/2009","01/21/2009","Transaction Description","51.83" +"01/20/2009","01/21/2009","Transaction Description","21.00" +"01/20/2009","01/21/2009","Transaction Description","76.34" +"01/21/2009","01/23/2009","Transaction Description","28.00" +"01/21/2009","01/22/2009","Transaction Description","46.45" +"01/21/2009","01/23/2009","Transaction Description","15.98" +"01/22/2009","01/24/2009","Transaction Description","39.02" +"01/22/2009","01/23/2009","Transaction Description","60.00" +"01/25/2009","01/26/2009","Transaction Description","153.05" +"01/28/2009","01/29/2009","Transaction Description","17.98" +"01/31/2009","02/02/2009","Transaction Description","15.84" +"01/31/2009","02/02/2009","Transaction Description","10.00" +"01/31/2009","02/02/2009","Transaction Description","40.00" +"02/01/2009","02/02/2009","Transaction Description","41.00" +"02/01/2009","02/02/2009","Transaction Description","144.39" +"02/02/2009","02/03/2009","Transaction Description","30.50" +"02/02/2009","02/03/2009","Transaction Description","23.00" +"02/02/2009","02/03/2009","Transaction Description","93.77" +"02/03/2009","02/05/2009","Transaction Description","7.33" +"02/03/2009","02/04/2009","Transaction Description","21.00" +"02/03/2009","02/04/2009","Transaction Description","41.47" +"02/03/2009","02/04/2009","Transaction Description","36.50" +"02/03/2009","02/05/2009","Transaction Description","56.49" +"02/03/2009","02/04/2009","Transaction Description","40.97" +"02/05/2009","02/09/2009","Transaction Description","87.24" +"02/05/2009","02/06/2009","Transaction Description","33.02" +"02/06/2009","02/09/2009","Transaction Description","40.00" +"02/06/2009","02/07/2009","Transaction Description","30.00" +"02/07/2009","02/10/2009","Transaction Description","296.35" +"02/08/2009","02/09/2009","Transaction Description","144.15" +"02/08/2009","02/09/2009","Transaction Description","214.36" +"02/08/2009","02/11/2009","Transaction Description","77.24" +"02/09/2009","02/11/2009","Transaction Description","39.19" +"02/10/2009","02/12/2009","Transaction Description","56.31" +"02/10/2009","02/12/2009","Transaction Description","10.00" +"02/10/2009","02/11/2009","Transaction Description","54.36" +"02/11/2009","02/12/2009","Transaction Description","63.17" +"02/11/2009","02/12/2009","Transaction Description","89.94" +"02/2009/11","02/13/2009","Transaction Description","65.00" + +Date downloaded:,"02/17/2009" diff --git a/test/com/moneydance/modules/features/mdcsvimporter/CSVDataTest.java b/test/com/moneydance/modules/features/mdcsvimporter/CSVDataTest.java new file mode 100644 index 0000000..cf2973b --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/CSVDataTest.java @@ -0,0 +1,104 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.apps.md.model.Account; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVDataTest +{ + public CSVDataTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader csvReader = new CSVReader( data ); + CSVData csvData = new CSVData( csvReader ); + + csvData.parseIntoLines( ',' ); + + System.out.println( "finished transReader.parse" ); + + doTest1( csvData ); + csvReader.close(); + } + + private void doTest1( CSVData reader ) + throws IOException + { + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 1" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "Column 2" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 11" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 12" ); + assertFalse( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 21" ); + assertTrue( reader.nextField() ); + assertEquals( reader.getField(), "value 22" ); + assertFalse( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertFalse( reader.nextField() ); + + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/CSVReaderTest.java b/test/com/moneydance/modules/features/mdcsvimporter/CSVReaderTest.java new file mode 100644 index 0000000..ee875a1 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/CSVReaderTest.java @@ -0,0 +1,87 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.io.IOException; +import java.io.StringReader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class CSVReaderTest +{ + public CSVReaderTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + private final String test1 = "\"Column 1\",\"Column 2\"\n\"value 11\",\"value 12\"\n" + + "\"value 21\",\"value 22\""; + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + +// @Test + @Ignore + public void simpleTest1() + throws IOException + { + StringReader data = new StringReader( test1 ); + CSVReader cvsReader = new CSVReader( data ); + doTest1( cvsReader ); + } + + private void doTest1( CSVReader reader ) + throws IOException + { + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "Column 1" ); + assertEquals( reader.nextField(), "Column 2" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 11" ); + assertEquals( reader.nextField(), "value 12" ); + assertNull( reader.nextField() ); + assertTrue( reader.nextLine() ); + assertEquals( reader.nextField(), "value 21" ); + assertEquals( reader.nextField(), "value 22" ); + assertNull( reader.nextField() ); + assertFalse( reader.nextLine() ); + assertNull( reader.nextField() ); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialogTest.java b/test/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialogTest.java new file mode 100644 index 0000000..e22b184 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/CustomReaderDialogTest.java @@ -0,0 +1,124 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class CustomReaderDialogTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public CustomReaderDialogTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { +// main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ + @Ignore + public void expectDateProblem() + throws IOException + { + URL url = MainTest.class.getResource( "aa-test.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + //String testUri = ImportDialog.RUN_ARGS_FILE + "=./aa-test.csv" + + "&fileformat=eu date test" + + "&importaccount=IMPORT BANK" + + "&importtype=online&JUNITFLAG2" + ; + + main1.invoke( testUri ); + + } + +// @Test + @Ignore + public void dummySoItHasOneTest() + { + + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/DateGuesserTest.java b/test/com/moneydance/modules/features/mdcsvimporter/DateGuesserTest.java new file mode 100644 index 0000000..4461eb6 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/DateGuesserTest.java @@ -0,0 +1,80 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import com.moneydance.modules.features.mdcsvimporter.DateGuesser; +import com.moneydance.modules.features.mdcsvimporter.CSVReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import org.junit.Ignore; + +/** + * + * @author miki + */ +public class DateGuesserTest +{ + public DateGuesserTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test of class DateGuesser. + */ +// @Test + @Ignore + public void testCheckDateString() + throws IOException + { + Reader file = new InputStreamReader( + DateGuesserTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + CSVReader reader = new CSVReader( file ); + DateGuesser guesser = new DateGuesser(); + + while ( reader.nextLine() ) { + for ( String s = reader.nextField(); s != null; s = reader.nextField() ) { + guesser.checkDateString( s ); + } + } + + guesser.getBestFormatProbability(); + } +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/MainTest.java b/test/com/moneydance/modules/features/mdcsvimporter/MainTest.java new file mode 100644 index 0000000..a1fec2a --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/MainTest.java @@ -0,0 +1,153 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.moneydance.modules.features.mdcsvimporter; + +import java.net.URL; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Stan Towianski + * NOTE: Cannot test everything I want to because I cannot get FeatureModuleContext() because + * I do not know how to 'start' Moneydance itself, so I cannot get account lists or anything. + */ +public class MainTest +{ + Main main1 = new Main(); + //MoneydanceGUI mdgui = new MoneydanceGUI(); + /* + FeatureModuleContext context = new FeatureModuleContext() { + + public RootAccount getRootAccount() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public String getVersion() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public int getBuild() { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void showURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerFeature(FeatureModule fm, String string, Image image, String string1) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerHomePageView(FeatureModule fm, HomePageView hpv) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public void registerAccountEditor(FeatureModule fm, int i, AccountEditor ae) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + */ + + public MainTest() + { + } + + @BeforeClass + public static void setUpClass() + throws Exception + { + } + + @AfterClass + public static void tearDownClass() + throws Exception + { + } + + @Before + public void setUp() + { + main1.init(); + } + + @After + public void tearDown() + { + } + + @Test + public void noopTest() + throws IOException + { + System.out.println( "finished noopTest() test." ); + } + + /** + * Test + */ +// @Test + @Ignore + public void expectInvalidFileAndImportaccount() + throws IOException + { + String testUri = ImportDialog.RUN_ARGS_FILE + "=/zzz111222qqq.csv" + + "&fileformat=Discover Card" + + "&importaccount=IMPORT BANK" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILE ); + assertEquals( (Integer) main1.getErrCodeList().get( 1 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_IMPORTACCOUNT ); + } + + @Ignore + public void expectInvalidFileformat() + throws IOException + { +// Reader file = new InputStreamReader( +// MainTest.class.getResourceAsStream( "dateGuesser.csv" ) ); + + URL url = MainTest.class.getResource( "dateGuesser.csv" ); + System.out.println( "url filepath =" + url.getFile() + "=" ); + + String testUri = ImportDialog.RUN_ARGS_FILE + "=" + url.getFile() + + "&fileformat=Discover Card" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_INVALID_FILEFORMAT_FOR_FILE ); + } + +// @Test + @Ignore + public void expectMissingFileArg() + throws IOException + { + String testUri = "importaccount=1232zxzcx" + + "&deletecsvfileflag" + + "&importtype=online&JUNITFLAG&processFlag" + ; + + main1.invoke( testUri ); + + assertEquals( (Integer) main1.getErrCodeList().get( 0 ), (Integer) ImportDialog.RUN_ARGS_ERRORCODE_REQUIRES_FILE ); + } + +} \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/aa-test.csv b/test/com/moneydance/modules/features/mdcsvimporter/aa-test.csv new file mode 100644 index 0000000..f18b4fe --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/aa-test.csv @@ -0,0 +1,5 @@ +"Dato";"Tekst";"Beløb";"Saldo";"Status";"Afstemt" +"30.08.2011";"Valutahandel";"6,819.74";"6,819.74";"Udført";"Nej" +"30.08.2011";"Kontantvaluta";"-35.00";"6,784.74";"Udført";"Nej" +"05.09.2011";"Udbetaling";"-5.000.00";"1,784.74";"Udført";"Nej" +"13.09.2011";"Panidraetdk";"-100.00";"1,684.74";"Udført";"Nej" \ No newline at end of file diff --git a/test/com/moneydance/modules/features/mdcsvimporter/dateGuesser.csv b/test/com/moneydance/modules/features/mdcsvimporter/dateGuesser.csv new file mode 100644 index 0000000..688ce29 --- /dev/null +++ b/test/com/moneydance/modules/features/mdcsvimporter/dateGuesser.csv @@ -0,0 +1,52 @@ +Transaction Date,Posting Date,Description,Amount +"02/02/2009","02/02/2009","Transaction Description","-5,082.82" +"01/15/2009","01/16/2009","Transaction Description","30.00" +"01/15/2009","01/16/2009","Transaction Description","84.53" +"01/16/2009","01/20/2009","Transaction Description","24.00" +"01/16/2009","01/19/2009","Transaction Description","19.81" +"01/17/2009","01/19/2009","Transaction Description","195.00" +"01/17/2009","01/19/2009","Transaction Description","31.34" +"01/17/2009","01/19/2009","Transaction Description","63.53" +"01/17/2009","01/19/2009","Transaction Description","11.30" +"01/20/2009","01/27/2009","Transaction Description","32.00" +"01/20/2009","01/21/2009","Transaction Description","51.83" +"01/20/2009","01/21/2009","Transaction Description","21.00" +"01/20/2009","01/21/2009","Transaction Description","76.34" +"01/21/2009","01/23/2009","Transaction Description","28.00" +"01/21/2009","01/22/2009","Transaction Description","46.45" +"01/21/2009","01/23/2009","Transaction Description","15.98" +"01/22/2009","01/24/2009","Transaction Description","39.02" +"01/22/2009","01/23/2009","Transaction Description","60.00" +"01/25/2009","01/26/2009","Transaction Description","153.05" +"01/28/2009","01/29/2009","Transaction Description","17.98" +"01/31/2009","02/02/2009","Transaction Description","15.84" +"01/31/2009","02/02/2009","Transaction Description","10.00" +"01/31/2009","02/02/2009","Transaction Description","40.00" +"02/01/2009","02/02/2009","Transaction Description","41.00" +"02/01/2009","02/02/2009","Transaction Description","144.39" +"02/02/2009","02/03/2009","Transaction Description","30.50" +"02/02/2009","02/03/2009","Transaction Description","23.00" +"02/02/2009","02/03/2009","Transaction Description","93.77" +"02/03/2009","02/05/2009","Transaction Description","7.33" +"02/03/2009","02/04/2009","Transaction Description","21.00" +"02/03/2009","02/04/2009","Transaction Description","41.47" +"02/03/2009","02/04/2009","Transaction Description","36.50" +"02/03/2009","02/05/2009","Transaction Description","56.49" +"02/03/2009","02/04/2009","Transaction Description","40.97" +"02/05/2009","02/09/2009","Transaction Description","87.24" +"02/05/2009","02/06/2009","Transaction Description","33.02" +"02/06/2009","02/09/2009","Transaction Description","40.00" +"02/06/2009","02/07/2009","Transaction Description","30.00" +"02/07/2009","02/10/2009","Transaction Description","296.35" +"02/08/2009","02/09/2009","Transaction Description","144.15" +"02/08/2009","02/09/2009","Transaction Description","214.36" +"02/08/2009","02/11/2009","Transaction Description","77.24" +"02/09/2009","02/11/2009","Transaction Description","39.19" +"02/10/2009","02/12/2009","Transaction Description","56.31" +"02/10/2009","02/12/2009","Transaction Description","10.00" +"02/10/2009","02/11/2009","Transaction Description","54.36" +"02/11/2009","02/12/2009","Transaction Description","63.17" +"02/11/2009","02/12/2009","Transaction Description","89.94" +"02/2009/11","02/13/2009","Transaction Description","65.00" + +Date downloaded:,"02/17/2009"