jpos / jPOS

jPOS Project
http://jpos.org
GNU Affero General Public License v3.0
599 stars 458 forks source link

Fix/isomsg set isocomponent #513

Closed barspi closed 1 year ago

barspi commented 1 year ago

The current implementation of ISOMsg.set(String fpath, ISOComponent c) has some pathological behavior.

Example 1

// New component with no explicit id/fieldnumber (so it's internally -1)
ISOAmount am = new ISOAmount();
am.setValue("8402000011112222");

ISOMsg m = new ISOMsg()
m.set("95.2.8", am);

This produces

<isomsg>
  <isomsg id="95">
    <isomsg id="2">
    </isomsg>
  </isomsg>
</isomsg>

The last element of the path (subfield 8 of 95.2) is not created, and the ISOAmount is not added anywhere.

Example 2

ISOAmount am = new ISOAmount(16);  // Now, give the component an explicit id
am.setValue("8402000011112222");

ISOMsg m = new ISOMsg()
m.set("95.2.8", am);

// Fails!!
// assertNotNull(m.getComponent("95.2.8"));
<isomsg>
  <isomsg id="95">
    <isomsg id="2">
      <field id="16" currency="840" type="amount" value="111122.22"/>
    </isomsg>
  </isomsg>
</isomsg>

OK, so now the component is added to the tree, but what happened to the last fpath part, namely subfield 8?

The only current way to make it work is if the component is given an explicit id, and that id matches the last part of the fpath.

This PR attempts to fix this, by inserting the component at the point of the last path, such that

assertNotNull(m.getComponent("95.2.8"));
assertEquals(am, m.getComponent("95.2.8"));

New tests have been added.