001 /* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016 package org.opengion.fukurou.util; 017 018 import java.util.Set; 019 import java.util.TreeSet; 020 import java.util.Iterator; 021 022 /** 023 * ReplaceString.java ã¯ã€è¤?•°ã®æ–?—å?ã‚’ä¸?‹¬ç½®æ›ã™ã‚‹å?åˆã«ä½¿ç”¨ã™ã‚‹ã‚¯ãƒ©ã‚¹ã§ã™ã? 024 * 025 * add メソãƒ?ƒ‰ã§ã€?–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã€çµ‚äº?‚¢ãƒ‰ãƒ¬ã‚¹ã€ç½®æ›æ–‡å—å?を指定ã—ã€? 026 * æœ?¾Œã«ã€replaceAll ã§ã€å¤‰æ›ã‚’行ã„ã¾ã™ã? 027 * 通常ã€ç•°ãªã‚‹æ–‡å—å?ã‚’ä¸?‹¬ã§å¤‰æ›ã™ã‚‹å ´åˆã?é€??ã«å¤‰æ›ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’求ã‚ã¦ã€? 028 * 後ã‚ã‹ã‚‰é ?«ç½®æ›ã—ã¦ã?‹ãªã?¨ã€å‰ã‹ã‚‰å‡¦ç?™ã‚‹ã¨å‡¦ç?”ã¨ã«ã‚¢ãƒ‰ãƒ¬ã‚¹ã? 029 * 変更ã«ãªã‚Šä¸?‹ã‚‰å?計算ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã?ã“れã¯ã€ç™»éŒ²æ™‚ã?ã€ã©ã®ã‚ˆã†ãª 030 * é ?ºã§ã‚‚よãã?replaceAll 時ã«ã€å?部ã«ç™»éŒ²æŒ?®šã‚ã‚‹å¤‰æ›æ–?—å?ã®é–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚ˆã‚Š 031 * 自動的ã«é€??ã§ç½®æ›ã™ã‚‹ãŸã‚ã?è¤?•°ã®ç½®æ›å?æ‰?Œã‚ã£ã¦ã‚‚ã?ã¾ã¨ã‚ã¦å‡¦ç?§ãã¾ã™ã? 032 * ãŸã ã—ã?è¤?•°ã®ç½®æ›å?æ‰?Œã‚ã‚‹å ´åˆã?é‡è¤?¦ç´?Œã‚れã°ã€ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã™ã? 033 * 034 * @version 4.0 035 * @author Kazuhiko Hasegawa 036 * @since JDK5.0, 037 */ 038 public final class ReplaceString { 039 private final Set<ReplaceData> set = new TreeSet<ReplaceData>(); 040 041 /** 042 * 開始アドレスã€çµ‚äº?‚¢ãƒ‰ãƒ¬ã‚¹ã€ç½®æ›æ–‡å—å?を指定ã—ç½®æ›å¯¾è±¡ã‚’追åŠ?—ã¾ã™ã? 043 * é€šå¸¸ã€æ–‡å—å?ã‚’ç½®æ›ã™ã‚‹ã¨ã€å?ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãšã‚Œã‚‹ã?を防ã為ã€? 044 * 後ã‚ã‹ã‚‰ã€ç½®æ›ã‚’行ã„ã¾ã™ã?ä¸?‹¬ç½®æ›ã?ã€è¤?•°ã®æ–?—å?ç½®æ›ã‚’ã€?–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã® 045 * 後ã‚ã‹ã‚‰ã€ç½®æ›ã‚’å§‹ã‚る為ã®ã€å?期データを登録ã—ã¾ã™ã? 046 * 登録é ??ã€ç½®æ›é?ã¨ã¯ç„¡é–¢ä¿‚ã«è¨å®šå¯èƒ½ã§ã™ã? 047 * 048 * @param start ç½®æ›é–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ 049 * @param end ç½®æ›çµ‚äº?‚¢ãƒ‰ãƒ¬ã‚¹ 050 * @param newStr ç½®æ›æ–‡å—å? 051 */ 052 public void add( final int start, final int end, final String newStr ) { 053 set.add( new ReplaceData( start, end, newStr ) ); 054 } 055 056 /** 057 * ç½®æ›å?æ–?—å?を指定ã—ã¦ã€ç½®æ›å?ç?‚’実行ã—ã¾ã™ã? 058 * add メソãƒ?ƒ‰ã§æŒ?®šã—ãŸæ–‡å—å?を実際ã«ç½®æ›å?ç?—ã¾ã™ã? 059 * 060 * @param target ç½®æ›å?æ–?—å? 061 * 062 * @return ç½®æ›å¾Œæ–‡å—å? 063 */ 064 public String replaceAll( final String target ) { 065 Iterator<ReplaceData> ite = set.iterator(); 066 StringBuilder buf = new StringBuilder( target ); 067 while( ite.hasNext() ) { 068 ReplaceData data = ite.next(); 069 buf = data.replace( buf ); 070 } 071 return buf.toString(); 072 } 073 074 /** 075 * ç½®æ›æ–‡å—å?を管ç?™ã‚‹å?部クラス 076 * 077 * @version 4.0 078 * @author Kazuhiko Hasegawa 079 * @since JDK5.0, 080 */ 081 private static class ReplaceData implements Comparable<ReplaceData> { 082 private final int start ; 083 private final int end ; 084 private final String newStr ; 085 private final int hCode ; 086 087 /** 088 * 開始アドレスã€çµ‚äº?‚¢ãƒ‰ãƒ¬ã‚¹ã€ç½®æ›æ–‡å—å?を指定ã—ã¾ã™ã? 089 * é€šå¸¸ã€æ–‡å—å?ã‚’ç½®æ›ã™ã‚‹ã¨ã€å?ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãšã‚Œã‚‹ã?を防ã為ã€? 090 * 後ã‚ã‹ã‚‰ã€ç½®æ›ã‚’行ã„ã¾ã™ã?ä¸?‹¬ç½®æ›ã?ã€è¤?•°ã®æ–?—å?ç½®æ›ã‚’ã€?–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã® 091 * 後ã‚ã‹ã‚‰ã€ç½®æ›ã‚’å§‹ã‚る為ã®ã€å?期データを登録ã—ã¾ã™ã? 092 * 登録é ??ã€ç½®æ›é?ã¨ã¯ç„¡é–¢ä¿‚ã«è¨å®šå¯èƒ½ã§ã™ã? 093 * 094 * @param start ç½®æ›é–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ 095 * @param end ç½®æ›çµ‚äº?‚¢ãƒ‰ãƒ¬ã‚¹ 096 * @param newStr ç½®æ›æ–‡å—å? 097 */ 098 public ReplaceData( final int start, final int end, final String newStr ) { 099 this.start = start; 100 this.end = end; 101 this.newStr = newStr ; 102 hCode = ( newStr + start + "_" + end ).hashCode(); 103 } 104 105 /** 106 * ç½®æ›å?ç?‚’実行ã—ã¾ã™ã? 107 * 108 * @param buf StringBuilder 入力文å—å? 109 * @return 出力文å—å? 110 */ 111 public StringBuilder replace( final StringBuilder buf ) { 112 return buf.replace( start,end,newStr ); 113 } 114 115 /** 116 * æŒ?®šã?ReplaceDataã®é–‹å§?終äº?Œé‡ãªã£ã¦ã?‚‹ã‹ã©ã?‹ã‚’判定ã—ã¾ã™ã? 117 * return 118 * | o.E S | E o.S | 119 * â‘? S----E | ?? | ã€ï¼œã? | false 120 * o.S----o.E | | | 121 * â‘¡ S----E | ?? | ≧ | true 122 * o.S----o.E | | | 123 * â‘¢ S----E | ≧ | ?? | true 124 * o.S----o.E | | | 125 * â‘£ S----E | ã€ï¼œã? | ?? | false 126 * o.S----o.E | | | 127 * 128 * @og.rev 5.7.2.1 (2014/01/17) åˆ¤å®šçµæžœã® true/false ãŒå転ã—ã¦ã?Ÿã®ã§ã€ä¿®æ£ 129 * 130 * @param other ReplaceData 入力文å—å? 131 * @return オーãƒã?ラãƒ??ã—ã¦ã?‚‹ã‹ã©ã?‹(true:䏿£/false:æ£å¸¸) 132 */ 133 public boolean isOverlap( final ReplaceData other ) { 134 // return ! ( ( other == null ) || ( other.end < start ) || ( end < other.start ) ); 135 // return ( ( other == null ) || ( other.end < start ) || ( end < other.start ) ); 136 return ( other == null ) || ! ( ( other.end < start ) || ( end < other.start ) ); 137 } 138 139 /** 140 * 自然比è¼?ƒ¡ã‚½ãƒ?ƒ‰ 141 * インタフェース Comparable 㮠実è£?§ã™ã? 142 * 登録ã•れãŸé–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã®é™é?ã«ãªã‚‹ã‚ˆã?«æ¯”è¼?—ã¾ã™ã? 143 * ãªãŠã?比è¼?¯¾ç…§ã‚ªãƒ–ジェクトã¨ã‚ªãƒ¼ãƒã?ラãƒ??ã—ã¦ã?‚‹å ´åˆã?ã€? 144 * 比è¼?§ããªã?¨ã—ã¦ã€IllegalArgumentException を発行ã—ã¾ã™ã? 145 * 146 * @og.rev 5.7.4.0 (2014/03/07) åŒä¸?‚ªãƒ–ジェクトã?判定を追åŠ? 147 * 148 * @param other 比è¼?¯¾è±¡ã®Object 149 * @return 開始アドレスã®é™é?(自åˆ??アドレスãŒå°ã•ã??åˆã?ã€?¼? 150 * @throws IllegalArgumentException 引数オブジェクトãŒã‚ªãƒ¼ãƒã?ラãƒ??ã—ã¦ã?‚‹å ´å? 151 */ 152 public int compareTo( final ReplaceData other ) { 153 if( other == null ) { 154 String errMsg = "引数㫠null ã¯è¨å®šã§ãã¾ã›ã‚“ã€? ; 155 throw new IllegalArgumentException( errMsg ); 156 } 157 158 // 5.7.4.0 (2014/03/07) åŒä¸?‚ªãƒ–ジェクトã?判定を追åŠ? 159 if( other.hCode == hCode ) { return 0; } 160 161 if( isOverlap( other) ) { 162 String errMsg = "比è¼?¯¾ç…§ã‚ªãƒ–ジェクトã¨ã‚ªãƒ¼ãƒã?ラãƒ??ã—ã¦ã?¾ã™ã?" 163 + " this =[" + start + "],[" + end + "],[" + newStr + "]" 164 + " other=[" + other.start + "],[" + other.end + "],[" + other.newStr + "]" ; 165 throw new IllegalArgumentException( errMsg ); 166 } 167 return other.start - start; // é–‹å§‹é?ã®é™é? 168 } 169 170 /** 171 * ã“ã?オブジェクトã¨ä»–ã?オブジェクトãŒç‰ã—ã?‹ã©ã?‹ã‚’示ã—ã¾ã™ã? 172 * インタフェース Comparable 㮠実è£?«é–¢é€£ã—ã¦ã€å?定義ã—ã¦ã?¾ã™ã? 173 * 174 * @param other 比è¼?¯¾è±¡ã®å‚ç?オブジェクãƒ? 175 * @return obj å¼•æ•°ã«æŒ?®šã•れãŸã‚ªãƒ–ジェクトã¨ã“ã?オブジェクトãŒç‰ã—ã??åˆã? trueã€ãã?§ãªã??åˆã? false 176 * 177 */ 178 public boolean equals( final Object object ) { 179 if( object instanceof ReplaceData ) { 180 ReplaceData other = (ReplaceData)object ; 181 return start == other.start && 182 end == other.end && 183 newStr.equals( other.newStr ) ; 184 } 185 return false ; 186 } 187 188 /** 189 * オブジェクトã?ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ‰å?ã‚’è¿”ã—ã¾ã™ã? 190 * ã“ã?メソãƒ?ƒ‰ã¯ã€java.util.Hashtable ã«ã‚ˆã£ã¦æä¾›ã•れるよã†ãª 191 * ãƒãƒƒã‚·ãƒ¥ãƒ??ブルã§ä½¿ç”¨ã™ã‚‹ãŸã‚ã«ç”¨æ„ã•れã¦ã?¾ã™ã? 192 * equals( Object ) メソãƒ?ƒ‰ã‚’オーãƒã?ライトã—ãŸå?åˆã?ã€hashCode() メソãƒ?ƒ‰ã‚? 193 * å¿?š 記述ã™ã‚‹å¿?¦ãŒã‚りã¾ã™ã? 194 * 195 * 196 * @return ã“ã?オブジェクトã?ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ‰å? 197 * 198 */ 199 public int hashCode() { 200 return hCode ; 201 } 202 } 203 }