1
2
3
4 package net.sourceforge.jsh3modtool.mod;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.Date;
11 import java.util.LinkedList;
12 import java.util.List;
13
14 import javax.xml.parsers.DocumentBuilderFactory;
15 import javax.xml.parsers.ParserConfigurationException;
16
17 import net.sourceforge.jsh3modtool.modpackage.ModPackage;
18
19 import org.w3c.dom.Document;
20 import org.w3c.dom.Element;
21 import org.w3c.dom.Node;
22 import org.w3c.dom.NodeList;
23 import org.xml.sax.SAXException;
24
25 /***
26 * @author redsolo
27 */
28 public class DefaultGameMod implements GameMod
29 {
30 private Document modConfiguration;
31 private String name;
32 private String version;
33 private String description;
34 private URL website;
35 private Date created;
36 private Date updated;
37 privateModPackage modPackage/package-summary.html">ong> ModPackage modPackage;
38
39 publicDefaultGameMod(ModPackage modpackage) throws IOException, MissingEntryException, InvalidConfigurationException/package-summary.html">ong> DefaultGameMod(ModPackage modpackage) throws IOException, MissingEntryException, InvalidConfigurationException
40 {
41 super();
42 modPackage = modpackage;
43 initConfiguration();
44 assertPackageEntries();
45 }
46
47 public String getName()
48 {
49 return name;
50 }
51
52 public String getVersion()
53 {
54 return version;
55 }
56
57 public String getDescription()
58 {
59 return description;
60 }
61
62 public Date getCreatedDate()
63 {
64 return created;
65 }
66
67 public Date getUpdatedDate()
68 {
69 return updated;
70 }
71
72 public URL getWebsite()
73 {
74 return website;
75 }
76
77 public List getScreenshots()
78 {
79 List screenshotsList = new LinkedList();
80 Element rootElement = modConfiguration.getDocumentElement();
81
82 NodeList screenshotsNodeList = rootElement.getElementsByTagName("screenshots");
83 if (screenshotsNodeList.getLength() > 0)
84 {
85 screenshotsNodeList = ((Element) screenshotsNodeList.item(0)).getElementsByTagName("screenshot");
86 for (int i = 0; i < screenshotsNodeList.getLength(); i++)
87 {
88 try
89 {
90 Element element = (Element) screenshotsNodeList.item(i);
91 String sourceStr = parseConfigurationValue(element, "source", true);
92 String descriptionStr = parseConfigurationValue(element, "description", false);
93 String summaryStr = parseConfigurationValue(element, "name", false);
94 screenshotsList.add( new DefaultModScreenShot(modPackage, sourceStr, descriptionStr, summaryStr) );
95 } catch (InvalidConfigurationException e)
96 {
97 ;
98 }
99 }
100 }
101 return screenshotsList;
102 }
103
104 public List getGameFiles()
105 {
106 List gameFiles = new LinkedList();
107 Element rootElement = modConfiguration.getDocumentElement();
108
109 NodeList gameFilesNodeList = rootElement.getElementsByTagName("gamefiles");
110 if (gameFilesNodeList.getLength() > 0)
111 {
112 gameFilesNodeList = ((Element) gameFilesNodeList.item(0)).getElementsByTagName("file");
113 for (int i = 0; i < gameFilesNodeList.getLength(); i++)
114 {
115 try
116 {
117 Element element = (Element) gameFilesNodeList.item(i);
118 String sourceStr = parseConfigurationValue(element, "source", false);
119 String destStr = parseConfigurationValue(element, "dest", false);
120 gameFiles.add( new DefaultModGameFile(modPackage, sourceStr, destStr) );
121 } catch (InvalidConfigurationException e)
122 {
123 ;
124 }
125 }
126 }
127 return gameFiles;
128 }
129
130 public List getAuthors()
131 {
132 List authors = new LinkedList();
133 Element rootElement = modConfiguration.getDocumentElement();
134
135 NodeList authorsNodeList = rootElement.getElementsByTagName("authors");
136 if (authorsNodeList.getLength() > 0)
137 {
138 authorsNodeList = ((Element) authorsNodeList.item(0)).getElementsByTagName("author");
139 for (int i = 0; i < authorsNodeList.getLength(); i++)
140 {
141 try
142 {
143 Element element = (Element) authorsNodeList.item(i);
144 String aliasStr = parseConfigurationValue(element, "alias", false);
145 String nameStr = parseConfigurationValue(element, "name", false);
146 String emailStr = parseConfigurationValue(element, "email", false);
147 URL authorWebsite = parseURL(parseConfigurationValue(element, "website", false));
148
149 authors.add( new DefaultModAuthor(aliasStr, nameStr, emailStr, authorWebsite) );
150 } catch (MalformedURLException e)
151 {
152 } catch (InvalidConfigurationException e)
153 {
154 ;
155 }
156 }
157 }
158 return authors;
159 }
160
161 /***
162 * Initializes the configuration.
163 * @throws IOException thrown if there was problem reading from the mod pacakge.
164 * @throws InvalidConfigurationException thrown if the configurataion is invalid.
165 */
166 private void initConfiguration() throws IOException, InvalidConfigurationException
167 {
168 InputStream confStream = modPackage.getEntry("/gamemod.xml");
169
170 try
171 {
172 modConfiguration = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(confStream);
173 Element rootElement = modConfiguration.getDocumentElement();
174
175 name = parseConfigurationValue(rootElement, "name", true);
176 description = parseConfigurationValue(rootElement, "description", true);
177
178 version = parseConfigurationValue(rootElement, "version", false);
179 website = parseURL(parseConfigurationValue(rootElement, "website", false));
180
181 String createdStr = parseConfigurationValue(rootElement, "created", false);
182 if (createdStr != null)
183 {
184 created = new Date(Long.valueOf(createdStr).longValue());
185 }
186 String updatedStr = parseConfigurationValue(rootElement, "updated", false);
187 if (updatedStr != null)
188 {
189 updated = new Date(Long.valueOf(updatedStr).longValue());
190 }
191
192 } catch (SAXException saxe)
193 {
194 throw new InvalidConfigurationException("The xml is not valid.", saxe);
195 } catch (ParserConfigurationException pce)
196 {
197 throw new InvalidConfigurationException("Problem reading the xml.", pce);
198 }
199 }
200
201 /***
202 * @param urlStr
203 * @throws MalformedURLException
204 */
205 private URL parseURL(String urlStr) throws MalformedURLException
206 {
207 URL url = null;
208 if (urlStr != null)
209 {
210 try
211 {
212 url = new URL(urlStr);
213 } catch (MalformedURLException mue)
214 {
215 url = new URL("http://" + urlStr);
216 }
217 }
218 return url;
219 }
220
221 /***
222 * Parses and returns a specified value.
223 * @param rootElement the XML element
224 * @param valueName the configuration value to look for.
225 * @param isRequired if the value isnt found, then a exception will be thrown if it is required.
226 * @return the value; null if it wasnt found.
227 * @throws InvalidConfigurationException
228 */
229 private String parseConfigurationValue(Element rootElement, String valueName, boolean isRequired) throws InvalidConfigurationException
230 {
231 String value = null;
232 NodeList nodeList;
233 nodeList = rootElement.getElementsByTagName(valueName);
234 if (nodeList.getLength() > 0)
235 {
236 value = getTextContent( (Element) nodeList.item(0) );
237 } else
238 {
239 if (isRequired)
240 {
241 throw new InvalidConfigurationException("'" + valueName + "' element is required");
242 }
243 }
244 return value;
245 }
246
247 private String getTextContent(Element element)
248 {
249 String text = null;
250 Node firstChild = element.getFirstChild();
251 if ( firstChild != null)
252 {
253 text = firstChild.getNodeValue();
254 }
255 return text;
256 }
257
258 /***
259 * Asserts that all source entries in the node list exists in the mod package.
260 * @param nodeList the root element
261 * @param nodeName the name of the nodes to check.
262 * @param tagName the tag that should be asserted that exists in the xml.
263 * @throws MissingEntryException thrown if an entry is specified but does not exists in the package.
264 * @throws InvalidConfigurationException thrown if an entry does not exists.
265 */
266 private void assertEntries(Element element, String nodeName, String tagName, boolean isEntry) throws MissingEntryException, InvalidConfigurationException
267 {
268 Node child = element.getFirstChild();
269 while (child != null)
270 {
271 if ((child.getNodeName().equals(nodeName))
272 && (child.getNodeType() == Node.ELEMENT_NODE))
273 {
274 NodeList sourceList = ((Element) child).getElementsByTagName(tagName);
275 if (sourceList.getLength() == 0)
276 {
277 throw new InvalidConfigurationException("Entry element '" + nodeName + "' does not contain the '" + tagName + "' element");
278 } else
279 {
280 if (isEntry)
281 {
282 String entryName = getTextContent((Element) sourceList.item(0));
283 if (!modPackage.entryExists(entryName))
284 {
285 throw new MissingEntryException(entryName);
286 }
287 }
288 }
289 }
290 child = child.getNextSibling();
291 }
292 }
293
294 /***
295 * Asserts that all file entries in the mod package exists.
296 * @throws MissingEntryException thrown if any entry is missing in the mod package.
297 * @throws InvalidConfigurationException thrown if the configuration is not valid.
298 */
299 private void assertPackageEntries() throws MissingEntryException, InvalidConfigurationException
300 {
301 Element rootElement = modConfiguration.getDocumentElement();
302
303 NodeList nodeList = rootElement.getElementsByTagName("screenshots");
304 if (nodeList.getLength() > 0)
305 {
306 Element screenshotsElement = (Element) nodeList.item(0);
307 assertEntries(screenshotsElement, "screenshot", "source", true);
308 }
309
310 nodeList = rootElement.getElementsByTagName("gamefiles");
311 if (nodeList.getLength() > 0)
312 {
313 Element gamefilesElement = (Element) nodeList.item(0);
314 assertEntries(gamefilesElement, "file", "source", true);
315 assertEntries(gamefilesElement, "file", "dest", false);
316 } else
317 {
318 throw new InvalidConfigurationException("The element 'gamefiles' does not exist.");
319 }
320 }
321 }