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 public GenericSubFieldPackager() throws ISOException 048 { 049 super(); 050 } 051 052 @Override 053 public int getFieldNumber() { 054 return fieldId; 055 } 056 057 @Override 058 public void setGenericPackagerParams(Attributes atts) { 059 super.setGenericPackagerParams(atts); 060 fieldId = Integer.parseInt(atts.getValue("id")); 061 } 062 063 @Override 064 public int unpack (ISOComponent m, byte[] b) throws ISOException 065 { 066 LogEvent evt = new LogEvent (this, "unpack"); 067 try 068 { 069 if (m.getComposite() != m) 070 throw new ISOException ("Can't call packager on non Composite"); 071 if (b.length == 0) 072 return 0; // nothing to do 073 if (logger != null) // save a few CPU cycle if no logger available 074 evt.addMessage (ISOUtil.hexString (b)); 075 076 int consumed=0; 077 ISOBitMap bitmap = new ISOBitMap (-1); 078 079 BitSet bmap = null; 080 int maxField = fld.length; 081 if (emitBitMap()) 082 { 083 consumed += getBitMapfieldPackager().unpack(bitmap,b,consumed); 084 bmap = (BitSet) bitmap.getValue(); 085 m.set (bitmap); 086 maxField = bmap.size(); 087 } 088 for (int i=getFirstField(); i<maxField && consumed < b.length; i++) 089 { 090 if ((bmap == null || bmap.get(i)) && i<fld.length && fld[i] != null) { 091 ISOComponent c = fld[i].createComponent(i); 092 consumed += fld[i].unpack (c, b, consumed); 093 m.set(c); 094 } 095 } 096 if (b.length != consumed) 097 { 098 evt.addMessage ( 099 "WARNING: unpack len=" +b.length +" consumed=" +consumed); 100 } 101 return consumed; 102 } 103 catch (ISOException e) 104 { 105 evt.addMessage (e); 106 throw e; 107 } 108 catch (Exception e) 109 { 110 evt.addMessage (e); 111 throw new ISOException (e); 112 } 113 finally 114 { 115 Logger.log (evt); 116 } 117 } 118 119 /** 120 * Pack the subfield into a byte array 121 */ 122 @Override 123 public byte[] pack(ISOComponent m) throws ISOException 124 { 125 LogEvent evt = new LogEvent (this, "pack"); 126 try (ByteArrayOutputStream bout = new ByteArrayOutputStream(100)) 127 { 128 ISOComponent c; 129 Map fields = m.getChildren(); 130 131 if (emitBitMap()) 132 { 133 // BITMAP (-1 in HashTable) 134 c = (ISOComponent) fields.get (-1); 135 byte[] b = getBitMapfieldPackager().pack(c); 136 bout.write(b); 137 } 138 139 for (int i=getFirstField(); i<=m.getMaxField(); i++) 140 { 141 c = (ISOComponent) fields.get (i); 142 if (c == null && !emitBitMap()) 143 c = new ISOField (i, ""); 144 if (c != null) { 145 try 146 { 147 byte[] b = fld[i].pack(c); 148 bout.write(b); 149 } 150 catch (Exception e) 151 { 152 evt.addMessage ("error packing subfield "+i); 153 evt.addMessage (c); 154 evt.addMessage (e); 155 throw e; 156 } 157 } 158 } 159 160 byte[] d = bout.toByteArray(); 161 if (logger != null) // save a few CPU cycle if no logger available 162 evt.addMessage (ISOUtil.hexString (d)); 163 return d; 164 } 165 catch (ISOException e) 166 { 167 evt.addMessage (e); 168 throw e; 169 } 170 catch (Exception e) 171 { 172 evt.addMessage (e); 173 throw new ISOException (e); 174 } 175 finally 176 { 177 Logger.log(evt); 178 } 179 } 180} 181 182