1 package cz.cuni.amis.pogamut.ut2004.storyworld.place;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileReader;
6 import java.io.IOException;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import com.thoughtworks.xstream.XStream;
12 import com.thoughtworks.xstream.annotations.XStreamAlias;
13 import com.thoughtworks.xstream.annotations.XStreamOmitField;
14 import com.thoughtworks.xstream.io.xml.DomDriver;
15
16 import cz.cuni.amis.utils.collections.MyCollections;
17 import cz.cuni.amis.utils.token.Token;
18 import cz.cuni.amis.utils.token.Tokens;
19
20 @XStreamAlias("storyworld")
21 public class SPStoryWorldData {
22
23 @XStreamAlias("places")
24 private List<SPStoryPlace> places;
25
26 @XStreamAlias("bases")
27 private List<SPStoryPlaceBase> bases;
28
29 @XStreamOmitField
30 private Map<Token, SPStoryPlace> placesMap;
31
32 @XStreamOmitField
33 private Map<Token, SPStoryPlaceBase> basesMap;
34
35 @XStreamOmitField
36 private String file = "<generated in code>";
37
38 public SPStoryWorldData() {
39 }
40
41 public static SPStoryWorldData loadXML(File xmlFile) throws FileNotFoundException {
42
43
44 FileReader reader = new FileReader(xmlFile);
45 XStream xstream = new XStream(new DomDriver());
46 xstream.autodetectAnnotations(true);
47 xstream.alias(SPStoryWorldData.class.getAnnotation(XStreamAlias.class).value(), SPStoryWorldData.class);
48 Object obj = xstream.fromXML(reader);
49 try {
50 reader.close();
51 } catch (IOException e) {
52 }
53 if (!(obj instanceof SPStoryWorldData)) throw new RuntimeException("file " + xmlFile.getAbsolutePath() + " doesn't contain a xml with SPStoryWorldData");
54 SPStoryWorldData data = (SPStoryWorldData) obj;
55 data.file = xmlFile.getAbsolutePath();
56 return data;
57 }
58
59 public SPStoryWorldData(SPStoryPlace[] places, SPStoryPlaceBase[] bases) {
60 this.places = MyCollections.asList(places);
61 this.bases = MyCollections.asList(bases);
62 readResolve();
63 }
64
65
66
67
68
69 private SPStoryWorldData readResolve() {
70 placesMap = new HashMap<Token, SPStoryPlace>();
71 basesMap = new HashMap<Token, SPStoryPlaceBase>();
72 for (SPStoryPlace place : places) {
73 placesMap.put(place.getName(), place);
74 }
75 for (SPStoryPlaceBase base : bases) {
76 basesMap.put(base.getName(), base);
77 }
78 for (SPStoryPlace place : places) {
79 if (place.getInsidePlaceName() == null) continue;
80 SPStoryPlace inside = placesMap.get(Tokens.get(place.getInsidePlaceName()));
81 if (inside == null) {
82 String notice = basesMap.get(Tokens.get(place.getInsidePlaceName())) != null ? " Notice that provided name points to the /base/ not /place/, but /base/ places can't contain any other places!" : "";
83 throw new RuntimeException("story place '" + place.getName().getToken() + "' reference unknown place '" + place.getInsidePlaceName() + "'" + notice);
84 }
85 place.setInsidePlace(inside);
86 }
87 for (SPStoryPlaceBase base : bases) {
88 basesMap.put(base.getName(), base);
89 }
90 for (SPStoryPlaceBase base : bases) {
91 if (base.getInsidePlaceName() == null) continue;
92 SPStoryPlace inside = placesMap.get(Tokens.get(base.getInsidePlaceName()));
93 if (inside == null) {
94 String notice = basesMap.get(Tokens.get(base.getInsidePlaceName())) != null ? " Notice that provided name points to the /base/ not /place/, but /base/ places can't contain any other places!" : "";
95 throw new RuntimeException("story place '" + base.getName().getToken() + "' reference unknown place '" + base.getInsidePlaceName() + "'" + notice);
96 }
97 base.setInsidePlace(inside);
98 }
99 return this;
100 }
101
102 public Map<Token,SPStoryPlace> getPlaces() {
103 return placesMap;
104 }
105
106 public Map<Token, SPStoryPlaceBase> getBases() {
107 return basesMap;
108 }
109
110 public String getFile() {
111 return file;
112 }
113
114 @Override
115 public String toString() {
116 return "SPStoryWorldData[places=" + places.size() + ", bases=" + bases.size() + "]";
117 }
118
119 }