4 import java.util.ArrayList;
\r
5 import java.util.regex.Matcher;
\r
6 import java.util.regex.Pattern;
\r
8 import tainavi.SearchKey.TargetId;
\r
9 import tainavi.TVProgram.ProgFlags;
\r
10 import tainavi.TVProgram.ProgGenre;
\r
11 import tainavi.TVProgram.ProgOption;
\r
12 import tainavi.TVProgram.ProgScrumble;
\r
13 import tainavi.TVProgram.ProgSubgenre;
\r
16 public class SearchProgram {
\r
19 private ArrayList<SearchKey> searchKeys = new ArrayList<SearchKey>();
\r
21 private String searchKeyFile = null;
\r
22 protected void setSearchKeyFile(String s) { searchKeyFile = s; }
\r
24 private String searchKeyLabel = null;
\r
25 protected void setSearchKeyLabel(String s) { searchKeyLabel = s; }
\r
28 public void save() {
\r
29 System.out.println(searchKeyLabel+"設定を保存します: "+searchKeyFile);
\r
30 if ( ! CommonUtils.writeXML(searchKeyFile, searchKeys) ) {
\r
31 System.err.println(searchKeyLabel+"設定の保存に失敗しました.");
\r
37 public void load() {
\r
38 System.out.println(searchKeyLabel+"設定を読み込みます: "+searchKeyFile);
\r
39 searchKeys = (ArrayList<SearchKey>) CommonUtils.readXML(searchKeyFile);
\r
40 if ( searchKeys == null ) {
\r
41 System.err.println(searchKeyLabel+"設定を読み込めなかったので登録なしで起動します.");
\r
42 searchKeys = new ArrayList<SearchKey>();
\r
47 for (SearchKey sk : searchKeys) {
\r
51 if (sk.getOkiniiri() == null) {
\r
52 sk.setOkiniiri("★");
\r
58 public ArrayList<SearchKey> getSearchKeys() {
\r
63 public void add(SearchKey newkey) {
\r
64 searchKeys.add(newkey);
\r
67 public void add(int index, SearchKey newkey) {
\r
68 searchKeys.add(index, newkey);
\r
72 public void remove(String key) {
\r
73 for ( SearchKey k : searchKeys ) {
\r
74 if (k.getLabel().equals(key)) {
\r
75 searchKeys.remove(k);
\r
82 public SearchKey replace(String key, SearchKey sk) {
\r
84 for ( SearchKey k : searchKeys ) {
\r
85 if (k.getLabel().equals(key)) {
\r
86 searchKeys.add(i,sk);
\r
87 searchKeys.remove(i+1);
\r
96 public void compile(SearchKey keyword) {
\r
98 keyword.alTarget = new ArrayList<TargetId>();
\r
99 keyword.alKeyword_regex = new ArrayList<Pattern>();
\r
100 keyword.alKeyword = new ArrayList<String>();
\r
101 keyword.alContain = new ArrayList<String>();
\r
104 ArrayList<String> sTtmp = new ArrayList<String>();
\r
105 ArrayList<String> mRtmp = new ArrayList<String>();
\r
106 ArrayList<String> sCtmp = new ArrayList<String>();
\r
111 ma = Pattern.compile("(.*?)\t").matcher(keyword.getTarget());
\r
112 while (ma.find()) {
\r
113 sTtmp.add(String.valueOf(ma.group(1)));
\r
116 ma = Pattern.compile("(.*?)\t").matcher(keyword.getKeyword());
\r
117 while (ma.find()) {
\r
118 mRtmp.add(ma.group(1));
\r
121 ma = Pattern.compile("(.*?)\t").matcher(keyword.getContain());
\r
122 while (ma.find()) {
\r
123 sCtmp.add(String.valueOf(ma.group(1)));
\r
127 for (int x=0; x<sTtmp.size(); x++) {
\r
128 if (sCtmp.get(x).equals("0")) {
\r
129 setAlKeyword(keyword, x, sTtmp.get(x), mRtmp.get(x), sCtmp.get(x));
\r
132 for (int x=0; x<sTtmp.size(); x++) {
\r
133 if (sCtmp.get(x).equals("1")) {
\r
134 setAlKeyword(keyword, x, sTtmp.get(x), mRtmp.get(x), sCtmp.get(x));
\r
138 private void setAlKeyword(SearchKey keyword, int x, String sT, String mR, String sC) {
\r
140 TargetId ti = TargetId.getTargetId(sT);
\r
141 keyword.alTarget.add(ti);
\r
145 case TITLEANDDETAIL:
\r
149 if (keyword.getCaseSensitive() == false) {
\r
150 keyword.alKeyword_regex.add(Pattern.compile("("+TraceProgram.replacePop(mR)+")"));
\r
153 keyword.alKeyword_regex.add(Pattern.compile("("+mR+")"));
\r
156 case STARTDATETIME:
\r
157 keyword.alKeyword_regex.add(Pattern.compile("("+mR+")"));
\r
160 keyword.alKeyword_regex.add(null);
\r
167 Matcher ma = Pattern.compile("^(\\d+) ").matcher(mR);
\r
169 keyword.alLength.add(Integer.valueOf(ma.group(1)));
\r
172 keyword.alLength.add(0);
\r
176 keyword.alLength.add(0);
\r
184 Matcher ma = Pattern.compile("^(\\d\\d)(:\\d\\d)").matcher(mR);
\r
186 Integer t = Integer.valueOf(ma.group(1));
\r
187 t += (CommonUtils.isLateNight(t)?(24):(0));
\r
188 keyword.alKeyword_plane.add(String.format("%02d%s", t, ma.group(2)));
\r
189 //System.out.println(keyword.alKeyword_plane.get(keyword.alKeyword_plane.size()-1));
\r
192 keyword.alKeyword_plane.add("");
\r
196 keyword.alKeyword_plane.add(mR);
\r
200 keyword.alKeyword.add(TraceProgram.replacePop(mR));
\r
201 keyword.alKeyword_pop.add(TraceProgram.replacePop(mR));
\r
202 keyword.alContain.add(sC);
\r
208 private static int compareDT(String target, String limit)
\r
210 Matcher ma = Pattern.compile("^(\\d\\d)(:\\d\\d)").matcher(target);
\r
212 Integer t = Integer.valueOf(ma.group(1));
\r
213 t += (CommonUtils.isLateNight(t)?(24):(0));
\r
214 String ts = String.format("%02d%s", t, ma.group(2));
\r
215 return ts.compareTo(limit);
\r
222 private static String matchedString = null;
\r
223 public static String getMatchedString() { return matchedString; }
\r
225 public static boolean isMatchKeyword(SearchKey keyword, String center, ProgDetailList tvd)
\r
228 ArrayList<TargetId> sT = keyword.alTarget;
\r
229 ArrayList<Pattern> mRe = keyword.alKeyword_regex;
\r
230 //ArrayList<String> mR = keyword.alKeyword;
\r
231 ArrayList<String> mRp = keyword.alKeyword_plane;
\r
232 //ArrayList<String> mRpop = keyword.alKeyword_pop;
\r
233 ArrayList<String> sC = keyword.alContain;
\r
234 ArrayList<Integer> sL = keyword.alLength;
\r
236 matchedString = null;
\r
240 boolean isOrMatch = false;
\r
241 for (int x=0; x<sT.size(); x++) {
\r
243 boolean isCurMatch = false;
\r
244 TargetId ti = sT.get(x);
\r
248 if (ti == TargetId.TITLE || ti == TargetId.TITLEANDDETAIL) {
\r
249 if (keyword.getCaseSensitive() == false) {
\r
250 mx = mRe.get(x).matcher(tvd.titlePop);
\r
253 if (matchedString == null) {
\r
254 int srcLen = tvd.title.length();
\r
255 int keyLen = mx.group(1).length();
\r
256 int keyIdx = tvd.titlePop.indexOf(mx.group(1));
\r
257 char[] ch = tvd.title.toCharArray();
\r
261 for (int i=0; i<srcLen; i++) {
\r
262 if ( ! TraceProgram.isOmittedChar(ch[i])) {
\r
265 if (matchIdx < 0 && keyIdx == cnt-1) {
\r
269 if (matchIdx >= 0 && cnt < keyLen) {
\r
273 matchedString = tvd.title.substring(matchIdx,matchIdx+matchLen);
\r
278 if (tvd.title.indexOf(mRp.get(x)) >= 0) {
\r
280 if (matchedString == null) {
\r
281 matchedString = mRp.get(x);
\r
289 if (ti == TargetId.DETAIL || ti == TargetId.TITLEANDDETAIL) {
\r
290 if (keyword.getCaseSensitive() == false) {
\r
291 mx = mRe.get(x).matcher(tvd.detailPop);
\r
297 if (tvd.detail.indexOf(mRp.get(x)) >= 0) {
\r
305 if (keyword.getCaseSensitive() == false) {
\r
306 mx = mRe.get(x).matcher(center);
\r
312 if (center.indexOf(mRp.get(x)) >= 0) {
\r
319 ProgGenre gr = ProgGenre.get(mRp.get(x));
\r
320 if ( gr != null ) {
\r
321 isCurMatch = tvd.isEqualsGenre(gr, null);
\r
325 ProgSubgenre sgr = ProgSubgenre.get(mRp.get(x));
\r
326 if ( sgr != null ) {
\r
327 isCurMatch = tvd.isEqualsGenre(null, sgr);
\r
331 case NEW: // 5,6,7,8,12,13
\r
332 if (tvd.flag == ProgFlags.NEW) {
\r
337 if (tvd.flag == ProgFlags.LAST) {
\r
342 for (ProgOption o : tvd.getOption()) {
\r
343 if (o == ProgOption.REPEAT) {
\r
350 for (ProgOption o : tvd.getOption()) {
\r
351 if (o == ProgOption.FIRST) {
\r
358 for (ProgOption o : tvd.getOption()) {
\r
359 if (o == ProgOption.SPECIAL) {
\r
366 for (ProgOption o : tvd.getOption()) {
\r
367 if (o == ProgOption.RATING) {
\r
374 if (tvd.noscrumble == ProgScrumble.NOSCRUMBLE) {
\r
379 for (ProgOption o : tvd.getOption()) {
\r
380 if (o == ProgOption.LIVE) {
\r
387 for (ProgOption o : tvd.getOption()) {
\r
388 if (o == ProgOption.BILINGUAL) {
\r
395 for (ProgOption o : tvd.getOption()) {
\r
396 if (o == ProgOption.MULTIVOICE) {
\r
403 for (ProgOption o : tvd.getOption()) {
\r
404 if (o == ProgOption.STANDIN) {
\r
412 if (tvd.length >= sL.get(x)) {
\r
417 case STARTA: // 10,11,14
\r
418 if (compareDT(tvd.start,mRp.get(x)) >= 0) {
\r
423 if (compareDT(tvd.start,mRp.get(x)) <= 0) {
\r
427 case STARTDATETIME:
\r
428 mx = mRe.get(x).matcher(tvd.startDateTime);
\r
440 if (keyword.getCondition().equals("0")) {
\r
442 if (sC.get(x).equals("0") && isCurMatch == false) {
\r
446 else if (sC.get(x).equals("1") && isCurMatch == true) {
\r
453 if (sC.get(x).equals("0") && isCurMatch == true) {
\r
457 else if (sC.get(x).equals("1") && isCurMatch == true) {
\r
460 // ★★★ 特殊動作注意!番ナビスレ Part.11 No.274付近参照 ★★★
\r
461 // 「含む ∪ 含む ∪ 含まない ∪ 含まない」ではなく
\r
462 // 「( 含む ∪ 含む ) ∩ ~(含まない ∪ 含まない)」となる
\r
469 if (keyword.getCondition().equals("0")) {
\r
470 // 0:次のすべての条件に一致で、すべての条件に適合した場合
\r
474 // 1:次のいずれかの条件に一致、の場合
\r
482 public SearchProgram() {
\r
483 setSearchKeyFile("env"+File.separator+"keyword.xml");
\r
484 setSearchKeyLabel("キーワード検索");
\r