001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.iso.packager; 020 021import org.jpos.iso.*; 022import org.jpos.util.LogEvent; 023import org.jpos.util.Logger; 024 025import java.io.ByteArrayOutputStream; 026import java.util.BitSet; 027import java.util.Map; 028import org.xml.sax.Attributes; 029 030/** 031 * GenericSubFieldPackager 032 * Used to pack composite SubFields from the GenericPackager 033 * 034 * @author Eoin Flood 035 * @see GenericPackager 036 * 037 * This class is basically the same as Base1SubFieldPackager except that it extends 038 * GenericPackager which means that parameters such as emitBitmap, maxvalidField and 039 * bitmapField can be specified in the GenericPackager xml config file. 040 */ 041 042public class GenericSubFieldPackager extends GenericPackager implements ISOSubFieldPackager 043{ 044 045 private Integer fieldId = 0; 046 047 /** 048 * Default constructor. 049 * @throws ISOException if configuration fails 050 */ 051 public GenericSubFieldPackager() throws ISOException 052 { 053 super(); 054 } 055 056 @Override 057 public int getFieldNumber() { 058 return fieldId; 059 } 060 061 @Override 062 public void setGenericPackagerParams(Attributes atts) { 063 super.setGenericPackagerParams(atts); 064 fieldId = Integer.parseInt(atts.getValue("id")); 065 } 066 067 @Override 068 public int unpack (ISOComponent m, byte[] b) throws ISOException 069 { 070 LogEvent evt = new LogEvent (this, "unpack"); 071 try 072 { 073 if (m.getComposite() != m) 074 throw new ISOException ("Can't call packager on non Composite"); 075 if (b.length == 0) 076 return 0; // nothing to do 077 if (logger != null) // save a few CPU cycle if no logger available 078 evt.addMessage (ISOUtil.hexString (b)); 079 080 int consumed=0; 081 ISOBitMap bitmap = new ISOBitMap (-1); 082 083 BitSet bmap = null; 084 int maxField = fld.length; 085 if (emitBitMap()) 086 { 087 consumed += getBitMapfieldPackager().unpack(bitmap,b,consumed); 088 bmap = (BitSet) bitmap.getValue(); 089 m.set (bitmap); 090 maxField = bmap.size(); 091 } 092 for (int i=getFirstField(); i<maxField && consumed < b.length; i++) 093 { 094 if ((bmap == null || bmap.get(i)) && i<fld.length && fld[i] != null) { 095 ISOComponent c = fld[i].createComponent(i); 096 consumed += fld[i].unpack (c, b, consumed); 097 m.set(c); 098 } 099 } 100 if (b.length != consumed) 101 { 102 evt.addMessage ( 103 "WARNING: unpack len=" +b.length +" consumed=" +consumed); 104 } 105 return consumed; 106 } 107 catch (ISOException e) 108 { 109 evt.addMessage (e); 110 throw e; 111 } 112 catch (Exception e) 113 { 114 evt.addMessage (e); 115 throw new ISOException (e); 116 } 117 finally 118 { 119 Logger.log (evt); 120 } 121 } 122 123 /** 124 * Pack the subfield into a byte array 125 */ 126 @Override 127 public byte[] pack(ISOComponent m) throws ISOException 128 { 129 LogEvent evt = new LogEvent (this, "pack"); 130 try (ByteArrayOutputStream bout = new ByteArrayOutputStream(100)) 131 { 132 ISOComponent c; 133 Map fields = m.getChildren(); 134 135 if (emitBitMap()) 136 { 137 // BITMAP (-1 in HashTable) 138 c = (ISOComponent) fields.get (-1); 139 byte[] b = getBitMapfieldPackager().pack(c); 140 bout.write(b); 141 } 142 143 for (int i=getFirstField(); i<=m.getMaxField(); i++) 144 { 145 c = (ISOComponent) fields.get (i); 146 if (c == null && !emitBitMap()) 147 c = new ISOField (i, ""); 148 if (c != null) { 149 try 150 { 151 byte[] b = fld[i].pack(c); 152 bout.write(b); 153 } 154 catch (Exception e) 155 { 156 evt.addMessage ("error packing subfield "+i); 157 evt.addMessage (c); 158 evt.addMessage (e); 159 throw e; 160 } 161 } 162 } 163 164 byte[] d = bout.toByteArray(); 165 if (logger != null) // save a few CPU cycle if no logger available 166 evt.addMessage (ISOUtil.hexString (d)); 167 return d; 168 } 169 catch (ISOException e) 170 { 171 evt.addMessage (e); 172 throw e; 173 } 174 catch (Exception e) 175 { 176 evt.addMessage (e); 177 throw new ISOException (e); 178 } 179 finally 180 { 181 Logger.log(evt); 182 } 183 } 184} 185 186