diff --git a/pom.xml b/pom.xml
index c4a4970..a6e9c5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,10 @@
test
+
+ Enrique Zamudio
+ http://javamexico.org/blogs/ezamudio
+
chochos
diff --git a/src/main/java/com/solab/iso8583/MessageFactory.java b/src/main/java/com/solab/iso8583/MessageFactory.java
index c3bdc0d..40ca272 100644
--- a/src/main/java/com/solab/iso8583/MessageFactory.java
+++ b/src/main/java/com/solab/iso8583/MessageFactory.java
@@ -208,7 +208,7 @@ public class MessageFactory {
* and the rest of the message must come. */
public IsoMessage parseMessage(byte[] buf, int isoHeaderLength) throws ParseException {
IsoMessage m = new IsoMessage(isoHeaderLength > 0 ? new String(buf, 0, isoHeaderLength) : null);
- //TODO it only parses ASCII messages for now
+ //TODO Not really sure if binary support really works, unit tests pending...
int type = 0;
if (useBinary) {
type = ((buf[isoHeaderLength] & 0xff) << 8) | (buf[isoHeaderLength + 1] & 0xff);
@@ -425,6 +425,8 @@ public class MessageFactory {
return typeTemplates.get(type);
}
+ /** Invoke this method in case you want to freeze the configuration, making message and parsing
+ * templates, as well as iso headers and custom fields, immutable. */
public void freeze() {
typeTemplates = Collections.unmodifiableMap(typeTemplates);
parseMap = Collections.unmodifiableMap(parseMap);
diff --git a/src/site/apt/iso8583.apt b/src/site/apt/iso8583.apt
index 51e518d..b395113 100644
--- a/src/site/apt/iso8583.apt
+++ b/src/site/apt/iso8583.apt
@@ -29,7 +29,7 @@ Introduction to ISO8583
*--------------*----------------*-----------------+
| Time | TIME | Time of day in format HHMMSS, fixed width of 6. |
*--------------*----------------*-----------------+
-| Amount | AMOUNT | Currency amount, a positive number expressed in cents, with a fixed width of 4. For example one dollar is encoded as 000000000100 |
+| Amount | AMOUNT | Currency amount, a positive number expressed in cents, with a fixed width of 12. For example one dollar is encoded as 000000000100 |
*--------------*----------------*-----------------+
| LLVAR | LLVAR | Variable-width alphanumeric value, up to 99 characters long. The length of the value is encoded in the first 2 characters of the value, for example "HEY" is encoded as 03HEY |
*--------------*----------------*-----------------+
@@ -116,7 +116,7 @@ ISO 8583 types and their corresponding j8583 types
In these cases, the sender first encodes the whole message, measures it, and sends the length as a 2- or 4-byte
unsigned integer (most significant bit first). This way the receiver knows to read 2 or 4 bytes, interpret them
as an unsigned integer, and read those many bytes to get an ISO message. Using 2 bytes allows for messages of up
- to 65535 bytes, and 4 bytes allows for 2.14 million bytes long, which is a bit of overkill, given that a message
+ to 65535 bytes, and 4 bytes allows for 2.14 billion bytes long, which is a bit of overkill, given that a message
can be as long as 127290 bytes, if it's encoded in ASCII and has 127 LLLVAR fields each with 999 characters.
*** Message terminator
diff --git a/src/site/es/apt/groovy.apt b/src/site/es/apt/groovy.apt
index 3f691f2..a0c4607 100644
--- a/src/site/es/apt/groovy.apt
+++ b/src/site/es/apt/groovy.apt
@@ -1,27 +1,27 @@
-----
- Groovy compatibility
+ Compatibilidad con Groovy
-----
-Isn't ANY Java library compatible with Groovy?
+¿Qué no cualquier biblioteca de Java es compatible con Groovy?
- Yes, of course. You can use j8583 in Groovy just as you would use any other Java library. However,
- some j8583 classes have certain methods in them written specifically for usage within Groovy.
+ Por supuesto. Se puede utilizar j8583 en Groovy al igual que cualquier otra biblioteca de Java. Sin embargo,
+ algunas clases de j8583 tienen algunos métodos con el expreso propósito de ser utilizados desde Groovy.
-* j8583 short-hand in Groovy
+* Atajos de j8583 en Groovy
- In Java, you can deal with values in an IsoMessage like this:
+ En Java, se pueden manejar los valores de un IsoMessage en alguna de las siguientes formas:
+-----
-message.setValue(32, "Some value", IsoType.LLVAR, 0);
+message.setValue(32, "Algun valor", IsoType.LLVAR, 0);
IsoValue isoValue = message.getField(32);
String value = (String)message.getObjectValue(32);
Object value2 = message.getField(32).getValue();
+-----
- In Groovy you can do the same like this
+ En Groovy se puede hacer lo mismo de esta forma:
+-----
-message[32] = IsoType.LLVAR("Some value")
+message[32] = IsoType.LLVAR("Algun valor")
message[7] = IsoType.DATE10(new Date())
message[41] = IsoType.ALPHA("Term", 16)
message[11] = IsoType.NUMERIC(123, 6)
@@ -29,7 +29,8 @@ IsoValue isoValue = message[32]
def value = message[32]?.value
+-----
- This is because the IsoMessage class has get <<>> and <<>> methods that work similar
- to <<>> and <<>>, and the IsoType class has two <<>> methods, with and without
- length, which return IsoValue instances with the proper type and length. The variant that has a length parameter
- must be used with NUMERIC and ALPHA types, and the other types can use the variant without length.
+ Esto es posible gracias a que la clase IsoMessage implementa los métodos <<>> y <<>>, que
+ funcionan de manera similar a <<>> y <<>>; la clase IsoType tiene dos variantes del
+ método <<>>, una con longitud y otra sin longitud, los cuales devuelven instancias de IsoValue con
+ el valor y longitud apropiados. La variante con longitud debe ser utiliza para crear valores tipo
+ NUMERIC y ALPHA, mientras que los demás tipos pueden utilizar la variante sin longitud.
diff --git a/src/site/es/apt/guide.apt b/src/site/es/apt/guide.apt
index 1bc1f65..b8f0878 100644
--- a/src/site/es/apt/guide.apt
+++ b/src/site/es/apt/guide.apt
@@ -1,8 +1,8 @@
-----
- Usage Guide
+ Guía del usuario
-----
-Usage Guide
+Guía del usuario
Esta guía explica brevemente cómo configurar y utilizar j8583. Para conocer más acerca del protocolo
ISO8583 como tal, favor de leer la {{{iso8583.html}página correspondiente}}.
diff --git a/src/site/es/apt/iso8583.apt b/src/site/es/apt/iso8583.apt
index 51e518d..c8a5832 100644
--- a/src/site/es/apt/iso8583.apt
+++ b/src/site/es/apt/iso8583.apt
@@ -2,143 +2,153 @@
ISO8583
-----
-Introduction to ISO8583
+Introducción al protocolo ISO8583
- The specification is available at iso.org and it's gotten really complicated; this is just an introduction
- to the generalities of the specification. There is actually a
- {{{http://en.wikipedia.org/wiki/ISO_8583}really good article}} on Wikipedia covering the whole spec and its
- different versions.
+ La especificación completa está disponible en el sitio iso.org y es bastante complicada; esta es únicamente
+ una introducción muy simple a las generalidades del protocolo. Wikipedia tiene un
+ {{{http://en.wikipedia.org/wiki/ISO_8583}artículo bastante completo}} que abarca la especificación completa
+ en sus distintas versiones.
-* Data types
+* Tipos de datos
- ISO 8583 specifies a lot of data types, the most common of which are implemented directly in j8583 through
- the <<>> enum. Here is a table of the most common ISO types and their j8583 counterpart:
+ ISO 8583 especifica muchos tipos de datos, de los cuales se eligieron los más comunes para ser implementados
+ en j8583 por medio del enum <<>>. A continuación se presenta una tabla con los tipos ISO más comunes
+ y su contraparte en j8583:
*--------------*----------------*-----------------+
-| <> | <> | <> |
+| <> | <> | <> |
*--------------*----------------*-----------------+
-| Numeric | NUMERIC | Fixed-width numeric values, padded with zeroes to the left.|
+| Numérico | NUMERIC | Valores numéricos de longitud fija, rellenos con ceros a la izquierda.
*--------------*----------------*-----------------+
-| Alphanumeric | ALPHA | Fixed-width alphanumeric values, padded with spaces to the right.|
+| Alfanumérico | ALPHA | Valores alfanuméricos de longitud fija, rellenos con espacios a la derecha.
*--------------*----------------*-----------------+
-| Date | DATE10 | Date in format mmddHHMMSS, fixed width of 10. |
+| Fecha | DATE10 | Fecha en formato mmddHHMMSS, con longitud fija de 10.
*--------------*----------------*-----------------+
-| Date | DATE4 | Date in format mmdd, fixed width of 4. |
+| Fecha | DATE4 | Fecha en formato mmdd, con longitud fija de 4.
*--------------*----------------*-----------------+
-| Expiration Date | DATE_EXP | Date in format yymm, fixed width of 4. Used for credit card expiration dates. |
+| Fecha de expiración | DATE_EXP | Fecha en formato aamm, con longitud fija de 4. Se usa por ejemplo para fechas de expiración de tarjetas de crédito.
*--------------*----------------*-----------------+
-| Time | TIME | Time of day in format HHMMSS, fixed width of 6. |
+| Hora | TIME | Hora del día en formato HHMMSS, con longitud fija de 6. |
*--------------*----------------*-----------------+
-| Amount | AMOUNT | Currency amount, a positive number expressed in cents, with a fixed width of 4. For example one dollar is encoded as 000000000100 |
+| Monto | AMOUNT | Monto en alguna moneda, expresado en centavos, con una longitud fija de 12. Por ejemplo un dólar se codifica como 000000000100
*--------------*----------------*-----------------+
-| LLVAR | LLVAR | Variable-width alphanumeric value, up to 99 characters long. The length of the value is encoded in the first 2 characters of the value, for example "HEY" is encoded as 03HEY |
+| LLVAR | LLVAR | Valor alfanumérico de longitud variable, hasta 99 caracteres. La longitud del valor se codifica en los dos primeros caracteres del valor; por ejemplo "HOLA" se codifica como 04HOLA
*--------------*----------------*-----------------+
-| LLLVAR | LLLVAR | Variable-width alphanumeric value, up to 999 characters long. The length of the value is encoded in the first 3 characters of the value, for example "HEY" is encoded as 003HEY |
+| LLLVAR | LLLVAR | Valor alfanumérico de longitud variable, hasta 999 caracteres. La longitud del valor se codifica en los dos primeros caracteres del valor; por ejemplo "HOLA" se codifica como 004HOLA
*--------------*----------------*-----------------+
-ISO 8583 types and their corresponding j8583 types
+Tipos de ISO8583 y sus contrapartes en j8583
-* Common scenarios
+* Escenarios típicos
- ISO8583 implementations can vary a lot, depending on the provider, and the type of products and transactions it
- is being used for; but there are certain fields which are almost always used in a very similar manner. I will
- describe those here. <> This is only something I have learned from experience, and I must say
- my experience has been rather limited to mobile carrier providers. Here I focus more on the field number and
- type, rather on the usage of the field itself.
+ Las implementaciones de ISO8583 pueden variar mucho dependiendo del proveedor, así como de los productos o
+ servicios manejados y las transacciones que se van a procesar, pero casi siempre hay ciertos campos que se
+ utilizan de la misma manera. A continuación se describen estos campos. <> Esto es algo que he
+ aprendido únicamente por experiencia, la cual ha sido limitada principalmente a proveedores de telefonía celular.
+ Aquí me enfoco más a describir un campo por su tipo y número, más que el uso que se le pueda dar.
-** Message types
+** Tipos de mensaje
- These are some of the most common message types. There is some logic to this, if you look at the message types
- as 2-byte hex values: The first byte states the type of operation: 02 are payments, 04 reversals, 08 tests;
- the second byte indicates if it's a request or a response. And sometimes repeated requests should end in 1
- instead of 0, for example reversals are 0400 the first time but 0401 the next time you send them.
+ Estos son algunos de los tipos de mensaje más común. Estos tipos siguen cierta lógica, si se les ve como
+ valores de 2 bytes; el primer byte indica el tipo de operación: 02 son pagos, 04 son reversos, 08 son pruebas;
+ el segundo byte indica si es una petición o una respuesta. Y en ocasiones, los reenvíos de peticiones deben
+ terminar en 1 en vez de 0, por ejemplo un reverso se envía por primera vez como 0400 pero en ocasiones
+ subsecuentes se debe reenviar como 0401.
*------:--+
-| 0200 | A payment or sale request.
+| 0200 | Una petición de pago o venta.
*------:--+
-| 0210 | A payment or sale response.
+| 0210 | Una respuesta de pago o venta.
*------:--+
-| 0400 | A reversal request (to undo a previous 0200 operation).
+| 0400 | Petición de reverso (para revertir una operación 0200 previa).
*------:--+
-| 0410 | A reversal response.
+| 0410 | Respuesta de reverso.
*------:--+
-| 0600 | A query (to check the status of a previous operation, or check an account's balance, etc).
+| 0600 | Una consulta (por ejemplo de saldo o de una operación previa).
*------:--+
-| 0610 | A query response.
+| 0610 | Respuesta de consulta.
*------:--+
-| 0800 | An echo request (just to keep the connection alive and make sure the other side is responsive).
+| 0800 | Petición de eco (para mantener viva una conexión y asegurarse que el otro lado de la conexión sigue respondiendo).
*------:--+
-| 0810 | An echo response.
+| 0810 | Respuesta de eco.
*------:--+
- Some implementations require you to send 0400 for a reversal when you only have the request (so in case of
- timeout you use 0400) and 0420 when you did get the response (so in case of some other error in your system).
+ Algunas implementaciones requieren que se envíe 0400 cuando solamente se tiene la petición 0200 sin haber obtenido
+ respuesta (en caso de expirar el tiempo de espera para el 0210), y enviar 0420 cuando ya se obtuvo respuesta
+ (en caso de que ocurra algún otro error en el sistema, después de recibir el 0210).
-** Common fields
+** Campos comunes
- [Field 3] Operation code, NUMERIC of length 6.
+ [Field 3] Código de operación, NUMERIC de longitud 6.
- [Field 4] Amount, AMOUNT.
+ [Field 4] Monto, tipo AMOUNT.
- [Field 7] Date, DATE10.
+ [Field 7] Fecha de la transacción, tipo DATE10.
- [Field 11] Trace, NUMERIC of length 6.
+ [Field 11] Número de trace, NUMERIC de longitud 6.
- [Field 17] Transaction date, DATE4.
+ [Field 17] Fecha de la transacción, tipo DATE4.
- [Field 37] Reference number, NUMERIC of length 12.
+ [Field 37] Número de referencia, NUMERIC de longitud 12.
- [Field 38] Confirmation number, NUMERIC of length 6.
+ [Field 38] Número de confirmación, NUMERIC de longitud 6.
- [Field 39] Response code, NUMERIC of length 2.
+ [Field 39] Código de respuesta, NUMERIC de longitud 2.
- [Field 41] Terminal ID, ALPHA of length 8 or 16.
+ [Field 41] Identificador de la terminal de venta, ALPHA de longitud 8 ó 16.
- [Field 49] Currency, NUMERIC of length 3. See the {{{http://en.wikipedia.org/wiki/ISO_4217}ISO 4217}} table of currencies.
+ [Field 49] Código de moneda, NUMERIC de longitud 3. Ver la tabla de códigos {{{http://es.wikipedia.org/wiki/ISO_4217}ISO 4217}}.
- [Field 128] MAC (Message Authentication Code). Usually ALPHA or NUMERIC of length 16.
+ [Field 128] MAC (Código de autenticación de mensaje). Generalmente ALPHA o NUMERIC de longitud 16.
[]
-** Asynchronous transmission and reception
+** Transmisión y recepción asíncrona
- When communicating two systems with ISO8583, usually the communication is asynchronous and all messages are
- handled through a single connection. Between a terminal and a bigger system the communication will be synchronous.
+ Cuando se comunican dos sistemas con ISO8583, generalmente la comunicación es asíncrona y todos los mensajes
+ se manejan por una misma conexión. Entre una terminal y un sistema de mayor tamaño, la comunicación suele ser
+ síncrona.
- In asynchronous communications, the client can send any number of requests to the server, and the server may
- respond to those requests in a different order in which they were sent. This is why the trace number (field 11)
- is very important and should not be reused; if the client sends requests with traces 123000, 123001 and 123002,
- the server may send back first 123001, then 123002, then 123000. The client will know which response corresponds
- to which request by checking the trace of the responses.
+ En la comunicación asíncrona, el cliente puede enviar cualquier cantidad de peticiones al servidor, y el servidor
+ puede enviar las respuestas en un orden distinto. Es por esto que el número de traza (campo 11) es tan importante
+ y no se debe repetir en periodos cortos de tiempo; si el cliente envía peticiones con trazas 123000, 123001 y
+ 123002, el server puede contestar primero la 123001, luego 123002, y finalmente la 123000. El cliente sabrá
+ a qué petición corresponde cada respuesta por medio del número de traza.
- The messages can vary in length depending on the message type and the fields it contains. The protocol was
- designed so that a message can be read in parts; first the message type, then the primary bitmap, and from there
- the rest of the fields (secondary bitmap included) can be read and processed one by one. This is very convenient
- for small devices like POS terminals, but is not very efficient in larger systems with a high transaction volume.
- In these cases, the sender first encodes the whole message, measures it, and sends the length as a 2- or 4-byte
- unsigned integer (most significant bit first). This way the receiver knows to read 2 or 4 bytes, interpret them
- as an unsigned integer, and read those many bytes to get an ISO message. Using 2 bytes allows for messages of up
- to 65535 bytes, and 4 bytes allows for 2.14 million bytes long, which is a bit of overkill, given that a message
- can be as long as 127290 bytes, if it's encoded in ASCII and has 127 LLLVAR fields each with 999 characters.
+ Los mensajes pueden variar en su longitud según el tipo de mensaje y los campos que contenga. El protocolo fue
+ diseñado de modo que un mensaje se pueda leer en partes; primero el tipo de mensaje, luego el bitmap primario,
+ y a partir de ahí se leerá cada campo que indique el bitmap, uno por uno. Esto es muy conveniente para
+ dispositivos pequeños con poca memoria, como terminales de punto de venta, pero no es muy eficiente en sistemas
+ grandes que procesan un gran volumen de operaciones. En estos casos, generalmente se envía primero un encabezado
+ de longitud indicando el tamaño del mensaje como un entero sin signo de 2 ó 4 bytes (con el bit más significativo
+ primero). De esta forma, el receptor siempre lee primero 2 ó 4 bytes, los interpreta como un entero sin signo
+ y después lee tantos bytes como indique ese encabezado, para convertir esa trama en un IsoMessage. Un encabezado
+ de 2 bytes permite mensajes hasta de 65535 bytes, mientras que un encabezado de 4 bytes permite mensajes de
+ 2147 millones de bytes, lo cual es más que suficiente, dado que un mensaje puede medir hasta 127290 bytes,
+ si se codifica en ASCII y tiene 127 campos tipo LLLVAR cada uno con 999 caracteres.
-*** Message terminator
+*** Terminador de mensaje
- The length header that is sent before a message is very useful to separate the reading operation from the parsing
- of the message; you can dedicate a thread to read from a socket, and put those buffers on a queue where another
- thread parses them. However, a length header only says how many bytes to read and so the reader must read all
- those bytes, but what if the message is invalid because it is than the length says? To avoid this error,
- some systems use a message terminator. This is just a character that must be found at the end of every message.
- If messages are encoded as text, a common terminator is ASCII 0x03. The terminator may or may not be counted
- as part of the message, that depends on the implementation. You can specify the terminator via the <<>>
- property of an IsoMessage, of preferably in the MessageFactory so that all new messages already will have the
- property set. To keep the messages from using a terminator, set <<>> to -1.
+ El encabezado de longitud que se envía antes de un mensaje es muy útil para separar la operación de lectura
+ de la operación de procesamiento del mensaje; se puede dedicar un hilo a leer de un socket y encolar esas
+ tramas para que otro hilo las convierta en IsoMessages. Sin embargo, el encabezado de longitud únicamente indica
+ cuántos bytes hay que leer, para que el receptor sepa que tiene que recibir al menos ese número de bytes, pero
+ ¿qué pasa si el mensaje en realidad es de lo que dice la longitud? Habrá problemas leyendo el
+ siguiente mensaje. Para evitar este error, algunos sistemas implementa un terminador de mensaje, que es
+ simplemente un caracter que va al final de cada mensaje. Si los mensajes se codifican como texto, un terminador
+ común es ASCII 0x03. El terminador puede ser contado como parte del mensaje (incluido en el encabezado de
+ longitud) o ser contado aparte, depende de la implementación. Se puede especificar el terminador en la propiedad
+ <<>> de un IsoMessage, y también en la misma propiedad de la MessageFactory para que todos los mensajes
+ creados por la fábrica ya contengan el terminador y lo incluyan al generar sus tramas. Para no utilizar un
+ terminador, se debe indicar -1 en el <<>> (este es el valor por defecto).
-** Binary encoding
+** Codificación binaria
- Many ISO8583 implementations use plain text for the messages (even if the length header is binary). But some
- implementations encode the messages as binary. The main differences are that the message type is only 2 bytes
- long instead of 4 (the ASCII version is actually a hex representation of the message type), the bitmap is not
- hex-encoded, so it's only 8 bytes long; and all numeric values (including date/time fields) are encoded using
- {{{http://en.wikipedia.org/wiki/Binary-coded_decimal}BCD}} (including the headers for LLVAR and LLLVAR fields).
+ Muchas implementaciones de ISO8583 utilizan texto simple para los mensajes (aunque el encabezado de longitud
+ sea binario). Pero algunas implementaciones codifican sus mensajes en binario. Entre las diferencias
+ principales tenemos que el tipo de mensaje es de 2 bytes en vez de 4 (la versión ASCII de hecho es una
+ representación de texto hexadecimal el tipo de mensaje), el bitmap no viene codificado en hexadecimal por lo
+ que mide sólo 8 bytes; y todos los valores numéricos (incluyendo campos tipo fecha/hora) se codifican usando
+ {{{http://es.wikipedia.org/wiki/Binary-coded_decimal}BCD}} (incluyendo los encabezados de campos LLVAR y LLLVAR).
- You can encode messages in binary by setting the <<>> property of IsoMessages, or in the MessageFactory
- directly by setting the <<>> so that it gets set on all new messages. It must be set in
- the MessageFactory if you want it to parse binary messages.
+ Se pueden codificar un mensaje en formato binario activando la propiedad <<>> de un IsoMessage, o la
+ propiedad <<>> de la MessageFactory, para afectar los mensajes creados a partir de ese momento.
+ Además para poder leer mensajes en formato binario se debe activar la propiedad en la MessageFactory.