4 * License : The MIT License
\r
5 * Copyright(c) 2008 olyutorskii
\r
8 package jp.sourceforge.jindolf.archiver;
\r
10 import java.io.IOException;
\r
11 import java.io.Writer;
\r
12 import java.util.Collections;
\r
13 import java.util.LinkedList;
\r
14 import java.util.List;
\r
15 import jp.sourceforge.jindolf.corelib.DisclosureType;
\r
16 import jp.sourceforge.jindolf.corelib.LandDef;
\r
17 import jp.sourceforge.jindolf.corelib.PeriodType;
\r
18 import jp.sourceforge.jindolf.corelib.PreDefAvatar;
\r
24 public class VillageData{
\r
26 private final List<PeriodResource> resourceList;
\r
28 private final LandDef landDef;
\r
29 private final int villageId;
\r
30 private final String baseUri;
\r
32 private String fullName = "";
\r
33 private int commitHour = -1;
\r
34 private int commitMinute = -1;
\r
35 private String graveIconUri;
\r
37 private final List<AvatarData> avatarList = new LinkedList<AvatarData>();
\r
38 private int undefAvatarNo = 1;
\r
40 private final List<PeriodData> periodList = new LinkedList<PeriodData>();
\r
45 * @param resourceList PeriodResource並び
\r
47 public VillageData(List<PeriodResource> resourceList){
\r
50 validatePeriodResource(resourceList);
\r
52 this.resourceList = new LinkedList<PeriodResource>(resourceList);
\r
54 PeriodResource resource1st = this.resourceList.get(0);
\r
55 this.landDef = resource1st.getLandDef();
\r
56 this.villageId = resource1st.getVillageId();
\r
57 this.baseUri = getBaseUri(this.resourceList);
\r
64 * PeriodResourceの組が正当かチェックする。
\r
66 * <li>全て同じ国に属していなければならない
\r
67 * <li>全て同じ村に属していなければならない
\r
68 * <li>日付は0から始まる連続した数値でなければならない
\r
69 * <li>プロローグで始まらなければならない
\r
70 * <li>エピローグで終わらなければならない
\r
71 * <li>進行日はプロローグとエピローグに挟まれていなければならない
\r
73 * @param list PeriodResource並び
\r
74 * @throws IllegalArgumentException 引数が正当でない
\r
76 public static void validatePeriodResource(List<PeriodResource> list)
\r
77 throws IllegalArgumentException{
\r
78 LandDef landDef = null;
\r
81 PeriodType periodType = null;
\r
83 for(PeriodResource resource : list){
\r
84 if(landDef == null){
\r
85 landDef = resource.getLandDef();
\r
86 }else if(resource.getLandDef() != landDef){
\r
87 throw new IllegalArgumentException();
\r
91 villageId = resource.getVillageId();
\r
92 }else if(resource.getVillageId() != villageId){
\r
93 throw new IllegalArgumentException();
\r
97 lastDay = resource.getDay();
\r
98 if(lastDay != 0) throw new IllegalArgumentException();
\r
100 if(resource.getDay() != lastDay + 1){
\r
101 throw new IllegalArgumentException();
\r
103 lastDay = resource.getDay();
\r
106 if(periodType == null){
\r
107 periodType = resource.getPeriodType();
\r
108 if(periodType != PeriodType.PROLOGUE){
\r
109 throw new IllegalArgumentException();
\r
111 if(lastDay != 0) throw new IllegalArgumentException();
\r
112 }else if(periodType == PeriodType.PROLOGUE){
\r
113 periodType = resource.getPeriodType();
\r
114 if(periodType != PeriodType.PROGRESS){
\r
115 throw new IllegalArgumentException();
\r
117 }else if(periodType == PeriodType.PROGRESS){
\r
118 periodType = resource.getPeriodType();
\r
119 }else if(periodType == PeriodType.EPILOGUE){
\r
120 throw new IllegalArgumentException();
\r
124 if(lastDay < 0) throw new IllegalArgumentException();
\r
125 if(periodType != PeriodType.EPILOGUE){
\r
126 throw new IllegalArgumentException();
\r
133 * 全PeriodResourceから、共通するベースURIを抽出する。
\r
134 * @param list PeriodResource並び
\r
135 * @return ベースURI文字列
\r
136 * @throws IllegalArgumentException ベースURIが一致していない
\r
138 public static String getBaseUri(List<PeriodResource> list)
\r
139 throws IllegalArgumentException{
\r
140 String result = null;
\r
142 for(PeriodResource resource : list){
\r
143 String urlText = resource.getOrigUrlText();
\r
144 urlText = urlText.replaceAll("[^/]*$", "");
\r
145 if(result == null){
\r
148 if( ! result.equals(urlText) ){
\r
149 throw new IllegalArgumentException();
\r
161 public LandDef getLandDef(){
\r
162 return this.landDef;
\r
169 public int getVillageId(){
\r
170 return this.villageId;
\r
177 public String getBaseUri(){
\r
178 return this.baseUri;
\r
185 public String getFullName(){
\r
186 return this.fullName;
\r
191 * @param fullName 村フルネーム
\r
193 public void setFullName(String fullName){
\r
194 this.fullName = fullName;
\r
202 public int getCommitHour(){
\r
203 return this.commitHour;
\r
208 * @param commitHour 更新時
\r
210 public void setCommitHour(int commitHour){
\r
211 this.commitHour = commitHour;
\r
219 public int getCommitMinute(){
\r
220 return this.commitMinute;
\r
225 * @param commitMinute 更新分
\r
227 public void setCommitMinute(int commitMinute){
\r
228 this.commitMinute = commitMinute;
\r
234 * @return 墓アイコンURI文字列
\r
236 public String getGraveIconUri(){
\r
237 if(this.graveIconUri == null){
\r
238 return this.landDef.getTombFaceIconURI().toASCIIString();
\r
240 return this.graveIconUri;
\r
244 * 墓アイコンURI文字列を設定する。
\r
245 * @param graveIconUri 墓アイコンURI文字列
\r
247 public void setGraveIconUri(String graveIconUri){
\r
248 this.graveIconUri = graveIconUri;
\r
253 * 全Periodの開示状況から総合開示状況を算出する。
\r
256 public DisclosureType getDisclosureType(){
\r
257 DisclosureType result = DisclosureType.COMPLETE;
\r
259 for(PeriodData period : this.periodList){
\r
260 DisclosureType type = period.getDisclosureType();
\r
263 return DisclosureType.HOT;
\r
265 result = DisclosureType.UNCOMPLETE;
\r
277 * @param period Periodモデル
\r
279 public void addPeriodData(PeriodData period){
\r
280 this.periodList.add(period);
\r
285 * PeriodResourcenar並びを取得する。
\r
286 * @return PeriodResource並び
\r
288 public List<PeriodResource> getPeriodResourceList(){
\r
289 return Collections.unmodifiableList(this.resourceList);
\r
293 * 未知の新規Avatarを生成する。
\r
295 * Avatarのフルネーム、短縮名、識別子が設定される。
\r
296 * @param avfullName Avatarのフルネーム
\r
297 * @return 新規Avatarモデル
\r
299 public AvatarData createAvatar(String avfullName){
\r
300 AvatarData avatar = new AvatarData();
\r
302 avatar.setFullName(avfullName);
\r
304 String[] token = avfullName.split("\\s");
\r
305 String shortName = token[token.length - 1];
\r
306 avatar.setShortName(shortName);
\r
308 String avatarId = "ukavatar" + this.undefAvatarNo;
\r
309 this.undefAvatarNo++;
\r
310 avatar.setAvatarId(avatarId);
\r
316 * AvatarフルネームからAvatarを得る。
\r
317 * まだこの村にいないAvatarならAvatar一覧に登録される。
\r
318 * @param seq Avatarフルネーム
\r
319 * @return Avatarモデル
\r
321 public AvatarData getAvatarData(CharSequence seq){
\r
322 for(AvatarData avatar : this.avatarList){
\r
323 String avfullName = avatar.getFullName();
\r
324 if(avfullName.contentEquals(seq)){
\r
329 PreDefAvatar predefAvatar =
\r
330 AvatarData.getPreDefAvatar(seq);
\r
331 if(predefAvatar != null){
\r
332 AvatarData avatar = new AvatarData(predefAvatar);
\r
333 this.avatarList.add(avatar);
\r
337 AvatarData avatar = createAvatar(seq.toString());
\r
338 this.avatarList.add(avatar);
\r
344 * avatarList要素のXML出力。
\r
345 * @param writer 出力先
\r
346 * @throws IOException 出力エラー
\r
348 public void dumpAvatarList(Writer writer) throws IOException{
\r
349 writer.append("<avatarList>").append("\n\n");
\r
351 for(AvatarData avatar : this.avatarList){
\r
352 avatar.dumpXml(writer);
\r
353 writer.append('\n');
\r
356 writer.append("</avatarList>").append('\n');
\r
363 * @param writer 出力先
\r
364 * @throws IOException 出力エラー
\r
366 public void dumpPeriodList(Writer writer) throws IOException{
\r
367 for(PeriodData period : this.periodList){
\r
368 period.dumpXml(writer);
\r
369 writer.append('\n');
\r
376 * @param writer 出力先
\r
377 * @throws IOException 出力エラー
\r
379 public void dumpXml(Writer writer) throws IOException{
\r
380 writer.append("<village\n");
\r
382 XmlUtils.indent(writer, 1);
\r
383 XmlUtils.dumpNameSpaceDecl(writer);
\r
384 writer.append('\n');
\r
386 XmlUtils.indent(writer, 1);
\r
387 XmlUtils.dumpSiNameSpaceDecl(writer);
\r
388 writer.append('\n');
\r
390 XmlUtils.indent(writer, 1);
\r
391 XmlUtils.dumpSchemeLocation(writer);
\r
392 writer.append('\n');
\r
394 XmlUtils.indent(writer, 1);
\r
395 XmlUtils.attrOut(writer, "xml:lang", "ja-JP");
\r
396 writer.append('\n');
\r
398 XmlUtils.indent(writer, 1);
\r
399 XmlUtils.attrOut(writer, "xml:base", this.baseUri);
\r
400 writer.append('\n');
\r
402 XmlUtils.indent(writer, 1);
\r
403 XmlUtils.attrOut(writer, "fullName", this.fullName);
\r
405 writer.append(' ');
\r
406 XmlUtils.attrOut(writer, "vid", Integer.toString(this.villageId));
\r
407 writer.append('\n');
\r
409 XmlUtils.indent(writer, 1);
\r
410 XmlUtils.timeAttrOut(writer,
\r
412 this.commitHour, this.commitMinute);
\r
413 writer.append('\n');
\r
415 XmlUtils.indent(writer, 1);
\r
416 XmlUtils.attrOut(writer, "state", "gameover");
\r
418 DisclosureType type = getDisclosureType();
\r
419 if(type != DisclosureType.COMPLETE){
\r
420 writer.append(' ');
\r
421 XmlUtils.attrOut(writer, "disclosure", type.getXmlName());
\r
425 if(this.landDef.isValidVillageId(this.villageId)){
\r
430 writer.append(' ');
\r
431 XmlUtils.attrOut(writer, "isValid", isValid);
\r
432 writer.append('\n');
\r
434 XmlUtils.indent(writer, 1);
\r
435 XmlUtils.attrOut(writer, "landName", this.landDef.getLandName());
\r
437 writer.append(' ');
\r
438 XmlUtils.attrOut(writer, "formalName", this.landDef.getFormalName());
\r
439 writer.append('\n');
\r
441 XmlUtils.indent(writer, 1);
\r
442 XmlUtils.attrOut(writer, "landId", this.landDef.getLandId());
\r
444 writer.append(' ');
\r
445 XmlUtils.attrOut(writer, "landPrefix", this.landDef.getLandPrefix());
\r
446 writer.append('\n');
\r
448 XmlUtils.indent(writer, 1);
\r
449 String locale = this.landDef.getLocale().toString();
\r
450 locale = locale.replaceAll("_", "-");
\r
451 XmlUtils.attrOut(writer, "locale", locale);
\r
453 writer.append(' ');
\r
454 XmlUtils.attrOut(writer,
\r
455 "origencoding", this.landDef.getEncoding().name());
\r
457 writer.append(' ');
\r
458 XmlUtils.attrOut(writer,
\r
459 "timezone", this.landDef.getTimeZone().getID());
\r
460 writer.append('\n');
\r
462 XmlUtils.indent(writer, 1);
\r
463 XmlUtils.attrOut(writer, "graveIconURI", getGraveIconUri());
\r
464 writer.append('\n');
\r
466 XmlUtils.indent(writer, 1);
\r
467 XmlUtils.attrOut(writer, "generator", JinArchiver.GENERATOR);
\r
468 writer.append('\n');
\r
470 writer.append(">").append('\n');
\r
472 writer.append('\n');
\r
473 dumpAvatarList(writer);
\r
475 writer.append('\n');
\r
476 dumpPeriodList(writer);
\r
478 writer.append("</village>").append("\n");
\r