Commit 5695a96a by gechengyang

完善代码

parent 7b2d8e63
...@@ -6,7 +6,11 @@ ...@@ -6,7 +6,11 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" path="src/main/resources"/> <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> <classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes> <attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
...@@ -18,6 +22,6 @@ ...@@ -18,6 +22,6 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7"/>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>
/target/
#Tue Feb 12 10:54:25 CST 2019
eclipse.preferences.version=1
useAssemblyMapping=true
#Tue Feb 12 11:31:34 CST 2019
eclipse.preferences.version=1 eclipse.preferences.version=1
encoding//src/main/java=UTF-8 encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/main/resources/tags.properties=UTF-8 encoding//src/main/resources/tags.properties=UTF-8
encoding//src/test/java=UTF-8 encoding//src/test/java=UTF-8
encoding/<project>=UTF-8 encoding/<project>=UTF-8
#Tue Feb 12 11:31:34 CST 2019
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.compiler.source=1.7
...@@ -39,6 +39,12 @@ ...@@ -39,6 +39,12 @@
<version>2.8.5</version> <version>2.8.5</version>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency> <dependency>
......
...@@ -12,6 +12,7 @@ import com.brilliace.swifteditor.tag.TagLine; ...@@ -12,6 +12,7 @@ import com.brilliace.swifteditor.tag.TagLine;
import com.brilliace.swifteditor.tag.message.MessageFormat; import com.brilliace.swifteditor.tag.message.MessageFormat;
import com.brilliace.swifteditor.tag.message.SWFMessage; import com.brilliace.swifteditor.tag.message.SWFMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/** /**
* Hello world! * Hello world!
...@@ -19,13 +20,14 @@ import com.google.gson.Gson; ...@@ -19,13 +20,14 @@ import com.google.gson.Gson;
*/ */
public class App public class App
{ {
static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
public static void main( String[] args ) throws IOException public static void main( String[] args ) throws IOException
{ {
TagFormat.WalkTagCell("61", "6!n[4!n]2a[1!a]15d1!a3!c16x['//'16x]['CRLF'34x]"); // TagFormat.WalkTagCell("61", "6!n[4!n]2a[1!a]15d1!a3!c16x['//'16x]['CRLF'34x]");
// System.out.println( TagFormat.TagMap.get("71F").toAnalyzeReg() ); // System.out.println( TagFormat.TagMap.get("71F").toAnalyzeReg() );
// TagLine t59 = TagFormat.TagMap.get("79"); // TagLine t59 = TagFormat.TagMap.get("59");
// t59.setValue("14314321\n423424234\nasdgfasdgfasf\nafdagfadsf\r\nasdfasdfsaf"); // t59.setValue("/14314321\n423424234\nasdgfasdgfasf\nafdagfadsf\r\nasdfasdfsaf");
// System.out.println(t59); // System.out.println(gson.toJson(t59));
// System.out.println(new Gson().toJson(TagFormat.TagMap.get("34B").toSegRegMap())); // System.out.println(new Gson().toJson(TagFormat.TagMap.get("34B").toSegRegMap()));
// System.out.println(new Gson().toJson(TagFormat.WalkTagCell("51A", "['/'<DC>]['/'34x]['CRLF']<SWIFTBIC>"))); // System.out.println(new Gson().toJson(TagFormat.WalkTagCell("51A", "['/'<DC>]['/'34x]['CRLF']<SWIFTBIC>")));
// for(Map.Entry<String, TagLine> entry: TagFormat.TagMap.entrySet()) // for(Map.Entry<String, TagLine> entry: TagFormat.TagMap.entrySet())
...@@ -34,7 +36,6 @@ public class App ...@@ -34,7 +36,6 @@ public class App
// } // }
// MessageFormat.loadSWFMessage(); // MessageFormat.loadSWFMessage();
// SWFMessage swf = MessageFormat.getSWFMessage("202"); // SWFMessage swf = MessageFormat.getSWFMessage("202");
// //toJSON();
// System.out.println(swf.toFormatJSON()); // System.out.println(swf.toFormatJSON());
// generMTFormat(); // generMTFormat();
// System.out.println("111"); // System.out.println("111");
......
package com.brilliace.swifteditor.tag.message; package com.brilliace.swifteditor.tag.message;
import java.io.BufferedReader;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -14,727 +12,630 @@ import java.util.regex.Pattern; ...@@ -14,727 +12,630 @@ import java.util.regex.Pattern;
import com.brilliace.swifteditor.tag.TagFormat; import com.brilliace.swifteditor.tag.TagFormat;
import com.brilliace.swifteditor.tag.TagLine; import com.brilliace.swifteditor.tag.TagLine;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
public class MessageAnalyzer { public class MessageAnalyzer {
/* /*
* @param msg:报文字符串; 传递报文字符串,将其中的文首都解析出来。 对于ACK/NCK报文,后面会附带原报,会出现文首重复的情况,将附带的原报文首的KEY添加负号做为KEY,避免覆盖。 * @param msg:报文字符串; 传递报文字符串,将其中的文首都解析出来。
* 如果后面附带了S等带字母的“文首”,则直接使用其Acsii码,作为KEY。 * 对于ACK/NCK报文,后面会附带原报,会出现文首重复的情况,将附带的原报文首的KEY添加负号做为KEY,避免覆盖。
*/ * 如果后面附带了S等带字母的“文首”,则直接使用其Acsii码,作为KEY。
public static Map<Integer, String> anlyMsgHead(String msg) */
{ public static Map<Integer, String> anlyMsgHead(String msg) {
Map<Integer, String> headSet = new HashMap<Integer, String>(); Map<Integer, String> headSet = new HashMap<Integer, String>();
String reg = "\\{[\\d|S]:"; String reg = "\\{[\\d|S]:";
Matcher m = Pattern.compile(reg).matcher(msg); Matcher m = Pattern.compile(reg).matcher(msg);
int lstEnd = -1; int lstEnd = -1;
int lstHead = -1; int lstHead = -1;
while (m.find()) while (m.find()) {
{ if (lstEnd > 0 && lstHead > 0) {
if (lstEnd > 0 && lstHead > 0) String val = msg.substring(lstEnd, m.start() - 1);
{ if (!headSet.containsKey(lstHead)) {
String val = msg.substring(lstEnd, m.start() - 1); headSet.put(lstHead, val);
if (!headSet.containsKey(lstHead)) } else {
{ headSet.put(-lstHead, val);
headSet.put(lstHead, val); }
} }
else String g = m.group();
{ char c = g.charAt(1);
headSet.put(-lstHead, val); lstHead = c;
} if (c >= '0' && c <= '9') // 对于是数字的,则以数字做KEY,否则以Acsii码做主键
} lstHead -= '0';
String g = m.group(); lstEnd = m.end();
char c = g.charAt(1); }
lstHead = c; if (lstEnd > 0 && lstHead > 0) // 将最后一个文首存入Map
if (c >= '0' && c <= '9') // 对于是数字的,则以数字做KEY,否则以Acsii码做主键 {
lstHead -= '0'; int lstidx = msg.lastIndexOf('}');
lstEnd = m.end(); if (lstidx <= lstEnd)
} return headSet;
if (lstEnd > 0 && lstHead > 0) // 将最后一个文首存入Map if (!headSet.containsKey(lstHead))
{ headSet.put(lstHead, msg.substring(lstEnd, lstidx));
int lstidx = msg.lastIndexOf('}'); else
if (lstidx <= lstEnd) headSet.put(-lstHead, msg.substring(lstEnd, lstidx));
return headSet; }
if (!headSet.containsKey(lstHead)) return headSet;
headSet.put(lstHead, msg.substring(lstEnd, lstidx)); }
else
headSet.put(-lstHead, msg.substring(lstEnd, lstidx)); /*
} * @param mt:对正文block 4中包含的栏位名称和栏位值切割,以换行符加“:”来切割
return headSet; */
} public static List<String[]> msgTxtAnly(String mt) {
if (mt.startsWith(":"))
/* mt = "\r\n" + mt;
* @param mt:对正文block 4中包含的栏位名称和栏位值切割,以换行符加“:”来切割 String[] tags = mt.split("[\\r\\n]{1,2}:");
*/ List<String[]> list = new ArrayList<String[]>();
public static List<String[]> msgTxtAnly(String mt) for (String tv : tags) {
{ if (tv.trim().length() > 0) {
if(mt.startsWith(":")) int i = tv.indexOf(':');
mt = "\r\n"+mt; if (i > 0) {
String[] tags = mt.split("[\\r\\n]{1,2}:"); String[] arr = new String[2];
List<String[]> list = new ArrayList<String[]>(); arr[0] = tv.substring(0, i);
for (String tv : tags) arr[1] = tv.substring(i + 1);
{ list.add(arr);
if (tv.trim().length() > 0) }
{ }
int i = tv.indexOf(':'); }
if (i > 0) if (list.size() > 0) {
{ String[] lstOne = list.get(list.size() - 1);
String[] arr = new String[2]; int i = lstOne[1].lastIndexOf("\r\n");
arr[0] = tv.substring(0, i); if (i < 0) {
arr[1] = tv.substring(i + 1); i = lstOne[1].lastIndexOf("\r");
list.add(arr); }
} if (i < 0) {
} i = lstOne[1].lastIndexOf("\n");
} }
if (list.size() > 0) if (i > -1) {
{ lstOne[1] = lstOne[1].substring(0, i);
String[] lstOne = list.get(list.size() - 1); list.set(list.size() - 1, lstOne);
int i = lstOne[1].lastIndexOf("\r\n"); }
if (i < 0) }
{ return list;
i = lstOne[1].lastIndexOf("\r"); }
}
if (i < 0) /* 屏蔽不同的系统的换行符差异,获取换行符位置 */
{ private static int getLinePos(String str) {
i = lstOne[1].lastIndexOf("\n"); if (str == null)
} return -1;
if (i > -1) int idxr = str.indexOf("\r");
{ int idxn = str.indexOf("\n");
lstOne[1] = lstOne[1].substring(0, i); if (idxr > -1 && idxn > -1)// \r\n连接在一起
list.set(list.size() - 1, lstOne); {
} return idxr < idxn ? idxr : idxn;
} } else {
return list; return idxr <= idxn ? idxn : idxr;// 单个\r或者\n的情况,返回较大的
} }
}
/* 屏蔽不同的系统的换行符差异,获取换行符位置 */
private static int getLinePos(String str) public static Map<String, String> getSwfMsgInfoViaMsg(Map<Integer, String> heads) {
{ Map<String, String> infMap = new HashMap<String, String>();
if (str == null)
return -1; String hd4 = heads.get(4);
int idxr = str.indexOf("\r"); boolean isNACK = false; // 是否为ACK/NCK报文
int idxn = str.indexOf("\n"); if (hd4 != null) {
if (idxr > -1 && idxn > -1)// \r\n连接在一起 if (hd4.contains("{451:0}") || hd4.contains("{451:1}")) {
{ isNACK = true;
return idxr < idxn ? idxr : idxn; if (hd4.contains("{451:0}"))
} infMap.put("mty", "ACK");
else else
{ infMap.put("mty", "NCK");
return idxr <= idxn ? idxn : idxr;// 单个\r或者\n的情况,返回较大的 // infMap.put("ehf",heads.get(-4) );
} int errIdx = hd4.indexOf("{405:");
} if (errIdx > -1) {
int idx2 = hd4.indexOf("}", errIdx);// 获取下一个括号
public static Map<String, String> getSwfMsgInfoViaMsg(Map<Integer, String> heads) if (idx2 > -1)
{ infMap.put("errcod", hd4.substring(errIdx + 5, idx2));// 将错误码放进去
Map<String, String> infMap = new HashMap<String, String>(); }
} else
String hd4 = heads.get(4); // 非ACK 或NCK报文
boolean isNACK = false; // 是否为ACK/NCK报文 {
if (hd4 != null)
{ }
if (hd4.contains("{451:0}") || hd4.contains("{451:1}")) }
{ /* 处理报文或者附带的报文的文首和正文 */
isNACK = true; String hd2 = heads.containsKey(-2) ? heads.get(-2) : heads.get(2);
if (hd4.contains("{451:0}")) String hd1 = heads.containsKey(-1) ? heads.get(-1) : heads.get(1);
infMap.put("mty", "ACK"); String hd3 = heads.containsKey(-3) ? heads.get(-3) : heads.get(3);
else hd4 = heads.containsKey(-4) ? heads.get(-4) : heads.get(4);
infMap.put("mty", "NCK"); String hd5 = heads.containsKey(-5) ? heads.get(-5) : heads.get(5);
// infMap.put("ehf",heads.get(-4) ); if (hd5 != null)
int errIdx = hd4.indexOf("{405:"); infMap.put("trl", hd5);
if (errIdx > -1) String msgTyp = null; // 报文类型,如果为NCK/ACK报文,则该类型值为附带的原文里面的类型
{ String direct = null; // 报文收发方向
int idx2 = hd4.indexOf("}", errIdx);// 获取下一个括号 if (hd2 != null) // 拆解2文首
if (idx2 > -1) {
infMap.put("errcod", hd4.substring(errIdx + 5, idx2));// 将错误码放进去 // 如果2文首不为空,开始获取收发方向和报文类型
} if (hd2.length() >= 4) {
} direct = hd2.substring(0, 1);
else infMap.put("direct", direct);// 存储报文方向
// 非ACK 或NCK报文 msgTyp = hd2.substring(1, 4);
{ if ("I".equals(direct)) // 发出报文
{
} if (hd2.length() >= 16) {
} String rcvbic = hd2.substring(4, 16); // 获取收报行
/* 处理报文或者附带的报文的文首和正文 */ infMap.put("rcvbic", rcvbic);
String hd2 = heads.containsKey(-2) ? heads.get(-2) : heads.get(2); }
String hd1 = heads.containsKey(-1) ? heads.get(-1) : heads.get(1); if (hd2.length() >= 17)
String hd3 = heads.containsKey(-3) ? heads.get(-3) : heads.get(3); infMap.put("prt", hd2.substring(16, 17));// 电报优先级
hd4 = heads.containsKey(-4) ? heads.get(-4) : heads.get(4); if (hd2.length() >= 18)
String hd5 = heads.containsKey(-5) ? heads.get(-5) : heads.get(5); infMap.put("tns", hd2.substring(17, 18));
if (hd5 != null) if (hd2.length() >= 21)
infMap.put("trl", hd5); infMap.put("dyt", hd2.substring(18, 21));
String msgTyp = null; // 报文类型,如果为NCK/ACK报文,则该类型值为附带的原文里面的类型 } else if ("O".equals(direct)) {
String direct = null; // 报文收发方向 if (hd2.length() >= 26) {
if (hd2 != null) // 拆解2文首 String sndbic = hd2.substring(14, 26);
{ infMap.put("sndbic", sndbic); // 获取发报行
// 如果2文首不为空,开始获取收发方向和报文类型 if (hd2.length() >= 36) {
if (hd2.length() >= 4) infMap.put("mir", hd2.substring(8, 14) + " " + hd2.substring(14, 36));// 获取MIR
{ if (hd2.length() == 47)
direct = hd2.substring(0, 1); infMap.put("prt", hd2.substring(46));// 电报优先级
infMap.put("direct", direct);// 存储报文方向 }
msgTyp = hd2.substring(1, 4); }
if ("I".equals(direct)) // 发出报文 }
{ }
if (hd2.length() >= 16) }
{ if (hd1 != null) // 拆解1文首
String rcvbic = hd2.substring(4, 16); // 获取收报行 {
infMap.put("rcvbic", rcvbic); if (hd1.length() >= 15) {
} String bnk1 = hd1.substring(3, 15);
if (hd2.length() >= 17) if ("O".equals(direct)) {
infMap.put("prt", hd2.substring(16, 17));// 电报优先级 infMap.put("rcvbic", bnk1);
if (hd2.length() >= 18) } else if ("I".equals(direct)) {
infMap.put("tns", hd2.substring(17, 18)); infMap.put("sndbic", bnk1);
if (hd2.length() >= 21) }
infMap.put("dyt", hd2.substring(18, 21)); if (hd2 != null && hd2.length() >= 14) {
} infMap.put("mor", hd2.substring(8, 14) + " " + hd1.substring(3));// 获取MOR
else if ("O".equals(direct)) }
{ }
if (hd2.length() >= 26) }
{ if (hd3 != null) {
String sndbic = hd2.substring(14, 26); if (hd3.contains("{119:COV}")) {
infMap.put("sndbic", sndbic); // 获取发报行 msgTyp = msgTyp + "COV";
if (hd2.length() >= 36) }
{ if (hd3.contains("{FMT:")) {
infMap.put("mir", hd2.substring(8, 14) + " " + hd2.substring(14, 36));// 获取MIR String fmt = hd3.substring(1, hd3.length() - 1);
if (hd2.length() == 47) String args[] = fmt.split(":");
infMap.put("prt", hd2.substring(46));// 电报优先级 infMap.put("fmttype", args[0]);
} infMap.put("fmtstd", args[1]);
} String strarry[] = hd3.split("\\}");
} for (String substr : strarry) {
} substr = substr.substring(1);
} String sp[] = substr.split(":");
if (hd1 != null) // 拆解1文首 if (sp.length == 2) {
{ infMap.put(sp[0], sp[1]);
if (hd1.length() >= 15) } else {
{ infMap.put(sp[0], null);
String bnk1 = hd1.substring(3, 15); }
if ("O".equals(direct)) }
{ }
infMap.put("rcvbic", bnk1); // else if(hd3.contains("{119:STP}"))
} // msgTyp = msgTyp + "+";
else if ("I".equals(direct)) Matcher m = Pattern.compile("\\{108:\\w+\\}").matcher(hd3);
{ if (m.find()) {
infMap.put("sndbic", bnk1); String gp = m.group();
} int idx = gp.indexOf(":");
if (hd2 != null && hd2.length() >= 14) infMap.put("sndnum", gp.substring(idx + 1, gp.length() - 1)); /* 取发报流水号 */
{ }
infMap.put("mor", hd2.substring(8, 14) + " " + hd1.substring(3));// 获取MOR }
} infMap.put("std", "MT");
} if (!isNACK)
} infMap.put("mty", msgTyp);// 报文类型已经添加,存入Map中
if (hd3 != null) else
{ infMap.put("emty", msgTyp);// 获取附带的报文类型
if (hd3.contains("{119:COV}")) if (hd4 != null) // 处理4域,即正文
{ {
msgTyp = msgTyp + "COV"; List<String[]> kv = msgTxtAnly(hd4);
} for (String[] strArr : kv) {
if (hd3.contains("{FMT:")) if (strArr[0].endsWith("20"))// 业务编号
{ {
String fmt = hd3.substring(1, hd3.length() - 1); if (!infMap.containsKey("ref")) // 如果没有填入20栏,则将20栏填入,已填入则不进行覆盖。为nXX系列报文附带原报的情况
String args[] = fmt.split(":"); {
infMap.put("fmttype", args[0]); if (strArr[1].length() > 16)
infMap.put("fmtstd", args[1]); infMap.put("ref", strArr[1].substring(0, 16).trim());
String strarry[] = hd3.split("\\}"); else
for (String substr : strarry) infMap.put("ref", strArr[1].trim());
{ }
substr = substr.substring(1); }
String sp[] = substr.split(":"); if (strArr[0].endsWith("21"))// 相关编号
if (sp.length == 2) {
{ if (!infMap.containsKey("tscref")) // 如果没有填入21栏,则将21栏填入,已填入则不进行覆盖。为nXX系列报文附带原报的情况
infMap.put(sp[0], sp[1]); {
} if (strArr[1].length() > 16)
else infMap.put("tscref", strArr[1].substring(0, 16));
{ else
infMap.put(sp[0], null); infMap.put("tscref", strArr[1]);
} }
} }
} if (strArr[0].endsWith("22C"))// 300报文的COMMON REFFERENCE
// else if(hd3.contains("{119:STP}")) {
// msgTyp = msgTyp + "+";
Matcher m = Pattern.compile("\\{108:\\w+\\}").matcher(hd3); }
if (m.find()) if (strArr[0].endsWith("32A"))// 金额币种起息日
{ {
String gp = m.group(); if (strArr[1].matches("\\d{6}[A-Z]{3}\\d{1,15},\\d*")) {
int idx = gp.indexOf(":"); String valDat = strArr[1].substring(0, 6);
infMap.put("sndnum", gp.substring(idx + 1, gp.length() - 1)); /* 取发报流水号 */ String cur = strArr[1].substring(6, 9);
} String amt = strArr[1].substring(9);
} infMap.put("vludat", valDat);
infMap.put("std", "MT"); infMap.put("amt", amt.replace(",", "."));
if (!isNACK) infMap.put("cur", cur);
infMap.put("mty", msgTyp);// 报文类型已经添加,存入Map中 }
else }
infMap.put("emty", msgTyp);// 获取附带的报文类型
if (hd4 != null) // 处理4域,即正文 if (strArr[0].matches("62[FM]")) {
{ // 950/940对账单的币种金额起息日
List<String[]> kv = msgTxtAnly(hd4); if (strArr[1] != null && strArr[1].matches("[DC]\\d{6}[A-Z]{3}\\d{1,15},\\d*")) {
for (String[] strArr : kv) String valDat = strArr[1].substring(1, 7);
{ String cur = strArr[1].substring(7, 10);
if (strArr[0].endsWith("20"))// 业务编号 String amt = strArr[1].substring(10).replace(",", ".");
{ infMap.put("vludat", valDat);
if (!infMap.containsKey("ref")) // 如果没有填入20栏,则将20栏填入,已填入则不进行覆盖。为nXX系列报文附带原报的情况 infMap.put("amt", amt.replace(",", "."));
{ infMap.put("cur", cur);
if (strArr[1].length() > 16) } else
infMap.put("ref", strArr[1].substring(0, 16).trim()); return infMap;
else }
infMap.put("ref", strArr[1].trim()); if (strArr[0].matches("25")) // 获取940/950里面的账号
} {
} String act = strArr[1];
if (strArr[0].endsWith("21"))// 相关编号 infMap.put("act", act);
{ }
if (!infMap.containsKey("tscref")) // 如果没有填入21栏,则将21栏填入,已填入则不进行覆盖。为nXX系列报文附带原报的情况 if ("O".equals(infMap.get("direct")) && strArr[0].matches("54A") && strArr[1] != null) {
{ String actbic = strArr[1];
if (strArr[1].length() > 16) int secondLine = getLinePos(actbic);
infMap.put("tscref", strArr[1].substring(0, 16)); if (secondLine > -1) {
else actbic = actbic.substring(secondLine);
infMap.put("tscref", strArr[1]); actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n
} }
} infMap.put("actbic", actbic);
if (strArr[0].endsWith("22C"))// 300报文的COMMON REFFERENCE }
{ if ("O".equals(infMap.get("direct")) && strArr[0].matches("53A") && strArr[1] != null) {
String actbic = strArr[1];
} int secondLine = getLinePos(actbic);
if (strArr[0].endsWith("32A"))// 金额币种起息日 if (secondLine > -1) {
{ actbic = actbic.substring(secondLine);
if (strArr[1].matches("\\d{6}[A-Z]{3}\\d{1,15},\\d*")) actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n
{ }
String valDat = strArr[1].substring(0, 6); infMap.put("t53bic", actbic);
String cur = strArr[1].substring(6, 9); }
String amt = strArr[1].substring(9); if ("I".equals(direct) && strArr[0].matches("53A") && strArr[1] != null) {
infMap.put("vludat", valDat); String actbic = strArr[1];
infMap.put("amt", amt.replace(",", ".")); int secondLine = getLinePos(actbic);
infMap.put("cur", cur); if (secondLine > -1) {
} actbic = actbic.substring(secondLine);
} actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n
}
if (strArr[0].matches("62[FM]")) infMap.put("actbic", actbic);
{ }
// 950/940对账单的币种金额起息日 if (strArr[0].matches("50[AK]") && strArr[1] != null) {
if (strArr[1] != null && strArr[1].matches("[DC]\\d{6}[A-Z]{3}\\d{1,15},\\d*")) int index = getLinePos(strArr[1]);
{ if (index > -1 && strArr[1].startsWith("/"))
String valDat = strArr[1].substring(1, 7); infMap.put("act", strArr[1].substring(1, index));
String cur = strArr[1].substring(7, 10); if (strArr[0].endsWith("K")) {
String amt = strArr[1].substring(10).replace(",", "."); if (index > -1) {
infMap.put("vludat", valDat); String nam = strArr[1].substring(index).replaceAll("^[\\r\\n]{1,2}", "");
infMap.put("amt", amt.replace(",", ".")); infMap.put("ordnamadr", nam);
infMap.put("cur", cur); } else {
} infMap.put("ordnamadr", strArr[1]);
else }
return infMap; }
} }
if (strArr[0].matches("25")) // 获取940/950里面的账号 if (strArr[0].matches("59") && strArr[1] != null) {
{ int index = getLinePos(strArr[1]);
String act = strArr[1]; String nam = strArr[1];
infMap.put("act", act); if (index > -1 && strArr[1].startsWith("/")) {
} String act = strArr[1].substring(1, index);// 取出前面的账号
if ("O".equals(infMap.get("direct")) && strArr[0].matches("54A") && strArr[1] != null) infMap.put("act", act);// 填入59域的账号,收益人账号
{ infMap.put("benact", act);// 查询查复使用,需区分50域的账号
String actbic = strArr[1]; nam = strArr[1].substring(index).replaceAll("^[\\r\\n]{1,2}", "");
int secondLine = getLinePos(actbic); }
if (secondLine > -1) infMap.put("bennamadr", nam);
{ }
actbic = actbic.substring(secondLine); // 下面主要对MT300起作用
actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n if (strArr[0].endsWith("22C")) {
} if (!infMap.containsKey("comref")) // 如果没有填入22C栏
infMap.put("actbic", actbic); {
} if (strArr[1].length() > 16)
if ("O".equals(infMap.get("direct")) && strArr[0].matches("53A") && strArr[1] != null) infMap.put("comref", strArr[1].substring(0, 16));
{ else
String actbic = strArr[1]; infMap.put("comref", strArr[1]);
int secondLine = getLinePos(actbic); }
if (secondLine > -1) }
{ if (strArr[0].endsWith("33B")) {
actbic = actbic.substring(secondLine); String cur = strArr[1].substring(0, 3);
actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n String amt = strArr[1].substring(3);
} infMap.put("sellamt", amt.replace(",", "."));
infMap.put("t53bic", actbic); infMap.put("sellcur", cur);
}
if ("I".equals(direct) && strArr[0].matches("53A") && strArr[1] != null) }
{
String actbic = strArr[1]; // 这里主要是对MT320起作用
int secondLine = getLinePos(actbic); if (strArr[0].endsWith("17R")) {
if (secondLine > -1) if (!infMap.containsKey("BorL"))
{ infMap.put("BorL", strArr[1]);
actbic = actbic.substring(secondLine); }
actbic = actbic.replaceAll("\\r|\\n", "");// 去除遗留的\r\n if (strArr[0].endsWith("34E")) {
} String tagN = strArr[1].substring(0, 1);
infMap.put("actbic", actbic); String interest = "";
} if ("N".equals(tagN))
if (strArr[0].matches("50[AK]") && strArr[1] != null) interest = strArr[1].substring(4);
{ else
int index = getLinePos(strArr[1]); interest = strArr[1].substring(3);
if (index > -1 && strArr[1].startsWith("/")) infMap.put("interest", interest.replace(",", "."));
infMap.put("act", strArr[1].substring(1, index)); }
if (strArr[0].endsWith("K")) // 公共区域
{ if (strArr[0].endsWith("30V")) {
if (index > -1) if (!infMap.containsKey("m3xValDate"))
{ infMap.put("m3xValDate", strArr[1]);
String nam = strArr[1].substring(index).replaceAll("^[\\r\\n]{1,2}", ""); }
infMap.put("ordnamadr", nam);
} if (strArr[0].endsWith("32B")) {
else String cur = strArr[1].substring(0, 3);
{ String amt = strArr[1].substring(3);
infMap.put("ordnamadr", strArr[1]); infMap.put("buyamt", amt.replace(",", "."));
} infMap.put("buycur", cur);
}
} }
if (strArr[0].matches("59") && strArr[1] != null) }
{ }
int index = getLinePos(strArr[1]); return infMap;
String nam = strArr[1]; }
if (index > -1 && strArr[1].startsWith("/"))
{ /*
String act = strArr[1].substring(1, index);// 取出前面的账号 * @param msg:报文字符串
infMap.put("act", act);// 填入59域的账号,收益人账号 * 对报文信息的基本获取,如果是NCK/ACK报文则mty为NCK/ACK,如有附带报文,则附带的报文类型由emty记录
infMap.put("benact", act);// 查询查复使用,需区分50域的账号 */
nam = strArr[1].substring(index).replaceAll("^[\\r\\n]{1,2}", ""); public static Map<String, String> getSwfMsgInfoViaMsg(String msg) {
}
infMap.put("bennamadr", nam);
}
// 下面主要对MT300起作用
if (strArr[0].endsWith("22C"))
{
if (!infMap.containsKey("comref")) // 如果没有填入22C栏
{
if (strArr[1].length() > 16)
infMap.put("comref", strArr[1].substring(0, 16));
else
infMap.put("comref", strArr[1]);
}
}
if (strArr[0].endsWith("33B"))
{
String cur = strArr[1].substring(0, 3);
String amt = strArr[1].substring(3);
infMap.put("sellamt", amt.replace(",", "."));
infMap.put("sellcur", cur);
}
// 这里主要是对MT320起作用
if (strArr[0].endsWith("17R"))
{
if (!infMap.containsKey("BorL"))
infMap.put("BorL", strArr[1]);
}
if (strArr[0].endsWith("34E"))
{
String tagN = strArr[1].substring(0, 1);
String interest = "";
if ("N".equals(tagN))
interest = strArr[1].substring(4);
else
interest = strArr[1].substring(3);
infMap.put("interest", interest.replace(",", "."));
}
// 公共区域
if (strArr[0].endsWith("30V"))
{
if (!infMap.containsKey("m3xValDate"))
infMap.put("m3xValDate", strArr[1]);
}
if (strArr[0].endsWith("32B"))
{
String cur = strArr[1].substring(0, 3);
String amt = strArr[1].substring(3);
infMap.put("buyamt", amt.replace(",", "."));
infMap.put("buycur", cur);
}
}
}
return infMap;
}
/*
* @param msg:报文字符串 对报文信息的基本获取,如果是NCK/ACK报文则mty为NCK/ACK,如有附带报文,则附带的报文类型由emty记录
*/
public static Map<String, String> getSwfMsgInfoViaMsg(String msg)
{
if (msg == null || msg.trim().length() == 0) if (msg == null || msg.trim().length() == 0)
return new HashMap<String,String>(); return new HashMap<String, String>();
Map<Integer,String> headers = anlyMsgHead(msg); Map<Integer, String> headers = anlyMsgHead(msg);
return getSwfMsgInfoViaMsg(headers); return getSwfMsgInfoViaMsg(headers);
} }
/***
* 解析TD的格式报文 /***
* @param msg * 解析TD的格式报文
* @return *
*/ * @param msg
public static Map<String,String> getSwfMsgInfoViaTDMsg(String msg) * @return
{ */
Map<String,String> bscInfo = new HashMap<String,String>(); public static Map<String, String> getSwfMsgInfoViaTDMsg(String msg) {
String reg = ":MT:(\\d{3})[\\r\\n]{1,2}:IO:(\\w{2,11})[\\r\\n]{1,2}:II:(\\w{2,11})[\\r\\n]{1,2}:MP:(\\w)"; Map<String, String> bscInfo = new HashMap<String, String>();
Matcher m = Pattern.compile(reg).matcher(msg); String reg = ":MT:(\\d{3})[\\r\\n]{1,2}:IO:(\\w{2,11})[\\r\\n]{1,2}:II:(\\w{2,11})[\\r\\n]{1,2}:MP:(\\w)";
if(!m.find()) Matcher m = Pattern.compile(reg).matcher(msg);
return bscInfo ;// 错误的格式 if (!m.find())
//bscInfo.put("mty", m.group(1)); return bscInfo;// 错误的格式
bscInfo.put("sndbic", m.group(3)); // bscInfo.put("mty", m.group(1));
bscInfo.put("rcvbic", m.group(2)); bscInfo.put("sndbic", m.group(3));
bscInfo.put("prt", m.group(4)); bscInfo.put("rcvbic", m.group(2));
int idx = msg.indexOf(":EOH:", m.end()); bscInfo.put("prt", m.group(4));
String tdmsgHead= msg.substring(0,idx); int idx = msg.indexOf(":EOH:", m.end());
bscInfo.put("tdmsgHead", tdmsgHead);//存头,方便前端组报 String tdmsgHead = msg.substring(0, idx);
if(tdmsgHead.indexOf(":119:COV")> -1) bscInfo.put("tdmsgHead", tdmsgHead);// 存头,方便前端组报
{ if (tdmsgHead.indexOf(":119:COV") > -1) {
bscInfo.put("mty", m.group(1)+"COV"); bscInfo.put("mty", m.group(1) + "COV");
} } else
else bscInfo.put("mty", m.group(1));
bscInfo.put("mty", m.group(1));
msg = msg.substring(idx + ":EOH:".length());
if (msg.endsWith("-"))
msg = msg.substring(idx+":EOH:".length()); msg = msg.substring(0, msg.length() - 1);
if(msg.endsWith("-")) Map<Integer, String> headers = new HashMap<Integer, String>();
msg = msg.substring(0, msg.length()-1); headers.put(4, msg);
Map<Integer,String> headers = new HashMap<Integer,String>(); Map<String, String> infoMap = getSwfMsgInfoViaMsg(headers);
headers.put(4, msg); infoMap.put("mty", bscInfo.get("mty"));
Map<String,String> infoMap = getSwfMsgInfoViaMsg(headers); bscInfo.putAll(infoMap);
infoMap.put("mty", bscInfo.get("mty")); return bscInfo;
bscInfo.putAll(infoMap); }
return bscInfo;
} public static SWFMessage loadSwiftFile(String path) {
public static SWFMessage loadSwiftFile(String path) return loadSwiftMessage(readFull(path));
{ }
return loadSwiftMessage(readFull(path));
} public static SWFMessage loadSwiftMessage(String message) {
Map<Integer, String> headers = null;
public static SWFMessage loadSwiftMessage(String message)
{ Map<String, String> bscInfo = null;
Map<Integer,String> headers = null; if (message.startsWith(":MT:")) // TD内部报文
{
Map<String,String> bscInfo = null; bscInfo = getSwfMsgInfoViaTDMsg(message);
if(message.startsWith(":MT:")) // TD内部报文 int index = message.indexOf(":EOH:") + ":EOH:".length();
{ int lastIndex = message.lastIndexOf("-");
bscInfo = getSwfMsgInfoViaTDMsg(message); if (lastIndex > 0)
int index = message.indexOf(":EOH:")+":EOH:".length(); message = message.substring(index, lastIndex).trim();
int lastIndex = message.lastIndexOf("-"); else
if(lastIndex > 0) message = message.substring(index);
message = message.substring(index, lastIndex).trim(); headers = new HashMap<Integer, String>();
else headers.put(4, message);
message = message.substring(index); } else {
headers = new HashMap<Integer,String>(); headers = anlyMsgHead(message);
headers.put(4, message); bscInfo = getSwfMsgInfoViaMsg(headers);
} }
else // 取出报文类型
{ String mty = bscInfo.get("mty");
headers = anlyMsgHead(message); System.out.print("---------" + mty);
bscInfo = getSwfMsgInfoViaMsg(headers); SWFMessage swf = MessageFormat.getSWFMessage(mty);
} swf.setHeaders(headers);
//取出报文类型 swf.setBscInfo(bscInfo);
String mty = bscInfo.get("mty"); List<String[]> tags = msgTxtAnly(headers.get(4));
System.out.print("---------"+mty); String tagsCombo = getTagsStr(tags);
SWFMessage swf = MessageFormat.getSWFMessage(mty); loadSwiftMessage(swf, tagsCombo, tags);
swf.setHeaders(headers); return swf;
swf.setBscInfo(bscInfo); }
List<String[]> tags = msgTxtAnly(headers.get(4));
String tagsCombo = getTagsStr(tags); private static int loadSwiftMessage(MessageArea area, String tagsCombo, List<String[]> tags) {
loadSwiftMessage(swf,tagsCombo,tags); StringBuilder buf = new StringBuilder();
return swf; generReg(area, buf);
} String reg = buf.toString();
Matcher m = Pattern.compile(reg).matcher(tagsCombo);
private static int loadSwiftMessage(MessageArea area,String tagsCombo,List<String[]> tags) if (!m.find() || m.start() == m.end())
{ return -1; // 栏位格式不符
StringBuilder buf = new StringBuilder(); List<MessageArea> fieldList = ((AbstractMessageArea) area).getFields();
generReg(area,buf); for (int i = 0; i < fieldList.size(); i++) {
String reg = buf.toString(); MessageArea item = fieldList.get(i);
Matcher m = Pattern.compile(reg).matcher(tagsCombo); if (item.getType() == MessageArea.TAG) {
if(!m.find() || m.start() == m.end()) // 直接捕获对应分组
return -1; //栏位格式不符 TagLine tag = (TagLine) item;
List<MessageArea> fieldList = ((AbstractMessageArea) area).getFields(); String grpName = "T" + String.valueOf(tag.getTno());
for(int i=0; i< fieldList.size();i++) String value = m.group(grpName);
{ if (value == null)
MessageArea item = fieldList.get(i); continue;
if(item.getType() == MessageArea.TAG) String[] valArr = value.split(",");
{ // tag.setName(valArr[0]);
//直接捕获对应分组 if (tag.getName().endsWith("a")) {
TagLine tag = (TagLine)item; TagLine tag2 = TagFormat.getTagLine(valArr[0]);
String grpName = "T"+String.valueOf(tag.getTno()); tag2.setDesp(tag.getDesp());
String value = m.group(grpName); tag2.setTno(tag.getTno());
if(value == null) tag2.setName(valArr[0]);
continue; tag2.setStatus(tag.getStatus());
String[] valArr = value.split(","); tag2.getSuffix().addAll(tag.getSuffix());
//tag.setName(valArr[0]); tag = tag2;
if(tag.getName().endsWith("a")) fieldList.set(i, tag); // 置换新的栏位
{ }
TagLine tag2 = TagFormat.getTagLine(valArr[0]); int idx = Integer.parseInt(valArr[1].substring(0, valArr[1].length() - 1));
tag2.setDesp(tag.getDesp()); tag.setValue(tags.get(idx)[1]);// 还要考虑值分解
tag2.setTno(tag.getTno()); } else if (item.getType() == MessageArea.CYCLIST) {
tag2.setName(valArr[0]); String grpName = String.valueOf("C" + item.getName());
tag2.setStatus(tag.getStatus()); String value = m.group(grpName); // 新的块级
tag2.getSuffix().addAll(tag.getSuffix()); if (value == null || value.length() == 0)
tag = tag2; continue;
fieldList.set(i, tag); //置换新的栏位
} MessageArea cp = ((AbstractMessageArea) item).getFields().get(0);// 默认有一个组项
int idx = Integer.parseInt(valArr[1].substring(0, valArr[1].length()-1)); int offset = 0;
tag.setValue(tags.get(idx)[1]);//还要考虑值分解 do {
}else if(item.getType() == MessageArea.CYCLIST ) offset = loadSwiftMessage(cp, value, tags);
{ if (offset <= 0)
String grpName = String.valueOf("C"+item.getName()); break;
String value = m.group(grpName); //新的块级
if(value == null || value.length() == 0) if (offset >= value.length())
continue; break; // 提前终止,避免不必要的空循环
cp = ((AbstractMessageArea) item).getPattern().clone();
MessageArea cp = ((AbstractMessageArea) item).getFields().get(0);//默认有一个组项 item.addSubArea(cp);
int offset = 0; value = value.substring(offset);
do{ } while (true);
offset = loadSwiftMessage(cp,value,tags); } else if (item.getType() == MessageArea.SEQLIST) {
if(offset <= 0) String grpName = String.valueOf("S" + item.getName());
break; String value = m.group(grpName); // 新的块级
if (value == null || value.length() == 0)
if(offset >= value.length()) continue;
break; //提前终止,避免不必要的空循环
cp = ((AbstractMessageArea) item).getPattern().clone(); MessageArea cp = ((AbstractMessageArea) item).getFields().get(0);// 默认有一个组项
item.addSubArea(cp); int offset = 0;
value = value.substring(offset); do {
} offset = loadSwiftMessage(cp, value, tags);
while(true); if (offset <= 0)
}else if(item.getType() == MessageArea.SEQLIST ) break;
{
String grpName = String.valueOf("S"+item.getName()); if (offset >= value.length())
String value = m.group(grpName); //新的块级 break; // 提前终止,避免不必要的空循环
if(value == null || value.length() == 0) cp = ((AbstractMessageArea) item).getPattern().clone();
continue; item.addSubArea(cp);
value = value.substring(offset);
MessageArea cp = ((AbstractMessageArea) item).getFields().get(0);//默认有一个组项 } while (true);
int offset = 0; }
do{ }
offset = loadSwiftMessage(cp,value,tags); return m.end();
if(offset <= 0) }
break;
private static String getTagsStr(List<String[]> tags) {
if(offset >= value.length()) StringBuilder buf = new StringBuilder();
break; //提前终止,避免不必要的空循环 int cnt = 0;
cp = ((AbstractMessageArea) item).getPattern().clone(); for (String[] item : tags) {
item.addSubArea(cp); // System.out.println(item[0]+"-----"+item[1]);
value = value.substring(offset); buf.append(item[0] + "," + cnt);
} cnt++;
while(true); buf.append(";");
} }
} return buf.toString();
return m.end(); }
}
public static void generReg(MessageArea area, StringBuilder sb) {
private static String getTagsStr(List<String[]> tags)
{ if (area.getType() == MessageArea.TAG) {
StringBuilder buf = new StringBuilder(); TagLine tag = (TagLine) area;
int cnt = 0; sb.append("(?<T" + tag.getTno() + ">");
for(String[] item:tags) if (tag.getSuffix().size() != 0) {
{ sb.append(tag.getName().substring(0, 2));
//System.out.println(item[0]+"-----"+item[1]); sb.append('[');
buf.append(item[0]+","+cnt); boolean hasOpt = false;
cnt++; for (String item : tag.getSuffix()) {
buf.append(";"); if (item.length() == 2)
} hasOpt = true;
return buf.toString(); else
} sb.append(item.charAt(2));
}
public static void generReg(MessageArea area,StringBuilder sb) sb.append(']');
{ if (hasOpt)
sb.append('?');
if(area.getType() == MessageArea.TAG)
{ } else
TagLine tag = (TagLine)area; sb.append(tag.getName());
sb.append("(?<T"+tag.getTno()+">"); sb.append(",\\d{1,3};)");
if(tag.getSuffix().size() != 0 ) if ("O".equals(tag.getStatus()))
{ sb.append('?');
sb.append(tag.getName().substring(0, 2)); return;
sb.append('['); }
boolean hasOpt = false; String defaultReg = ((AbstractMessageArea) area).getAnlyReg();
for(String item : tag.getSuffix()) if (defaultReg != null) {
{ sb.append(defaultReg);
if(item.length()==2) return;
hasOpt = true; }
else
sb.append(item.charAt(2)); if (area instanceof SWFMessage) {
} for (MessageArea item : ((AbstractMessageArea) area).getFields()) {
sb.append(']'); generReg(item, sb);
if(hasOpt) }
sb.append('?'); } else if (area.getType() == MessageArea.CYCLIST) {
StringBuilder buf = new StringBuilder();
} buf.append('(');
else buf.append("?<C" + area.getName() + ">");
sb.append(tag.getName()); buf.append('(');
sb.append(",\\d{1,3};)"); for (MessageArea item : ((AbstractMessageArea) area).getFields()) {
if("O".equals(tag.getStatus())) generReg(item, buf);
sb.append('?'); }
return ; buf.append(")*"); // 块级区域的可选
} buf.append(')');
String defaultReg = ((AbstractMessageArea) area).getAnlyReg(); ((AbstractMessageArea) area).setAnlyReg(buf.toString());
if(defaultReg!=null) sb.append(buf);
{ } else if (area.getType() == MessageArea.SEQLIST) {
sb.append(defaultReg); StringBuilder buf = new StringBuilder();
return; buf.append('(');
} buf.append("?<S" + area.getName() + ">");
buf.append('(');
if(area instanceof SWFMessage) for (MessageArea item : ((AbstractMessageArea) area).getFields()) {
{ generReg(item, buf);
for(MessageArea item : ((AbstractMessageArea) area).getFields()) }
{ SEQList seqlst = (SEQList) area;
generReg(item,sb); buf.append(')');
} if (seqlst.getCyc() > 0)
} buf.append(")+"); // 块级区域的可选
else if(area.getType() == MessageArea.CYCLIST ) buf.append(')');
{ if ("O".equals(seqlst.getOm()))
StringBuilder buf = new StringBuilder(); buf.append('?');
buf.append('('); ((AbstractMessageArea) area).setAnlyReg(buf.toString());
buf.append("?<C"+area.getName()+">"); sb.append(buf);
buf.append('('); } else if (area.getType() == MessageArea.CYC || area.getType() == MessageArea.SEQ) {
for(MessageArea item : ((AbstractMessageArea) area).getFields()) StringBuilder buf = new StringBuilder();
{ for (MessageArea item : ((AbstractMessageArea) area).getFields()) {
generReg(item,buf); generReg(item, buf);
} }
buf.append(")*"); //块级区域的可选 ((AbstractMessageArea) area).setAnlyReg(buf.toString());
buf.append(')'); sb.append(buf);
((AbstractMessageArea) area).setAnlyReg(buf.toString()); }
sb.append(buf); }
}
else if(area.getType() == MessageArea.SEQLIST) public static String generReg(SWFMessage swf) {
{ StringBuilder sb = new StringBuilder();
StringBuilder buf = new StringBuilder(); generReg(swf, sb);
buf.append('('); return sb.toString();
buf.append("?<S"+area.getName()+">"); }
buf.append('(');
for(MessageArea item : ((AbstractMessageArea) area).getFields()) public static String readFull(String path) {
{ try {
generReg(item,buf);
}
SEQList seqlst = (SEQList)area;
buf.append(')');
if(seqlst.getCyc()>0)
buf.append(")+"); //块级区域的可选
buf.append(')');
if("O".equals(seqlst.getOm()))
buf.append('?');
((AbstractMessageArea) area).setAnlyReg(buf.toString());
sb.append(buf);
}
else if(area.getType() == MessageArea.CYC || area.getType() == MessageArea.SEQ)
{
StringBuilder buf = new StringBuilder();
for(MessageArea item : ((AbstractMessageArea) area).getFields())
{
generReg(item,buf);
}
((AbstractMessageArea) area).setAnlyReg(buf.toString());
sb.append(buf);
}
}
public static String generReg(SWFMessage swf)
{
StringBuilder sb = new StringBuilder();
generReg(swf,sb);
return sb.toString();
}
public static String readFull(String path)
{
try {
FileReader reader = new FileReader(path); FileReader reader = new FileReader(path);
char[] buf = new char[1024]; char[] buf = new char[1024];
try { try {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int len = -1; int len = -1;
while((len = reader.read(buf))!=-1) while ((len = reader.read(buf)) != -1) {
{ sb.append(buf, 0, len);
sb.append(buf,0,len);
} }
reader.close(); reader.close();
return sb.toString(); return sb.toString();
...@@ -747,17 +648,22 @@ public class MessageAnalyzer { ...@@ -747,17 +648,22 @@ public class MessageAnalyzer {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
public static void main(String[] args)
{ public static void main(String[] args) {
// SWFMessage swf = MessageFormat.getSWFMessage("202COV"); // SWFMessage swf = MessageFormat.getSWFMessage("202COV");
// System.out.println(swf.toFormatJSON()); // System.out.println(swf.toFormatJSON());
// MessageFormat.loadSWFMessage(); // MessageFormat.loadSWFMessage();
String path = "/Volumes/FUKAI/00026202.TXT"; String path = "d:/black/103.sf2";
String msg = readFull(path); String msg = readFull(path);
SWFMessage swf =loadSwiftMessage(msg); SWFMessage swf = loadSwiftMessage(msg);
System.out.print(swf.toJSON()); System.out.println("swiftType=" + swf.getMtType());
} List<LinkedTreeMap> list = new Gson().fromJson(swf.toFormatJSON(), List.class);
// System.out.println(list);
// System.out.print(swf.toJSON());
for (LinkedTreeMap map : list) {
System.out.println(map.get("tag") + "...." + map.get("tagValue"));
}
}
} }
package com.brilliance.black.util;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import com.brilliace.swifteditor.tag.message.MessageAnalyzer;
import com.brilliace.swifteditor.tag.message.SWFMessage;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
public class BlackListUtil {
private static List<SwiftTagInfo> swiftTagBlacks = new ArrayList<SwiftTagInfo>();
private static List<SwiftTagInfo> getSwiftTagBlacks(String blackTagPath) {
try {
if (swiftTagBlacks.size() == 0) {
List<String> fileList = IOUtils.readLines(new FileInputStream(new File(blackTagPath)), "utf-8");
for (String str : fileList) {
if (str == null || str.trim().equals(""))
continue;
String arr[] = str.split("\t");
SwiftTagInfo swiftTagBlack = new SwiftTagInfo();
swiftTagBlack.setMty(arr[0]);
swiftTagBlack.setTag(arr[1]);
swiftTagBlack.setDataPosition(arr[2]);
swiftTagBlack.setShootType(arr[3]);
swiftTagBlacks.add(swiftTagBlack);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return swiftTagBlacks;
}
private static List<SwiftTagInfo> getSwiftTagBlacksByMty(String blackTagPath, String mty) {
getSwiftTagBlacks(blackTagPath);
List<SwiftTagInfo> lswiftTagBlacks = new ArrayList<SwiftTagInfo>();
for (SwiftTagInfo swiftTagBlack : swiftTagBlacks) {
if (swiftTagBlack.getMty().equals(mty)) {
lswiftTagBlacks.add(swiftTagBlack);
}
}
return lswiftTagBlacks;
}
@SuppressWarnings("rawtypes")
public static List<Map<String, Object>> detailsOfTags(String msg, String blackTagPath) {
List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>();
SWFMessage swf = MessageAnalyzer.loadSwiftMessage(msg);
System.out.println("swiftType=" + swf.getMtType());
List<SwiftTagInfo> swiftTagBlacks = getSwiftTagBlacksByMty(blackTagPath, swf.getMtType());
@SuppressWarnings("rawtypes")
List<LinkedTreeMap> list = new Gson().fromJson(swf.toFormatJSON(), List.class);
System.out.println(swf.toJSON());
for (SwiftTagInfo swiftTagBlack : swiftTagBlacks) {
String tag = swiftTagBlack.getTag();
for (LinkedTreeMap map : list) {
if (map.get("tag") != null && map.get("tag").equals(tag)) {
Map<String, Object> retMap = new HashMap<String, Object>();
retMap.put("tag", tag);
retMap.put("label", map.get("label"));
if (map.get("tagValue") != null) {
List tagValueList = (List) map.get("tagValue");
for (Object obj : tagValueList) {
if (obj instanceof Map) {
retMap.put("tagValue", ((Map) obj).get(swiftTagBlack.getDataPosition()));
retMap.put("shootType", swiftTagBlack.getShootType());
}
}
}
ret.add(retMap);
}
}
}
return ret;
}
public static void main(String[] args) throws Exception {
String swiftMsg = IOUtils.toString(new FileInputStream(new File("d:/black/103.sf2")), "utf-8");
List<Map<String, Object>> list = detailsOfTags(swiftMsg, "C:/Users/ge/Desktop/blackList.txt");
System.out.println("list=" + list);
}
}
package com.brilliance.black.util;
public class SwiftTagInfo {
private String mty;// 报文类型
private String tag;
private String dataPosition;// 数据域位置 S1 S2 S3 S4 ...
private String shootType;// 1:BIC检查 2:名称地址检查
public String getMty() {
return mty;
}
public String getTag() {
return tag;
}
public String getShootType() {
return shootType;
}
public void setMty(String mty) {
this.mty = mty;
}
public void setTag(String tag) {
this.tag = tag;
}
public void setShootType(String shootType) {
this.shootType = shootType;
}
public String getDataPosition() {
return dataPosition;
}
public void setDataPosition(String dataPosition) {
this.dataPosition = dataPosition;
}
}
Manifest-Version: 1.0
Built-By: fukai
Build-Jdk: 1.8.0_121
Created-By: Maven Integration for Eclipse
#Generated by Maven Integration for Eclipse
#Tue Nov 06 10:48:36 CST 2018
version=0.0.1-SNAPSHOT
groupId=com.brilliace
m2e.projectName=swifteditor
m2e.projectLocation=/Users/fukai/Documents/workspace/swifteditor
artifactId=swifteditor
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.brilliace</groupId>
<artifactId>swifteditor</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>swifteditor</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10.1</version>
</dependency>
<!-- <dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.5</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
<!-- <scope>test</scope> -->
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>swifteditor</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
#Generated by Maven #Generated by Maven
#Tue Nov 06 10:48:50 CST 2018 #Tue Aug 20 11:08:02 CST 2019
version=0.0.1-SNAPSHOT version=0.0.1-SNAPSHOT
groupId=com.brilliace groupId=com.brilliace
artifactId=swifteditor artifactId=swifteditor
com/brilliace/swifteditor/tag/message/CYCList.class com\brilliace\swifteditor\tag\message\CYC.class
com/brilliace/swifteditor/tag/message/CYC.class com\brilliace\swifteditor\tag\TagCell.class
com/brilliace/swifteditor/tag/TagFormat.class com\brilliace\swifteditor\tag\message\SWFMessage.class
com/brilliace/swifteditor/tag/message/MessageArea.class com\brilliace\swifteditor\tag\message\SEQList.class
com/brilliace/swifteditor/tag/message/SWFMessage.class com\brilliace\swifteditor\tag\message\CYCList.class
com/brilliace/swifteditor/tag/message/MessageAnalyzer.class com\brilliace\swifteditor\tag\message\AbstractMessageArea.class
com/brilliace/swifteditor/tag/message/SEQ.class com\brilliace\swifteditor\tag\message\SEQ.class
com/brilliace/swifteditor/tag/message/AbstractMessageArea.class com\brilliace\swifteditor\tag\TagFormat.class
com/brilliace/swifteditor/tag/message/JSOutputTools.class com\brilliace\swifteditor\tag\message\MessageArea.class
com/brilliace/swifteditor/tag/TagLine.class com\brilliace\swifteditor\App.class
com/brilliace/swifteditor/tag/message/MessageFormat.class com\brilliace\swifteditor\tag\message\JSOutputTools.class
com/brilliace/swifteditor/tag/TagAnalyzer.class com\brilliace\swifteditor\tag\TagLine.class
com/brilliace/swifteditor/App.class com\brilliace\swifteditor\tag\message\MessageFormat.class
com/brilliace/swifteditor/tag/TagCell.class com\brilliace\swifteditor\tag\TagAnalyzer.class
com/brilliace/swifteditor/tag/message/SEQList.class com\brilliace\swifteditor\tag\message\MessageAnalyzer.class
com/brilliace/swifteditor/AppTest.class com\brilliace\swifteditor\AppTest.class
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<testsuite tests="1" failures="0" name="com.brilliace.swifteditor.AppTest" time="0.004" errors="0" skipped="0"> <testsuite failures="0" time="0.006" errors="0" skipped="0" tests="1" name="com.brilliace.swifteditor.AppTest">
<properties> <properties>
<property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/> <property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
<property name="sun.boot.library.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib"/> <property name="sun.boot.library.path" value="G:\eclipse64\jdk1.7\jre\bin"/>
<property name="java.vm.version" value="25.121-b13"/> <property name="java.vm.version" value="24.75-b04"/>
<property name="gopherProxySet" value="false"/>
<property name="java.vm.vendor" value="Oracle Corporation"/> <property name="java.vm.vendor" value="Oracle Corporation"/>
<property name="maven.multiModuleProjectDirectory" value="/Users/fukai/Documents/workspace/swifteditor"/>
<property name="java.vendor.url" value="http://java.oracle.com/"/> <property name="java.vendor.url" value="http://java.oracle.com/"/>
<property name="path.separator" value=":"/> <property name="path.separator" value=";"/>
<property name="guice.disable.misplaced.annotation.check" value="true"/> <property name="guice.disable.misplaced.annotation.check" value="true"/>
<property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/> <property name="java.vm.name" value="Java HotSpot(TM) 64-Bit Server VM"/>
<property name="file.encoding.pkg" value="sun.io"/> <property name="file.encoding.pkg" value="sun.io"/>
<property name="user.script" value=""/>
<property name="user.country" value="CN"/> <property name="user.country" value="CN"/>
<property name="sun.java.launcher" value="SUN_STANDARD"/> <property name="sun.java.launcher" value="SUN_STANDARD"/>
<property name="sun.os.patch.level" value="unknown"/> <property name="sun.os.patch.level" value=""/>
<property name="java.vm.specification.name" value="Java Virtual Machine Specification"/> <property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
<property name="user.dir" value="/Users/fukai/Documents/workspace/swifteditor"/> <property name="user.dir" value="G:\work\swifteditor_java"/>
<property name="java.runtime.version" value="1.8.0_121-b13"/> <property name="java.runtime.version" value="1.7.0_75-b13"/>
<property name="java.awt.graphicsenv" value="sun.awt.CGraphicsEnvironment"/> <property name="java.awt.graphicsenv" value="sun.awt.Win32GraphicsEnvironment"/>
<property name="java.endorsed.dirs" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/endorsed"/> <property name="java.endorsed.dirs" value="G:\eclipse64\jdk1.7\jre\lib\endorsed"/>
<property name="os.arch" value="x86_64"/> <property name="os.arch" value="amd64"/>
<property name="java.io.tmpdir" value="/var/folders/pd/hbf3q9xx6fq6p9j1nn7kx0xw0000gn/T/"/> <property name="java.io.tmpdir" value="C:\Users\ge\AppData\Local\Temp\"/>
<property name="line.separator" value=" <property name="line.separator" value="
"/> "/>
<property name="java.vm.specification.vendor" value="Oracle Corporation"/> <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
<property name="os.name" value="Mac OS X"/> <property name="user.variant" value=""/>
<property name="classworlds.conf" value="/Users/fukai/Documents/workspace/.metadata/.plugins/org.eclipse.m2e.launching/launches/m2conf6118131129949174889.tmp"/> <property name="os.name" value="Windows 8.1"/>
<property name="sun.jnu.encoding" value="UTF-8"/> <property name="classworlds.conf" value="G:\work\cbpp\.metadata\.plugins\org.eclipse.m2e.launching\launches\m2conf5593905727808716630.tmp"/>
<property name="java.library.path" value="/Users/fukai/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."/> <property name="sun.jnu.encoding" value="GBK"/>
<property name="java.library.path" value="G:\eclipse64\jdk1.7\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;d:\Program Files\Git\cmd;D:\Program Files\TortoiseSVN\bin;D:\Program Files\nodejs\;d:\Program Files (x86)\Tesseract-OCR;C:\Users\ge\AppData\Local\Microsoft\WindowsApps;G:\eclipse64\jdk1.8\bin;D:\Program\apache-maven-3.2.3\bin;&quot;E:\reactNative\android\sdk\tools;E:\reactNative\android\sdk\platform-tools&quot;;C:\Users\ge\AppData\Roaming\npm;E:\reactNative\android\sdk\platforms;E:\reactNative\android\sdk\platform-tools;E:\SoftWare\mysql-5.6.24-winx64\bin;D:\Program Files\nodejs;;."/>
<property name="java.specification.name" value="Java Platform API Specification"/> <property name="java.specification.name" value="Java Platform API Specification"/>
<property name="java.class.version" value="52.0"/> <property name="java.class.version" value="51.0"/>
<property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/> <property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
<property name="os.version" value="10.14.1"/> <property name="os.version" value="6.3"/>
<property name="user.home" value="/Users/fukai"/> <property name="user.home" value="C:\Users\ge"/>
<property name="user.timezone" value="Asia/Shanghai"/> <property name="user.timezone" value="Asia/Shanghai"/>
<property name="java.awt.printerjob" value="sun.lwawt.macosx.CPrinterJob"/> <property name="java.awt.printerjob" value="sun.awt.windows.WPrinterJob"/>
<property name="java.specification.version" value="1.8"/> <property name="java.specification.version" value="1.7"/>
<property name="file.encoding" value="UTF-8"/> <property name="file.encoding" value="GBK"/>
<property name="user.name" value="fukai"/> <property name="user.name" value="ge"/>
<property name="java.class.path" value="/Users/fukai/eclipse/jee-neon/Eclipse.app/Contents/Eclipse/../../../../../.p2/pool/plugins/org.eclipse.m2e.maven.runtime_1.7.0.20160603-1931/jars/plexus-classworlds-2.5.2.jar"/> <property name="java.class.path" value="/G:/eclipse64/plugins/org.eclipse.m2e.maven.runtime_1.5.0.20140605-2032/jars/plexus-classworlds-2.5.1.jar"/>
<property name="java.vm.specification.version" value="1.8"/> <property name="org.slf4j.simpleLogger.defaultLogLevel" value="info"/>
<property name="java.vm.specification.version" value="1.7"/>
<property name="sun.arch.data.model" value="64"/> <property name="sun.arch.data.model" value="64"/>
<property name="java.home" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre"/> <property name="java.home" value="G:\eclipse64\jdk1.7\jre"/>
<property name="sun.java.command" value="org.codehaus.plexus.classworlds.launcher.Launcher -B -gs /Users/fukai/apache-maven-3.3.9/conf/settings.xml -s /Users/fukai/apache-maven-3.3.9/conf/settings.xml install"/> <property name="sun.java.command" value="org.codehaus.plexus.classworlds.launcher.Launcher -B -s D:\MavenRepository\settings.xml install"/>
<property name="java.specification.vendor" value="Oracle Corporation"/> <property name="java.specification.vendor" value="Oracle Corporation"/>
<property name="user.language" value="zh"/> <property name="user.language" value="zh"/>
<property name="awt.toolkit" value="sun.lwawt.macosx.LWCToolkit"/> <property name="awt.toolkit" value="sun.awt.windows.WToolkit"/>
<property name="java.vm.info" value="mixed mode"/> <property name="java.vm.info" value="mixed mode"/>
<property name="java.version" value="1.8.0_121"/> <property name="java.version" value="1.7.0_75"/>
<property name="java.ext.dirs" value="/Users/fukai/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java"/> <property name="java.ext.dirs" value="G:\eclipse64\jdk1.7\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext"/>
<property name="sun.boot.class.path" value="/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/classes"/> <property name="sun.boot.class.path" value="G:\eclipse64\jdk1.7\jre\lib\resources.jar;G:\eclipse64\jdk1.7\jre\lib\rt.jar;G:\eclipse64\jdk1.7\jre\lib\sunrsasign.jar;G:\eclipse64\jdk1.7\jre\lib\jsse.jar;G:\eclipse64\jdk1.7\jre\lib\jce.jar;G:\eclipse64\jdk1.7\jre\lib\charsets.jar;G:\eclipse64\jdk1.7\jre\lib\jfr.jar;G:\eclipse64\jdk1.7\jre\classes"/>
<property name="java.vendor" value="Oracle Corporation"/> <property name="java.vendor" value="Oracle Corporation"/>
<property name="maven.home" value="/Users/fukai/Documents/workspace/swifteditor/EMBEDDED"/> <property name="maven.home" value="G:\work\swifteditor_java\EMBEDDED"/>
<property name="file.separator" value="/"/> <property name="file.separator" value="\"/>
<property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/> <property name="java.vendor.url.bug" value="http://bugreport.sun.com/bugreport/"/>
<property name="sun.cpu.endian" value="little"/> <property name="sun.cpu.endian" value="little"/>
<property name="sun.io.unicode.encoding" value="UnicodeBig"/> <property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
<property name="sun.cpu.isalist" value=""/> <property name="sun.desktop" value="windows"/>
<property name="sun.cpu.isalist" value="amd64"/>
</properties> </properties>
<testcase classname="com.brilliace.swifteditor.AppTest" name="testApp" time="0.004"/> <testcase time="0.006" classname="com.brilliace.swifteditor.AppTest" name="testApp"/>
</testsuite> </testsuite>
\ No newline at end of file
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Test set: com.brilliace.swifteditor.AppTest Test set: com.brilliace.swifteditor.AppTest
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 sec Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.008 sec
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment