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.tlv;
020
021
022import org.jpos.iso.ISOComponent;
023import org.jpos.iso.ISOException;
024import org.jpos.iso.ISOHeader;
025import org.jpos.iso.ISOMsg;
026import org.jpos.iso.ISOPackager;
027
028import java.io.IOException;
029import java.io.InputStream;
030import java.io.OutputStream;
031import java.io.PrintStream;
032import java.util.Map;
033
034
035/**
036 * A {@link TagValue} whose value is a reference to an {@link org.jpos.iso.ISOMsg}.
037 * @author Vishnu Pillai
038 */
039public class ISOMsgRef {
040
041    private final ISOMsg delegate;
042    private int offset = 0;
043
044    /** Constructs a reference wrapper for the given message.
045     * @param delegate the ISO message to wrap
046     */
047    public ISOMsgRef(ISOMsg delegate) {
048        if (delegate == null) {
049            throw new IllegalArgumentException("delegate cannot be null");
050        }
051        this.delegate = delegate;
052    }
053
054    /** Returns an offset-indexed reference message for the given field.
055     * @param fieldNumber the field number
056     * @return the reference ISOMsg
057     */
058    public ISOMsg reference(int fieldNumber) {
059        return new Ref(fieldNumber);
060    }
061
062
063    /** Inner class providing offset-indexed access to a referenced ISO message. */
064    public class Ref extends ISOMsg implements OffsetIndexedComposite {
065
066        private Integer fieldNumber;
067
068        private Ref(int fieldNumber) {
069            this.fieldNumber = fieldNumber;
070        }
071
072        @Override
073        public void incOffset() {
074            if (offset < delegate.getMaxField()) {
075                offset++;
076            }
077        }
078
079        @Override
080        public void setOffset(int offset) {
081            if (offset <= delegate.getMaxField()) {
082                ISOMsgRef.this.offset = offset;
083            }
084        }
085
086        @Override
087        public void resetOffset() {
088            offset = 0;
089        }
090
091        @Override
092        public int getOffset() {
093            return offset;
094        }
095
096        @Override
097        public Object getKey() throws ISOException {
098            return fieldNumber;
099        }
100
101
102        @Override
103        public void setFieldNumber(final int fieldNumber) {
104            this.fieldNumber = fieldNumber;
105        }
106
107        @Override
108        public void setValue(final Object obj) throws ISOException {
109            delegate.setValue(obj);
110        }
111
112
113        @Override
114        public void set(final ISOComponent c) throws ISOException {
115            delegate.set(c);
116        }
117
118
119        @Override
120        public void unset(final int fldno) {
121            delegate.unset(fldno);
122        }
123
124
125        @Override
126        public ISOComponent getComposite() {
127            if (delegate.getComposite() == delegate) {
128                return this;
129            } else {
130                return null;
131            }
132        }
133
134
135        @Override
136        public Object getValue() {
137            return delegate.getValue();
138        }
139
140
141        @Override
142        public byte[] getBytes() throws ISOException {
143            return delegate.getBytes();
144        }
145
146
147        @Override
148        public int getMaxField() {
149            return delegate.getMaxField();
150        }
151
152
153        @Override
154        public Map getChildren() {
155            return delegate.getChildren();
156        }
157
158
159        @Override
160        public void pack(final OutputStream out) throws IOException, ISOException {
161            delegate.pack(out);
162        }
163
164
165        @Override
166        public void dump(final PrintStream p, final String indent) {
167            delegate.dump(p, indent);
168        }
169
170
171        @Override
172        public byte[] pack() throws ISOException {
173            return delegate.pack();
174        }
175
176
177        @Override
178        public int unpack(final byte[] b) throws ISOException {
179            return delegate.unpack(b);
180        }
181
182
183        @Override
184        public void unpack(final InputStream in) throws IOException, ISOException {
185            delegate.unpack(in);
186        }
187
188        @Override
189        public void setDirection(int direction) {
190            delegate.setDirection(direction);
191        }
192
193        @Override
194        public void setHeader(byte[] b) {
195            delegate.setHeader(b);
196        }
197
198        @Override
199        public void setHeader(ISOHeader header) {
200            delegate.setHeader(header);
201        }
202
203        @Override
204        public byte[] getHeader() {
205            return delegate.getHeader();
206        }
207
208        @Override
209        public ISOHeader getISOHeader() {
210            return delegate.getISOHeader();
211        }
212
213        @Override
214        public int getDirection() {
215            return delegate.getDirection();
216        }
217
218        @Override
219        public boolean isIncoming() {
220            return delegate.isIncoming();
221        }
222
223        @Override
224        public boolean isOutgoing() {
225            return delegate.isOutgoing();
226        }
227
228        @Override
229        public void setPackager(ISOPackager p) {
230            delegate.setPackager(p);
231        }
232
233        @Override
234        public ISOPackager getPackager() {
235            return delegate.getPackager();
236        }
237
238        @Override
239        public void set(int fldno, String value) {
240            delegate.set(fldno, value);
241        }
242
243        @Override
244        public void set(String fpath, String value) {
245            delegate.set(fpath, value);
246        }
247
248        @Override
249        public void set(String fpath, ISOComponent c) throws ISOException {
250            delegate.set(fpath, c);
251        }
252
253        @Override
254        public void set(String fpath, byte[] value) {
255            delegate.set(fpath, value);
256        }
257
258        @Override
259        public void set(int fldno, byte[] value) {
260            delegate.set(fldno, value);
261        }
262
263        @Override
264        public void unset(int[] flds) {
265            delegate.unset(flds);
266        }
267
268        @Override
269        public void unset(String fpath) {
270            delegate.unset(fpath);
271        }
272
273        @Override
274        public void recalcBitMap() throws ISOException {
275            delegate.recalcBitMap();
276        }
277
278        @Override
279        public ISOComponent getComponent(int fldno) {
280            return delegate.getComponent(fldno);
281        }
282
283        @Override
284        public Object getValue(int fldno) {
285            return delegate.getValue(fldno);
286        }
287
288        @Override
289        public Object getValue(String fpath) throws ISOException {
290            return delegate.getValue(fpath);
291        }
292
293        @Override
294        public ISOComponent getComponent(String fpath) throws ISOException {
295            return delegate.getComponent(fpath);
296        }
297
298        @Override
299        public String getString(int fldno) {
300            return delegate.getString(fldno);
301        }
302
303        @Override
304        public String getString(String fpath) {
305            return delegate.getString(fpath);
306        }
307
308        @Override
309        public byte[] getBytes(int fldno) {
310            return delegate.getBytes(fldno);
311        }
312
313        @Override
314        public byte[] getBytes(String fpath) {
315            return delegate.getBytes(fpath);
316        }
317
318        @Override
319        public boolean hasField(int fldno) {
320            return delegate.hasField(fldno);
321        }
322
323        @Override
324        public boolean hasFields(int[] fields) {
325            return delegate.hasFields(fields);
326        }
327
328        @Override
329        public boolean hasField(String fpath) {
330            return delegate.hasField(fpath);
331        }
332
333        @Override
334        public boolean hasFields() {
335            return delegate.hasFields();
336        }
337
338        @Override
339        public Object clone() {
340            return delegate.clone();
341        }
342
343        @Override
344        public Object clone(int[] fields) {
345            return delegate.clone(fields);
346        }
347
348        @Override
349        public void merge(ISOMsg m) {
350            delegate.merge(m);
351        }
352
353        @Override
354        public String toString() {
355            return delegate.toString();
356        }
357
358        @Override
359        public boolean isInner() {
360            return delegate.isInner();
361        }
362
363        @Override
364        public void setMTI(String mti) throws ISOException {
365            delegate.setMTI(mti);
366        }
367
368        @Override
369        public void move(int oldFieldNumber, int newFieldNumber) throws ISOException {
370            delegate.move(oldFieldNumber, newFieldNumber);
371        }
372
373        @Override
374        public String getMTI() throws ISOException {
375            return delegate.getMTI();
376        }
377
378        @Override
379        public boolean isRequest() throws ISOException {
380            return delegate.isRequest();
381        }
382    }
383
384}