2 * characters in village
\r
4 * License : The MIT License
\r
5 * Copyright(c) 2008 olyutorskii
\r
8 package jp.sourceforge.jindolf;
\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
26 * Avatar またの名をキャラクター。
\r
28 public class Avatar implements Comparable<Avatar> {
\r
31 public static final Avatar AVATAR_GERD;
\r
33 private static final List<Avatar> AVATAR_LIST;
\r
34 private static final Map<String, Avatar> AVATAR_MAP;
\r
36 private static final Pattern AVATAR_PATTERN;
\r
39 List<PreDefAvatar> predefs;
\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
53 AVATAR_LIST = buildAvatarList(predefs);
\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
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
67 avatarGroupRegex.append('(')
\r
68 .append(Pattern.quote(fullName))
\r
71 AVATAR_PATTERN = Pattern.compile(avatarGroupRegex.toString());
\r
73 AVATAR_GERD = getPredefinedAvatar("楽天家 ゲルト");
\r
75 assert AVATAR_LIST instanceof RandomAccess;
\r
76 assert AVATAR_GERD != null;
\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
91 * @param jobTitle 職業名
\r
93 * @param identifier 識別文字列
\r
95 private Avatar(String name,
\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
104 this.fullName = (this.jobTitle + " " + this.name).intern();
\r
106 this.hashNum = this.fullName.hashCode() ^ this.idNum;
\r
113 * @param fullName フルネーム
\r
115 // TODO 当面は呼ばれないはず。Z国とか向け。
\r
116 public Avatar(String fullName){
\r
117 this.fullName = fullName.intern();
\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
128 this.jobTitle = null;
\r
133 this.identifier = "???".intern();
\r
135 this.hashNum = this.fullName.hashCode() ^ this.idNum;
\r
143 * @param predefs 定義済みAvatar元データ群
\r
144 * @return ソートされた定義済みAvatarのリスト
\r
146 private static List<Avatar> buildAvatarList(List<PreDefAvatar> predefs){
\r
147 List<Avatar> result = new ArrayList<Avatar>(predefs.size());
\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
158 result.add(avatar);
\r
161 Collections.sort(result);
\r
162 result = Collections.unmodifiableList(result);
\r
168 * 定義済みAvatar群のリストを返す。
\r
169 * @return Avatarのリスト
\r
171 public static List<Avatar> getPredefinedAvatarList(){
\r
172 return AVATAR_LIST;
\r
177 * @param fullName Avatarのフルネーム
\r
178 * @return Avatar。フルネームが一致するAvatarが無ければnull
\r
180 // TODO 20キャラ程度ならListをなめる方が早いか?
\r
181 public static Avatar getPredefinedAvatar(String fullName){
\r
182 return AVATAR_MAP.get(fullName);
\r
187 * @param fullName Avatarのフルネーム
\r
188 * @return Avatar。フルネームが一致するAvatarが無ければnull
\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
201 * 定義済みAvatar名に一致しないか調べる。
\r
202 * @param matcher マッチャ
\r
203 * @return 一致したAvatar。一致しなければnull。
\r
205 public static Avatar lookingAtAvatar(Matcher matcher){
\r
206 matcher.usePattern(AVATAR_PATTERN);
\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
224 public String getFullName(){
\r
225 return this.fullName;
\r
232 public String getJobTitle(){
\r
233 return this.jobTitle;
\r
240 public String getName(){
\r
248 public int getIdNum(){
\r
256 public String getIdentifier(){
\r
257 return this.identifier;
\r
262 * @param obj {@inheritDoc}
\r
263 * @return {@inheritDoc}
\r
266 public boolean equals(Object obj){
\r
271 if( ! (obj instanceof Avatar) ){
\r
274 Avatar other = (Avatar) obj;
\r
276 boolean nameMatch = this.fullName.equals(other.fullName);
\r
277 boolean idMatch = this.idNum == other.idNum;
\r
279 if(nameMatch && idMatch) return true;
\r
286 * @return {@inheritDoc}
\r
289 public int hashCode(){
\r
290 return this.hashNum;
\r
294 public String toString(){
\r
295 return getFullName();
\r
301 * @param avatar {@inheritDoc}
\r
302 * @return {@inheritDoc}
\r
305 public int compareTo(Avatar avatar){
\r
306 if(avatar == null) return +1;
\r
307 return this.idNum - avatar.idNum;
\r