Merge branch 'disruptive-notification' into next
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 27 Feb 2016 09:55:01 +0000 (10:55 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 27 Feb 2016 09:55:01 +0000 (10:55 +0100)
pom.xml
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/UpdateChecker.java
src/main/java/net/pterodactylus/sone/core/event/UpdateFoundEvent.java
src/main/java/net/pterodactylus/sone/main/SonePlugin.java
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/main/resources/i18n/sone.en.properties
src/main/resources/templates/notify/newVersionNotification.html
src/test/java/net/pterodactylus/sone/core/UpdateCheckerTest.java

diff --git a/pom.xml b/pom.xml
index 2ca12c0..72dd184 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                                <artifactId>maven-assembly-plugin</artifactId>
                                <version>2.2-beta-5</version>
                                <configuration>
+                                       <finalName>sone</finalName>
                                        <descriptorRefs>
                                                <descriptorRef>jar-with-dependencies</descriptorRef>
                                        </descriptorRefs>
                        <plugin>
                                <groupId>org.jacoco</groupId>
                                <artifactId>jacoco-maven-plugin</artifactId>
-                               <version>0.7.1.201405082137</version>
+                               <version>0.7.6.201602180812</version>
                                <executions>
                                        <execution>
                                                <id>default-prepare-agent</id>
index 99a5654..5a95810 100644 (file)
@@ -204,14 +204,14 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         *            The database
         */
        @Inject
-       public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database) {
+       public Core(Configuration configuration, FreenetInterface freenetInterface, IdentityManager identityManager, UpdateChecker updateChecker, WebOfTrustUpdater webOfTrustUpdater, EventBus eventBus, Database database) {
                super("Sone Core");
                this.configuration = configuration;
                this.freenetInterface = freenetInterface;
                this.identityManager = identityManager;
                this.soneDownloader = new SoneDownloaderImpl(this, freenetInterface);
                this.imageInserter = new ImageInserter(freenetInterface, freenetInterface.new InsertTokenSupplier());
-               this.updateChecker = new UpdateChecker(eventBus, freenetInterface);
+               this.updateChecker = updateChecker;
                this.webOfTrustUpdater = webOfTrustUpdater;
                this.eventBus = eventBus;
                this.database = database;
index 146383a..2fba40b 100644 (file)
@@ -28,6 +28,8 @@ import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.inject.Singleton;
+
 import net.pterodactylus.sone.core.FreenetInterface.Fetched;
 import net.pterodactylus.sone.core.event.UpdateFoundEvent;
 import net.pterodactylus.sone.main.SonePlugin;
@@ -45,6 +47,7 @@ import freenet.support.api.Bucket;
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
+@Singleton
 public class UpdateChecker {
 
        /** The logger. */
@@ -63,7 +66,8 @@ public class UpdateChecker {
        private long latestEdition;
 
        /** The current latest known version. */
-       private Version currentLatestVersion = SonePlugin.VERSION;
+       private Version currentLatestVersion;
+       private final Version currentRunningVersion;
 
        /** The release date of the latest version. */
        private long latestVersionDate;
@@ -77,9 +81,11 @@ public class UpdateChecker {
         *            The freenet interface to use
         */
        @Inject
-       public UpdateChecker(EventBus eventBus, FreenetInterface freenetInterface) {
+       public UpdateChecker(EventBus eventBus, FreenetInterface freenetInterface, Version currentVersion) {
                this.eventBus = eventBus;
                this.freenetInterface = freenetInterface;
+               this.currentRunningVersion = currentVersion;
+               this.currentLatestVersion = currentVersion;
        }
 
        //
@@ -93,7 +99,7 @@ public class UpdateChecker {
         * @return {@code true} if a new version was found
         */
        public boolean hasLatestVersion() {
-               return currentLatestVersion.compareTo(SonePlugin.VERSION) > 0;
+               return currentLatestVersion.compareTo(currentRunningVersion) > 0;
        }
 
        /**
@@ -218,9 +224,22 @@ public class UpdateChecker {
                if (version.compareTo(currentLatestVersion) > 0) {
                        currentLatestVersion = version;
                        latestVersionDate = releaseTime;
-                       logger.log(Level.INFO, String.format("Found new version: %s (%tc)", version, new Date(releaseTime)));
-                       eventBus.post(new UpdateFoundEvent(version, releaseTime, edition));
+                       boolean disruptive = disruptiveVersionBetweenCurrentAndFound(properties);
+                       logger.log(Level.INFO, String.format("Found new version: %s (%tc%s)", version, new Date(releaseTime), disruptive ? ", disruptive" : ""));
+                       eventBus.post(new UpdateFoundEvent(version, releaseTime, edition, disruptive));
+               }
+       }
+
+       private boolean disruptiveVersionBetweenCurrentAndFound(Properties properties) {
+               for (String key : properties.stringPropertyNames()) {
+                       if (key.startsWith("DisruptiveVersion/")) {
+                               Version disruptiveVersion = Version.parse(key.substring("DisruptiveVersion/".length()));
+                               if (disruptiveVersion.compareTo(currentRunningVersion) > 0) {
+                                       return true;
+                               }
+                       }
                }
+               return false;
        }
 
 }
index e8cb8e5..85e4d25 100644 (file)
@@ -26,61 +26,32 @@ import net.pterodactylus.util.version.Version;
  */
 public class UpdateFoundEvent {
 
-       /** The version that was found. */
        private final Version version;
-
-       /** The time the update was released. */
        private final long releaseTime;
-
-       /** The latest edition of the update page. */
        private final long latestEdition;
+       private final boolean disruptive;
 
-       /**
-        * Creates a new “update found” event.
-        *
-        * @param version
-        *            The version of the update
-        * @param releaseTime
-        *            The release time of the update
-        * @param latestEdition
-        *            The latest edition of the update page
-        */
-       public UpdateFoundEvent(Version version, long releaseTime, long latestEdition) {
+       public UpdateFoundEvent(Version version, long releaseTime, long latestEdition, boolean disruptive) {
                this.version = version;
                this.releaseTime = releaseTime;
                this.latestEdition = latestEdition;
+               this.disruptive = disruptive;
        }
 
-       //
-       // ACCESSORS
-       //
-
-       /**
-        * Returns the version of the update.
-        *
-        * @return The version of the update
-        */
        public Version version() {
                return version;
        }
 
-       /**
-        * Returns the release time of the update.
-        *
-        * @return The releae time of the update (in milliseconds since Jan 1, 1970
-        *         UTC)
-        */
        public long releaseTime() {
                return releaseTime;
        }
 
-       /**
-        * Returns the latest edition of the update page.
-        *
-        * @return The latest edition of the update page
-        */
        public long latestEdition() {
                return latestEdition;
        }
 
+       public boolean disruptive() {
+               return disruptive;
+       }
+
 }
index 828d1af..53a942d 100644 (file)
@@ -250,6 +250,7 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
                                bind(Context.class).toInstance(context);
                                bind(getOptionalContextTypeLiteral()).toInstance(of(context));
                                bind(SonePlugin.class).toInstance(SonePlugin.this);
+                               bind(Version.class).toInstance(VERSION);
                                if (startConfiguration.getBooleanValue("Developer.LoadFromFilesystem").getValue(false)) {
                                        String path = startConfiguration.getStringValue("Developer.FilesystemPath").getValue(null);
                                        if (path != null) {
index 4da2177..4b4ac88 100644 (file)
@@ -1019,9 +1019,10 @@ public class WebInterface {
         */
        @Subscribe
        public void updateFound(UpdateFoundEvent updateFoundEvent) {
-               newVersionNotification.getTemplateContext().set("latestVersion", updateFoundEvent.version());
-               newVersionNotification.getTemplateContext().set("latestEdition", updateFoundEvent.latestEdition());
-               newVersionNotification.getTemplateContext().set("releaseTime", updateFoundEvent.releaseTime());
+               newVersionNotification.set("latestVersion", updateFoundEvent.version());
+               newVersionNotification.set("latestEdition", updateFoundEvent.latestEdition());
+               newVersionNotification.set("releaseTime", updateFoundEvent.releaseTime());
+               newVersionNotification.set("disruptive", updateFoundEvent.disruptive());
                notificationManager.addNotification(newVersionNotification);
        }
 
index 40a12b1..ae57376 100644 (file)
@@ -455,6 +455,7 @@ Notification.SoneRescued.Text=The following Sones have been rescued:
 Notification.SoneRescued.Text.RememberToUnlock=Please remember to control the posts and replies you have given and don’t forget to unlock your Sones!
 Notification.LockedSones.Text=The following Sones have been locked for more than 5 minutes. Please check if you really want to keep these Sones locked:
 Notification.NewVersion.Text=Version {version} of the Sone plugin was found. Download it from USK@nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI,DuQSUZiI~agF8c-6tjsFFGuZ8eICrzWCILB60nT8KKo,AQACAAE/sone/{edition}​!
+Notification.NewVersion.Disruptive.Text=It is {em}highly recommended{/em} that you update to this version as it may be possible that you are missing a lot of content with your current version!
 Notification.InsertingImages.Text=The following images are being inserted:
 Notification.InsertedImages.Text=The following images have been inserted:
 Notification.ImageInsertFailed.Text=The following images could not be inserted:
index 599a7e6..f35ecaf 100644 (file)
@@ -1 +1,4 @@
 <div class="text"><%= Notification.NewVersion.Text|l10n|replace needle=="{version}" replacement=latestVersion|replace needle=="{edition}" replacement=latestEdition|parse sone=="nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI"></div>
+<%if disruptive>
+       <div class="text"><%= Notification.NewVersion.Disruptive.Text|l10n|html|replace needle=="{em}" replacement=="<em>"|replace needle=="{/em}" replacement=="</em>"></div>
+<%/if>
index a5e3b2a..44819ee 100644 (file)
@@ -1,7 +1,6 @@
 package net.pterodactylus.sone.core;
 
 import static java.lang.Long.MAX_VALUE;
-import static net.pterodactylus.sone.main.SonePlugin.VERSION;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
@@ -44,7 +43,8 @@ public class UpdateCheckerTest {
 
        private final EventBus eventBus = mock(EventBus.class);
        private final FreenetInterface freenetInterface = mock(FreenetInterface.class);
-       private final UpdateChecker updateChecker = new UpdateChecker(eventBus, freenetInterface);
+       private final Version currentVersion = new Version(1, 0, 0);
+       private final UpdateChecker updateChecker = new UpdateChecker(eventBus, freenetInterface, currentVersion);
 
        @Before
        public void startUpdateChecker() {
@@ -54,7 +54,7 @@ public class UpdateCheckerTest {
        @Test
        public void newUpdateCheckerDoesNotHaveALatestVersion() {
                assertThat(updateChecker.hasLatestVersion(), is(false));
-               assertThat(updateChecker.getLatestVersion(), is(VERSION));
+               assertThat(updateChecker.getLatestVersion(), is(currentVersion));
        }
 
        @Test
@@ -87,23 +87,33 @@ public class UpdateCheckerTest {
                setupFetchResult(createFutureFetchResult());
                setupCallbackWithEdition(MAX_VALUE, true, false);
                verifyAFreenetUriIsFetched();
-               ArgumentCaptor<UpdateFoundEvent> updateFoundEvent = forClass(UpdateFoundEvent.class);
-               verify(eventBus, times(1)).post(updateFoundEvent.capture());
-               assertThat(updateFoundEvent.getValue().version(), is(new Version(99, 0, 0)));
-               assertThat(updateFoundEvent.getValue().releaseTime(), is(11865368297000L));
-               assertThat(updateChecker.getLatestVersion(), is(new Version(99, 0, 0)));
-               assertThat(updateChecker.getLatestVersionDate(), is(11865368297000L));
-               assertThat(updateChecker.hasLatestVersion(), is(true));
+               verifyEventIsFired(new Version(99, 0, 0), 11865368297000L, false);
+               verifyThatUpdateCheckerKnowsLatestVersion(new Version(99, 0, 0), 11865368297000L);
        }
 
        private FetchResult createFutureFetchResult() {
                ClientMetadata clientMetadata = new ClientMetadata("application/xml");
                Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
                                "CurrentVersion/Version: 99.0.0\n" +
-                               "CurrentVersion/ReleaseTime: 11865368297000").getBytes());
+                               "CurrentVersion/ReleaseTime: 11865368297000\n" +
+                               "DisruptiveVersion/0.1.2: true").getBytes());
                return new FetchResult(clientMetadata, fetched);
        }
 
+       private void verifyEventIsFired(Version version, long releaseTime, boolean disruptive) {
+               ArgumentCaptor<UpdateFoundEvent> updateFoundEvent = forClass(UpdateFoundEvent.class);
+               verify(eventBus, times(1)).post(updateFoundEvent.capture());
+               assertThat(updateFoundEvent.getValue().version(), is(version));
+               assertThat(updateFoundEvent.getValue().releaseTime(), is(releaseTime));
+               assertThat(updateFoundEvent.getValue().disruptive(), is(disruptive));
+       }
+
+       private void verifyThatUpdateCheckerKnowsLatestVersion(Version version, long releaseTime) {
+               assertThat(updateChecker.getLatestVersion(), is(version));
+               assertThat(updateChecker.getLatestVersionDate(), is(releaseTime));
+               assertThat(updateChecker.hasLatestVersion(), is(true));
+       }
+
        @Test
        public void callbackDoesNotStartIfNoNewEditionIsFound() {
                setupFetchResult(createPastFetchResult());
@@ -230,4 +240,22 @@ public class UpdateCheckerTest {
                return new FetchResult(clientMetadata, fetched);
        }
 
+       @Test
+       public void disruptiveVersionGetsNotification() {
+               setupFetchResult(createDisruptiveVersionFetchResult());
+               setupCallbackWithEdition(MAX_VALUE, true, false);
+               verifyAFreenetUriIsFetched();
+               verifyEventIsFired(new Version(1, 2, 3), 1289417883000L, true);
+               verifyThatUpdateCheckerKnowsLatestVersion(new Version(1, 2, 3), 1289417883000L);
+       }
+
+       private FetchResult createDisruptiveVersionFetchResult() {
+               ClientMetadata clientMetadata = new ClientMetadata("application/xml");
+               Bucket fetched = new ArrayBucket(("# MapConfigurationBackendVersion=1\n" +
+                               "CurrentVersion/Version: 1.2.3\n" +
+                               "CurrentVersion/ReleaseTime: 1289417883000\n" +
+                               "DisruptiveVersion/1.2.3: true").getBytes());
+               return new FetchResult(clientMetadata, fetched);
+       }
+
 }