OSDN Git Service

from subversion repository
[jindolf/Jindolf.git] / src / main / java / jp / sourceforge / jindolf / Avatar.java
1 /*\r
2  * characters in village\r
3  *\r
4  * Copyright(c) 2008 olyutorskii\r
5  * $Id: Avatar.java 972 2009-12-26 05:05:15Z 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     private static final List<Avatar>        AVATAR_LIST;\r
27     private static final Map<String, Avatar> AVATAR_MAP;\r
28 \r
29     private static final Pattern AVATAR_PATTERN;\r
30 \r
31     /** ゲルト。 */\r
32     public static final Avatar AVATAR_GERD;\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      * 定義済みAvatar群の生成。\r
73      * @param predefs 定義済みAvatar元データ群\r
74      * @return ソートされた定義済みAvatarのリスト\r
75      */\r
76     private static List<Avatar> buildAvatarList(List<PreDefAvatar> predefs){\r
77         List<Avatar> result = new ArrayList<Avatar>(predefs.size());\r
78 \r
79         for(PreDefAvatar preDefAvatar : predefs){\r
80             String shortName = preDefAvatar.getShortName();\r
81             String jobTitle  = preDefAvatar.getJobTitle();\r
82             int serialNo     = preDefAvatar.getSerialNo();\r
83             String avatarId  = preDefAvatar.getAvatarId();\r
84             Avatar avatar = new Avatar(shortName,\r
85                                        jobTitle,\r
86                                        serialNo,\r
87                                        avatarId );\r
88             result.add(avatar);\r
89         }\r
90 \r
91         Collections.sort(result);\r
92         result = Collections.unmodifiableList(result);\r
93 \r
94         return result;\r
95     }\r
96 \r
97     /**\r
98      * 定義済みAvatar群のリストを返す。\r
99      * @return Avatarのリスト\r
100      */\r
101     public static List<Avatar> getPredefinedAvatarList(){\r
102         return AVATAR_LIST;\r
103     }\r
104 \r
105     /**\r
106      * 定義済みAvatarを返す。\r
107      * @param fullName Avatarのフルネーム\r
108      * @return Avatar。フルネームが一致するAvatarが無ければnull\r
109      */\r
110     // TODO 20キャラ程度ならListをなめる方が早いか?\r
111     public static Avatar getPredefinedAvatar(String fullName){\r
112         return AVATAR_MAP.get(fullName);\r
113     }\r
114 \r
115     /**\r
116      * 定義済みAvatarを返す。\r
117      * @param fullName Avatarのフルネーム\r
118      * @return Avatar。フルネームが一致するAvatarが無ければnull\r
119      */\r
120     public static Avatar getPredefinedAvatar(CharSequence fullName){\r
121         for(Avatar avatar : AVATAR_LIST){\r
122             String avatarName = avatar.getFullName();\r
123             if(avatarName.contentEquals(fullName)){\r
124                 return avatar;\r
125             }\r
126         }\r
127         return null;\r
128     }\r
129 \r
130     /**\r
131      * 定義済みAvatar名に一致しないか調べる。\r
132      * @param matcher マッチャ\r
133      * @return 一致したAvatar。一致しなければnull。\r
134      */\r
135     public static Avatar lookingAtAvatar(Matcher matcher){\r
136         matcher.usePattern(AVATAR_PATTERN);\r
137 \r
138         if( ! matcher.lookingAt() ) return null;\r
139         int groupCt = matcher.groupCount();\r
140         for(int group = 1; group <= groupCt; group++){\r
141             if(matcher.start(group) >= 0){\r
142                 Avatar avatar = AVATAR_LIST.get(group - 1);\r
143                 return avatar;\r
144             }\r
145         }\r
146 \r
147         return null;\r
148     }\r
149 \r
150     private final String name;\r
151     private final String jobTitle;\r
152     private final String fullName;\r
153     private final int idNum;\r
154     private final String identifier;\r
155     private final int hashNum;\r
156 \r
157     /**\r
158      * Avatarを生成する。\r
159      * @param name 名前\r
160      * @param jobTitle 職業名\r
161      * @param idNum 通し番号\r
162      * @param identifier 識別文字列\r
163      */\r
164     private Avatar(String name,\r
165                     String jobTitle,\r
166                     int idNum,\r
167                     String identifier ){\r
168         this.name = name.intern();\r
169         this.jobTitle = jobTitle.intern();\r
170         this.idNum = idNum;\r
171         this.identifier = identifier.intern();\r
172 \r
173         this.fullName = (this.jobTitle + " " + this.name).intern();\r
174 \r
175         this.hashNum = this.fullName.hashCode() ^ this.idNum;\r
176 \r
177         return;\r
178     }\r
179 \r
180     /**\r
181      * Avatarを生成する。\r
182      * @param fullName フルネーム\r
183      */\r
184     // TODO 当面は呼ばれないはず。Z国とか向け。\r
185     public Avatar(String fullName){\r
186         this.fullName = fullName.intern();\r
187         this.idNum = -1;\r
188 \r
189         String[] tokens = this.fullName.split("\\p{Blank}+", 2);\r
190         if(tokens.length == 1){\r
191             this.jobTitle = null;\r
192             this.name = this.fullName;\r
193         }else if(tokens.length == 2){\r
194             this.jobTitle = tokens[0].intern();\r
195             this.name = tokens[1].intern();\r
196         }else{\r
197             this.jobTitle = null;\r
198             this.name = null;\r
199             assert false;\r
200         }\r
201 \r
202         this.identifier = "???".intern();\r
203 \r
204         this.hashNum = this.fullName.hashCode() ^ this.idNum;\r
205 \r
206         return;\r
207     }\r
208 \r
209     /**\r
210      * フルネームを取得する。\r
211      * @return フルネーム\r
212      */\r
213     public String getFullName(){\r
214         return this.fullName;\r
215     }\r
216 \r
217     /**\r
218      * 職業名を取得する。\r
219      * @return 職業名\r
220      */\r
221     public String getJobTitle(){\r
222         return this.jobTitle;\r
223     }\r
224 \r
225     /**\r
226      * 通常名を取得する。\r
227      * @return 通常名\r
228      */\r
229     public String getName(){\r
230         return this.name;\r
231     }\r
232 \r
233     /**\r
234      * 通し番号を返す。\r
235      * @return 通し番号\r
236      */\r
237     public int getIdNum(){\r
238         return this.idNum;\r
239     }\r
240 \r
241     /**\r
242      * 識別文字列を返す。\r
243      * @return 識別文字列\r
244      */\r
245     public String getIdentifier(){\r
246         return this.identifier;\r
247     }\r
248 \r
249     /**\r
250      * {@inheritDoc}\r
251      * @param obj {@inheritDoc}\r
252      * @return {@inheritDoc}\r
253      */\r
254     @Override\r
255     public boolean equals(Object obj){\r
256         if(this == obj){\r
257             return true;\r
258         }\r
259 \r
260         if( ! (obj instanceof Avatar) ){\r
261             return false;\r
262         }\r
263         Avatar other = (Avatar) obj;\r
264 \r
265         boolean nameMatch = this.fullName.equals(other.fullName);\r
266         boolean idMatch = this.idNum == other.idNum;\r
267 \r
268         if(nameMatch && idMatch) return true;\r
269 \r
270         return false;\r
271     }\r
272 \r
273     /**\r
274      * {@inheritDoc}\r
275      * @return {@inheritDoc}\r
276      */\r
277     @Override\r
278     public int hashCode(){\r
279         return this.hashNum;\r
280     }\r
281 \r
282     @Override\r
283     public String toString(){\r
284         return getFullName();\r
285     }\r
286 \r
287     /**\r
288      * {@inheritDoc}\r
289      * 通し番号順に順序づける。\r
290      * @param avatar {@inheritDoc}\r
291      * @return {@inheritDoc}\r
292      */\r
293     public int compareTo(Avatar avatar){\r
294         if(avatar == null) return +1;\r
295         return this.idNum - avatar.idNum;\r
296     }\r
297 \r
298 }\r