OSDN Git Service

ファイルエンコーディング設定修正
[coroid/NicoBrowser.git] / src / nicobrowser / NamePattern.java
1 package nicobrowser;
2
3 import java.io.UnsupportedEncodingException;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6
7 /**
8  *
9  * @author yuki
10  */
11 public class NamePattern {
12
13     private static final String titlePattern = "{title}";
14     private static final String idPattern = "{id}";
15     private static final String lowPattern = "{low}";
16     private static Logger log = LoggerFactory.getLogger(NamePattern.class);
17     private final String pattern;
18     private String replaceFrom = "";
19     private String replaceTo = "";
20     private String id = "";
21     private String title = "";
22     private boolean isNotLow = true;
23
24     public NamePattern(String pattern) {
25         this.pattern = pattern;
26     }
27
28     /**
29      * 保存ファイル名の命名規則.
30      *
31      * @param pattern 命名パターン.
32      * @param replaceFrom 禁則文字を指定する.
33      * @param replaceTo 禁則文字をこの文字列に置換する.
34      * @param title ファイル名に用いるタイトル文字列.
35      */
36     public NamePattern(String pattern, String replaceFrom, String replaceTo, String title) {
37         this.pattern = pattern;
38         this.replaceFrom = replaceFrom;
39         this.replaceTo = replaceTo;
40         this.title = title;
41     }
42
43     public final String createFileName() {
44         String res = replacePlaceHolder(pattern);
45         return replaceIllegalChar(res);
46     }
47
48     public final String createFileName(String id, boolean isNotLow) {
49         this.id = id;
50         this.isNotLow = isNotLow;
51
52         return createFileName();
53     }
54
55     public final void setId(String id) {
56         this.id = id;
57     }
58
59     public final void setIsNotLow(boolean isNotLow) {
60         this.isNotLow = isNotLow;
61     }
62
63     public final void setReplaceFrom(String replaceFrom) {
64         this.replaceFrom = replaceFrom;
65     }
66
67     public final void setReplaceTo(String replaceTo) {
68         this.replaceTo = replaceTo;
69     }
70
71     public final void setTitle(String title) {
72         this.title = title;
73     }
74
75     protected String replacePlaceHolder(String str) {
76         String res = str.replace(titlePattern, title);
77         res = res.replace(idPattern, id);
78         String low = isNotLow ? "" : "low";
79         res = res.replace(lowPattern, low);
80         return res;
81     }
82
83     private String replaceIllegalChar(String res) {
84 //        // TODO 正規表現で書き直す
85 //        char[] replaceds = new char[replaceFrom.length()];
86 //        replaceFrom.getChars(0, replaceFrom.length(), replaceds, 0);
87 //        StringBuilder str = new StringBuilder();
88 //        for (int i = 0; i < res.length(); i++) {
89 //            char c = res.charAt(i);
90 //            String moji = String.valueOf(c);
91 //            for (char replaced : replaceds) {
92 //                if (c == replaced) {
93 //                    moji = replaceTo;
94 //                }
95 //            }
96 //            str.append(moji);
97 //        }
98 //        return getSanitizedDescription(str.toString());
99         return getSanitizedDescription(res);
100     }
101
102     public static String getSanitizedDescription(String decodedDesc) {
103         String fileNameCharset = System.getProperty("fileNameCharset", "");
104
105         String narrowedDesc = narrowCharset(decodedDesc, fileNameCharset);
106
107         // 実体参照を更に実体参照するケースがあるので二回置換する
108         narrowedDesc = replaceER(replaceER(narrowedDesc));
109
110         char descArray[] = narrowedDesc.toCharArray();
111
112         for (int i = 0; i < descArray.length; i++) {
113             char c = descArray[i];
114             switch (c) {
115                 case '\\':
116                 case '\u00a5':
117                     c = '¥';
118                     break;
119                 case '/':
120                     c = '/';
121                     break;
122                 case ':':
123                     c = ':';
124                     break;
125                 case '*':
126                     c = '*';
127                     break;
128                 case '?':
129                     c = '?';
130                     break;
131                 case '"':
132                     c = '”';
133                     break;
134                 case '<':
135                     c = '<';
136                     break;
137                 case '>':
138                     c = '>';
139                     break;
140                 case '|':
141                     c = '|';
142                     break;
143                 case '\u203e':// c = '~'; break;
144                 case '\u301c':// c = '~'; break;
145                 case '\u2016':
146                 case '\u2212':
147                 case '\u00a2':
148                 case '\u00a3':
149                 case '\u00ac':
150                     c = '-';
151                     break;
152             }
153
154             descArray[i] = c;
155         }
156         return new String(descArray);
157     }
158
159     private static String replaceER(String src) {
160         return src.replaceAll("&amp;", "&").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", "\"").
161                 replaceAll("&apos;", "'");
162     }
163
164     // 一旦目的の文字コードにしてから戻して、対応してない文字を '?' にする
165     static String narrowCharset(String str, String charsetName) {
166         String narrowedDesc = str;
167         if (!charsetName.equals("")) {
168             try {
169                 narrowedDesc =
170                         new String(str.getBytes(charsetName), charsetName);
171                 // characters which are not supported by the charset
172                 // become '?'
173             } catch (UnsupportedEncodingException e) {
174                 log.warn(e.toString());
175             }
176         }
177         return narrowedDesc;
178     }
179 }