Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
*/
char paddingChar() default ' ';

/**
* The character to pad with if data is null
* @return the null character
*/
char nullChar() default ' ';

Class<? extends FixedFormatter> formatter() default ByTypeFormatter.class;

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,28 @@ public class FormatInstructions {
private int length;
private Align alignment;
private char paddingChar;
private char nullChar;
private FixedFormatPatternData fixedFormatPatternData;
private FixedFormatBooleanData fixedFormatBooleanData;
private FixedFormatNumberData fixedFormatNumberData;
private FixedFormatDecimalData fixedFormatDecimalData;

public FormatInstructions(int length, Align alignment, char paddingChar, FixedFormatPatternData fixedFormatPatternData, FixedFormatBooleanData fixedFormatBooleanData, FixedFormatNumberData fixedFormatNumberData, FixedFormatDecimalData fixedFormatDecimalData) {
public FormatInstructions(int length, Align alignment, char paddingChar, FixedFormatPatternData fixedFormatPatternData, FixedFormatBooleanData fixedFormatBooleanData, FixedFormatNumberData fixedFormatNumberData, FixedFormatDecimalData fixedFormatDecimalData) {
this.length = length;
this.alignment = alignment;
this.paddingChar = paddingChar;
this.nullChar = paddingChar;
this.fixedFormatPatternData = fixedFormatPatternData;
this.fixedFormatBooleanData = fixedFormatBooleanData;
this.fixedFormatNumberData = fixedFormatNumberData;
this.fixedFormatDecimalData = fixedFormatDecimalData;
}

public FormatInstructions(int length, Align alignment, char paddingChar, char nullChar, FixedFormatPatternData fixedFormatPatternData, FixedFormatBooleanData fixedFormatBooleanData, FixedFormatNumberData fixedFormatNumberData, FixedFormatDecimalData fixedFormatDecimalData) {
this.length = length;
this.alignment = alignment;
this.paddingChar = paddingChar;
this.nullChar = nullChar;
this.fixedFormatPatternData = fixedFormatPatternData;
this.fixedFormatBooleanData = fixedFormatBooleanData;
this.fixedFormatNumberData = fixedFormatNumberData;
Expand All @@ -58,7 +71,11 @@ public Align getAlignment() {
public char getPaddingChar() {
return paddingChar;
}


public char getNullChar() {
return nullChar;
}

public FixedFormatPatternData getFixedFormatPatternData() {
return fixedFormatPatternData;
}
Expand All @@ -79,7 +96,8 @@ public String toString() {
return "FormatInstructions{" +
"length=" + length +
", alignment=" + alignment +
", paddingChar='" + paddingChar + "'" +
", paddingChar='" + paddingChar + "'" +
", nullChar='" + nullChar + "'" +
", fixedFormatPatternData=" + fixedFormatPatternData +
", fixedFormatBooleanData=" + fixedFormatBooleanData +
", fixedFormatNumberData=" + fixedFormatNumberData +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,23 @@ protected <T> Object readDataAccordingFieldAnnotation(Class<T> clazz, String dat
loadedData = load(datatype, dataToParse);
} else {
try {
loadedData = formatter.parse(dataToParse, formatdata);
boolean isNull = false;
final char nullChar = formatdata.getNullChar();
final char paddChar = formatdata.getPaddingChar();
if (nullChar != paddChar) {
isNull = true;
for (int i = 0; i < dataToParse.length(); i++) {
if (nullChar != dataToParse.charAt(i)) {
isNull = false;
break;
}
}
}
if (isNull) {
loadedData = null;
} else {
loadedData = formatter.parse(dataToParse, formatdata);
}
} catch (RuntimeException e) {
throw new ParseException(data, dataToParse, clazz, method, context, formatdata, e);
}
Expand Down Expand Up @@ -279,7 +295,11 @@ private <T> String exportDataAccordingFieldAnnotation(T fixedFormatRecord, Metho
if (valueObject != null && valueObject.getClass().getAnnotation(Record.class) != null) {
result = export(valueObject);
} else {
result = formatter.format(valueObject, formatdata);
if (valueObject != null) {
result = formatter.format(valueObject, formatdata);
} else {
result = StringUtils.leftPad("", formatdata.getLength(), formatdata.getNullChar());
}
}
if (LOG.isDebugEnabled()) {
LOG.debug(format("exported %s ", result));
Expand Down Expand Up @@ -315,7 +335,7 @@ private FormatInstructions getFormatInstructions(Method method, Field fieldAnno)
FixedFormatBooleanData booleanData = getFixedFormatBooleanData(method.getAnnotation(FixedFormatBoolean.class));
FixedFormatNumberData numberData = getFixedFormatNumberData(method.getAnnotation(FixedFormatNumber.class));
FixedFormatDecimalData decimalData = getFixedFormatDecimalData(method.getAnnotation(FixedFormatDecimal.class));
return new FormatInstructions(fieldAnno.length(), fieldAnno.align(), fieldAnno.paddingChar(), patternData, booleanData, numberData, decimalData);
return new FormatInstructions(fieldAnno.length(), fieldAnno.align(), fieldAnno.paddingChar(), fieldAnno.nullChar(), patternData, booleanData, numberData, decimalData);
}

private FixedFormatPatternData getFixedFormatPatternData(FixedFormatPattern annotation) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright 2004 the original author or authors.
*
* 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 com.ancientprogramming.fixedformat4j.format.impl;

import com.ancientprogramming.fixedformat4j.annotation.*;

import java.math.BigDecimal;
import java.util.Date;

/**
* A record used in testcases
*
* @author Jacob von Eyben - http://www.ancientprogramming.com
* @since 1.0.0
*/
@Record
public class MyNullableRecord {

private String stringData;
private Integer integerData;
private Date dateData;
private Character charData;
private Boolean booleanData;
private Long longData;
private Double doubleData;
private Float floatData;
private BigDecimal bigDecimalData;
private float simpleFloatData;


@Field(offset = 1, length = 10, align = Align.RIGHT, paddingChar = '*', nullChar=' ')
public String getStringData() {
return stringData;
}

public void setStringData(String stringData) {
this.stringData = stringData;
}

@Field(offset = 11, length = 5, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
public Integer getIntegerData() {
return integerData;
}

public void setIntegerData(Integer integerData) {
this.integerData = integerData;
}

@Field(offset = 16, length = 8)
public Date getDateData() {
return dateData;
}

public void setDateData(Date dateData) {
this.dateData = dateData;
}

@Field(offset = 24, length = 1)
public Character getCharData() {
return charData;
}

public void setCharData(Character charData) {
this.charData = charData;
}

@Field(offset = 25, length = 1)
public Boolean isBooleanData() {
return booleanData;
}

public void setBooleanData(Boolean booleanData) {
this.booleanData = booleanData;
}

@Field(offset = 26, length = 4, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
public Long getLongData() {
return longData;
}

public void setLongData(Long longData) {
this.longData = longData;
}

@Field(offset = 30, length = 10, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
public Double getDoubleData() {
return doubleData;
}

public void setDoubleData(Double doubleData) {
this.doubleData = doubleData;
}

@Field(offset = 40, length = 10, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
public Float getFloatData() {
return floatData;
}

public void setFloatData(Float floatData) {
this.floatData = floatData;
}

@Field(offset = 50, length = 10, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
@FixedFormatDecimal(decimals = 4, decimalDelimiter = ' ', useDecimalDelimiter = true)
@FixedFormatNumber(sign = Sign.PREPEND)
public BigDecimal getBigDecimalData() {
return bigDecimalData;
}

public void setBigDecimalData(BigDecimal bigDecimalData) {
this.bigDecimalData = bigDecimalData;
}

@Field(offset = 60, length = 10, align = Align.RIGHT, paddingChar = '0', nullChar=' ')
public float getSimpleFloatData() {
return simpleFloatData;
}

public void setSimpleFloatData(float simpleFloatData) {
this.simpleFloatData = simpleFloatData;
}


@Record
static class MyStaticNestedClass {

private String stringData;

@Field(offset = 1, length = 10)
public String getStringData() {
return stringData;
}

public void setStringData(String stringData) {
this.stringData = stringData;
}
}

@Record
class MyInnerClass {

private String stringData;

@Field(offset = 1, length = 10)
public String getStringData() {
return stringData;
}

public void setStringData(String stringData) {
this.stringData = stringData;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2004 the original author or authors.
*
* 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 com.ancientprogramming.fixedformat4j.format.impl;

import java.math.BigDecimal;
import java.util.Calendar;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ancientprogramming.fixedformat4j.format.FixedFormatManager;

/**
* @author Jacob von Eyben - http://www.ancientprogramming.com
* @since 1.0.0
*/
public class TestNullableFixedFormatManagerImpl extends TestCase {
private static final Log LOG = LogFactory.getLog(TestNullableFixedFormatManagerImpl.class);


public static final String MY_NULLABLE_RECORD_DATA = " 20080514CT001100000010350000002056-0012 01200000002056";
public static final String MY_NONNULL_RECORD_DATA = "**********0000020080514CT001100000010350000002056-0012 01200000002056";

FixedFormatManager manager = null;

@Override
protected void setUp() throws Exception {
super.setUp();
manager = new FixedFormatManagerImpl();
}

public void testLoadNullableRecord() {
MyNullableRecord loadedRecord = manager.load(MyNullableRecord.class, MY_NULLABLE_RECORD_DATA);
Assert.assertNotNull(loadedRecord);
Assert.assertEquals(null, loadedRecord.getStringData());
Assert.assertTrue(loadedRecord.isBooleanData());
}

public void testLoadNonNullRecord() {
MyNullableRecord loadedRecord = manager.load(MyNullableRecord.class, MY_NONNULL_RECORD_DATA);
Assert.assertNotNull(loadedRecord);
Assert.assertEquals("", loadedRecord.getStringData());
Assert.assertTrue(loadedRecord.isBooleanData());
}


public void testExportNullableRecordObject() {
MyNullableRecord myRecord = createMyNullableRecord();
Assert.assertEquals(MY_NULLABLE_RECORD_DATA,manager.export(myRecord));
myRecord = createMyNonNullRecord();
Assert.assertEquals(MY_NONNULL_RECORD_DATA, manager.export(myRecord));
}

private MyNullableRecord createMyNullableRecord() {
Calendar someDay = Calendar.getInstance();
someDay.set(2008, 4, 14, 0, 0, 0);
someDay.set(Calendar.MILLISECOND, 0);

MyNullableRecord myRecord = new MyNullableRecord();
myRecord.setBooleanData(true);
myRecord.setCharData('C');
myRecord.setDateData(someDay.getTime());
myRecord.setDoubleData(10.35);
myRecord.setFloatData(20.56F);
myRecord.setLongData(11L);
myRecord.setIntegerData(null);
myRecord.setStringData(null);
myRecord.setBigDecimalData(new BigDecimal(-12.012));
myRecord.setSimpleFloatData(20.56F);
return myRecord;
}

private MyNullableRecord createMyNonNullRecord() {
Calendar someDay = Calendar.getInstance();
someDay.set(2008, 4, 14, 0, 0, 0);
someDay.set(Calendar.MILLISECOND, 0);

MyNullableRecord myRecord = new MyNullableRecord();
myRecord.setBooleanData(true);
myRecord.setCharData('C');
myRecord.setDateData(someDay.getTime());
myRecord.setDoubleData(10.35);
myRecord.setFloatData(20.56F);
myRecord.setLongData(11L);
myRecord.setIntegerData(0);
myRecord.setStringData("");
myRecord.setBigDecimalData(new BigDecimal(-12.012));
myRecord.setSimpleFloatData(20.56F);
return myRecord;
}

}