+ /**
+ * Parses a Sone from the given input stream and updates the given Sone, or
+ * creates a new Sone.
+ *
+ * @param originalSone
+ * The Sone to update (may be {@code null})
+ * @param soneInputStream
+ * The input stream to parse the Sone from
+ * @return The parsed Sone
+ */
+ public Sone parseSone(Sone originalSone, InputStream soneInputStream) {
+ /* TODO - impose a size limit? */
+ Sone sone;
+
+ Document document;
+ /* XML parsing is not thread-safe. */
+ synchronized (this) {
+ document = XML.transformToDocument(soneInputStream);
+ }
+ if (document == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Could not parse XML for Sone %s!", new Object[] { originalSone });
+ return null;
+ }
+ SimpleXML soneXml;
+ try {
+ soneXml = SimpleXML.fromDocument(document);
+ } catch (NullPointerException npe1) {
+ /* for some reason, invalid XML can cause NPEs. */
+ logger.log(Level.WARNING, "XML for Sone " + originalSone + " can not be parsed!", npe1);
+ return null;
+ }
+
+ /* check ID. */
+ String soneId = soneXml.getValue("id", null);
+ if ((originalSone != null) && !originalSone.getId().equals(soneId)) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded ID for Sone %s (%s) does not match known ID (%s)!", new Object[] { originalSone, originalSone.getId(), soneId });
+ return null;
+ }
+
+ /* load Sone from core. */
+ sone = originalSone;
+ if (sone == null) {
+ sone = core.getSone(soneId);
+ }
+
+ String soneName = soneXml.getValue("name", null);
+ if (soneName == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded name for Sone %s was null!", new Object[] { sone });
+ return null;
+ }
+ sone.setName(soneName);
+
+ String soneTime = soneXml.getValue("time", null);
+ if (soneTime == null) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded time for Sone %s was null!", new Object[] { sone });
+ return null;
+ }
+ try {
+ sone.setTime(Long.parseLong(soneTime));
+ } catch (NumberFormatException nfe1) {
+ /* TODO - mark Sone as bad. */
+ logger.log(Level.WARNING, "Downloaded Sone %s with invalid time: %s", new Object[] { sone, soneTime });
+ return null;
+ }