Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c17b05bbc | ||
|
|
3e3fbaa3fa | ||
|
|
ba486239bd | ||
|
|
c57ad2c5ee | ||
|
|
6b7ec73e92 | ||
|
|
0f3cdec460 | ||
|
|
327041d3c0 | ||
|
|
a8f699343f | ||
|
|
a09b72e66e | ||
|
|
1cbda9aaa9 | ||
|
|
bb1b23b282 | ||
|
|
9c16e3c063 | ||
|
|
e497b7e929 | ||
|
|
61b90d4489 | ||
|
|
29a9411b9c | ||
|
|
1d7eadf2c7 | ||
|
|
515a632251 | ||
|
|
ccfedec8a6 | ||
|
|
8aa3ec35ad | ||
|
|
2c3d3e8a6d |
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
apply plugin:'java'
|
apply plugin:'java'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
defaultTasks 'build'
|
defaultTasks 'build'
|
||||||
version='1.9.0'
|
version='1.10.2'
|
||||||
description='Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.'
|
description='Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.'
|
||||||
sourceCompatibility=6
|
sourceCompatibility=6
|
||||||
targetCompatibility=6
|
targetCompatibility=6
|
||||||
@@ -17,9 +17,9 @@ configurations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'org.slf4j:slf4j-api:1.7.5'
|
compile 'org.slf4j:slf4j-api:1.7.7'
|
||||||
testCompile 'junit:junit:4.11'
|
testCompile 'junit:junit:4.11'
|
||||||
testRuntime 'org.slf4j:slf4j-simple:1.7.5'
|
testRuntime 'org.slf4j:slf4j-simple:1.7.7'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.javadoc.options.use=true
|
tasks.javadoc.options.use=true
|
||||||
@@ -34,7 +34,7 @@ task sourcesJar(type:Jar) {
|
|||||||
classifier='sources'
|
classifier='sources'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(Compile) { Compile compile ->
|
tasks.withType(AbstractCompile) { AbstractCompile compile ->
|
||||||
compile.options.debug = true
|
compile.options.debug = true
|
||||||
compile.options.compilerArgs = ['-Xlint:all']
|
compile.options.compilerArgs = ['-Xlint:all']
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ uploadArchives {
|
|||||||
beforeDeployment { MavenDeployment deployment ->
|
beforeDeployment { MavenDeployment deployment ->
|
||||||
signing.signPom(deployment)
|
signing.signPom(deployment)
|
||||||
}
|
}
|
||||||
repository(url:'http://oss.sonatype.org/service/local/staging/deploy/maven2/') {
|
repository(url:'https://oss.sonatype.org/service/local/staging/deploy/maven2/') {
|
||||||
authentication(userName:nexusUsername, password:nexusPassword)
|
authentication(userName:nexusUsername, password:nexusPassword)
|
||||||
}
|
}
|
||||||
pom.project {
|
pom.project {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.sf.j8583</groupId>
|
<groupId>net.sf.j8583</groupId>
|
||||||
<artifactId>j8583</artifactId>
|
<artifactId>j8583</artifactId>
|
||||||
<version>1.9.0</version>
|
<version>1.9.1</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>j8583</name>
|
<name>j8583</name>
|
||||||
<description>Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.</description>
|
<description>Java implementation of the ISO 8583 protocol, focused on making the creation, edition and reading of ISO8583 messages as simple and flexible as possible.</description>
|
||||||
|
|||||||
@@ -496,4 +496,10 @@ public class IsoMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Remove the specified fields from the message. */
|
||||||
|
public void removeFields(int... idx) {
|
||||||
|
for (int i : idx) {
|
||||||
|
setField(i, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|||||||
package com.solab.iso8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/** Defines the possible values types that can be used in the fields.
|
/** Defines the possible values types that can be used in the fields.
|
||||||
* Some types required the length of the value to be specified (NUMERIC
|
* Some types required the length of the value to be specified (NUMERIC
|
||||||
@@ -76,17 +78,23 @@ public enum IsoType {
|
|||||||
|
|
||||||
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP or TIME; throws an exception
|
/** Formats a Date if the receiver is DATE10, DATE4, DATE_EXP or TIME; throws an exception
|
||||||
* otherwise. */
|
* otherwise. */
|
||||||
public String format(Date value) {
|
public String format(final Date value, final TimeZone tz) {
|
||||||
|
final SimpleDateFormat sdf;
|
||||||
if (this == DATE10) {
|
if (this == DATE10) {
|
||||||
return String.format("%Tm%<Td%<TH%<TM%<TS", value);
|
sdf = new SimpleDateFormat("MMddHHmmss");
|
||||||
} else if (this == DATE4) {
|
} else if (this == DATE4) {
|
||||||
return String.format("%Tm%<Td", value);
|
sdf = new SimpleDateFormat("MMdd");
|
||||||
} else if (this == DATE_EXP) {
|
} else if (this == DATE_EXP) {
|
||||||
return String.format("%Ty%<Tm", value);
|
sdf = new SimpleDateFormat("yyMM");
|
||||||
} else if (this == TIME) {
|
} else if (this == TIME) {
|
||||||
return String.format("%TH%<TM%<TS", value);
|
sdf = new SimpleDateFormat("HHmmss");
|
||||||
}
|
} else {
|
||||||
throw new IllegalArgumentException("Cannot format date as " + this);
|
throw new IllegalArgumentException("Cannot format date as " + this);
|
||||||
|
}
|
||||||
|
if (tz != null) {
|
||||||
|
sdf.setTimeZone(tz);
|
||||||
|
}
|
||||||
|
return sdf.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Formats the string to the given length (length is only useful if type is ALPHA, NUMERIC or BINARY). */
|
/** Formats the string to the given length (length is only useful if type is ALPHA, NUMERIC or BINARY). */
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import com.solab.iso8583.util.Bcd;
|
import com.solab.iso8583.util.Bcd;
|
||||||
import com.solab.iso8583.util.HexCodec;
|
import com.solab.iso8583.util.HexCodec;
|
||||||
@@ -42,6 +43,7 @@ public class IsoValue<T> implements Cloneable {
|
|||||||
private CustomField<T> encoder;
|
private CustomField<T> encoder;
|
||||||
private int length;
|
private int length;
|
||||||
private String encoding;
|
private String encoding;
|
||||||
|
private TimeZone tz;
|
||||||
|
|
||||||
public IsoValue(IsoType t, T value) {
|
public IsoValue(IsoType t, T value) {
|
||||||
this(t, value, null);
|
this(t, value, null);
|
||||||
@@ -172,6 +174,14 @@ public class IsoValue<T> implements Cloneable {
|
|||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the timezone, useful for date fields. */
|
||||||
|
public void setTimeZone(TimeZone value) {
|
||||||
|
tz = value;
|
||||||
|
}
|
||||||
|
public TimeZone getTimeZone() {
|
||||||
|
return tz;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the formatted value as a String. The formatting depends on the type of the
|
/** Returns the formatted value as a String. The formatting depends on the type of the
|
||||||
* receiver. */
|
* receiver. */
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@@ -195,7 +205,7 @@ public class IsoValue<T> implements Cloneable {
|
|||||||
} else if (type == IsoType.LLVAR || type == IsoType.LLLVAR) {
|
} else if (type == IsoType.LLVAR || type == IsoType.LLLVAR) {
|
||||||
return encoder == null ? value.toString() : encoder.encodeField(value);
|
return encoder == null ? value.toString() : encoder.encodeField(value);
|
||||||
} else if (value instanceof Date) {
|
} else if (value instanceof Date) {
|
||||||
return type.format((Date)value);
|
return type.format((Date)value, tz);
|
||||||
} else if (type == IsoType.BINARY) {
|
} else if (type == IsoType.BINARY) {
|
||||||
if (value instanceof byte[]) {
|
if (value instanceof byte[]) {
|
||||||
final byte[] _v = (byte[])value;
|
final byte[] _v = (byte[])value;
|
||||||
@@ -262,7 +272,7 @@ public class IsoValue<T> implements Cloneable {
|
|||||||
} else if (ldiff == 2) {
|
} else if (ldiff == 2) {
|
||||||
lhead = "00" + lhead;
|
lhead = "00" + lhead;
|
||||||
}
|
}
|
||||||
outs.write(lhead.getBytes(encoding));
|
outs.write(encoding == null ? lhead.getBytes():lhead.getBytes(encoding));
|
||||||
} else {
|
} else {
|
||||||
//write the length in ASCII
|
//write the length in ASCII
|
||||||
if (digits == 3) {
|
if (digits == 3) {
|
||||||
|
|||||||
@@ -21,14 +21,9 @@ package com.solab.iso8583;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.BitSet;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import com.solab.iso8583.parse.DateTimeParseInfo;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -275,6 +270,20 @@ public class MessageFactory<T extends IsoMessage> {
|
|||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the timezone for the specified FieldParseInfo, if it's indeed for parsing dates. */
|
||||||
|
public void setTimezoneForParseGuide(int messageType, int field, TimeZone tz) {
|
||||||
|
Map<Integer, FieldParseInfo> guide = parseMap.get(messageType);
|
||||||
|
if (guide != null) {
|
||||||
|
FieldParseInfo fpi = guide.get(field);
|
||||||
|
if (fpi instanceof DateTimeParseInfo) {
|
||||||
|
((DateTimeParseInfo) fpi).setTimeZone(tz);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.warn("Field {} for message type {} is not for dates, cannot set timezone",
|
||||||
|
field, messageType);
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates a new message instance from the buffer, which must contain a valid ISO8583
|
/** Creates a new message instance from the buffer, which must contain a valid ISO8583
|
||||||
* message. If the factory is set to use binary messages then it will try to parse
|
* message. If the factory is set to use binary messages then it will try to parse
|
||||||
* a binary message.
|
* a binary message.
|
||||||
@@ -364,7 +373,7 @@ public class MessageFactory<T extends IsoMessage> {
|
|||||||
throw new ParseException("Insufficient length for secondary bitmap", minlength);
|
throw new ParseException("Insufficient length for secondary bitmap", minlength);
|
||||||
}
|
}
|
||||||
if (forceStringEncoding) {
|
if (forceStringEncoding) {
|
||||||
byte[] _bb = new String(buf, isoHeaderLength+4, 16, encoding).getBytes();
|
byte[] _bb = new String(buf, isoHeaderLength+20, 16, encoding).getBytes();
|
||||||
System.arraycopy(_bb, 0, bitmapBuffer, 20+isoHeaderLength, 16);
|
System.arraycopy(_bb, 0, bitmapBuffer, 20+isoHeaderLength, 16);
|
||||||
}
|
}
|
||||||
for (int i = isoHeaderLength + 20; i < isoHeaderLength + 36; i++) {
|
for (int i = isoHeaderLength + 20; i < isoHeaderLength + 36; i++) {
|
||||||
|
|||||||
@@ -31,13 +31,8 @@ import com.solab.iso8583.IsoValue;
|
|||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
*/
|
*/
|
||||||
public class Date10ParseInfo extends FieldParseInfo {
|
public class Date10ParseInfo extends DateTimeParseInfo {
|
||||||
|
|
||||||
private static final long FUTURE_TOLERANCE;
|
|
||||||
|
|
||||||
static {
|
|
||||||
FUTURE_TOLERANCE = Long.parseLong(System.getProperty("j8583.future.tolerance", "900000"));
|
|
||||||
}
|
|
||||||
public Date10ParseInfo() {
|
public Date10ParseInfo() {
|
||||||
super(IsoType.DATE10, 10);
|
super(IsoType.DATE10, 10);
|
||||||
}
|
}
|
||||||
@@ -72,6 +67,9 @@ public class Date10ParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.SECOND, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
|
cal.set(Calendar.SECOND, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48);
|
||||||
}
|
}
|
||||||
cal.set(Calendar.MILLISECOND,0);
|
cal.set(Calendar.MILLISECOND,0);
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
|
}
|
||||||
adjustWithFutureTolerance(cal);
|
adjustWithFutureTolerance(cal);
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
@@ -103,17 +101,11 @@ public class Date10ParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.MINUTE, tens[3]);
|
cal.set(Calendar.MINUTE, tens[3]);
|
||||||
cal.set(Calendar.SECOND, tens[4]);
|
cal.set(Calendar.SECOND, tens[4]);
|
||||||
cal.set(Calendar.MILLISECOND,0);
|
cal.set(Calendar.MILLISECOND,0);
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
|
}
|
||||||
adjustWithFutureTolerance(cal);
|
adjustWithFutureTolerance(cal);
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void adjustWithFutureTolerance(Calendar cal) {
|
|
||||||
//We need to handle a small tolerance into the future (a couple of minutes)
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
long then = cal.getTimeInMillis();
|
|
||||||
if (then > now && then-now > FUTURE_TOLERANCE) {
|
|
||||||
cal.add(Calendar.YEAR, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.solab.iso8583.IsoValue;
|
|||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
*/
|
*/
|
||||||
public class Date4ParseInfo extends FieldParseInfo {
|
public class Date4ParseInfo extends DateTimeParseInfo {
|
||||||
|
|
||||||
public Date4ParseInfo() {
|
public Date4ParseInfo() {
|
||||||
super(IsoType.DATE4, 4);
|
super(IsoType.DATE4, 4);
|
||||||
@@ -61,6 +61,9 @@ public class Date4ParseInfo extends FieldParseInfo {
|
|||||||
} else {
|
} else {
|
||||||
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
|
cal.set(Calendar.MONTH, ((buf[pos] - 48) * 10) + buf[pos + 1] - 49);
|
||||||
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
|
cal.set(Calendar.DATE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
|
||||||
|
}
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
}
|
}
|
||||||
Date10ParseInfo.adjustWithFutureTolerance(cal);
|
Date10ParseInfo.adjustWithFutureTolerance(cal);
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
@@ -87,7 +90,10 @@ public class Date4ParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.MONTH, tens[0] - 1);
|
cal.set(Calendar.MONTH, tens[0] - 1);
|
||||||
cal.set(Calendar.DATE, tens[1]);
|
cal.set(Calendar.DATE, tens[1]);
|
||||||
cal.set(Calendar.MILLISECOND,0);
|
cal.set(Calendar.MILLISECOND,0);
|
||||||
Date10ParseInfo.adjustWithFutureTolerance(cal);
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
|
}
|
||||||
|
DateTimeParseInfo.adjustWithFutureTolerance(cal);
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.solab.iso8583.IsoValue;
|
|||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
*/
|
*/
|
||||||
public class DateExpParseInfo extends FieldParseInfo {
|
public class DateExpParseInfo extends DateTimeParseInfo {
|
||||||
|
|
||||||
public DateExpParseInfo() {
|
public DateExpParseInfo() {
|
||||||
super(IsoType.DATE_EXP, 4);
|
super(IsoType.DATE_EXP, 4);
|
||||||
@@ -63,6 +63,9 @@ public class DateExpParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - (cal.get(Calendar.YEAR) % 100)
|
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - (cal.get(Calendar.YEAR) % 100)
|
||||||
+ ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
|
+ ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
|
||||||
cal.set(Calendar.MONTH, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 49);
|
cal.set(Calendar.MONTH, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 49);
|
||||||
|
}
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
}
|
}
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
@@ -93,6 +96,9 @@ public class DateExpParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)
|
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)
|
||||||
- (cal.get(Calendar.YEAR) % 100) + tens[0]);
|
- (cal.get(Calendar.YEAR) % 100) + tens[0]);
|
||||||
cal.set(Calendar.MONTH, tens[1] - 1);
|
cal.set(Calendar.MONTH, tens[1] - 1);
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
|
}
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.solab.iso8583.parse;
|
||||||
|
|
||||||
|
import com.solab.iso8583.IsoType;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for date/time parsers.
|
||||||
|
*
|
||||||
|
* @author Enrique Zamudio
|
||||||
|
* Date: 18/12/13 18:21
|
||||||
|
*/
|
||||||
|
public abstract class DateTimeParseInfo extends FieldParseInfo {
|
||||||
|
|
||||||
|
protected static final long FUTURE_TOLERANCE;
|
||||||
|
protected TimeZone tz;
|
||||||
|
|
||||||
|
static {
|
||||||
|
FUTURE_TOLERANCE = Long.parseLong(System.getProperty("j8583.future.tolerance", "900000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DateTimeParseInfo(IsoType type, int length) {
|
||||||
|
super(type, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeZone(TimeZone value) {
|
||||||
|
tz = value;
|
||||||
|
}
|
||||||
|
public TimeZone getTimeZone() {
|
||||||
|
return tz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void adjustWithFutureTolerance(Calendar cal) {
|
||||||
|
//We need to handle a small tolerance into the future (a couple of minutes)
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long then = cal.getTimeInMillis();
|
||||||
|
if (then > now && then-now > FUTURE_TOLERANCE) {
|
||||||
|
cal.add(Calendar.YEAR, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ import com.solab.iso8583.IsoValue;
|
|||||||
public abstract class FieldParseInfo {
|
public abstract class FieldParseInfo {
|
||||||
|
|
||||||
protected IsoType type;
|
protected IsoType type;
|
||||||
protected int length;
|
protected final int length;
|
||||||
private String encoding = System.getProperty("file.encoding");
|
private String encoding = System.getProperty("file.encoding");
|
||||||
protected boolean forceStringDecoding;
|
protected boolean forceStringDecoding;
|
||||||
private CustomField<?> decoder;
|
private CustomField<?> decoder;
|
||||||
@@ -137,7 +137,7 @@ public abstract class FieldParseInfo {
|
|||||||
|
|
||||||
protected int decodeLength(byte[] buf, int pos, int digits) throws UnsupportedEncodingException {
|
protected int decodeLength(byte[] buf, int pos, int digits) throws UnsupportedEncodingException {
|
||||||
if (forceStringDecoding) {
|
if (forceStringDecoding) {
|
||||||
return Integer.parseInt(new String(buf, pos, digits, encoding));
|
return Integer.parseInt(new String(buf, pos, digits, encoding), 10);
|
||||||
} else if (digits == 3) {
|
} else if (digits == 3) {
|
||||||
return ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
|
return ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -49,22 +49,23 @@ public class LlbinParseInfo extends FieldParseInfo {
|
|||||||
throw new ParseException(String.format("Insufficient LLBIN header field %d",
|
throw new ParseException(String.format("Insufficient LLBIN header field %d",
|
||||||
field), pos);
|
field), pos);
|
||||||
}
|
}
|
||||||
length = decodeLength(buf, pos, 2);
|
final int len = decodeLength(buf, pos, 2);
|
||||||
if (length < 0) {
|
if (len < 0) {
|
||||||
throw new ParseException(String.format("Invalid LLBIN field %d length %d pos %d",
|
throw new ParseException(String.format("Invalid LLBIN field %d length %d pos %d",
|
||||||
field, length, pos), pos);
|
field, len, pos), pos);
|
||||||
}
|
}
|
||||||
if (length+pos+2 > buf.length) {
|
if (len+pos+2 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for LLBIN field %d, pos %d (LEN states '%s')",
|
"Insufficient data for LLBIN field %d, pos %d (LEN states '%s')",
|
||||||
field, pos, new String(buf, pos, 2)), pos);
|
field, pos, new String(buf, pos, 2)), pos);
|
||||||
}
|
}
|
||||||
byte[] binval = length == 0 ? new byte[0] : HexCodec.hexDecode(new String(buf, pos + 2, length));
|
byte[] binval = len == 0 ? new byte[0] : HexCodec.hexDecode(
|
||||||
|
new String(buf, pos + 2, len));
|
||||||
if (custom == null) {
|
if (custom == null) {
|
||||||
return new IsoValue<byte[]>(type, binval, binval.length, null);
|
return new IsoValue<byte[]>(type, binval, binval.length, null);
|
||||||
} else if (custom instanceof CustomBinaryField) {
|
} else if (custom instanceof CustomBinaryField) {
|
||||||
try {
|
try {
|
||||||
T dec = ((CustomBinaryField<T>)custom).decodeBinaryField(buf, pos + 2, length);
|
T dec = ((CustomBinaryField<T>)custom).decodeBinaryField(buf, pos + 2, len);
|
||||||
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
|
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
|
||||||
new IsoValue<T>(type, dec, 0, custom);
|
new IsoValue<T>(type, dec, 0, custom);
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
@@ -74,7 +75,7 @@ public class LlbinParseInfo extends FieldParseInfo {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
T dec = custom.decodeField(new String(buf, pos + 2, length));
|
T dec = custom.decodeField(new String(buf, pos + 2, len));
|
||||||
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
|
return dec == null ? new IsoValue<byte[]>(type, binval, binval.length, null) :
|
||||||
new IsoValue<T>(type, dec, binval.length, custom);
|
new IsoValue<T>(type, dec, binval.length, custom);
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
@@ -98,7 +99,7 @@ public class LlbinParseInfo extends FieldParseInfo {
|
|||||||
}
|
}
|
||||||
final int l = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
final int l = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
throw new ParseException(String.format("Invalid bin LLBIN length %d pos %d", length, pos), pos);
|
throw new ParseException(String.format("Invalid bin LLBIN length %d pos %d", l, pos), pos);
|
||||||
}
|
}
|
||||||
if (l+pos+1 > buf.length) {
|
if (l+pos+1 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
|
|||||||
@@ -46,34 +46,35 @@ public class LllvarParseInfo extends FieldParseInfo {
|
|||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for LLLVAR header field %d pos %d", field, pos), pos);
|
"Insufficient data for LLLVAR header field %d pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
length = decodeLength(buf, pos, 3);
|
final int len = decodeLength(buf, pos, 3);
|
||||||
if (length < 0) {
|
if (len < 0) {
|
||||||
throw new ParseException(String.format("Invalid LLLVAR length %d field %d pos %d",
|
throw new ParseException(String.format("Invalid LLLVAR length %d field %d pos %d",
|
||||||
length, field, pos), pos);
|
len, field, pos), pos);
|
||||||
} else if (length+pos+3 > buf.length) {
|
} else if (len+pos+3 > buf.length) {
|
||||||
throw new ParseException(String.format("Insufficient data for LLLVAR field %d, pos %d",
|
throw new ParseException(String.format("Insufficient data for LLLVAR field %d, pos %d",
|
||||||
field, pos), pos);
|
field, pos), pos);
|
||||||
}
|
}
|
||||||
String _v;
|
String _v;
|
||||||
try {
|
try {
|
||||||
_v = length == 0 ? "" : new String(buf, pos + 3, length, getCharacterEncoding());
|
_v = len == 0 ? "" : new String(buf, pos + 3, len, getCharacterEncoding());
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for LLLVAR header, field %d pos %d", field, pos), pos);
|
"Insufficient data for LLLVAR header, field %d pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
//This is new: if the String's length is different from the specified length in the buffer,
|
//This is new: if the String's length is different from the specified length in the
|
||||||
//there are probably some extended characters. So we create a String from the rest of the buffer,
|
//buffer, there are probably some extended characters. So we create a String from
|
||||||
//and then cut it to the specified length.
|
//the rest of the buffer, and then cut it to the specified length.
|
||||||
if (_v.length() != length) {
|
if (_v.length() != len) {
|
||||||
_v = new String(buf, pos + 3, buf.length-pos-3, getCharacterEncoding()).substring(0, length);
|
_v = new String(buf, pos + 3, buf.length-pos-3,
|
||||||
|
getCharacterEncoding()).substring(0, len);
|
||||||
}
|
}
|
||||||
if (custom == null) {
|
if (custom == null) {
|
||||||
return new IsoValue<String>(type, _v, length, null);
|
return new IsoValue<String>(type, _v, len, null);
|
||||||
} else {
|
} else {
|
||||||
T decoded = custom.decodeField(_v);
|
T decoded = custom.decodeField(_v);
|
||||||
//If decode fails, return string; otherwise use the decoded object and its codec
|
//If decode fails, return string; otherwise use the decoded object and its codec
|
||||||
return decoded == null ? new IsoValue<String>(type, _v, length, null) :
|
return decoded == null ? new IsoValue<String>(type, _v, len, null) :
|
||||||
new IsoValue<T>(type, decoded, length, custom);
|
new IsoValue<T>(type, decoded, len, custom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,20 +87,22 @@ public class LllvarParseInfo extends FieldParseInfo {
|
|||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for bin LLLVAR header, field %d pos %d", field, pos), pos);
|
"Insufficient data for bin LLLVAR header, field %d pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
length = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
|
final int len = ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f);
|
||||||
if (length < 0) {
|
if (len < 0) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Invalid bin LLLVAR length %d, field %d pos %d", length, field, pos), pos);
|
"Invalid bin LLLVAR length %d, field %d pos %d", len, field, pos), pos);
|
||||||
} else if (length+pos+2 > buf.length) {
|
} else if (len+pos+2 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for bin LLLVAR field %d, pos %d", field, pos), pos);
|
"Insufficient data for bin LLLVAR field %d, pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
if (custom == null) {
|
if (custom == null) {
|
||||||
return new IsoValue<String>(type, new String(buf, pos + 2, length, getCharacterEncoding()), null);
|
return new IsoValue<String>(type, new String(buf, pos + 2, len, getCharacterEncoding()), null);
|
||||||
} else {
|
} else {
|
||||||
IsoValue<T> v = new IsoValue<T>(type, custom.decodeField(new String(buf, pos + 2, length, getCharacterEncoding())), custom);
|
IsoValue<T> v = new IsoValue<T>(type, custom.decodeField(
|
||||||
|
new String(buf, pos + 2, len, getCharacterEncoding())), custom);
|
||||||
if (v.getValue() == null) {
|
if (v.getValue() == null) {
|
||||||
return new IsoValue<String>(type, new String(buf, pos + 2, length, getCharacterEncoding()), null);
|
return new IsoValue<String>(type,
|
||||||
|
new String(buf, pos + 2, len, getCharacterEncoding()), null);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,37 +40,41 @@ public class LlvarParseInfo extends FieldParseInfo {
|
|||||||
final int pos, final CustomField<T> custom)
|
final int pos, final CustomField<T> custom)
|
||||||
throws ParseException, UnsupportedEncodingException {
|
throws ParseException, UnsupportedEncodingException {
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
throw new ParseException(String.format("Invalid LLVAR field %d %d", field, pos), pos);
|
|
||||||
} else if (pos+2 > buf.length) {
|
|
||||||
throw new ParseException(String.format("Insufficient data for LLVAR header, pos %d", pos), pos);
|
|
||||||
}
|
|
||||||
length = decodeLength(buf, pos, 2);
|
|
||||||
if (length < 0) {
|
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Invalid LLVAR length %d, field %d pos %d", length, field, pos), pos);
|
"Invalid LLVAR field %d %d", field, pos), pos);
|
||||||
} else if (length+pos+2 > buf.length) {
|
} else if (pos+2 > buf.length) {
|
||||||
|
throw new ParseException(String.format(
|
||||||
|
"Insufficient data for LLVAR header, pos %d", pos), pos);
|
||||||
|
}
|
||||||
|
final int len = decodeLength(buf, pos, 2);
|
||||||
|
if (len < 0) {
|
||||||
|
throw new ParseException(String.format(
|
||||||
|
"Invalid LLVAR length %d, field %d pos %d", len, field, pos), pos);
|
||||||
|
} else if (len+pos+2 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for LLVAR field %d, pos %d", field, pos), pos);
|
"Insufficient data for LLVAR field %d, pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
String _v;
|
String _v;
|
||||||
try {
|
try {
|
||||||
_v = length == 0 ? "" : new String(buf, pos + 2, length, getCharacterEncoding());
|
_v = len == 0 ? "" : new String(buf, pos + 2, len, getCharacterEncoding());
|
||||||
} catch (IndexOutOfBoundsException ex) {
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for LLVAR header, field %d pos %d", field, pos), pos);
|
"Insufficient data for LLVAR header, field %d pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
//This is new: if the String's length is different from the specified length in the buffer,
|
//This is new: if the String's length is different from the specified
|
||||||
//there are probably some extended characters. So we create a String from the rest of the buffer,
|
// length in the buffer, there are probably some extended characters.
|
||||||
//and then cut it to the specified length.
|
// So we create a String from the rest of the buffer, and then cut it to
|
||||||
if (_v.length() != length) {
|
// the specified length.
|
||||||
_v = new String(buf, pos + 2, buf.length-pos-2, getCharacterEncoding()).substring(0, length);
|
if (_v.length() != len) {
|
||||||
|
_v = new String(buf, pos + 2, buf.length-pos-2,
|
||||||
|
getCharacterEncoding()).substring(0, len);
|
||||||
}
|
}
|
||||||
if (custom == null) {
|
if (custom == null) {
|
||||||
return new IsoValue<String>(type, _v, length, null);
|
return new IsoValue<String>(type, _v, len, null);
|
||||||
} else {
|
} else {
|
||||||
T dec = custom.decodeField(_v);
|
T dec = custom.decodeField(_v);
|
||||||
return dec == null ? new IsoValue<String>(type, _v, length, null) :
|
return dec == null ? new IsoValue<String>(type, _v, len, null) :
|
||||||
new IsoValue<T>(type, dec, length, custom);
|
new IsoValue<T>(type, dec, len, custom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,22 +87,25 @@ public class LlvarParseInfo extends FieldParseInfo {
|
|||||||
field, pos), pos);
|
field, pos), pos);
|
||||||
} else if (pos+1 > buf.length) {
|
} else if (pos+1 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for bin LLVAR header, field %d pos %d", field, pos), pos);
|
"Insufficient data for bin LLVAR header, field %d pos %d",
|
||||||
|
field, pos), pos);
|
||||||
}
|
}
|
||||||
length = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
final int len = (((buf[pos] & 0xf0) >> 4) * 10) + (buf[pos] & 0x0f);
|
||||||
if (length < 0) {
|
if (len < 0) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Invalid bin LLVAR length %d, field %d pos %d", length, field, pos), pos);
|
"Invalid bin LLVAR length %d, field %d pos %d", len, field, pos), pos);
|
||||||
}
|
}
|
||||||
if (length+pos+1 > buf.length) {
|
if (len+pos+1 > buf.length) {
|
||||||
throw new ParseException(String.format(
|
throw new ParseException(String.format(
|
||||||
"Insufficient data for bin LLVAR field %d, pos %d", field, pos), pos);
|
"Insufficient data for bin LLVAR field %d, pos %d", field, pos), pos);
|
||||||
}
|
}
|
||||||
if (custom == null) {
|
if (custom == null) {
|
||||||
return new IsoValue<String>(type, new String(buf, pos + 1, length, getCharacterEncoding()), null);
|
return new IsoValue<String>(type, new String(buf, pos + 1, len,
|
||||||
|
getCharacterEncoding()), null);
|
||||||
} else {
|
} else {
|
||||||
T dec = custom.decodeField(new String(buf, pos + 1, length, getCharacterEncoding()));
|
T dec = custom.decodeField(new String(buf, pos + 1, len, getCharacterEncoding()));
|
||||||
return dec == null ? new IsoValue<String>(type, new String(buf, pos + 1, length, getCharacterEncoding()), null) :
|
return dec == null ? new IsoValue<String>(type,
|
||||||
|
new String(buf, pos + 1, len, getCharacterEncoding()), null) :
|
||||||
new IsoValue<T>(type, dec, custom);
|
new IsoValue<T>(type, dec, custom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.solab.iso8583.IsoValue;
|
|||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
*/
|
*/
|
||||||
public class TimeParseInfo extends FieldParseInfo {
|
public class TimeParseInfo extends DateTimeParseInfo {
|
||||||
|
|
||||||
|
|
||||||
public TimeParseInfo() {
|
public TimeParseInfo() {
|
||||||
@@ -58,6 +58,9 @@ public class TimeParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
|
cal.set(Calendar.HOUR_OF_DAY, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48);
|
||||||
cal.set(Calendar.MINUTE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
|
cal.set(Calendar.MINUTE, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48);
|
||||||
cal.set(Calendar.SECOND, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
|
cal.set(Calendar.SECOND, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48);
|
||||||
|
}
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
}
|
}
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
@@ -82,6 +85,9 @@ public class TimeParseInfo extends FieldParseInfo {
|
|||||||
cal.set(Calendar.HOUR_OF_DAY, tens[0]);
|
cal.set(Calendar.HOUR_OF_DAY, tens[0]);
|
||||||
cal.set(Calendar.MINUTE, tens[1]);
|
cal.set(Calendar.MINUTE, tens[1]);
|
||||||
cal.set(Calendar.SECOND, tens[2]);
|
cal.set(Calendar.SECOND, tens[2]);
|
||||||
|
if (tz != null) {
|
||||||
|
cal.setTimeZone(tz);
|
||||||
|
}
|
||||||
return new IsoValue<Date>(type, cal.getTime(), null);
|
return new IsoValue<Date>(type, cal.getTime(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<!ATTLIST template type NMTOKEN #REQUIRED >
|
<!ATTLIST template type NMTOKEN #REQUIRED >
|
||||||
<!ATTLIST template extends NMTOKEN #IMPLIED >
|
<!ATTLIST template extends NMTOKEN #IMPLIED >
|
||||||
|
|
||||||
<!ELEMENT parse ( field+ ) >
|
<!ELEMENT parse ( field* ) >
|
||||||
<!ATTLIST parse type NMTOKEN #REQUIRED >
|
<!ATTLIST parse type NMTOKEN #REQUIRED >
|
||||||
<!ATTLIST parse extends NMTOKEN #IMPLIED >
|
<!ATTLIST parse extends NMTOKEN #IMPLIED >
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
<item name="Download" href="http://sourceforge.net/projects/j8583/files/j8583/"/>
|
<item name="Download" href="http://sourceforge.net/projects/j8583/files/j8583/"/>
|
||||||
</links>
|
</links>
|
||||||
|
|
||||||
<menu name="j8583 1.9.0">
|
<menu name="j8583 1.9.1">
|
||||||
<item name="Introduction" href="index.html"/>
|
<item name="Introduction" href="index.html"/>
|
||||||
<item name="API docs" href="javadoc/index.html" />
|
<item name="API docs" href="javadoc/index.html" />
|
||||||
<item name="Beginner's Guide" href="guide.html"/>
|
<item name="Beginner's Guide" href="guide.html"/>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<item name="Descargar" href="http://sourceforge.net/projects/j8583/files/j8583/"/>
|
<item name="Descargar" href="http://sourceforge.net/projects/j8583/files/j8583/"/>
|
||||||
</links>
|
</links>
|
||||||
|
|
||||||
<menu name="j8583 1.9.0">
|
<menu name="j8583 1.9.1">
|
||||||
<item name="Introducción" href="index.html"/>
|
<item name="Introducción" href="index.html"/>
|
||||||
<item name="Documentación API" href="../javadoc/index.html" />
|
<item name="Documentación API" href="../javadoc/index.html" />
|
||||||
<item name="Guía de inicio" href="guide.html"/>
|
<item name="Guía de inicio" href="guide.html"/>
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,4 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import com.solab.iso8583.CustomField;
|
|
||||||
|
|
||||||
/** This is an example of a custom field codec, which converts between strings and instances of this same class.
|
/** This is an example of a custom field codec, which converts between strings and instances of this same class.
|
||||||
* It's used to test the encoding and decoding of custom fields by the message factory.
|
* It's used to test the encoding and decoding of custom fields by the message factory.
|
||||||
+1
-4
@@ -1,17 +1,14 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoType;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
import com.solab.iso8583.util.HexCodec;
|
import com.solab.iso8583.util.HexCodec;
|
||||||
|
|
||||||
/** Test binary message encoding and binary fields. */
|
/** Test binary message encoding and binary fields. */
|
||||||
+1
-5
@@ -1,9 +1,5 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.IsoType;
|
|
||||||
import com.solab.iso8583.IsoValue;
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
+1
-5
@@ -1,9 +1,5 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.IsoType;
|
|
||||||
import com.solab.iso8583.IsoValue;
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
import com.solab.iso8583.parse.*;
|
import com.solab.iso8583.parse.*;
|
||||||
import com.solab.iso8583.util.HexCodec;
|
import com.solab.iso8583.util.HexCodec;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.solab.iso8583;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/** Tests formatting of certain IsoTypes.
|
||||||
|
*
|
||||||
|
* @author Enrique Zamudio
|
||||||
|
*/
|
||||||
|
public class TestFormats {
|
||||||
|
|
||||||
|
private final Date date = new Date(96867296000l);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDateFormats() {
|
||||||
|
assert IsoType.DATE10.format(date, null).equals("0125213456");
|
||||||
|
assert IsoType.DATE4.format(date, null).equals("0125");
|
||||||
|
assert IsoType.DATE_EXP.format(date, null).equals("7301");
|
||||||
|
assert IsoType.TIME.format(date, null).equals("213456");
|
||||||
|
//Now with GMT
|
||||||
|
TimeZone gmt = TimeZone.getTimeZone("GMT");
|
||||||
|
Assert.assertEquals("0126033456", IsoType.DATE10.format(date, gmt));
|
||||||
|
Assert.assertEquals("0126", IsoType.DATE4.format(date, gmt));
|
||||||
|
Assert.assertEquals("7301", IsoType.DATE_EXP.format(date, gmt));
|
||||||
|
Assert.assertEquals("033456", IsoType.TIME.format(date, gmt));
|
||||||
|
//And now with GMT+1
|
||||||
|
gmt = TimeZone.getTimeZone("GMT+0100");
|
||||||
|
Assert.assertEquals("0126043456", IsoType.DATE10.format(date, gmt));
|
||||||
|
Assert.assertEquals("0126", IsoType.DATE4.format(date, gmt));
|
||||||
|
Assert.assertEquals("7301", IsoType.DATE_EXP.format(date, gmt));
|
||||||
|
Assert.assertEquals("043456", IsoType.TIME.format(date, gmt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumericFormats() {
|
||||||
|
assert IsoType.NUMERIC.format(123, 6).equals("000123");
|
||||||
|
assert IsoType.NUMERIC.format("hola", 6).equals("00hola");
|
||||||
|
assert IsoType.AMOUNT.format(12345, 0).equals("000001234500");
|
||||||
|
assert IsoType.AMOUNT.format(new BigDecimal("12345.67"), 0).equals("000001234567");
|
||||||
|
assert IsoType.AMOUNT.format("1234.56", 0).equals("000000123456");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringFormats() {
|
||||||
|
assert IsoType.ALPHA.format("hola", 3).equals("hol");
|
||||||
|
assert IsoType.ALPHA.format("hola", 4).equals("hola");
|
||||||
|
assert IsoType.ALPHA.format("hola", 6).equals("hola ");
|
||||||
|
assert IsoType.LLVAR.format("hola", 0).equals("hola");
|
||||||
|
assert IsoType.LLLVAR.format("hola", 0).equals("hola");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+22
-7
@@ -1,18 +1,15 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoValue;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.IsoType;
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
|
|
||||||
/** These are very simple tests for creating and manipulating messages.
|
/** These are very simple tests for creating and manipulating messages.
|
||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
@@ -82,7 +79,7 @@ public class TestIsoMessage {
|
|||||||
@Test
|
@Test
|
||||||
public void testParsing() throws IOException, ParseException {
|
public void testParsing() throws IOException, ParseException {
|
||||||
InputStream ins = getClass().getResourceAsStream("/parse1.txt");
|
InputStream ins = getClass().getResourceAsStream("/parse1.txt");
|
||||||
byte[] buf = new byte[400];
|
final byte[] buf = new byte[400];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while (ins.available() > 0) {
|
while (ins.available() > 0) {
|
||||||
buf[pos++] = (byte)ins.read();
|
buf[pos++] = (byte)ins.read();
|
||||||
@@ -96,6 +93,15 @@ public class TestIsoMessage {
|
|||||||
byte[] b3 = new byte[b2.length];
|
byte[] b3 = new byte[b2.length];
|
||||||
System.arraycopy(buf, 0, b3, 0, b3.length);
|
System.arraycopy(buf, 0, b3, 0, b3.length);
|
||||||
Assert.assertArrayEquals(b3, b2);
|
Assert.assertArrayEquals(b3, b2);
|
||||||
|
|
||||||
|
//Test it contains the correct fields
|
||||||
|
final List<Integer> fields = Arrays.asList(3, 4, 7, 11, 12, 13, 15, 17, 32, 35, 37, 38, 39, 41, 43, 49, 60, 61, 100, 102, 126);
|
||||||
|
testFields(iso, fields);
|
||||||
|
//Again, but now with forced encoding
|
||||||
|
mf.setForceStringEncoding(true);
|
||||||
|
iso = mf.parseMessage(buf, mf.getIsoHeader(0x210).length());
|
||||||
|
Assert.assertEquals(0x210, iso.getType());
|
||||||
|
testFields(iso, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -129,4 +135,13 @@ public class TestIsoMessage {
|
|||||||
throw new RuntimeException("Update failed!");
|
throw new RuntimeException("Update failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void testFields(IsoMessage m, List<Integer> fields) {
|
||||||
|
for (int i = 2; i < 128; i++) {
|
||||||
|
if (fields.contains(i)) {
|
||||||
|
Assert.assertTrue(m.hasField(i));
|
||||||
|
} else {
|
||||||
|
Assert.assertFalse(m.hasField(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-3
@@ -1,7 +1,5 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
import com.solab.iso8583.parse.ConfigParser;
|
import com.solab.iso8583.parse.ConfigParser;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
+33
-5
@@ -1,19 +1,19 @@
|
|||||||
package j8583;
|
package com.solab.iso8583;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoMessage;
|
|
||||||
import com.solab.iso8583.IsoValue;
|
|
||||||
import com.solab.iso8583.codecs.CompositeField;
|
import com.solab.iso8583.codecs.CompositeField;
|
||||||
import com.solab.iso8583.parse.NumericParseInfo;
|
import com.solab.iso8583.parse.NumericParseInfo;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.solab.iso8583.MessageFactory;
|
|
||||||
|
|
||||||
/** Test that parsing invalid messages is properly handled.
|
/** Test that parsing invalid messages is properly handled.
|
||||||
*
|
*
|
||||||
* @author Enrique Zamudio
|
* @author Enrique Zamudio
|
||||||
@@ -120,4 +120,32 @@ public class TestParsing {
|
|||||||
Assert.assertEquals("12345", f.getObjectValue(2));
|
Assert.assertEquals("12345", f.getObjectValue(2));
|
||||||
Assert.assertEquals(".", f.getObjectValue(3));
|
Assert.assertEquals(".", f.getObjectValue(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDates() throws ParseException, UnsupportedEncodingException {
|
||||||
|
IsoMessage m = mf.parseMessage("060002000000000000000125213456".getBytes(), 0);
|
||||||
|
Assert.assertNotNull(m);
|
||||||
|
Date f = m.getObjectValue(7);
|
||||||
|
Assert.assertNotNull(f);
|
||||||
|
GregorianCalendar cal = new GregorianCalendar();
|
||||||
|
cal.setTime(f);
|
||||||
|
Assert.assertEquals(Calendar.JANUARY, cal.get(Calendar.MONTH));
|
||||||
|
Assert.assertEquals(25, cal.get(Calendar.DATE));
|
||||||
|
Assert.assertEquals(21, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
mf.setTimezoneForParseGuide(0x600, 7, TimeZone.getTimeZone("GMT"));
|
||||||
|
m = mf.parseMessage("060002000000000000000125213456".getBytes(), 0);
|
||||||
|
f = m.getObjectValue(7);
|
||||||
|
cal.setTime(f);
|
||||||
|
Assert.assertEquals(Calendar.JANUARY, cal.get(Calendar.MONTH));
|
||||||
|
Assert.assertEquals(25, cal.get(Calendar.DATE));
|
||||||
|
Assert.assertEquals(15, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
mf.setTimezoneForParseGuide(0x600, 7, TimeZone.getTimeZone("GMT+0100"));
|
||||||
|
m = mf.parseMessage("060002000000000000000125213456".getBytes(), 0);
|
||||||
|
f = m.getObjectValue(7);
|
||||||
|
cal.setTime(f);
|
||||||
|
Assert.assertEquals(Calendar.JANUARY, cal.get(Calendar.MONTH));
|
||||||
|
Assert.assertEquals(25, cal.get(Calendar.DATE));
|
||||||
|
Assert.assertEquals(14, cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-4
@@ -1,13 +1,10 @@
|
|||||||
package j8583;
|
package com.solab.iso8583.parse;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoType;
|
import com.solab.iso8583.IsoType;
|
||||||
import com.solab.iso8583.MessageFactory;
|
import com.solab.iso8583.MessageFactory;
|
||||||
import com.solab.iso8583.IsoMessage;
|
import com.solab.iso8583.IsoMessage;
|
||||||
import com.solab.iso8583.codecs.BigIntBcdCodec;
|
import com.solab.iso8583.codecs.BigIntBcdCodec;
|
||||||
import com.solab.iso8583.codecs.LongBcdCodec;
|
import com.solab.iso8583.codecs.LongBcdCodec;
|
||||||
import com.solab.iso8583.parse.FieldParseInfo;
|
|
||||||
import com.solab.iso8583.parse.LlbinParseInfo;
|
|
||||||
import com.solab.iso8583.parse.LllbinParseInfo;
|
|
||||||
import com.solab.iso8583.util.HexCodec;
|
import com.solab.iso8583.util.HexCodec;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
+1
-4
@@ -1,11 +1,8 @@
|
|||||||
package j8583;
|
package com.solab.iso8583.parse;
|
||||||
|
|
||||||
import com.solab.iso8583.IsoType;
|
import com.solab.iso8583.IsoType;
|
||||||
import com.solab.iso8583.IsoValue;
|
import com.solab.iso8583.IsoValue;
|
||||||
import com.solab.iso8583.codecs.CompositeField;
|
import com.solab.iso8583.codecs.CompositeField;
|
||||||
import com.solab.iso8583.parse.AlphaParseInfo;
|
|
||||||
import com.solab.iso8583.parse.LlvarParseInfo;
|
|
||||||
import com.solab.iso8583.parse.NumericParseInfo;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
+3
-5
@@ -1,4 +1,4 @@
|
|||||||
package j8583;
|
package com.solab.iso8583.parse;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,8 +10,6 @@ import org.junit.*;
|
|||||||
|
|
||||||
import com.solab.iso8583.IsoType;
|
import com.solab.iso8583.IsoType;
|
||||||
import com.solab.iso8583.IsoValue;
|
import com.solab.iso8583.IsoValue;
|
||||||
import com.solab.iso8583.parse.Date10ParseInfo;
|
|
||||||
import com.solab.iso8583.parse.Date4ParseInfo;
|
|
||||||
|
|
||||||
/** Test that the dates are formatted and parsed correctly.
|
/** Test that the dates are formatted and parsed correctly.
|
||||||
*
|
*
|
||||||
@@ -27,7 +25,7 @@ public class TestDates {
|
|||||||
today.set(GregorianCalendar.MINUTE,0);
|
today.set(GregorianCalendar.MINUTE,0);
|
||||||
today.set(GregorianCalendar.SECOND,0);
|
today.set(GregorianCalendar.SECOND,0);
|
||||||
today.set(GregorianCalendar.MILLISECOND,0);
|
today.set(GregorianCalendar.MILLISECOND,0);
|
||||||
byte[] buf = IsoType.DATE4.format(soon).getBytes();
|
byte[] buf = IsoType.DATE4.format(soon, null).getBytes();
|
||||||
IsoValue<Date> comp = new Date4ParseInfo().parse(0, buf, 0, null);
|
IsoValue<Date> comp = new Date4ParseInfo().parse(0, buf, 0, null);
|
||||||
Assert.assertEquals(comp.getValue(), today.getTime());
|
Assert.assertEquals(comp.getValue(), today.getTime());
|
||||||
//Now with the binary
|
//Now with the binary
|
||||||
@@ -40,7 +38,7 @@ public class TestDates {
|
|||||||
@Test
|
@Test
|
||||||
public void testDate10FutureTolerance() throws ParseException, IOException {
|
public void testDate10FutureTolerance() throws ParseException, IOException {
|
||||||
Date soon = new Date(System.currentTimeMillis() + 50000);
|
Date soon = new Date(System.currentTimeMillis() + 50000);
|
||||||
byte[] buf = IsoType.DATE10.format(soon).getBytes();
|
byte[] buf = IsoType.DATE10.format(soon, null).getBytes();
|
||||||
IsoValue<Date> comp = new Date10ParseInfo().parse(0, buf, 0, null);
|
IsoValue<Date> comp = new Date10ParseInfo().parse(0, buf, 0, null);
|
||||||
assert comp.getValue().after(new Date());
|
assert comp.getValue().after(new Date());
|
||||||
//Now with the binary
|
//Now with the binary
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.solab.iso8583.parse;
|
||||||
|
|
||||||
|
import com.solab.iso8583.IsoValue;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test parsing of data with different encodings.
|
||||||
|
*
|
||||||
|
* @author Enrique Zamudio
|
||||||
|
* Date: 05/03/14 16:55
|
||||||
|
*/
|
||||||
|
public class TestEncoding {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void windowsToUtf8() throws UnsupportedEncodingException, ParseException {
|
||||||
|
final String data = "05ácido";
|
||||||
|
final byte[] buf = data.getBytes("ISO-8859-1");
|
||||||
|
final LlvarParseInfo parser = new LlvarParseInfo();
|
||||||
|
parser.setCharacterEncoding("UTF-8");
|
||||||
|
IsoValue<?> field = parser.parse(1, buf, 0, null);
|
||||||
|
Assert.assertNotEquals(field.getValue(), data.substring(2));
|
||||||
|
parser.setCharacterEncoding("ISO-8859-1");
|
||||||
|
field = parser.parse(1, buf, 0, null);
|
||||||
|
Assert.assertEquals(data.substring(2), field.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
package j8583;
|
package com.solab.iso8583.util;
|
||||||
|
|
||||||
import com.solab.iso8583.util.Bcd;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
+1
-4
@@ -1,11 +1,8 @@
|
|||||||
package j8583;
|
package com.solab.iso8583.util;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.solab.iso8583.util.HexCodec;
|
|
||||||
|
|
||||||
|
|
||||||
public class TestHexCodec {
|
public class TestHexCodec {
|
||||||
|
|
||||||
public void encodeDecode(String hex) {
|
public void encodeDecode(String hex) {
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package j8583;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.solab.iso8583.IsoType;
|
|
||||||
|
|
||||||
/** Tests formatting of certain IsoTypes.
|
|
||||||
*
|
|
||||||
* @author Enrique Zamudio
|
|
||||||
*/
|
|
||||||
public class TestFormats {
|
|
||||||
|
|
||||||
private Date date = new Date(96867296000l);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDateFormats() {
|
|
||||||
assert IsoType.DATE10.format(date).equals("0125213456");
|
|
||||||
assert IsoType.DATE4.format(date).equals("0125");
|
|
||||||
assert IsoType.DATE_EXP.format(date).equals("7301");
|
|
||||||
assert IsoType.TIME.format(date).equals("213456");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNumericFormats() {
|
|
||||||
assert IsoType.NUMERIC.format(123, 6).equals("000123");
|
|
||||||
assert IsoType.NUMERIC.format("hola", 6).equals("00hola");
|
|
||||||
assert IsoType.AMOUNT.format(12345, 0).equals("000001234500");
|
|
||||||
assert IsoType.AMOUNT.format(new BigDecimal("12345.67"), 0).equals("000001234567");
|
|
||||||
assert IsoType.AMOUNT.format("1234.56", 0).equals("000000123456");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStringFormats() {
|
|
||||||
assert IsoType.ALPHA.format("hola", 3).equals("hol");
|
|
||||||
assert IsoType.ALPHA.format("hola", 4).equals("hola");
|
|
||||||
assert IsoType.ALPHA.format("hola", 6).equals("hola ");
|
|
||||||
assert IsoType.LLVAR.format("hola", 0).equals("hola");
|
|
||||||
assert IsoType.LLLVAR.format("hola", 0).equals("hola");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user