2 * characters in village
\r
4 * Copyright(c) 2008 olyutorskii
\r
5 * $Id: Avatar.java 972 2009-12-26 05:05:15Z olyutorskii $
\r
8 package jp.sourceforge.jindolf;
\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
22 * Avatar またの名をキャラクター。
\r
24 public class Avatar implements Comparable<Avatar> {
\r
26 private static final List<Avatar> AVATAR_LIST;
\r
27 private static final Map<String, Avatar> AVATAR_MAP;
\r
29 private static final Pattern AVATAR_PATTERN;
\r
32 public static final Avatar AVATAR_GERD;
\r
35 List<PreDefAvatar> predefs;
\r
37 DocumentBuilder builder = XmlUtils.createDocumentBuilder();
\r
38 predefs = PreDefAvatar.buildPreDefAvatarList(builder);
\r
39 }catch(RuntimeException e){
\r
41 }catch(Exception e){
\r
42 throw new ExceptionInInitializerError(e);
\r
45 AVATAR_LIST = buildAvatarList(predefs);
\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
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
59 avatarGroupRegex.append('(')
\r
60 .append(Pattern.quote(fullName))
\r
63 AVATAR_PATTERN = Pattern.compile(avatarGroupRegex.toString());
\r
65 AVATAR_GERD = getPredefinedAvatar("楽天家 ゲルト");
\r
67 assert AVATAR_LIST instanceof RandomAccess;
\r
68 assert AVATAR_GERD != null;
\r
73 * @param predefs 定義済みAvatar元データ群
\r
74 * @return ソートされた定義済みAvatarのリスト
\r
76 private static List<Avatar> buildAvatarList(List<PreDefAvatar> predefs){
\r
77 List<Avatar> result = new ArrayList<Avatar>(predefs.size());
\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
91 Collections.sort(result);
\r
92 result = Collections.unmodifiableList(result);
\r
98 * 定義済みAvatar群のリストを返す。
\r
99 * @return Avatarのリスト
\r
101 public static List<Avatar> getPredefinedAvatarList(){
\r
102 return AVATAR_LIST;
\r
107 * @param fullName Avatarのフルネーム
\r
108 * @return Avatar。フルネームが一致するAvatarが無ければnull
\r
110 // TODO 20キャラ程度ならListをなめる方が早いか?
\r
111 public static Avatar getPredefinedAvatar(String fullName){
\r
112 return AVATAR_MAP.get(fullName);
\r
117 * @param fullName Avatarのフルネーム
\r
118 * @return Avatar。フルネームが一致するAvatarが無ければnull
\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
131 * 定義済みAvatar名に一致しないか調べる。
\r
132 * @param matcher マッチャ
\r
133 * @return 一致したAvatar。一致しなければnull。
\r
135 public static Avatar lookingAtAvatar(Matcher matcher){
\r
136 matcher.usePattern(AVATAR_PATTERN);
\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
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
160 * @param jobTitle 職業名
\r
161 * @param idNum 通し番号
\r
162 * @param identifier 識別文字列
\r
164 private Avatar(String name,
\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
173 this.fullName = (this.jobTitle + " " + this.name).intern();
\r
175 this.hashNum = this.fullName.hashCode() ^ this.idNum;
\r
182 * @param fullName フルネーム
\r
184 // TODO 当面は呼ばれないはず。Z国とか向け。
\r
185 public Avatar(String fullName){
\r
186 this.fullName = fullName.intern();
\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
197 this.jobTitle = null;
\r
202 this.identifier = "???".intern();
\r
204 this.hashNum = this.fullName.hashCode() ^ this.idNum;
\r
213 public String getFullName(){
\r
214 return this.fullName;
\r
221 public String getJobTitle(){
\r
222 return this.jobTitle;
\r
229 public String getName(){
\r
237 public int getIdNum(){
\r
245 public String getIdentifier(){
\r
246 return this.identifier;
\r
251 * @param obj {@inheritDoc}
\r
252 * @return {@inheritDoc}
\r
255 public boolean equals(Object obj){
\r
260 if( ! (obj instanceof Avatar) ){
\r
263 Avatar other = (Avatar) obj;
\r
265 boolean nameMatch = this.fullName.equals(other.fullName);
\r
266 boolean idMatch = this.idNum == other.idNum;
\r
268 if(nameMatch && idMatch) return true;
\r
275 * @return {@inheritDoc}
\r
278 public int hashCode(){
\r
279 return this.hashNum;
\r
283 public String toString(){
\r
284 return getFullName();
\r
290 * @param avatar {@inheritDoc}
\r
291 * @return {@inheritDoc}
\r
293 public int compareTo(Avatar avatar){
\r
294 if(avatar == null) return +1;
\r
295 return this.idNum - avatar.idNum;
\r