I am using jPOS for creating ISO8583 message, I am using the genericpackager but it seems it only support data fields of fixed length. I want to prepend the length of the field before the field if it has a variable size.
I am using below:
<isofield
id="34"
length="32"
name="Extended Primary Account Number"
class="org.jpos.iso.IF_CHAR"/>
and in .java fileisoMsg.set(34, "12345ABCDE");
What change do I need to make to prepend the length of the field before the field.
For each isofield - you need to modify the class to match the requirements for the appropriate field configuration.
http://jpos.org/doc/javadoc/org/jpos/iso/packager/GenericPackager.html
For instance you can use any of the isofield classes with a Length indicator (L)
such as:
class="org.jpos.iso.IFA_LLCHAR"/>
Or
class="org.jpos.iso.IFB_LLNUM"/>
to support a variable length field.
Where the first example is ASCII 2 byte Length and the second one is Binary 2 byte Length.
you can find a list of sample generic packagers here: https://github.com/jpos/jPOS/tree/master/jpos/src/dist/cfg/packager
you can find a list of isofield classes (start with IF_) here: https://github.com/jpos/jPOS/tree/master/jpos/src/main/java/org/jpos/iso
Related
For more control and clarity of the unpack ISO8583 message , I wanted to print the length of each field, my first attempt was this:
.getFieldPackager(i).getLength()
In a code like this:
Gp=new GenericPackager("./iso87ascii.xml");
message.setPackager(Gp);
for (int i = 0; i <= 128; i++) {
if (message.hasField(i)) {
System.out.println(message.getPackager().getFieldDescription(message, i) +
Gp.getFieldPackager(i).getLength()+
message.getString(i));
}
For fields with variable lengths, it shows the maximum length, not the actual length.
Can any body help?
Edit:
As stated in the comment, We can calculate the length of field:
message.getString(n).getLength()
but we can not figure out what length Jpos has as the length of the field, and if JPos is wrong, there is no way to control it.
We only need the first number of the field, which represents the length of the field, with Jpos terms
You are printing out the configuration of the jPOS Packager, you won’t have addressability to data and its field lengths until you parse and unpack a message using a packager into an ISOMsg Object using message.unpack() - once you unpack() you can get the length of the data using message.getString(n).getLength() or equivalent.
Looking at https://developers.google.com/protocol-buffers/docs/proto3#scalar it appears that string and bytes types don't limit the length? Does it mean that we're expected to specify the length of transmitted string in a separate field, e.g. :
message Person {
string name = 1;
int32 name_len = 2;
int32 user_id = 3;
...
}
The wire type used for string/byte is Length-delimited. This means that the message includes the strings length. How this is made available to you will depend upon the language you are using - for example the table says that in C++ a string type is used so you can call name.length() to retrieve the length.
So there is no need to specify the length in a separate field.
One of the things that I wished GPB did was allow the schema to be used to set constraints on such things as list/array length, or numerical value ranges. The best you can do is to have a comment in the .proto file and hope that programmers pay attention to it!
Other serialisation technologies do do this, like XSD (though often the tools are poor), ASN.1 and JSON schema. It's very useful. If GPB added these (it doesn't change wire formats), GPB would be pretty well "complete".
I have a dataset with columns containing numbers. However, some of the rows in that column have missing data. Instead of numbers, a dash (-) is placed in the cell.
What I want to happen is to separate those rows with a dash and output them to a separate excel file. Those without the dash, should output to a csv file.
I tried the "filter rows" but it gives me an error:
Unexpected conversion error while converting value [constant String] to a Number
constant String : couldn't convert String to number
constant String : couldn't convert String to number : non-numeric character found at position 1 for value [-]
My condition is if
Column1 CONTAINS - (String)
You cant try to convert to number in the select step,and handler the error, if can not convert to number that mean that is (-)
You can convert missing value indicators (like a dash or any other string) to null in Text-File-Input - see field option "Null if". That way you still can use the metadata detection feature and will not trip over a dash arriving in a Number field.
With CSV-File-Input you should stick to the String datatype until a Null-If step has cleansed the values, so you can change the datatype to Number in a Select-Values step.
If you must preserve the dash character, don't use metadata detection (as it suggests datatype Number) or use more rows to sample (so a field with a dash is encountered) or just revert the datatype to String again before saving and running the transformation.
My solution lies on the first 'Replace in String'. I replaced the dash into something numeric and can easily be distinguished from the rest of the numbers (I used 9999) and carried on with the rest of my process.
In filter rows, I had no problems anymore with the data type because both my variables and condition contained numbers, therefore, it no longer had to convert anything.
After filter rows, I added the 'Null-if' to remove the random 9999 that I used
just to have something to replace the dash.
After that, the separation was made just as I hope it would.
Thanks to #marabu for the Null-if idea.
Is there any way of programmatically getting the value of a Text Symbol at runtime?
The scenario is that I have a simple report that calls a function module. I receive an exported parameter in variable LV_MSG of type CHAR1. This indicates a certain status message created in the program, for instance F (Fail), X (Match) or E (Error). I currently use a CASE statement to switch on LV_MSG and fill another variable with a short description of the message. These descriptions are maintained as text symbols that I retrieve at compile time with text-MS# where # is the same as the possible returns of LV_MSG, for instance text-MSX has the value "Exact Match Found".
Now it seems to me that the entire CASE statement is unnecessary as I could just assign to my description variable the value of the text symbol with ID 'MS' + LV_MSG (pseudocode, would use CONCATENATE). Now my issue is how I can find a text symbol based on the String representation of its ID at runtime. Is this even possible?
If it is, my code would look cleaner and I wouldn't have to update my actual code when new messages are added in the function module, as I would simply have to add a new text symbol. But would this approach be any faster or would it in fact degrade the report's performance?
Personally, I would probably define a domain and use the fixed values of the domain to represent the values. This way, you would even get around the string concatenation. You can use the function module DD_DOMVALUE_TEXT_GET to easily access the language-dependent text of a domain value.
To access the text elements of a program, use a function module like READ_TEXT_ELEMENTS.
Be aware that generic programming like this will definitely slow down your program. Whether it would make your code look cleaner is in the eye of the beholder - if the values change rarely, I don't see why a simple CASE statement should be inferior to some generic text access.
Hope I understand you correctly but here goes. This is possible with a little trickery, all the text symbols in a report are defined as variables in the program (with the name text-abc where abc is the text ID). So you can use the following:
data: lt_all_text type standard table of textpool with default key,
lsr_text type ref to textpool.
"Load texts - you will only want to do this once
read textpool sy-repid into lt_all_text language sy-langu.
sort lt_all_Text by entry.
"Find a text, the field KEY is the text ID without TEXT-
read table lt_all_text with key entry = i_wanted_text
reference into lsr_text binary search.
If you want the address you can add:
field-symbols: <l_text> type any.
data l_name type string.
data lr_address type ref to data.
concatenate 'TEXT-' lsr_text->key into l_name.
assign (l_name) to <l_text>.
if sy-subrc = 0.
get reference of <l_text> into lr_address.
endif.
As vwegert pointed out this is probably not the best solution, for error handling rather use message classes or exception objects. This is useful in other cases though so now you know how.
I am building an API endpoint that accepts DateTime as a parameter.
It is recommended not to use : character as part of the URI, so I can't simply use ISO 8601 format.
So far I have considered two formats:
A) Exclamation mark as minute delimiter:
http://api.example.com/resource/2013-08-29T12!15
Looks unnatural and even with clear documentation, API consumers are bound to make mistakes.
B) URI segment per DateTime part:
http://api.example.com/resource/2013/08/29/12/15
Looks unreadable. Also, once I add further numeric parameters - it will become incomprehensible!
Is there standard/convention for for representing date/time in URIs?
I'd use the data interchange standard format.
Check this: http://en.wikipedia.org/wiki/ISO_8601
You can use : in URI paths.
The colon is a reserved character, but it has no delimiting role in the path segment. So the following should apply:
If a reserved character is found in a URI component and no delimiting role is known for that character, then it must be interpreted as representing the data octet corresponding to that character's encoding in US-ASCII.
There is only one exception for relative-path references:
A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment of a relative-path reference, as it would be mistaken for a scheme name. Such a segment must be preceded by a dot-segment (e.g., "./this:that") to make a relative-path reference.
But note that some encoding libraries might percent-encode the colon anyway.