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