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; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.io.PrintStream; 025import java.util.Collections; 026import java.util.Map; 027 028/** 029 * implements a <b>Component</b> 030 * within a <b>Composite pattern</b> 031 * 032 * See 033 * <a href="/doc/javadoc/overview-summary.html">Overview</a> for details. 034 * 035 * @author apr@cs.com.uy 036 * @version $Id$ 037 * @see ISOMsg 038 * @see ISOField 039 * @see ISOException 040 */ 041public abstract class ISOComponent implements Cloneable { 042 /** Default constructor; no instance state to initialise. */ 043 protected ISOComponent() {} 044 /** 045 * Set a field within this message 046 * @param c - a component 047 * @exception ISOException always thrown by leaves; composites override this 048 */ 049 public void set (ISOComponent c) throws ISOException { 050 throw new ISOException ("Can't add to Leaf"); 051 } 052 /** 053 * Unset a field 054 * @param fldno - the field number 055 * @exception ISOException always thrown by leaves; composites override this 056 */ 057 public void unset (int fldno) throws ISOException { 058 throw new ISOException ("Can't remove from Leaf"); 059 } 060 /** 061 * In order to interchange <b>Composites</b> and <b>Leafs</b> we use 062 * getComposite(). A <b>Composite component</b> returns itself and 063 * a Leaf returns null. The base class ISOComponent provides 064 * <b>Leaf</b> functionality. 065 * 066 * @return ISOComponent 067 */ 068 public ISOComponent getComposite() { 069 return null; 070 } 071 /** 072 * valid on Leafs only. 073 * The value returned is used by ISOMsg as a key 074 * to this field. 075 * 076 * @return object representing the field number 077 * @exception ISOException thrown by composites; leaves return their key 078 */ 079 public Object getKey() throws ISOException { 080 throw new ISOException ("N/A in Composite"); 081 } 082 /** 083 * valid on Leafs only. 084 * @return object representing the field value 085 * @exception ISOException thrown by composites; leaves return their value 086 */ 087 public Object getValue() throws ISOException { 088 throw new ISOException ("N/A in Composite"); 089 } 090 /** 091 * get Value as bytes (when possible) 092 * @return byte[] representing this field 093 * @exception ISOException thrown by composites or when the value cannot be rendered as bytes 094 */ 095 public byte[] getBytes() throws ISOException { 096 throw new ISOException ("N/A in Composite"); 097 } 098 /** 099 * a Composite must override this function 100 * @return the max field number associated with this message 101 */ 102 public int getMaxField() { 103 return 0; 104 } 105 /** 106 * dummy behaviour - return empty map 107 * @return children (in this case 0 children) 108 */ 109 public Map getChildren() { 110 return Collections.emptyMap(); 111 } 112 /** 113 * changes this Component field number<br> 114 * Use with care, this method does not change 115 * any reference held by a Composite. 116 * @param fieldNumber new field number 117 */ 118 public abstract void setFieldNumber (int fieldNumber); 119 /** 120 * Returns the field number this component occupies within its container. 121 * 122 * @return the field number 123 */ 124 public abstract int getFieldNumber (); 125 /** 126 * Sets the value of this component. 127 * 128 * @param obj new value 129 * @throws ISOException if the value is rejected by the component implementation 130 */ 131 public abstract void setValue(Object obj) throws ISOException; 132 /** 133 * Packs this component into its on-wire byte representation. 134 * 135 * @return packed bytes 136 * @throws ISOException if packing fails 137 */ 138 public abstract byte[] pack() throws ISOException; 139 /** 140 * Unpacks this component from {@code b} starting at offset 0. 141 * 142 * @param b packed bytes 143 * @return number of bytes consumed 144 * @throws ISOException if unpacking fails 145 */ 146 public abstract int unpack(byte[] b) throws ISOException; 147 /** 148 * Writes a human-readable dump of this component for diagnostics. 149 * 150 * @param p destination stream 151 * @param indent prefix to apply to every emitted line 152 */ 153 public abstract void dump (PrintStream p, String indent); 154 /** 155 * Packs this component and writes it to {@code out}. 156 * 157 * @param out destination stream 158 * @throws IOException if writing fails 159 * @throws ISOException if packing fails 160 */ 161 public void pack (OutputStream out) throws IOException, ISOException { 162 out.write (pack ()); 163 } 164 /** 165 * Unpacks this component by reading from {@code in}. 166 * 167 * @param in source stream 168 * @throws IOException if reading fails 169 * @throws ISOException if unpacking fails 170 */ 171 public abstract void unpack (InputStream in) throws IOException, ISOException; 172}