View Javadoc
1   /*
2    * Created on 2005-may-13
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                      ; // Will never happen
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                     ; // Will never happen
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                     ; // Will never happen
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 }