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.rc; 020 021import org.jpos.core.Configurable; 022import org.jpos.core.Configuration; 023import org.jpos.core.ConfigurationException; 024import org.jpos.iso.ISOUtil; 025 026import java.io.IOException; 027import java.io.InputStream; 028import java.util.*; 029 030/** Converts between {@link CMF} result codes and ISO response codes. */ 031public class CMFConverter implements IRCConverter, Configurable { 032 private static final Map<Integer, RC> rcs = new HashMap<>(); 033 private static final Map<String, IRC> ircs = new HashMap<>(); 034 private Configuration cfg; 035 036 static { 037 try { 038 load ("org/jpos/rc/CMF.properties"); 039 load ("META-INF/org/jpos/rc/CMF.properties"); 040 } catch (IOException ignored) { } 041 } 042 043 /** Default constructor. */ 044 public CMFConverter() { 045 super(); 046 } 047 048 /** 049 * Creates a CMFConverter using the given configuration. 050 * @param cfg the configuration mapping IRC codes to RC values 051 */ 052 public CMFConverter(Configuration cfg) { 053 this.cfg = cfg; 054 } 055 056 @Override 057 public RC convert(IRC irc) { 058 String s = cfg != null ? cfg.get(Long.toString(irc.irc()), null) : null; 059 if (s != null) { 060 return buildRC(s); 061 } else if (rcs.containsKey(irc.irc())) 062 return rcs.get(irc.irc()); 063 064 s = irc.irc() > 9999 ? Long.toString(irc.irc()) : ISOUtil.zeropad(irc.irc(),4); 065 return new SimpleRC(s, (irc instanceof CMF ? ((CMF)irc).name().replace("_", " ") : null)); 066 } 067 068 @Override 069 public IRC convert (RC rc) { 070 IRC irc = ircs.get(rc.rc()); 071 if (irc == null) { 072 irc = CMF.valueOf(Integer.parseInt(rc.rc())); 073 } 074 return irc; 075 } 076 077 private static void load (String base) throws IOException { 078 try (InputStream in=loadResourceAsStream(base)) { 079 if (in != null) 080 addBundle(new PropertyResourceBundle(in)); 081 } 082 } 083 private static InputStream loadResourceAsStream(String name) { 084 InputStream in = null; 085 086 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 087 if (contextClassLoader != null) 088 in = contextClassLoader.getResourceAsStream(name); 089 if (in == null) 090 in = CMFConverter.class.getClassLoader().getResourceAsStream(name); 091 return in; 092 } 093 094 private static SimpleRC buildRC (String s) { 095 String[] ss = ISOUtil.commaDecode(s); 096 String rc = null; 097 String display = null; 098 if (ss.length > 0) 099 rc = ss[0]; 100 if (ss.length > 1) 101 display = ss[1]; 102 Objects.requireNonNull(rc, "Invalid result code"); 103 return new SimpleRC (rc, display); 104 } 105 106 private static void addBundle(ResourceBundle r) { 107 Enumeration en = r.getKeys(); 108 while (en.hasMoreElements()) { 109 String key = (String) en.nextElement(); 110 String value = r.getString(key); 111 RC rc = buildRC(value); 112 int irc = Integer.parseInt(key); 113 rcs.put (irc, rc); 114 ircs.put (rc.rc(), CMF.valueOf(irc)); 115 } 116 } 117 118 @Override 119 public void setConfiguration(Configuration cfg) throws ConfigurationException { 120 this.cfg = cfg; 121 } 122}