MoneyWiseQIFLine.java
/*
* MoneyWise: Finance Application
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.moneywise.quicken.file;
import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimal;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
import io.github.tonywasher.joceanus.oceanus.decimal.OceanusUnits;
import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
import io.github.tonywasher.joceanus.moneywise.quicken.definitions.MoneyWiseQLineType;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* A standard event line in the QIF file.
*
* @param <T> the line type
*/
public abstract class MoneyWiseQIFLine<T extends MoneyWiseQLineType> {
/**
* Reconciled flag.
*/
protected static final String QIF_RECONCILED = "X";
/**
* Transfer begin char.
*/
private static final String QIF_XFERSTART = "[";
/**
* Transfer end char.
*/
private static final String QIF_XFEREND = "]";
/**
* Class indicator.
*/
private static final String QIF_CLASS = "/";
/**
* Class separator.
*/
private static final String QIF_CLASSSEP = "-";
/**
* Category separator.
*/
private static final String QIF_CATSEP = "!";
/**
* Obtain line type.
*
* @return the line type
*/
public abstract T getLineType();
/**
* Format the data.
*
* @param pFormatter the data formatter
* @param pBuilder the string builder
*/
protected abstract void formatData(OceanusDataFormatter pFormatter,
StringBuilder pBuilder);
/**
* Format lines.
*
* @param pFormatter the data formatter
* @param pBuilder the string builder
*/
protected void formatLine(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Add the lineType */
final T myType = getLineType();
pBuilder.append(myType.getSymbol());
/* Format the Data */
formatData(pFormatter, pBuilder);
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFLine<?> myLine = (MoneyWiseQIFLine<?>) pThat;
/* Check value */
return getLineType().equals(myLine.getLineType());
}
@Override
public int hashCode() {
return getLineType().hashCode();
}
/**
* The String line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFStringLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The value.
*/
private final String theValue;
/**
* Constructor.
*
* @param pValue the Value
*/
protected MoneyWiseQIFStringLine(final String pValue) {
/* Store the value */
theValue = pValue;
}
@Override
public String toString() {
return getValue();
}
/**
* Obtain Value.
*
* @return the value
*/
protected String getValue() {
return theValue;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(theValue);
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFStringLine<?> myLine = (MoneyWiseQIFStringLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theValue.equals(myLine.getValue());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theValue.hashCode();
}
}
/**
* The Money line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFMoneyLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The money.
*/
private final OceanusMoney theMoney;
/**
* Constructor.
*
* @param pMoney the Money
*/
protected MoneyWiseQIFMoneyLine(final OceanusMoney pMoney) {
/* Store data */
theMoney = pMoney;
}
@Override
public String toString() {
return getMoney().toString();
}
/**
* Obtain Money.
*
* @return the money
*/
protected OceanusMoney getMoney() {
return theMoney;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Convert to Decimal */
final OceanusDecimal myDecimal = new OceanusDecimal(theMoney);
/* Append the string data */
pBuilder.append(pFormatter.formatObject(myDecimal));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFMoneyLine<?> myLine = (MoneyWiseQIFMoneyLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theMoney.equals(myLine.getMoney());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theMoney.hashCode();
}
}
/**
* The Date line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFDateLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The date.
*/
private final OceanusDate theDate;
/**
* Constructor.
*
* @param pDate the Date
*/
protected MoneyWiseQIFDateLine(final OceanusDate pDate) {
/* Store the date */
theDate = pDate;
}
@Override
public String toString() {
return getDate().toString();
}
/**
* Obtain Date.
*
* @return the date
*/
public OceanusDate getDate() {
return theDate;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(pFormatter.formatObject(theDate));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFDateLine<?> myLine = (MoneyWiseQIFDateLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theDate.equals(myLine.getDate());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theDate.hashCode();
}
}
/**
* The Flag line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFFlagLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The flag status.
*/
private final Boolean isSet;
/**
* Constructor.
*
* @param pSet is the flag set?
*/
protected MoneyWiseQIFFlagLine(final Boolean pSet) {
/* Store data */
isSet = pSet;
}
@Override
public String toString() {
return isSet().toString();
}
/**
* Obtain Cleared status.
*
* @return true/false
*/
protected Boolean isSet() {
return isSet;
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFFlagLine<?> myLine = (MoneyWiseQIFFlagLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return isSet.equals(myLine.isSet());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + isSet.hashCode();
}
}
/**
* The Cleared line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFClearedLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFFlagLine<X> {
/**
* Constructor.
*
* @param pSet is the flag set?
*/
protected MoneyWiseQIFClearedLine(final Boolean pSet) {
/* Call super-constructor */
super(pSet);
}
/**
* Obtain Cleared status.
*
* @return true/false
*/
public Boolean isCleared() {
return isSet();
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* If we should set the flag */
if (isSet()) {
/* Add the flag */
pBuilder.append(QIF_RECONCILED);
}
}
}
/**
* The Price line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFPriceLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The price.
*/
private final OceanusPrice thePrice;
/**
* Constructor.
*
* @param pPrice the Price
*/
protected MoneyWiseQIFPriceLine(final OceanusPrice pPrice) {
/* Store data */
thePrice = pPrice;
}
@Override
public String toString() {
return getPrice().toString();
}
/**
* Obtain price.
*
* @return the price
*/
protected OceanusPrice getPrice() {
return thePrice;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Convert to Decimal */
final OceanusDecimal myDecimal = new OceanusDecimal(thePrice);
/* Append the string data */
pBuilder.append(pFormatter.formatObject(myDecimal));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFPriceLine<?> myLine = (MoneyWiseQIFPriceLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return thePrice.equals(myLine.getPrice());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + thePrice.hashCode();
}
}
/**
* The Units line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFUnitsLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The units.
*/
private final OceanusUnits theUnits;
/**
* Constructor.
*
* @param pUnits the Units
*/
protected MoneyWiseQIFUnitsLine(final OceanusUnits pUnits) {
/* Store data */
theUnits = pUnits;
}
@Override
public String toString() {
return getUnits().toString();
}
/**
* Obtain units.
*
* @return the units
*/
protected OceanusUnits getUnits() {
return theUnits;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(pFormatter.formatObject(theUnits));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFUnitsLine<?> myLine = (MoneyWiseQIFUnitsLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theUnits.equals(myLine.getUnits());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theUnits.hashCode();
}
}
/**
* The Rate line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFRateLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The Rate.
*/
private final OceanusRate theRate;
/**
* Constructor.
*
* @param pPercent the percentage
*/
protected MoneyWiseQIFRateLine(final OceanusRate pPercent) {
/* Store data */
theRate = pPercent;
}
@Override
public String toString() {
return getRate().toString();
}
/**
* Obtain rate.
*
* @return the rate
*/
protected OceanusRate getRate() {
return theRate;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(pFormatter.formatObject(theRate));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFRateLine<?> myLine = (MoneyWiseQIFRateLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theRate.equals(myLine.getRate());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theRate.hashCode();
}
}
/**
* The Ratio line.
*
* @param <X> the line type
*/
protected abstract static class MoneyWiseQIFRatioLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The ratio.
*/
private final OceanusRatio theRatio;
/**
* Constructor.
*
* @param pRatio the Ratio
*/
protected MoneyWiseQIFRatioLine(final OceanusRatio pRatio) {
/* Store data */
theRatio = pRatio;
}
@Override
public String toString() {
return getRatio().toString();
}
/**
* Obtain ratio.
*
* @return the ratio
*/
protected OceanusRatio getRatio() {
return theRatio;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(pFormatter.formatObject(theRatio));
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFRatioLine<?> myLine = (MoneyWiseQIFRatioLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theRatio.equals(myLine.getRatio());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theRatio.hashCode();
}
}
/**
* The Security line.
*
* @param <X> the line type
*/
public abstract static class MoneyWiseQIFSecurityLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The security.
*/
private final MoneyWiseQIFSecurity theSecurity;
/**
* Constructor.
*
* @param pSecurity the Security
*/
protected MoneyWiseQIFSecurityLine(final MoneyWiseQIFSecurity pSecurity) {
/* Store data */
theSecurity = pSecurity;
}
@Override
public String toString() {
return theSecurity.toString();
}
/**
* Obtain account.
*
* @return the account
*/
public MoneyWiseQIFSecurity getSecurity() {
return theSecurity;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the security name */
pBuilder.append(theSecurity.getName());
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFSecurityLine<?> myLine = (MoneyWiseQIFSecurityLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return theSecurity.equals(myLine.getSecurity());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + theSecurity.hashCode();
}
}
/**
* The Account line.
*
* @param <X> the line type
*/
public abstract static class MoneyWiseQIFXferAccountLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The account.
*/
private final MoneyWiseQIFAccount theAccount;
/**
* The class list.
*/
private final List<MoneyWiseQIFClass> theClasses;
/**
* Constructor.
*
* @param pAccount the Account
*/
protected MoneyWiseQIFXferAccountLine(final MoneyWiseQIFAccount pAccount) {
this(pAccount, null);
}
/**
* Constructor.
*
* @param pAccount the Account
* @param pClasses the classes
*/
protected MoneyWiseQIFXferAccountLine(final MoneyWiseQIFAccount pAccount,
final List<MoneyWiseQIFClass> pClasses) {
/* Store data */
theAccount = pAccount;
theClasses = pClasses;
}
@Override
public String toString() {
return theAccount.toString();
}
/**
* Obtain account.
*
* @return the account
*/
public MoneyWiseQIFAccount getAccount() {
return theAccount;
}
/**
* Obtain class list.
*
* @return the class list
*/
public List<MoneyWiseQIFClass> getClassList() {
return theClasses;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(QIF_XFERSTART);
pBuilder.append(theAccount.getName());
pBuilder.append(QIF_XFEREND);
/* If we have classes */
if (theClasses != null) {
/* Add class indicator */
pBuilder.append(QIF_CLASS);
/* Iterate through the list */
final Iterator<MoneyWiseQIFClass> myIterator = theClasses.iterator();
while (myIterator.hasNext()) {
final MoneyWiseQIFClass myClass = myIterator.next();
/* Add to the list */
pBuilder.append(myClass.getName());
if (myIterator.hasNext()) {
pBuilder.append(QIF_CLASSSEP);
}
}
}
}
/**
* Parse account line.
*
* @param pFile the QIF File definitions
* @param pLine the line.
* @return the account name (or null)
*/
protected static MoneyWiseQIFAccount parseAccount(final MoneyWiseQIFFile pFile,
final String pLine) {
/* Determine line to use */
String myLine = pLine;
/* If the line contains a category separator */
if (pLine.contains(QIF_CATSEP)) {
/* Move to data following separator */
final int i = pLine.indexOf(QIF_CATSEP);
myLine = pLine.substring(i + 1);
}
/* If the line contains classes */
if (myLine.contains(QIF_CLASS)) {
/* drop class data */
final int i = myLine.indexOf(QIF_CLASS);
myLine = myLine.substring(0, i);
}
/* If we have the account delimiters */
if ((myLine.startsWith(QIF_XFERSTART))
&& (myLine.endsWith(QIF_XFEREND))) {
/* Remove account delimiters */
final int i = QIF_XFERSTART.length();
final int j = QIF_XFEREND.length();
final String myAccount = myLine.substring(i, myLine.length()
- j);
return pFile.getAccount(myAccount);
}
/* Return no account */
return null;
}
/**
* Parse account classes.
*
* @param pFile the QIF File
* @param pLine the line.
* @return the account name (or null)
*/
protected static List<MoneyWiseQIFClass> parseAccountClasses(final MoneyWiseQIFFile pFile,
final String pLine) {
/* Determine line to use */
String myLine = pLine;
/* If the line contains a category separator */
if (pLine.contains(QIF_CATSEP)) {
/* Move to data following separator */
final int i = pLine.indexOf(QIF_CATSEP);
myLine = pLine.substring(i + 1);
}
/* If the line contains classes */
if (myLine.contains(QIF_CLASS)) {
/* drop preceding data */
final int i = myLine.indexOf(QIF_CLASS);
myLine = myLine.substring(i + 1);
/* Build list of classes */
final String[] myClasses = myLine.split(QIF_CLASSSEP);
final List<MoneyWiseQIFClass> myList = new ArrayList<>();
for (String myClass : myClasses) {
myList.add(pFile.getClass(myClass));
}
/* Return the classes */
return myList;
}
/* Return no classes */
return null;
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFXferAccountLine<?> myLine = (MoneyWiseQIFXferAccountLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check account */
if (!theAccount.equals(myLine.getAccount())) {
return false;
}
/* Check classes */
final List<MoneyWiseQIFClass> myClasses = myLine.getClassList();
if (theClasses == null) {
return myClasses == null;
} else if (myClasses == null) {
return true;
}
return theClasses.equals(myClasses);
}
@Override
public int hashCode() {
int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
if (theClasses != null) {
myResult += theClasses.hashCode();
myResult *= MoneyWiseQIFFile.HASH_BASE;
}
return myResult + theAccount.hashCode();
}
}
/**
* The Payee line.
*
* @param <X> the line type
*/
public abstract static class MoneyWiseQIFPayeeLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The payee.
*/
private final MoneyWiseQIFPayee thePayee;
/**
* Constructor.
*
* @param pPayee the Payee
*/
protected MoneyWiseQIFPayeeLine(final MoneyWiseQIFPayee pPayee) {
/* Store data */
thePayee = pPayee;
}
@Override
public String toString() {
return thePayee.toString();
}
/**
* Obtain payee.
*
* @return the payee
*/
public MoneyWiseQIFPayee getPayee() {
return thePayee;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(thePayee.getName());
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFPayeeLine<?> myLine = (MoneyWiseQIFPayeeLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check value */
return thePayee.equals(myLine.getPayee());
}
@Override
public int hashCode() {
final int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
return myResult + thePayee.hashCode();
}
}
/**
* The Event Category line.
*
* @param <X> the line type
*/
public abstract static class MoneyWiseQIFCategoryLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The event category.
*/
private final MoneyWiseQIFEventCategory theCategory;
/**
* The class list.
*/
private final List<MoneyWiseQIFClass> theClasses;
/**
* Constructor.
*
* @param pCategory the Event Category
*/
protected MoneyWiseQIFCategoryLine(final MoneyWiseQIFEventCategory pCategory) {
this(pCategory, null);
}
/**
* Constructor.
*
* @param pCategory the Event Category
* @param pClasses the classes
*/
protected MoneyWiseQIFCategoryLine(final MoneyWiseQIFEventCategory pCategory,
final List<MoneyWiseQIFClass> pClasses) {
/* Store data */
theCategory = pCategory;
theClasses = pClasses;
}
@Override
public String toString() {
return theCategory.toString();
}
/**
* Obtain event category.
*
* @return the event category
*/
public MoneyWiseQIFEventCategory getEventCategory() {
return theCategory;
}
/**
* Obtain class list.
*
* @return the class list
*/
public List<MoneyWiseQIFClass> getClassList() {
return theClasses;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(theCategory.getName());
/* If we have classes */
if (theClasses != null) {
/* Add class indicator */
pBuilder.append(QIF_CLASS);
/* Iterate through the list */
final Iterator<MoneyWiseQIFClass> myIterator = theClasses.iterator();
while (myIterator.hasNext()) {
final MoneyWiseQIFClass myClass = myIterator.next();
/* Add to the list */
pBuilder.append(myClass.getName());
if (myIterator.hasNext()) {
pBuilder.append(QIF_CLASSSEP);
}
}
}
}
/**
* Parse category line.
*
* @param pFile the QIF File
* @param pLine the line.
* @return the account name (or null)
*/
protected static MoneyWiseQIFEventCategory parseCategory(final MoneyWiseQIFFile pFile,
final String pLine) {
/* Determine line to use */
String myLine = pLine;
/* If the line contains a category separator */
if (pLine.contains(QIF_CATSEP)) {
/* Drop data after separator */
final int i = pLine.indexOf(QIF_CATSEP);
myLine = pLine.substring(0, i);
}
/* If the line contains classes */
if (myLine.contains(QIF_CLASS)) {
/* drop class data */
final int i = myLine.indexOf(QIF_CLASS);
myLine = myLine.substring(0, i);
}
/* If we have the account delimiters */
if ((myLine.startsWith(QIF_XFERSTART))
&& (myLine.endsWith(QIF_XFEREND))) {
/* This is an account */
return null;
}
/* Return category */
return pFile.getCategory(myLine);
}
/**
* Parse category classes.
*
* @param pFile the QIF File
* @param pLine the line.
* @return the account name (or null)
*/
protected static List<MoneyWiseQIFClass> parseCategoryClasses(final MoneyWiseQIFFile pFile,
final String pLine) {
/* Determine line to use */
String myLine = pLine;
/* If the line contains a category separator */
if (pLine.contains(QIF_CATSEP)) {
/* Drop data after separator */
final int i = pLine.indexOf(QIF_CATSEP);
myLine = pLine.substring(0, i);
}
/* If the line contains classes */
if (myLine.contains(QIF_CLASS)) {
/* drop preceding data */
final int i = myLine.indexOf(QIF_CLASS);
myLine = myLine.substring(i + 1);
/* Build list of classes */
final String[] myClasses = myLine.split(QIF_CLASSSEP);
final List<MoneyWiseQIFClass> myList = new ArrayList<>();
for (String myClass : myClasses) {
myList.add(pFile.getClass(myClass));
}
/* Return the classes */
return myList;
}
/* Return no classes */
return null;
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFCategoryLine<?> myLine = (MoneyWiseQIFCategoryLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check category */
if (!theCategory.equals(myLine.getEventCategory())) {
return false;
}
/* Check classes */
final List<MoneyWiseQIFClass> myClasses = myLine.getClassList();
if (theClasses == null) {
return myClasses == null;
} else if (myClasses == null) {
return true;
}
return theClasses.equals(myClasses);
}
@Override
public int hashCode() {
int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
if (theClasses != null) {
myResult += theClasses.hashCode();
myResult *= MoneyWiseQIFFile.HASH_BASE;
}
return myResult + theCategory.hashCode();
}
}
/**
* The Event Category line.
*
* @param <X> the line type
*/
public abstract static class MoneyWiseQIFCategoryAccountLine<X extends MoneyWiseQLineType>
extends MoneyWiseQIFLine<X> {
/**
* The event category.
*/
private final MoneyWiseQIFEventCategory theCategory;
/**
* The account.
*/
private final MoneyWiseQIFAccount theAccount;
/**
* The class list.
*/
private final List<MoneyWiseQIFClass> theClasses;
/**
* Constructor.
*
* @param pCategory the Event Category
* @param pAccount the Account
*/
protected MoneyWiseQIFCategoryAccountLine(final MoneyWiseQIFEventCategory pCategory,
final MoneyWiseQIFAccount pAccount) {
this(pCategory, pAccount, null);
}
/**
* Constructor.
*
* @param pCategory the Event Category
* @param pAccount the Account
* @param pClasses the classes
*/
protected MoneyWiseQIFCategoryAccountLine(final MoneyWiseQIFEventCategory pCategory,
final MoneyWiseQIFAccount pAccount,
final List<MoneyWiseQIFClass> pClasses) {
/* Store data */
theCategory = pCategory;
theAccount = pAccount;
theClasses = pClasses;
}
/**
* Obtain event category.
*
* @return the event category
*/
public MoneyWiseQIFEventCategory getEventCategory() {
return theCategory;
}
/**
* Obtain account.
*
* @return the account
*/
public MoneyWiseQIFAccount getAccount() {
return theAccount;
}
/**
* Obtain class list.
*
* @return the class list
*/
public List<MoneyWiseQIFClass> getClassList() {
return theClasses;
}
@Override
protected void formatData(final OceanusDataFormatter pFormatter,
final StringBuilder pBuilder) {
/* Append the string data */
pBuilder.append(theCategory.getName());
pBuilder.append(QIF_CATSEP);
pBuilder.append(QIF_XFERSTART);
pBuilder.append(theAccount.getName());
pBuilder.append(QIF_XFEREND);
/* If we have classes */
if (theClasses != null) {
/* Add class indicator */
pBuilder.append(QIF_CLASS);
/* Iterate through the list */
final Iterator<MoneyWiseQIFClass> myIterator = theClasses.iterator();
while (myIterator.hasNext()) {
final MoneyWiseQIFClass myClass = myIterator.next();
/* Add to the list */
pBuilder.append(myClass.getName());
if (myIterator.hasNext()) {
pBuilder.append(QIF_CLASSSEP);
}
}
}
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (this == pThat) {
return true;
}
if (pThat == null) {
return false;
}
/* Check class */
if (!getClass().equals(pThat.getClass())) {
return false;
}
/* Cast correctly */
final MoneyWiseQIFCategoryAccountLine<?> myLine = (MoneyWiseQIFCategoryAccountLine<?>) pThat;
/* Check line type */
if (!getLineType().equals(myLine.getLineType())) {
return false;
}
/* Check category */
if (!theCategory.equals(myLine.getEventCategory())) {
return false;
}
/* Check account */
if (!theAccount.equals(myLine.getAccount())) {
return false;
}
/* Check classes */
final List<MoneyWiseQIFClass> myClasses = myLine.getClassList();
if (theClasses == null) {
return myClasses == null;
} else if (myClasses == null) {
return true;
}
return theClasses.equals(myClasses);
}
@Override
public int hashCode() {
int myResult = MoneyWiseQIFFile.HASH_BASE * getLineType().hashCode();
if (theClasses != null) {
myResult += theClasses.hashCode();
myResult *= MoneyWiseQIFFile.HASH_BASE;
}
myResult += theAccount.hashCode();
myResult *= MoneyWiseQIFFile.HASH_BASE;
return myResult + theCategory.hashCode();
}
}
}