Make the update time of a Sone final, set it in the Sone builder.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 7 Dec 2014 00:27:53 +0000 (01:27 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 7 Dec 2014 00:27:53 +0000 (01:27 +0100)
src/main/java/net/pterodactylus/sone/core/SoneParser.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractSoneBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java
src/main/java/net/pterodactylus/sone/database/SoneBuilder.java
src/main/java/net/pterodactylus/sone/database/memory/MemorySoneBuilder.java
src/test/java/net/pterodactylus/sone/data/impl/AbstractSoneBuilderTest.java

index 5851b18..6983d25 100644 (file)
@@ -62,14 +62,13 @@ public class SoneParser {
                if (originalSone.isLocal()) {
                        soneBuilder = soneBuilder.local();
                }
-               Sone sone = soneBuilder.build();
 
                SimpleXML soneXml;
                try {
                        soneXml = SimpleXML.fromDocument(document);
                } catch (NullPointerException npe1) {
                        /* for some reason, invalid XML can cause NPEs. */
-                       logger.log(Level.WARNING, String.format("XML for Sone %s can not be parsed!", sone), npe1);
+                       logger.log(Level.WARNING, String.format("XML for Sone %s can not be parsed!", originalSone), npe1);
                        return null;
                }
 
@@ -97,16 +96,17 @@ public class SoneParser {
                String soneTime = soneXml.getValue("time", null);
                if (soneTime == null) {
                        /* TODO - mark Sone as bad. */
-                       logger.log(Level.WARNING, String.format("Downloaded time for Sone %s was null!", sone));
+                       logger.log(Level.WARNING, String.format("Downloaded time for Sone %s was null!", originalSone));
                        return null;
                }
                try {
-                       sone.setTime(Long.parseLong(soneTime));
+                       soneBuilder.lastUpdated(Long.parseLong(soneTime));
                } catch (NumberFormatException nfe1) {
                        /* TODO - mark Sone as bad. */
-                       logger.log(Level.WARNING, String.format("Downloaded Sone %s with invalid time: %s", sone, soneTime));
+                       logger.log(Level.WARNING, String.format("Downloaded Sone %s with invalid time: %s", originalSone, soneTime));
                        return null;
                }
+               Sone sone = soneBuilder.build();
 
                SimpleXML clientXml = soneXml.getNode("client");
                if (clientXml != null) {
index a214677..b7dda3f 100644 (file)
@@ -15,6 +15,7 @@ public abstract class AbstractSoneBuilder implements SoneBuilder {
 
        protected Identity identity;
        protected boolean local;
+       protected long lastUpdated;
 
        @Override
        public SoneBuilder from(Identity identity) {
@@ -28,10 +29,17 @@ public abstract class AbstractSoneBuilder implements SoneBuilder {
                return this;
        }
 
+       @Override
+       public SoneBuilder lastUpdated(long lastUpdated) {
+               this.lastUpdated = lastUpdated;
+               return this;
+       }
+
        protected void validate() throws IllegalStateException {
                checkState(identity != null, "identity must not be null");
                checkState(!local || (identity instanceof OwnIdentity),
                                "can not create local Sone from remote identity");
+               checkState(lastUpdated > 0, "last update time must be set");
        }
 
 }
index 551e229..9b46988 100644 (file)
@@ -78,7 +78,7 @@ public class SoneImpl implements LocalSone {
        private volatile long latestEdition;
 
        /** The time of the last inserted update. */
-       private volatile long time;
+       private final long time;
 
        /** The status of this Sone. */
        private volatile SoneStatus status = SoneStatus.unknown;
@@ -119,11 +119,12 @@ public class SoneImpl implements LocalSone {
         * @param local
         *              {@code true} if the Sone is a local Sone, {@code false} otherwise
         */
-       public SoneImpl(Database database, Identity identity, boolean local) {
+       public SoneImpl(Database database, Identity identity, boolean local, long time) {
                this.database = database;
                this.id = identity.getId();
                this.identity = identity;
                this.local = local;
+               this.time = time;
        }
 
        //
@@ -246,7 +247,6 @@ public class SoneImpl implements LocalSone {
         * @return This Sone (for method chaining)
         */
        public Sone setTime(long time) {
-               this.time = time;
                return this;
        }
 
index d2047af..5ad9bcc 100644 (file)
@@ -13,6 +13,8 @@ public interface SoneBuilder {
        SoneBuilder from(Identity identity);
        SoneBuilder local();
 
+       SoneBuilder lastUpdated(long lastUpdated);
+
        Sone build() throws IllegalStateException;
 
 }
index 49531a1..7c135ce 100644 (file)
@@ -21,7 +21,7 @@ public class MemorySoneBuilder extends AbstractSoneBuilder {
        @Override
        public Sone build() throws IllegalStateException {
                validate();
-               return new SoneImpl(database, identity, local);
+               return new SoneImpl(database, identity, local, lastUpdated);
        }
 
 }
index 6bd40b6..9b64b6a 100644 (file)
@@ -26,29 +26,41 @@ public class AbstractSoneBuilderTest {
        @Test
        public void localSoneIsValidated() {
                Identity ownIdentity = mock(OwnIdentity.class);
-               soneBuilder.local().from(ownIdentity).build();
+               soneBuilder.local().from(ownIdentity).lastUpdated(1).build();
        }
 
        @Test(expected = IllegalStateException.class)
        public void localSoneIsNotValidatedIfIdentityIsNotAnOwnIdentity() {
                Identity identity = mock(Identity.class);
-               soneBuilder.local().from(identity).build();
+               soneBuilder.local().from(identity).lastUpdated(1).build();
        }
 
        @Test(expected = IllegalStateException.class)
        public void localSoneIsNotValidatedIfIdentityIsNull() {
-               soneBuilder.local().build();
+               soneBuilder.local().lastUpdated(1).build();
        }
 
        @Test
        public void remoteSoneIsValidated() {
                Identity identity = mock(Identity.class);
-               soneBuilder.from(identity).build();
+               soneBuilder.from(identity).lastUpdated(1).build();
        }
 
        @Test(expected = IllegalStateException.class)
        public void remoteSoneIsNotValidatedIfIdentityIsNull() {
-               soneBuilder.build();
+               soneBuilder.lastUpdated(1).build();
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void localSoneIsNotValidatedWithoutUpdateTime() {
+               Identity identity = mock(OwnIdentity.class);
+               soneBuilder.from(identity).local().build();
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void remoteSoneIsNotValidatedWithoutUpdateTime() {
+               Identity identity = mock(Identity.class);
+               soneBuilder.from(identity).build();
        }
 
 }