CommonTools (V0.4.0) | 2014-02-12 10:10 |
jautoregexer (V0.3.4.0) | 2014-02-12 09:53 |
Plugins ([Plugin] Memcached-Cache (For 0.3.4.0)) | 2014-02-12 10:11 |
JAutoRegexerの実行エンジンの実態は「org.dyndns.nuda.tools.regex.RegexProcessor」です。
RegexProcessorクラスのprocessメソッドで正規表現の解析を行います。
processメソッドのシグニチャは以下の通りです。
型Tはsource引数に指定された文字列(正規表現で解析を行う文字列)の解析結果が格納されるクラスです。
解析結果は上記シグニチャの通り、型Tのリスト型で帰ります。
JAutoRegexerで正規表現解析結果のマッピングに用いられるJavaBeansは厳密な意味でのJavaBeansではありません。
本来のJavaBeansは...
ですが、JAutoRegexerのそれは...
この一点です。
これを「RegexBean」と呼んでいます。
以下は、RegexBeanのサンプルです。
- package org.dyndns.nuda.tools.regex;
- import org.dyndns.nuda.tools.regex.annotation.Regex;
- import org.dyndns.nuda.tools.regex.annotation.RegexItem;
- @Regex(pattern = "(.+?):(.+?)://(.+?):(.+?)/(.+)")
- public class ConStrRegexBean {
- @RegexItem(groupIndex = 1)
- public String coreName;
- @RegexItem(groupIndex = 2)
- public String subProtocol;
- @RegexItem(groupIndex = 3)
- public String host;
- @RegexItem(groupIndex = 4)
- public String port;
- @RegexItem(groupIndex = 5)
- public String schemeName;
- @Override
- public String toString() {
- return "ConStrRegexBean [coreName=" + this.coreName + ", subProtocol="
- + this.subProtocol + ", host=" + this.host + ", port="
- + this.port + ", schemeName=" + this.schemeName + "]";
- }
- }
上記RegexBeanは
が付加されています。
@RegexアノテーションはJAutoRegexerエンジンに対して「どのようにテキストコンテンツを解析するのか」の指示を出すために用いられます。 通常は「pattern要素」に正規表現文字列を指定して用います。
@RegexItemアノテーションは@Regexアノテーションで指定した正規表現の解析結果をどのように展開(マッピング)するのかを指定します。 「groupIndex要素」がそのまま正規表現グループのインデックスとなります。
例えば、上記RegexBeanを用いて
- /**
- * 再帰的正規表現解析なしの場合に解析が成功することを確認する
- */
- @Test
- public void testProcess() {
- String testSource = "jdbc:mysql://192.168.0.1:3306/testdb";
- RegexProcessor p = new RegexProcessor();
- List<ConStrRegexBean> resultList = p.process(testSource,
- ConStrRegexBean.class);
- if (resultList.size() == 0) {
- Assert.fail();
- }
- ConStrRegexBean bean = resultList.get(0);
- Assert.assertEquals(bean.toString(), "jdbc", bean.coreName);
- Assert.assertEquals(bean.toString(), "mysql", bean.subProtocol);
- Assert.assertEquals(bean.toString(), "192.168.0.1", bean.host);
- Assert.assertEquals(bean.toString(), "3306", bean.port);
- Assert.assertEquals(bean.toString(), "testdb", bean.schemeName);
- }
とすれば、リストの0番目のRegexBean(ConStrRegexBean)に「jdbc:mysql://192.168.0.1:3306/testdb」が分解されて格納されます。
※上のサンプルコードはJAutoRegexerのテストケースから一部を抜き出したものです。
JAutoRegexerの特徴は、RegexBeanのプロパティとしてRegexBeanを指定できる点です。 以下のサンプルコードをご覧ください。
ConStrRegexBean02.java
- package org.dyndns.nuda.tools.regex;
- import java.util.List;
- import org.dyndns.nuda.tools.regex.annotation.Regex;
- import org.dyndns.nuda.tools.regex.annotation.RegexItem;
- @Regex(pattern = "(.+?):(.+?)://(.+?):(.+?)/(.+)")
- public class ConStrRegexBean02 {
- @RegexItem(groupIndex = 1)
- public String coreName;
- @RegexItem(groupIndex = 2)
- public String subProtocol;
- @RegexItem(groupIndex = 3)
- public List<HostRegexBean> host;
- @RegexItem(groupIndex = 4)
- public String port;
- @RegexItem(groupIndex = 5)
- public String schemeName;
- @Override
- public String toString() {
- return "ConStrRegexBean02 [coreName=" + this.coreName
- + ", subProtocol=" + this.subProtocol + ", host=" + this.host
- + ", port=" + this.port + ", schemeName=" + this.schemeName
- + "]";
- }
- }
HostRegexBean.java
- package org.dyndns.nuda.tools.regex;
- import org.dyndns.nuda.tools.regex.annotation.Regex;
- import org.dyndns.nuda.tools.regex.annotation.RegexItem;
- @Regex(pattern = "(.+?)\\.(.+?)\\.(.+?)\\.(.+?)")
- public class HostRegexBean {
- @RegexItem(groupIndex = 1)
- public String segment01;
- @RegexItem(groupIndex = 2)
- public String segment02;
- @RegexItem(groupIndex = 3)
- public String segment03;
- @RegexItem(groupIndex = 4)
- public String segment04;
- @Override
- public String toString() {
- return "HostRegexBean [segment01=" + this.segment01 + ", segment02="
- + this.segment02 + ", segment03=" + this.segment03
- + ", segment04=" + this.segment04 + "]";
- }
- }
ConStrRegexBean02クラスのhostフィールドがHostRegexBean型のリストで指定されています。
このRegexBeanを用いたサンプルコードを以下に示します。
- /**
- * 再帰的正規表現解析ありの場合に解析が成功することを確認する
- */
- @Test
- public void testProcess02() {
- String testSource = "jdbc:mysql://192.168.0.1:3306/testdb";
- RegexProcessor p = new RegexProcessor();
- List<ConStrRegexBean02> resultList = p.process(testSource,
- ConStrRegexBean02.class);
- if (resultList.size() == 0) {
- Assert.fail();
- }
- ConStrRegexBean02 bean = resultList.get(0);
- Assert.assertEquals(bean.toString(), "jdbc", bean.coreName);
- Assert.assertEquals(bean.toString(), "mysql", bean.subProtocol);
- Assert.assertEquals(bean.toString(), "3306", bean.port);
- Assert.assertEquals(bean.toString(), "testdb", bean.schemeName);
- List<HostRegexBean> host = bean.host;
- if (host.size() == 0) {
- Assert.fail();
- }
- HostRegexBean hostRegexBean = host.get(0);
- Assert.assertEquals(host.toString(), "192", hostRegexBean.segment01);
- Assert.assertEquals(host.toString(), "168", hostRegexBean.segment02);
- Assert.assertEquals(host.toString(), "0", hostRegexBean.segment03);
- Assert.assertEquals(host.toString(), "1", hostRegexBean.segment04);
- }
最初のサンプルコード(ConStrRegexBeanを用いたもの)では、単に解析結果をRegexBeanに展開して終わりでしたが、今回のサンプルコードは少々違います。
もうお気づきかと思われますが、RegexBeanのプロパティにRegexBeanのリストが指定された場合は、再帰的に正規表現を解析します。 上記コードの場合はhostフィールドに展開されるはずだった"192.168.0.1"という文字列がHostRegexBeanによって解析され展開されます。
具体的には「192, 168, 0, 1」の文字列が「segment01, segment02, segment03, segment04」にそれぞれ展開されます。
この再帰の回数に制限はありません。 JAutoRegexerは、現在のコンテキストで「解析する必要がある限り」根こそぎRegexBeanへの展開を行います。