View Javadoc

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  	 * Used by XStream after deserialization.
67  	 * @return
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 }