OSDN Git Service

例外の具体化
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / Avatar.java
1 /*\r
2  * characters in village\r
3  *\r
4  * License : The MIT License\r
5  * Copyright(c) 2008 olyutorskii\r
6  */\r
7 \r
8 package jp.sourceforge.jindolf;\r
9 \r
10 import java.io.IOException;\r
11 import java.net.URISyntaxException;\r
12 import java.util.ArrayList;\r
13 import java.util.Collections;\r
14 import java.util.HashMap;\r
15 import java.util.List;\r
16 import java.util.Map;\r
17 import java.util.RandomAccess;\r
18 import java.util.regex.Matcher;\r
19 import java.util.regex.Pattern;\r
20 import javax.xml.parsers.DocumentBuilder;\r
21 import javax.xml.parsers.ParserConfigurationException;\r
22 import jp.sourceforge.jindolf.corelib.PreDefAvatar;\r
23 import org.xml.sax.SAXException;\r
24 \r
25 /**\r
26  * Avatar またの名をキャラクター。\r
27  */\r
28 public class Avatar implements Comparable<Avatar> {\r
29 \r
30     /** ゲルト。 */\r
31     public static final Avatar AVATAR_GERD;\r
32 \r
33     private static final List<Avatar>        AVATAR_LIST;\r
34     private static final Map<String, Avatar> AVATAR_MAP;\r
35 \r
36     private static final Pattern AVATAR_PATTERN;\r
37 \r
38     static{\r
39         List<PreDefAvatar>  predefs;\r
40         try{\r
41             DocumentBuilder builder = XmlUtils.createDocumentBuilder();\r
42             predefs = PreDefAvatar.buildPreDefAvatarList(builder);\r
43         }catch(IOException e){\r
44             throw new ExceptionInInitializerError(e);\r
45         }catch(ParserConfigurationException e){\r
46             throw new ExceptionInInitializerError(e);\r
47         }catch(SAXException e){\r
48             throw new ExceptionInInitializerError(e);\r
49         }catch(URISyntaxException e){\r
50             throw new ExceptionInInitializerError(e);\r
51         }\r
52 \r
53         AVATAR_LIST = buildAvatarList(predefs);\r
54 \r
55         AVATAR_MAP = new HashMap<String, Avatar>();\r
56         for(Avatar avatar : AVATAR_LIST){\r
57             String fullName = avatar.getFullName();\r
58             AVATAR_MAP.put(fullName, avatar);\r
59         }\r
60 \r
61         StringBuilder avatarGroupRegex = new StringBuilder();\r
62         for(Avatar avatar : AVATAR_LIST){\r
63             String fullName = avatar.getFullName();\r
64             if(avatarGroupRegex.length() > 0){\r
65                 avatarGroupRegex.append('|');\r
66             }\r
67             avatarGroupRegex.append('(')\r
68                             .append(Pattern.quote(fullName))\r
69                             .append(')');\r
70         }\r
71         AVATAR_PATTERN = Pattern.compile(avatarGroupRegex.toString());\r
72 \r
73         AVATAR_GERD = getPredefinedAvatar("楽天家 ゲルト");\r
74 \r
75         assert AVATAR_LIST instanceof RandomAccess;\r
76         assert AVATAR_GERD != null;\r
77     }\r
78 \r
79 \r
80     private final String name;\r
81     private final String jobTitle;\r
82     private final String fullName;\r
83     private final int idNum;\r
84     private final String identifier;\r
85     private final int hashNum;\r
86 \r
87 \r
88     /**\r
89      * Avatarを生成する。\r
90      * @param name 名前\r
91      * @param jobTitle 職業名\r
92      * @param idNum 通し番号\r
93      * @param identifier 識別文字列\r
94      */\r
95     private Avatar(String name,\r
96                     String jobTitle,\r
97                     int idNum,\r
98                     String identifier ){\r
99         this.name = name.intern();\r
100         this.jobTitle = jobTitle.intern();\r
101         this.idNum = idNum;\r
102         this.identifier = identifier.intern();\r
103 \r
104         this.fullName = (this.jobTitle + " " + this.name).intern();\r
105 \r
106         this.hashNum = this.fullName.hashCode() ^ this.idNum;\r
107 \r
108         return;\r
109     }\r
110 \r
111     /**\r
112      * Avatarを生成する。\r
113      * @param fullName フルネーム\r
114      */\r
115     // TODO 当面は呼ばれないはず。Z国とか向け。\r
116     public Avatar(String fullName){\r
117         this.fullName = fullName.intern();\r
118         this.idNum = -1;\r
119 \r
120         String[] tokens = this.fullName.split("\\p{Blank}+", 2);\r
121         if(tokens.length == 1){\r
122             this.jobTitle = null;\r
123             this.name = this.fullName;\r
124         }else if(tokens.length == 2){\r
125             this.jobTitle = tokens[0].intern();\r
126             this.name = tokens[1].intern();\r
127         }else{\r
128             this.jobTitle = null;\r
129             this.name = null;\r
130             assert false;\r
131         }\r
132 \r
133         this.identifier = "???".intern();\r
134 \r
135         this.hashNum = this.fullName.hashCode() ^ this.idNum;\r
136 \r
137         return;\r
138     }\r
139 \r
140 \r
141     /**\r
142      * 定義済みAvatar群の生成。\r
143      * @param predefs 定義済みAvatar元データ群\r
144      * @return ソートされた定義済みAvatarのリスト\r
145      */\r
146     private static List<Avatar> buildAvatarList(List<PreDefAvatar> predefs){\r
147         List<Avatar> result = new ArrayList<Avatar>(predefs.size());\r
148 \r
149         for(PreDefAvatar preDefAvatar : predefs){\r
150             String shortName = preDefAvatar.getShortName();\r
151             String jobTitle  = preDefAvatar.getJobTitle();\r
152             int serialNo     = preDefAvatar.getSerialNo();\r
153             String avatarId  = preDefAvatar.getAvatarId();\r
154             Avatar avatar = new Avatar(shortName,\r
155                                        jobTitle,\r
156                                        serialNo,\r
157                                        avatarId );\r
158             result.add(avatar);\r
159         }\r
160 \r
161         Collections.sort(result);\r
162         result = Collections.unmodifiableList(result);\r
163 \r
164         return result;\r
165     }\r
166 \r
167     /**\r
168      * 定義済みAvatar群のリストを返す。\r
169      * @return Avatarのリスト\r
170      */\r
171     public static List<Avatar> getPredefinedAvatarList(){\r
172         return AVATAR_LIST;\r
173     }\r
174 \r
175     /**\r
176      * 定義済みAvatarを返す。\r
177      * @param fullName Avatarのフルネーム\r
178      * @return Avatar。フルネームが一致するAvatarが無ければnull\r
179      */\r
180     // TODO 20キャラ程度ならListをなめる方が早いか?\r
181     public static Avatar getPredefinedAvatar(String fullName){\r
182         return AVATAR_MAP.get(fullName);\r
183     }\r
184 \r
185     /**\r
186      * 定義済みAvatarを返す。\r
187      * @param fullName Avatarのフルネーム\r
188      * @return Avatar。フルネームが一致するAvatarが無ければnull\r
189      */\r
190     public static Avatar getPredefinedAvatar(CharSequence fullName){\r
191         for(Avatar avatar : AVATAR_LIST){\r
192             String avatarName = avatar.getFullName();\r
193             if(avatarName.contentEquals(fullName)){\r
194                 return avatar;\r
195             }\r
196         }\r
197         return null;\r
198     }\r
199 \r
200     /**\r
201      * 定義済みAvatar名に一致しないか調べる。\r
202      * @param matcher マッチャ\r
203      * @return 一致したAvatar。一致しなければnull。\r
204      */\r
205     public static Avatar lookingAtAvatar(Matcher matcher){\r
206         matcher.usePattern(AVATAR_PATTERN);\r
207 \r
208         if( ! matcher.lookingAt() ) return null;\r
209         int groupCt = matcher.groupCount();\r
210         for(int group = 1; group <= groupCt; group++){\r
211             if(matcher.start(group) >= 0){\r
212                 Avatar avatar = AVATAR_LIST.get(group - 1);\r
213                 return avatar;\r
214             }\r
215         }\r
216 \r
217         return null;\r
218     }\r
219 \r
220     /**\r
221      * フルネームを取得する。\r
222      * @return フルネーム\r
223      */\r
224     public String getFullName(){\r
225         return this.fullName;\r
226     }\r
227 \r
228     /**\r
229      * 職業名を取得する。\r
230      * @return 職業名\r
231      */\r
232     public String getJobTitle(){\r
233         return this.jobTitle;\r
234     }\r
235 \r
236     /**\r
237      * 通常名を取得する。\r
238      * @return 通常名\r
239      */\r
240     public String getName(){\r
241         return this.name;\r
242     }\r
243 \r
244     /**\r
245      * 通し番号を返す。\r
246      * @return 通し番号\r
247      */\r
248     public int getIdNum(){\r
249         return this.idNum;\r
250     }\r
251 \r
252     /**\r
253      * 識別文字列を返す。\r
254      * @return 識別文字列\r
255      */\r
256     public String getIdentifier(){\r
257         return this.identifier;\r
258     }\r
259 \r
260     /**\r
261      * {@inheritDoc}\r
262      * @param obj {@inheritDoc}\r
263      * @return {@inheritDoc}\r
264      */\r
265     @Override\r
266     public boolean equals(Object obj){\r
267         if(this == obj){\r
268             return true;\r
269         }\r
270 \r
271         if( ! (obj instanceof Avatar) ){\r
272             return false;\r
273         }\r
274         Avatar other = (Avatar) obj;\r
275 \r
276         boolean nameMatch = this.fullName.equals(other.fullName);\r
277         boolean idMatch = this.idNum == other.idNum;\r
278 \r
279         if(nameMatch && idMatch) return true;\r
280 \r
281         return false;\r
282     }\r
283 \r
284     /**\r
285      * {@inheritDoc}\r
286      * @return {@inheritDoc}\r
287      */\r
288     @Override\r
289     public int hashCode(){\r
290         return this.hashNum;\r
291     }\r
292 \r
293     @Override\r
294     public String toString(){\r
295         return getFullName();\r
296     }\r
297 \r
298     /**\r
299      * {@inheritDoc}\r
300      * 通し番号順に順序づける。\r
301      * @param avatar {@inheritDoc}\r
302      * @return {@inheritDoc}\r
303      */\r
304     @Override\r
305     public int compareTo(Avatar avatar){\r
306         if(avatar == null) return +1;\r
307         return this.idNum - avatar.idNum;\r
308     }\r
309 \r
310 }\r