Merge branch 'release-0.9.4' 0.9.4
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 27 Nov 2015 06:17:53 +0000 (07:17 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 27 Nov 2015 06:17:53 +0000 (07:17 +0100)
278 files changed:
pom.xml
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/FreenetInterface.java
src/main/java/net/pterodactylus/sone/core/ImageInserter.java
src/main/java/net/pterodactylus/sone/core/Options.java
src/main/java/net/pterodactylus/sone/core/Preferences.java
src/main/java/net/pterodactylus/sone/core/SoneDownloaderImpl.java
src/main/java/net/pterodactylus/sone/core/SoneException.java
src/main/java/net/pterodactylus/sone/core/SoneInsertException.java
src/main/java/net/pterodactylus/sone/core/SoneInserter.java
src/main/java/net/pterodactylus/sone/core/SoneParser.java
src/main/java/net/pterodactylus/sone/core/SoneRescuer.java
src/main/java/net/pterodactylus/sone/core/SoneUri.java
src/main/java/net/pterodactylus/sone/core/UpdateChecker.java
src/main/java/net/pterodactylus/sone/core/WebOfTrustUpdaterImpl.java
src/main/java/net/pterodactylus/sone/core/event/ImageEvent.java
src/main/java/net/pterodactylus/sone/core/event/ImageInsertAbortedEvent.java
src/main/java/net/pterodactylus/sone/core/event/ImageInsertFailedEvent.java
src/main/java/net/pterodactylus/sone/core/event/ImageInsertFinishedEvent.java
src/main/java/net/pterodactylus/sone/core/event/ImageInsertStartedEvent.java
src/main/java/net/pterodactylus/sone/core/event/MarkPostKnownEvent.java
src/main/java/net/pterodactylus/sone/core/event/MarkPostReplyKnownEvent.java
src/main/java/net/pterodactylus/sone/core/event/MarkSoneKnownEvent.java
src/main/java/net/pterodactylus/sone/core/event/NewPostFoundEvent.java
src/main/java/net/pterodactylus/sone/core/event/NewPostReplyFoundEvent.java
src/main/java/net/pterodactylus/sone/core/event/NewSoneFoundEvent.java
src/main/java/net/pterodactylus/sone/core/event/PostEvent.java
src/main/java/net/pterodactylus/sone/core/event/PostRemovedEvent.java
src/main/java/net/pterodactylus/sone/core/event/PostReplyEvent.java
src/main/java/net/pterodactylus/sone/core/event/PostReplyRemovedEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneInsertAbortedEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneInsertedEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneInsertingEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneLockedEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneRemovedEvent.java
src/main/java/net/pterodactylus/sone/core/event/SoneUnlockedEvent.java
src/main/java/net/pterodactylus/sone/core/event/UpdateFoundEvent.java
src/main/java/net/pterodactylus/sone/data/Album.java
src/main/java/net/pterodactylus/sone/data/Client.java
src/main/java/net/pterodactylus/sone/data/Fingerprintable.java
src/main/java/net/pterodactylus/sone/data/Identified.java
src/main/java/net/pterodactylus/sone/data/Image.java
src/main/java/net/pterodactylus/sone/data/Post.java
src/main/java/net/pterodactylus/sone/data/PostReply.java
src/main/java/net/pterodactylus/sone/data/Profile.java
src/main/java/net/pterodactylus/sone/data/Reply.java
src/main/java/net/pterodactylus/sone/data/Sone.java
src/main/java/net/pterodactylus/sone/data/TemporaryImage.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractAlbumBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractImageBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractPostBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractPostReplyBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/AbstractReplyBuilder.java
src/main/java/net/pterodactylus/sone/data/impl/AlbumBuilderImpl.java
src/main/java/net/pterodactylus/sone/data/impl/AlbumImpl.java
src/main/java/net/pterodactylus/sone/data/impl/DefaultPostBuilderFactory.java
src/main/java/net/pterodactylus/sone/data/impl/DefaultPostReplyBuilderFactory.java
src/main/java/net/pterodactylus/sone/data/impl/ImageBuilderImpl.java
src/main/java/net/pterodactylus/sone/data/impl/ImageImpl.java
src/main/java/net/pterodactylus/sone/data/impl/PostBuilderImpl.java
src/main/java/net/pterodactylus/sone/data/impl/PostImpl.java
src/main/java/net/pterodactylus/sone/data/impl/PostReplyBuilderImpl.java
src/main/java/net/pterodactylus/sone/data/impl/PostReplyImpl.java
src/main/java/net/pterodactylus/sone/data/impl/ReplyImpl.java
src/main/java/net/pterodactylus/sone/data/impl/SoneImpl.java
src/main/java/net/pterodactylus/sone/database/AlbumBuilder.java
src/main/java/net/pterodactylus/sone/database/AlbumBuilderFactory.java
src/main/java/net/pterodactylus/sone/database/AlbumDatabase.java
src/main/java/net/pterodactylus/sone/database/AlbumProvider.java
src/main/java/net/pterodactylus/sone/database/AlbumStore.java
src/main/java/net/pterodactylus/sone/database/Database.java
src/main/java/net/pterodactylus/sone/database/DatabaseException.java
src/main/java/net/pterodactylus/sone/database/ImageBuilder.java
src/main/java/net/pterodactylus/sone/database/ImageBuilderFactory.java
src/main/java/net/pterodactylus/sone/database/ImageDatabase.java
src/main/java/net/pterodactylus/sone/database/ImageProvider.java
src/main/java/net/pterodactylus/sone/database/ImageStore.java
src/main/java/net/pterodactylus/sone/database/PostBuilder.java
src/main/java/net/pterodactylus/sone/database/PostBuilderFactory.java
src/main/java/net/pterodactylus/sone/database/PostDatabase.java
src/main/java/net/pterodactylus/sone/database/PostProvider.java
src/main/java/net/pterodactylus/sone/database/PostReplyBuilder.java
src/main/java/net/pterodactylus/sone/database/PostReplyBuilderFactory.java
src/main/java/net/pterodactylus/sone/database/PostReplyDatabase.java
src/main/java/net/pterodactylus/sone/database/PostReplyProvider.java
src/main/java/net/pterodactylus/sone/database/PostReplyStore.java
src/main/java/net/pterodactylus/sone/database/PostStore.java
src/main/java/net/pterodactylus/sone/database/ReplyBuilder.java
src/main/java/net/pterodactylus/sone/database/SoneProvider.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryDatabase.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryPost.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryPostBuilder.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryPostReply.java
src/main/java/net/pterodactylus/sone/database/memory/MemoryPostReplyBuilder.java
src/main/java/net/pterodactylus/sone/fcp/AbstractSoneCommand.java
src/main/java/net/pterodactylus/sone/fcp/CreatePostCommand.java
src/main/java/net/pterodactylus/sone/fcp/CreateReplyCommand.java
src/main/java/net/pterodactylus/sone/fcp/DeletePostCommand.java
src/main/java/net/pterodactylus/sone/fcp/DeleteReplyCommand.java
src/main/java/net/pterodactylus/sone/fcp/FcpInterface.java
src/main/java/net/pterodactylus/sone/fcp/GetLocalSonesCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetPostCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetPostsCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetSoneCommand.java
src/main/java/net/pterodactylus/sone/fcp/GetSonesCommand.java
src/main/java/net/pterodactylus/sone/fcp/LikePostCommand.java
src/main/java/net/pterodactylus/sone/fcp/LikeReplyCommand.java
src/main/java/net/pterodactylus/sone/fcp/LockSoneCommand.java
src/main/java/net/pterodactylus/sone/fcp/UnlockSoneCommand.java
src/main/java/net/pterodactylus/sone/fcp/VersionCommand.java
src/main/java/net/pterodactylus/sone/freenet/L10nFilter.java
src/main/java/net/pterodactylus/sone/freenet/PluginStoreConfigurationBackend.java
src/main/java/net/pterodactylus/sone/freenet/SimpleFieldSetBuilder.java
src/main/java/net/pterodactylus/sone/freenet/fcp/AbstractCommand.java
src/main/java/net/pterodactylus/sone/freenet/fcp/Command.java
src/main/java/net/pterodactylus/sone/freenet/fcp/FcpException.java
src/main/java/net/pterodactylus/sone/freenet/plugin/PluginConnector.java
src/main/java/net/pterodactylus/sone/freenet/plugin/PluginException.java
src/main/java/net/pterodactylus/sone/freenet/plugin/event/ReceivedReplyEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/Context.java
src/main/java/net/pterodactylus/sone/freenet/wot/DefaultIdentity.java
src/main/java/net/pterodactylus/sone/freenet/wot/DefaultOwnIdentity.java
src/main/java/net/pterodactylus/sone/freenet/wot/Identity.java
src/main/java/net/pterodactylus/sone/freenet/wot/IdentityChangeDetector.java
src/main/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSender.java
src/main/java/net/pterodactylus/sone/freenet/wot/IdentityLoader.java
src/main/java/net/pterodactylus/sone/freenet/wot/IdentityManagerImpl.java
src/main/java/net/pterodactylus/sone/freenet/wot/OwnIdentity.java
src/main/java/net/pterodactylus/sone/freenet/wot/Trust.java
src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustConnector.java
src/main/java/net/pterodactylus/sone/freenet/wot/WebOfTrustException.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/IdentityAddedEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/IdentityEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/IdentityRemovedEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/IdentityUpdatedEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/OwnIdentityAddedEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/OwnIdentityEvent.java
src/main/java/net/pterodactylus/sone/freenet/wot/event/OwnIdentityRemovedEvent.java
src/main/java/net/pterodactylus/sone/main/DebugLoaders.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/main/DefaultLoaders.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/main/Loaders.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/main/SonePlugin.java
src/main/java/net/pterodactylus/sone/notify/ListNotification.java
src/main/java/net/pterodactylus/sone/notify/ListNotificationFilters.java
src/main/java/net/pterodactylus/sone/template/AlbumAccessor.java
src/main/java/net/pterodactylus/sone/template/CollectionAccessor.java
src/main/java/net/pterodactylus/sone/template/CssClassNameFilter.java
src/main/java/net/pterodactylus/sone/template/FilesystemTemplate.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/template/GetPagePlugin.java
src/main/java/net/pterodactylus/sone/template/HttpRequestAccessor.java
src/main/java/net/pterodactylus/sone/template/IdentityAccessor.java
src/main/java/net/pterodactylus/sone/template/ImageAccessor.java
src/main/java/net/pterodactylus/sone/template/ImageLinkFilter.java
src/main/java/net/pterodactylus/sone/template/JavascriptFilter.java
src/main/java/net/pterodactylus/sone/template/ParserFilter.java
src/main/java/net/pterodactylus/sone/template/PostAccessor.java
src/main/java/net/pterodactylus/sone/template/ProfileAccessor.java
src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java
src/main/java/net/pterodactylus/sone/template/ReplyGroupFilter.java
src/main/java/net/pterodactylus/sone/template/RequestChangeFilter.java
src/main/java/net/pterodactylus/sone/template/SoneAccessor.java
src/main/java/net/pterodactylus/sone/template/SubstringFilter.java
src/main/java/net/pterodactylus/sone/template/TrustAccessor.java
src/main/java/net/pterodactylus/sone/template/UniqueElementFilter.java
src/main/java/net/pterodactylus/sone/template/UnknownDateFilter.java
src/main/java/net/pterodactylus/sone/text/FreenetLinkPart.java
src/main/java/net/pterodactylus/sone/text/LinkPart.java
src/main/java/net/pterodactylus/sone/text/Parser.java
src/main/java/net/pterodactylus/sone/text/ParserContext.java
src/main/java/net/pterodactylus/sone/text/Part.java
src/main/java/net/pterodactylus/sone/text/PartContainer.java
src/main/java/net/pterodactylus/sone/text/PlainTextPart.java
src/main/java/net/pterodactylus/sone/text/PostPart.java
src/main/java/net/pterodactylus/sone/text/SonePart.java
src/main/java/net/pterodactylus/sone/text/SoneTextParser.java
src/main/java/net/pterodactylus/sone/text/SoneTextParserContext.java
src/main/java/net/pterodactylus/sone/text/TextFilter.java
src/main/java/net/pterodactylus/sone/utils/IntegerRangePredicate.java
src/main/java/net/pterodactylus/sone/web/AboutPage.java
src/main/java/net/pterodactylus/sone/web/BookmarkPage.java
src/main/java/net/pterodactylus/sone/web/BookmarksPage.java
src/main/java/net/pterodactylus/sone/web/CreateAlbumPage.java
src/main/java/net/pterodactylus/sone/web/CreatePostPage.java
src/main/java/net/pterodactylus/sone/web/CreateReplyPage.java
src/main/java/net/pterodactylus/sone/web/CreateSonePage.java
src/main/java/net/pterodactylus/sone/web/DeleteAlbumPage.java
src/main/java/net/pterodactylus/sone/web/DeleteImagePage.java
src/main/java/net/pterodactylus/sone/web/DeletePostPage.java
src/main/java/net/pterodactylus/sone/web/DeleteProfileFieldPage.java
src/main/java/net/pterodactylus/sone/web/DeleteReplyPage.java
src/main/java/net/pterodactylus/sone/web/DeleteSonePage.java
src/main/java/net/pterodactylus/sone/web/DismissNotificationPage.java
src/main/java/net/pterodactylus/sone/web/DistrustPage.java
src/main/java/net/pterodactylus/sone/web/EditAlbumPage.java
src/main/java/net/pterodactylus/sone/web/EditImagePage.java
src/main/java/net/pterodactylus/sone/web/EditProfileFieldPage.java
src/main/java/net/pterodactylus/sone/web/EditProfilePage.java
src/main/java/net/pterodactylus/sone/web/FollowSonePage.java
src/main/java/net/pterodactylus/sone/web/GetImagePage.java
src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java
src/main/java/net/pterodactylus/sone/web/IndexPage.java
src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java
src/main/java/net/pterodactylus/sone/web/LikePage.java
src/main/java/net/pterodactylus/sone/web/LockSonePage.java
src/main/java/net/pterodactylus/sone/web/LoginPage.java
src/main/java/net/pterodactylus/sone/web/LogoutPage.java
src/main/java/net/pterodactylus/sone/web/MarkAsKnownPage.java
src/main/java/net/pterodactylus/sone/web/NewPage.java
src/main/java/net/pterodactylus/sone/web/OptionsPage.java
src/main/java/net/pterodactylus/sone/web/ReloadingPage.java [new file with mode: 0644]
src/main/java/net/pterodactylus/sone/web/RescuePage.java
src/main/java/net/pterodactylus/sone/web/SearchPage.java
src/main/java/net/pterodactylus/sone/web/SoneTemplatePage.java
src/main/java/net/pterodactylus/sone/web/TrustPage.java
src/main/java/net/pterodactylus/sone/web/UnbookmarkPage.java
src/main/java/net/pterodactylus/sone/web/UnfollowSonePage.java
src/main/java/net/pterodactylus/sone/web/UnlikePage.java
src/main/java/net/pterodactylus/sone/web/UnlockSonePage.java
src/main/java/net/pterodactylus/sone/web/UntrustPage.java
src/main/java/net/pterodactylus/sone/web/UploadImagePage.java
src/main/java/net/pterodactylus/sone/web/ViewPostPage.java
src/main/java/net/pterodactylus/sone/web/ViewSonePage.java
src/main/java/net/pterodactylus/sone/web/WebInterface.java
src/main/java/net/pterodactylus/sone/web/ajax/BookmarkAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/CreatePostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/CreateReplyAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DeletePostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DeleteProfileFieldAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DeleteReplyAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DismissNotificationAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/DistrustAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/EditAlbumAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/EditImageAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/EditProfileFieldAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/FollowSoneAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetLikesAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetPostAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetReplyAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetStatusAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetTimesAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/GetTranslationPage.java
src/main/java/net/pterodactylus/sone/web/ajax/JsonPage.java
src/main/java/net/pterodactylus/sone/web/ajax/LikeAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/LockSoneAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/MarkAsKnownAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/MoveProfileFieldAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/TrustAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UnbookmarkAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UnfollowSoneAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UnlikeAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UnlockSoneAjaxPage.java
src/main/java/net/pterodactylus/sone/web/ajax/UntrustAjaxPage.java
src/main/java/net/pterodactylus/sone/web/page/FreenetPage.java
src/main/java/net/pterodactylus/sone/web/page/FreenetRequest.java
src/main/java/net/pterodactylus/sone/web/page/FreenetTemplatePage.java
src/main/java/net/pterodactylus/sone/web/page/PageToadlet.java
src/main/java/net/pterodactylus/sone/web/page/PageToadletFactory.java
src/main/resources/i18n/sone.es.properties
src/test/java/net/pterodactylus/sone/Matchers.java
src/test/java/net/pterodactylus/sone/database/memory/MemoryDatabaseTest.java
src/test/java/net/pterodactylus/sone/fcp/LockSoneCommandTest.java
src/test/java/net/pterodactylus/sone/fcp/UnlockSoneCommandTest.java
src/test/java/net/pterodactylus/sone/freenet/wot/DefaultIdentityTest.java
src/test/java/net/pterodactylus/sone/freenet/wot/DefaultOwnIdentityTest.java
src/test/java/net/pterodactylus/sone/freenet/wot/Identities.java
src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeDetectorTest.java
src/test/java/net/pterodactylus/sone/freenet/wot/IdentityChangeEventSenderTest.java
src/test/java/net/pterodactylus/sone/freenet/wot/IdentityLoaderTest.java
src/test/java/net/pterodactylus/sone/main/DebugLoadersTest.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/main/DefaultLoadersTest.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/template/FilesystemTemplateTest.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java
src/test/resources/net/pterodactylus/sone/main/template.txt [new file with mode: 0644]
template.txt [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index a76b3b2..2ca12c0 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
        <modelVersion>4.0.0</modelVersion>
        <groupId>net.pterodactylus</groupId>
        <artifactId>sone</artifactId>
-       <version>0.9.3</version>
+       <version>0.9.4</version>
        <dependencies>
                <dependency>
                        <groupId>net.pterodactylus</groupId>
                        <version>1.3</version>
                </dependency>
                <dependency>
+                       <groupId>org.jsoup</groupId>
+                       <artifactId>jsoup</artifactId>
+                       <version>1.7.1</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
                        <groupId>org.freenetproject</groupId>
                        <artifactId>fred</artifactId>
                        <version>0.7.5.1467.99.3</version>
index da209d8..99a5654 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Core.java - Copyright © 2010–2013 David Roden
+ * Sone - Core.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 81ed069..219377d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FreenetInterface.java - Copyright © 2010–2013 David Roden
+ * Sone - FreenetInterface.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 6b33897..d338161 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageInserter.java - Copyright © 2011–2013 David Roden
+ * Sone - ImageInserter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9e79fca..9a53202 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Options.java - Copyright © 2010–2013 David Roden
+ * Sone - Options.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 56bfa73..8123764 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Preferences.java - Copyright © 2013 David Roden
+ * Sone - Preferences.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index df5d0c1..6317abe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneDownloader.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneDownloaderImpl.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2b1f1de..246025d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneException.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneException.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f67f093..ffda655 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneInsertException.java - Copyright © 2011–2013 David Roden
+ * Sone - SoneInsertException.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index dbb7ef1..e34f19d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneInserter.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneInserter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2712bd3..ae1e2a5 100644 (file)
@@ -325,16 +325,13 @@ public class SoneParser {
                }
 
                /* okay, apparently everything was parsed correctly. Now import. */
-               /* atomic setter operation on the Sone. */
-               synchronized (sone) {
-                       sone.setProfile(profile);
-                       sone.setPosts(posts);
-                       sone.setReplies(replies);
-                       sone.setLikePostIds(likedPostIds);
-                       sone.setLikeReplyIds(likedReplyIds);
-                       for (Album album : topLevelAlbums) {
-                               sone.getRootAlbum().addAlbum(album);
-                       }
+               sone.setProfile(profile);
+               sone.setPosts(posts);
+               sone.setReplies(replies);
+               sone.setLikePostIds(likedPostIds);
+               sone.setLikeReplyIds(likedReplyIds);
+               for (Album album : topLevelAlbums) {
+                       sone.getRootAlbum().addAlbum(album);
                }
 
                return sone;
index f45e351..2ca4b4a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneRescuer.java - Copyright © 2011–2013 David Roden
+ * Sone - SoneRescuer.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index eeab32b..f62b4ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneUri.java - Copyright © 2013 David Roden
+ * Sone - SoneUri.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e24032f..146383a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UpdateChecker.java - Copyright © 2011–2013 David Roden
+ * Sone - UpdateChecker.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9aa6dec..82b14ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - WebOfTrustUpdater.java - Copyright © 2013 David Roden
+ * Sone - WebOfTrustUpdaterImpl.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2af6408..c9646ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageEvent.java - Copyright © 2013 David Roden
+ * Sone - ImageEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2431cf6..2316217 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageInsertAbortedEvent.java - Copyright © 2013 David Roden
+ * Sone - ImageInsertAbortedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7800537..b09cd45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageInsertFailedEvent.java - Copyright © 2013 David Roden
+ * Sone - ImageInsertFailedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 53023b0..06a506d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageInsertFinishedEvent.java - Copyright © 2013 David Roden
+ * Sone - ImageInsertFinishedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3b60277..b0f0c68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageInsertStartedEvent.java - Copyright © 2013 David Roden
+ * Sone - ImageInsertStartedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b8faac9..112361a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MarkPostKnownEvent.java - Copyright © 2013 David Roden
+ * Sone - MarkPostKnownEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e49fb31..d50a046 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MarkPostReplyKnownEvent.java - Copyright © 2013 David Roden
+ * Sone - MarkPostReplyKnownEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 48a5109..eb1ea3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MarkSoneKnownEvent.java - Copyright © 2013 David Roden
+ * Sone - MarkSoneKnownEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a7529a8..f77c462 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - NewPostFoundEvent.java - Copyright © 2013 David Roden
+ * Sone - NewPostFoundEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fb52bcc..68c2d20 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - NewPostReplyFoundEvent.java - Copyright © 2013 David Roden
+ * Sone - NewPostReplyFoundEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 32c6b71..623cf12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - NewSoneFoundEvent.java - Copyright © 2013 David Roden
+ * Sone - NewSoneFoundEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index aa47170..1b5cb68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostEvent.java - Copyright © 2013 David Roden
+ * Sone - PostEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7e07df7..850f712 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostRemovedEvent.java - Copyright © 2013 David Roden
+ * Sone - PostRemovedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b5e9a1f..f312fcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyEvent.java - Copyright © 2013 David Roden
+ * Sone - PostReplyEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 1ed4f9b..e900de5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyRemovedEvent.java - Copyright © 2013 David Roden
+ * Sone - PostReplyRemovedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 68691ed..324b230 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5884839..fa68c26 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneInsertAbortedEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneInsertAbortedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 936a134..6c276b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneInsertedEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneInsertedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 37effe9..4653317 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneInsertingEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneInsertingEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a707aca..251759d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneLockedEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneLockedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5b2e5d8..30bd317 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneRemovedEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneRemovedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 86100b4..17f8027 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneUnlockedEvent.java - Copyright © 2013 David Roden
+ * Sone - SoneUnlockedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2e7b341..e8cb8e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UpdateFoundEvent.java - Copyright © 2013 David Roden
+ * Sone - UpdateFoundEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c75088f..698206d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Album.java - Copyright © 2011–2013 David Roden
+ * Sone - Album.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 612a258..e8f5082 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Client.java - Copyright © 2010–2013 David Roden
+ * Sone - Client.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2cf34ed..df4e2d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Fingerprintable.java - Copyright © 2011–2013 David Roden
+ * Sone - Fingerprintable.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4892479..e748c7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Identified.java - Copyright © 2013 David Roden
+ * Sone - Identified.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 22ddc29..6413481 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Image.java - Copyright © 2011–2013 David Roden
+ * Sone - Image.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 95abae6..d666eb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Post.java - Copyright © 2010–2013 David Roden
+ * Sone - Post.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d010261..585b430 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReply.java - Copyright © 2010–2013 David Roden
+ * Sone - PostReply.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4970cf9..55faf18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Profile.java - Copyright © 2010–2013 David Roden
+ * Sone - Profile.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e9b7a1d..c92bacb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Reply.java - Copyright © 2010–2013 David Roden
+ * Sone - Reply.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e64a388..072f2c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Sone.java - Copyright © 2010–2013 David Roden
+ * Sone - Sone.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5c657ac..9383133 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - TemporaryImage.java - Copyright © 2011–2013 David Roden
+ * Sone - TemporaryImage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 8e15b6f..9be43b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractAlbumBuilder.java - Copyright © 2013 David Roden
+ * Sone - AbstractAlbumBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 533ba39..ad6d15f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractImageBuilder.java - Copyright © 2013 David Roden
+ * Sone - AbstractImageBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3a56dc9..3c6e547 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractPostBuilder.java - Copyright © 2013 David Roden
+ * Sone - AbstractPostBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 952a94e..be05424 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractPostReplyBuilder.java - Copyright © 2013 David Roden
+ * Sone - AbstractPostReplyBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2a68a13..71e1e53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReplyBuilder.java - Copyright © 2013 David Roden
+ * Sone - AbstractReplyBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index df61e36..72ae5a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryAlbumBuilder.java - Copyright © 2013 David Roden
+ * Sone - AlbumBuilderImpl.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3488577..41668ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Album.java - Copyright © 2011–2013 David Roden
+ * Sone - AlbumImpl.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4df8897..a0617b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultPostBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - DefaultPostBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e326304..1944ff9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultPostReplyBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - DefaultPostReplyBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ba7d75f..04ac778 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageBuilderImpl.java - Copyright © 2013 David Roden
+ * Sone - ImageBuilderImpl.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2df98b1..ddf01c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageImpl.java - Copyright © 2011–2013 David Roden
+ * Sone - ImageImpl.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 88a2d71..e6c1b66 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostBuilderImpl.java - Copyright © 2013 David Roden
+ * Sone - PostBuilderImpl.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9dcd7d0..365d28f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostImpl.java - Copyright © 2010–2013 David Roden
+ * Sone - PostImpl.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index dac84ad..a7abb66 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyBuilderImpl.java - Copyright © 2013 David Roden
+ * Sone - PostReplyBuilderImpl.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 30badf7..136d6a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyImpl.java - Copyright © 2010–2013 David Roden
+ * Sone - PostReplyImpl.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a67081f..3416241 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReplyImpl.java - Copyright © 2011–2013 David Roden
+ * Sone - ReplyImpl.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f7ebfb1..5024be2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneImpl.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneImpl.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a084ae7..f0b19cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumBuilder.java - Copyright © 2013 David Roden
+ * Sone - AlbumBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e7a537d..ff5ab6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - AlbumBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 01d91b6..7b37751 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumDatabase.java - Copyright © 2013 David Roden
+ * Sone - AlbumDatabase.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b83b179..83ce6dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumProvider.java - Copyright © 2013 David Roden
+ * Sone - AlbumProvider.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c625535..8c3c97b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumStore.java - Copyright © 2013 David Roden
+ * Sone - AlbumStore.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 971a427..c08162c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Database.java - Copyright © 2013 David Roden
+ * Sone - Database.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 43d3e77..abd1080 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DatabaseException.java - Copyright © 2013 David Roden
+ * Sone - DatabaseException.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index af405c7..08b9897 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageBuilder.java - Copyright © 2013 David Roden
+ * Sone - ImageBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 29b605b..6c40a22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - ImageBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b5e436d..97e81cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageDatabase.java - Copyright © 2013 David Roden
+ * Sone - ImageDatabase.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c9ad9e1..ecb1bd6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageProvider.java - Copyright © 2013 David Roden
+ * Sone - ImageProvider.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f09eff0..9c32542 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageStore.java - Copyright © 2013 David Roden
+ * Sone - ImageStore.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 449147a..3c1927f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostBuilder.java - Copyright © 2013 David Roden
+ * Sone - PostBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e74a6bd..98513de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - PostBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 40e6290..164224a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostDatabase.java - Copyright © 2013 David Roden
+ * Sone - PostDatabase.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7d5437a..353a524 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostProvider.java - Copyright © 2011–2013 David Roden
+ * Sone - PostProvider.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c031443..82b0c0b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyBuilder.java - Copyright © 2013 David Roden
+ * Sone - PostReplyBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cac3e30..8f4dfe8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyBuilderFactory.java - Copyright © 2013 David Roden
+ * Sone - PostReplyBuilderFactory.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c9a809f..c68b40c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyDatabase.java - Copyright © 2013 David Roden
+ * Sone - PostReplyDatabase.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e186e5b..dc89826 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyProvider.java - Copyright © 2013 David Roden
+ * Sone - PostReplyProvider.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 30268b8..939c100 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostReplyStore.java - Copyright © 2013 David Roden
+ * Sone - PostReplyStore.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 402a647..b4340b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostStore.java - Copyright © 2013 David Roden
+ * Sone - PostStore.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d83e7ce..93cf6b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReplyBuilder.java - Copyright © 2013 David Roden
+ * Sone - ReplyBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 73467a2..1c685ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneProvider.java - Copyright © 2011–2013 David Roden
+ * Sone - SoneProvider.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b830ba5..fa608e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryDatabase.java - Copyright © 2013 David Roden
+ * Sone - MemoryDatabase.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 180cf6c..d368fba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostImpl.java - Copyright © 2010–2013 David Roden
+ * Sone - MemoryPost.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d0b2c9f..d76f277 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryPostBuilder.java - Copyright © 2013 David Roden
+ * Sone - MemoryPostBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a6686ca..a48b017 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryPostReply.java - Copyright © 2013 David Roden
+ * Sone - MemoryPostReply.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 32ab1e0..2871b27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryPostReplyBuilder.java - Copyright © 2013 David Roden
+ * Sone - MemoryPostReplyBuilder.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d71ffc4..312bb9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractSoneCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - AbstractSoneCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f6c5dd9..cd596ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreatePostCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - CreatePostCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fe4bee8..65b0ac2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreateReplyCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - CreateReplyCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 00d5018..d411233 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeletePostCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - DeletePostCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e9c0926..8b2f5b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteReplyCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - DeleteReplyCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5612a4f..25cf4ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FcpInterface.java - Copyright © 2011–2013 David Roden
+ * Sone - FcpInterface.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b8684b0..fdef446 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetLocalSonesCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetLocalSonesCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c503f5b..2211677 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetPostCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetPostCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b22d356..0851616 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetPostFeedCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetPostFeedCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 1947718..baa7147 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetPostsCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetPostsCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e3ec1b1..2ad514f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetSoneCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetSoneCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9ff8587..770cb22 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetSonesCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - GetSonesCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 20d251c..d8d6604 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LikePostCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - LikePostCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a462f08..edfa742 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LikeReplyCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - LikeReplyCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5cad8ca..287ec91 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSoneCommand.java - Copyright © 2013 David Roden
+ * Sone - LockSoneCommand.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7ecfada..4870168 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSoneCommand.java - Copyright © 2013 David Roden
+ * Sone - UnlockSoneCommand.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c482f24..9533aca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - VersionCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - VersionCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c8075c5..b547a53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - L10nFilter.java - Copyright © 2010–2013 David Roden
+ * Sone - L10nFilter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index eec8aa3..dfc30f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PluginStoreConfigurationBackend.java - Copyright © 2010–2013 David Roden
+ * Sone - PluginStoreConfigurationBackend.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a256edb..2c68f07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SimpleFieldSetBuilder.java - Copyright © 2011–2013 David Roden
+ * Sone - SimpleFieldSetBuilder.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fa5a372..c516f0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AbstractCommand.java - Copyright © 2011–2013 David Roden
+ * Sone - AbstractCommand.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 32df6d8..d0f812a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Command.java - Copyright © 2011–2013 David Roden
+ * Sone - Command.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e40438c..34920f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FcpException.java - Copyright © 2011–2013 David Roden
+ * Sone - FcpException.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 56ac807..46343a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PluginConnector.java - Copyright © 2010–2013 David Roden
+ * Sone - PluginConnector.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fd3dec7..78e73cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PluginException.java - Copyright © 2010–2013 David Roden
+ * Sone - PluginException.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 89a8df3..feeb1ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReceivedReplyEvent.java - Copyright © 2013 David Roden
+ * Sone - ReceivedReplyEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f72e56d..4d5a3a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Context.java - Copyright © 2014 David Roden
+ * Sone - Context.java - Copyright © 2014–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index dc44aab..6313a1a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultIdentity.java - Copyright © 2010–2013 David Roden
+ * Sone - DefaultIdentity.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4a842e9..68e6f41 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultOwnIdentity.java - Copyright © 2010–2013 David Roden
+ * Sone - DefaultOwnIdentity.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d0cafc5..c6875e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Identity.java - Copyright © 2010–2013 David Roden
+ * Sone - Identity.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2fe10df..9703891 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityChangeDetector.java - Copyright © 2013 David Roden
+ * Sone - IdentityChangeDetector.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d087dec..d17efae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityChangeEventSender.java - Copyright © 2013 David Roden
+ * Sone - IdentityChangeEventSender.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 75ec828..a3b4f6c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityLoader.java - Copyright © 2013 David Roden
+ * Sone - IdentityLoader.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 70071f1..33b1ef6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityManager.java - Copyright © 2010–2013 David Roden
+ * Sone - IdentityManagerImpl.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index da6409b..2f0ade9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - OwnIdentity.java - Copyright © 2010–2013 David Roden
+ * Sone - OwnIdentity.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9a70a14..65c6dba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Trust.java - Copyright © 2010–2013 David Roden
+ * Sone - Trust.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 6f5ef85..ca3a38c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - WebOfTrustConnector.java - Copyright © 2010–2013 David Roden
+ * Sone - WebOfTrustConnector.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2b154fc..ae41613 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - WebOfTrustException.java - Copyright © 2010–2013 David Roden
+ * Sone - WebOfTrustException.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 69f17ef..897c04b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityAddedEvent.java - Copyright © 2013 David Roden
+ * Sone - IdentityAddedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c262513..60abcb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityEvent.java - Copyright © 2013 David Roden
+ * Sone - IdentityEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d5671cc..bdf2ff0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityRemovedEvent.java - Copyright © 2013 David Roden
+ * Sone - IdentityRemovedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 96ed694..0521f7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityUpdatedEvent.java - Copyright © 2013 David Roden
+ * Sone - IdentityUpdatedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index aacf2e8..f4bc97a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - OwnIdentityAddedEvent.java - Copyright © 2013 David Roden
+ * Sone - OwnIdentityAddedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 1216273..56a7156 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - OwnIdentityEvent.java - Copyright © 2013 David Roden
+ * Sone - OwnIdentityEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 437bd6d..0f8b201 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - OwnIdentityRemovedEvent.java - Copyright © 2013 David Roden
+ * Sone - OwnIdentityRemovedEvent.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/main/java/net/pterodactylus/sone/main/DebugLoaders.java b/src/main/java/net/pterodactylus/sone/main/DebugLoaders.java
new file mode 100644 (file)
index 0000000..11755e0
--- /dev/null
@@ -0,0 +1,41 @@
+package net.pterodactylus.sone.main;
+
+import java.io.File;
+
+import net.pterodactylus.sone.template.FilesystemTemplate;
+import net.pterodactylus.sone.web.ReloadingPage;
+import net.pterodactylus.util.template.FilesystemTemplateProvider;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateProvider;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Request;
+
+/**
+ * {@link Loaders} implementation that loads all resources from the filesystem.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class DebugLoaders implements Loaders {
+
+       private final String filesystemPath;
+
+       public DebugLoaders(String filesystemPath) {
+               this.filesystemPath = filesystemPath;
+       }
+
+       @Override
+       public Template loadTemplate(String path) {
+               return new FilesystemTemplate(new File(filesystemPath, path).getAbsolutePath());
+       }
+
+       @Override
+       public <REQ extends Request> Page<REQ> loadStaticPage(String basePath, String prefix, String mimeType) {
+               return new ReloadingPage<REQ>(basePath, new File(filesystemPath, prefix).getAbsolutePath(), mimeType);
+       }
+
+       @Override
+       public TemplateProvider getTemplateProvider() {
+               return new FilesystemTemplateProvider(new File(filesystemPath, "/templates/").getAbsolutePath());
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/sone/main/DefaultLoaders.java b/src/main/java/net/pterodactylus/sone/main/DefaultLoaders.java
new file mode 100644 (file)
index 0000000..e94e655
--- /dev/null
@@ -0,0 +1,53 @@
+package net.pterodactylus.sone.main;
+
+import static net.pterodactylus.util.template.TemplateParser.parse;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import net.pterodactylus.sone.web.WebInterface;
+import net.pterodactylus.util.io.Closer;
+import net.pterodactylus.util.template.ClassPathTemplateProvider;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateProvider;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Request;
+import net.pterodactylus.util.web.StaticPage;
+
+/**
+ * Default {@link Loaders} implementation that loads resources from the classpath.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class DefaultLoaders implements Loaders {
+
+       @Override
+       public Template loadTemplate(String path) {
+               InputStream templateInputStream = null;
+               Reader reader = null;
+               try {
+                       templateInputStream = getClass().getResourceAsStream(path);
+                       reader = new InputStreamReader(templateInputStream, "UTF-8");
+                       return parse(reader);
+               } catch (UnsupportedEncodingException uee1) {
+                       throw new RuntimeException("UTF-8 not supported.");
+               } finally {
+                       Closer.close(reader);
+                       Closer.close(templateInputStream);
+               }
+       }
+
+       @Override
+       public <REQ extends Request> Page<REQ> loadStaticPage(String pathPrefix, String basePath, String mimeType) {
+               return new StaticPage<REQ>(pathPrefix, basePath, mimeType) {
+               };
+       }
+
+       @Override
+       public TemplateProvider getTemplateProvider() {
+               return new ClassPathTemplateProvider(WebInterface.class, "/templates/");
+       }
+
+}
diff --git a/src/main/java/net/pterodactylus/sone/main/Loaders.java b/src/main/java/net/pterodactylus/sone/main/Loaders.java
new file mode 100644 (file)
index 0000000..34ee1b1
--- /dev/null
@@ -0,0 +1,22 @@
+package net.pterodactylus.sone.main;
+
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateProvider;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Request;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * Defines loaders for resources that can be loaded from various locations.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+@ImplementedBy(DefaultLoaders.class)
+public interface Loaders {
+
+       Template loadTemplate(String path);
+       <REQ extends Request> Page<REQ> loadStaticPage(String basePath, String prefix, String mimeType);
+       TemplateProvider getTemplateProvider();
+
+}
index 1df4a33..828d1af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SonePlugin.java - Copyright © 2010–2013 David Roden
+ * Sone - SonePlugin.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -116,12 +116,12 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
        }
 
        /** The version. */
-       public static final Version VERSION = new Version(0, 9, 3);
+       public static final Version VERSION = new Version(0, 9, 4);
 
        /** The current year at time of release. */
        private static final int YEAR = 2015;
        private static final String SONE_HOMEPAGE = "USK@nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI,DuQSUZiI~agF8c-6tjsFFGuZ8eICrzWCILB60nT8KKo,AQACAAE/sone/";
-       private static final int LATEST_EDITION = 70;
+       private static final int LATEST_EDITION = 71;
 
        /** The logger. */
        private static final Logger logger = getLogger(SonePlugin.class.getName());
@@ -250,6 +250,12 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
                                bind(Context.class).toInstance(context);
                                bind(getOptionalContextTypeLiteral()).toInstance(of(context));
                                bind(SonePlugin.class).toInstance(SonePlugin.this);
+                               if (startConfiguration.getBooleanValue("Developer.LoadFromFilesystem").getValue(false)) {
+                                       String path = startConfiguration.getStringValue("Developer.FilesystemPath").getValue(null);
+                                       if (path != null) {
+                                               bind(Loaders.class).toInstance(new DebugLoaders(path));
+                                       }
+                               }
                                bindListener(Matchers.any(), new TypeListener() {
 
                                        @Override
@@ -295,7 +301,6 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
         */
        @Override
        public void terminate() {
-               deregisterLoggerHandlers();
                try {
                        /* stop the web interface. */
                        webInterface.stop();
@@ -307,6 +312,8 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
                        webOfTrustConnector.stop();
                } catch (Throwable t1) {
                        logger.log(Level.SEVERE, "Error while shutting down!", t1);
+               } finally {
+                       deregisterLoggerHandlers();
                }
        }
 
index 9d1203b..101b1fb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ListNotification.java - Copyright © 2010–2013 David Roden
+ * Sone - ListNotification.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f93e1f4..1d4aa68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ListNotificationFilters.java - Copyright © 2010–2013 David Roden
+ * Sone - ListNotificationFilters.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9ef168a..e19a89a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AlbumAccessor.java - Copyright © 2011–2013 David Roden
+ * Sone - AlbumAccessor.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b5a4255..5449fa5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CollectionAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - CollectionAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a3f8db6..2b1f73c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CssClassNameFilter.java - Copyright © 2010–2013 David Roden
+ * Sone - CssClassNameFilter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/main/java/net/pterodactylus/sone/template/FilesystemTemplate.java b/src/main/java/net/pterodactylus/sone/template/FilesystemTemplate.java
new file mode 100644 (file)
index 0000000..473c191
--- /dev/null
@@ -0,0 +1,145 @@
+package net.pterodactylus.sone.template;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import net.pterodactylus.util.template.Part;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.template.TemplateException;
+import net.pterodactylus.util.template.TemplateParser;
+
+import freenet.support.io.Closer;
+
+import com.google.common.base.Charsets;
+
+/**
+ * {@link Template} implementation that can be reloaded from the filesystem.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class FilesystemTemplate extends Template {
+
+       private final String filename;
+       private final AtomicReference<LastLoadedTemplate> lastTemplate = new AtomicReference<LastLoadedTemplate>();
+       private final TemplateContext initialContext = new TemplateContext();
+       private final List<Part> parts = new ArrayList<Part>();
+
+       public FilesystemTemplate(String filename) {
+               this.filename = filename;
+       }
+
+       @Override
+       public TemplateContext getInitialContext() {
+               loadTemplate();
+               return initialContext;
+       }
+
+       private void loadTemplate() {
+               File templateFile = new File(filename);
+               if (!templateFile.exists()) {
+                       throw new TemplateFileNotFoundException(filename);
+               }
+               if (templateWasLoaded() && !templateFileHasBeenModifiedAfterLoading(templateFile)) {
+                       return;
+               }
+               InputStream templateInputStream = null;
+               Reader templateReader = null;
+               try {
+                       templateInputStream = new FileInputStream(templateFile);
+                       templateReader = new InputStreamReader(templateInputStream, Charsets.UTF_8);
+                       Template template = TemplateParser.parse(templateReader);
+                       lastTemplate.set(new LastLoadedTemplate(template));
+                       template.getInitialContext().mergeContext(initialContext);
+                       for (Part part : parts) {
+                               template.add(part);
+                       }
+               } catch (FileNotFoundException e) {
+                       throw new TemplateFileNotFoundException(filename);
+               } finally {
+                       Closer.close(templateReader);
+                       Closer.close(templateInputStream);
+               }
+       }
+
+       private boolean templateWasLoaded() {
+               return lastTemplate.get() != null;
+       }
+
+       private boolean templateFileHasBeenModifiedAfterLoading(File templateFile) {
+               return templateFile.lastModified() > lastTemplate.get().getLoadTime();
+       }
+
+       @Override
+       public void add(Part part) {
+               loadTemplate();
+               parts.add(part);
+               lastTemplate.get().getTemplate().add(part);
+       }
+
+       @Override
+       public void render(TemplateContext templateContext, Writer writer) throws TemplateException {
+               loadTemplate();
+               lastTemplate.get().getTemplate().render(templateContext, writer);
+       }
+
+       @Override
+       public Iterator<Part> iterator() {
+               loadTemplate();
+               return lastTemplate.get().getTemplate().iterator();
+       }
+
+       @Override
+       public int getLine() {
+               loadTemplate();
+               return lastTemplate.get().getTemplate().getLine();
+       }
+
+       @Override
+       public int getColumn() {
+               loadTemplate();
+               return lastTemplate.get().getTemplate().getColumn();
+       }
+
+       private static class LastLoadedTemplate {
+
+               private final Template template;
+               private final long loadTime = System.currentTimeMillis();
+
+               private LastLoadedTemplate(Template template) {
+                       this.template = template;
+               }
+
+               public Template getTemplate() {
+                       return template;
+               }
+
+               public long getLoadTime() {
+                       return loadTime;
+               }
+
+       }
+
+       /**
+        * Exception that signals that a template file could not be found.
+        *
+        * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+        */
+       public static class TemplateFileNotFoundException extends RuntimeException {
+
+               public TemplateFileNotFoundException(String filename) {
+                       super(filename);
+               }
+
+       }
+
+}
index d070fe9..ae53e58 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetPagePlugin.java - Copyright © 2010–2013 David Roden
+ * Sone - GetPagePlugin.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 0d888bc..3383a3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - HttpRequestAccessor.java - Copyright © 2011–2013 David Roden
+ * Sone - HttpRequestAccessor.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index efb4d16..3a49aed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - IdentityAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3ac684c..2c27933 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageAccessor.java - Copyright © 2011–2013 David Roden
+ * Sone - ImageAccessor.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9ede851..f560731 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageLinkFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - ImageLinkFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,6 +33,7 @@ import net.pterodactylus.util.template.TemplateContext;
 import net.pterodactylus.util.template.TemplateContextFactory;
 import net.pterodactylus.util.template.TemplateParser;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
 
 /**
@@ -79,11 +80,11 @@ public class ImageLinkFilter implements Filter {
                if (image == null) {
                        return null;
                }
-               String imageClass = valueOf(parameters.get("class"));
+               String imageClass = Optional.fromNullable(parameters.get("class")).transform(getStringValue()).orNull();
                int maxWidth = parseInt(valueOf(parameters.get("max-width")), MAX_VALUE);
                int maxHeight = parseInt(valueOf(parameters.get("max-height")), MAX_VALUE);
                String mode = valueOf(parameters.get("mode"));
-               String title = valueOf(parameters.get("title"));
+               String title = Optional.fromNullable(parameters.get("title")).transform(getStringValue()).orNull();
 
                TemplateContext linkTemplateContext = templateContextFactory.createTemplateContext();
                linkTemplateContext.set("class", imageClass);
@@ -117,4 +118,13 @@ public class ImageLinkFilter implements Filter {
                return stringWriter.toString();
        }
 
+       private Function<Object, String> getStringValue() {
+               return new Function<Object, String>() {
+                       @Override
+                       public String apply(Object input) {
+                               return (input != null) ? input.toString() : null;
+                       }
+               };
+       }
+
 }
index 9b8cd7e..809c53a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - JavascriptFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - JavascriptFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ec35e2e..109222e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ParserFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - ParserFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 78db678..f04ea83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - PostAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 762bc14..93bfc59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ProfileAccessor.java - Copyright © 2011–2013 David Roden
+ * Sone - ProfileAccessor.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b497a94..dc5ded0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReplyAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - ReplyAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3d5fda1..709ffbc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ReplyGroupFilter.java - Copyright © 2010–2013 David Roden
+ * Sone - ReplyGroupFilter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a5a4edf..211c4b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - RequestChangeFilter.java - Copyright © 2010–2013 David Roden
+ * Sone - RequestChangeFilter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 03973a1..4bb78af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 6efc5ed..101cbb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SubstringFilter.java - Copyright © 2010–2013 David Roden
+ * Sone - SubstringFilter.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7ba7a10..f3dd827 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - TrustAccessor.java - Copyright © 2010–2013 David Roden
+ * Sone - TrustAccessor.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fb5551d..005094e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UniqueElementFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - UniqueElementFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 077e1fd..7981d55 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnknownDateFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - UnknownDateFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c667f38..b8fd240 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FreenetLinkPart.java - Copyright © 2011–2013 David Roden
+ * Sone - FreenetLinkPart.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f531bab..2e7d331 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LinkPart.java - Copyright © 2011–2013 David Roden
+ * Sone - LinkPart.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2a7700a..f5f8f1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Parser.java - Copyright © 2010–2013 David Roden
+ * Sone - Parser.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4734906..9782008 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ParserContext.java - Copyright © 2010–2013 David Roden
+ * Sone - ParserContext.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4c1a188..8dee69b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Part.java - Copyright © 2010–2013 David Roden
+ * Sone - Part.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7d8acd6..75714f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PartContainer.java - Copyright © 2010–2013 David Roden
+ * Sone - PartContainer.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index aa6441b..9090eb3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PlainTextPart.java - Copyright © 2011–2013 David Roden
+ * Sone - PlainTextPart.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f7177c9..6aae37c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PostPart.java - Copyright © 2011–2013 David Roden
+ * Sone - PostPart.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a7b418b..3d3e666 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SonePart.java - Copyright © 2011–2013 David Roden
+ * Sone - SonePart.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a1675d7..f338286 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneTextParser.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneTextParser.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ba00916..3e7dc3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneTextParserContext.java - Copyright © 2011–2013 David Roden
+ * Sone - SoneTextParserContext.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f07a000..5782a23 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - TextFilter.java - Copyright © 2011–2013 David Roden
+ * Sone - TextFilter.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a4022de..a0470c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IntegerRangePredicate.java - Copyright © 2013 David Roden
+ * Sone - IntegerRangePredicate.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4b54a4b..581df3e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - AboutPage.java - Copyright © 2010–2013 David Roden
+ * Sone - AboutPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c0a8907..afb6a29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - BookmarkPage.java - Copyright © 2011–2013 David Roden
+ * Sone - BookmarkPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 0f53572..a86e044 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - BookmarksPage.java - Copyright © 2011–2013 David Roden
+ * Sone - BookmarksPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 1c599e4..539fa6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreateAlbumPage.java - Copyright © 2011–2013 David Roden
+ * Sone - CreateAlbumPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 6530a5b..46631ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreatePostPage.java - Copyright © 2010–2013 David Roden
+ * Sone - CreatePostPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 55903d8..5098f2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreateReplyPage.java - Copyright © 2010–2013 David Roden
+ * Sone - CreateReplyPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ef2d619..5ea2c1a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreateSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - CreateSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 98e8909..b3a7a06 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteAlbumPage.java - Copyright © 2011–2013 David Roden
+ * Sone - DeleteAlbumPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 77f3ab8..6934beb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteImagePage.java - Copyright © 2011–2013 David Roden
+ * Sone - DeleteImagePage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5a309fa..03a6933 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeletePostPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DeletePostPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 852cc91..0184a2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteProfileFieldPage.java - Copyright © 2011–2013 David Roden
+ * Sone - DeleteProfileFieldPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f7ca132..37b9fea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteReplyPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DeleteReplyPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 39d3fb3..90cc6cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - DeleteSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 40efa5d..d5bb6ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DismissNotificationPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DismissNotificationPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c8879a0..14411f9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DistrustPage.java - Copyright © 2011–2013 David Roden
+ * Sone - DistrustPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 66434e5..5244bc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditAlbumPage.java - Copyright © 2011–2013 David Roden
+ * Sone - EditAlbumPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 178add1..9ae7ed6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditImagePage.java - Copyright © 2010–2013 David Roden
+ * Sone - EditImagePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fe9d78f..8f5e4ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditProfileFieldPage.java - Copyright © 2011–2013 David Roden
+ * Sone - EditProfileFieldPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 162d637..5145358 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditProfilePage.java - Copyright © 2010–2013 David Roden
+ * Sone - EditProfilePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 11a680c..a83c46a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FollowSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - FollowSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 442ce7d..87e4fa2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetImagePage.java - Copyright © 2011–2013 David Roden
+ * Sone - GetImagePage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 60b22d5..442cdc0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ImageBrowserPage.java - Copyright © 2011–2013 David Roden
+ * Sone - ImageBrowserPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index e242f52..c5e80c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IndexPage.java - Copyright © 2010–2013 David Roden
+ * Sone - IndexPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d2e7abe..edb9980 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - KnownSonesPage.java - Copyright © 2010–2013 David Roden
+ * Sone - KnownSonesPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7f08e65..43d46a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LikePage.java - Copyright © 2010–2013 David Roden
+ * Sone - LikePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index f72252f..dc35b70 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - LockSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b5c608c..4b38a07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LoginPage.java - Copyright © 2010–2013 David Roden
+ * Sone - LoginPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index bc4c56d..aa8f401 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LogoutPage.java - Copyright © 2010–2013 David Roden
+ * Sone - LogoutPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 66ac635..215ce93 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MarkAsKnownPage.java - Copyright © 2011–2013 David Roden
+ * Sone - MarkAsKnownPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5977349..1757952 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - NewPage.java - Copyright © 2013 David Roden
+ * Sone - NewPage.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index c38f97b..dff7ecf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - OptionsPage.java - Copyright © 2010–2013 David Roden
+ * Sone - OptionsPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/main/java/net/pterodactylus/sone/web/ReloadingPage.java b/src/main/java/net/pterodactylus/sone/web/ReloadingPage.java
new file mode 100644 (file)
index 0000000..0c8f516
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Sone - ReloadingPage.java - Copyright © 2010–2015 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import net.pterodactylus.util.io.Closer;
+import net.pterodactylus.util.io.StreamCopier;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Request;
+import net.pterodactylus.util.web.Response;
+
+/**
+ * {@link Page} implementation that delivers static files from the filesystem.
+ *
+ * @param <REQ>
+ *            The type of the request
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ReloadingPage<REQ extends Request> implements Page<REQ> {
+
+       private final String pathPrefix;
+       private final String filesystemPath;
+       private final String mimeType;
+
+       public ReloadingPage(String pathPrefix, String filesystemPathPrefix, String mimeType) {
+               this.pathPrefix = pathPrefix;
+               this.filesystemPath = filesystemPathPrefix;
+               this.mimeType = mimeType;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String getPath() {
+               return pathPrefix;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public boolean isPrefixPage() {
+               return true;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public Response handleRequest(REQ request, Response response) throws IOException {
+               String path = request.getUri().getPath();
+               int lastSlash = path.lastIndexOf('/');
+               String filename = path.substring(lastSlash + 1);
+               InputStream fileInputStream = new FileInputStream(new File(filesystemPath, filename));
+               if (fileInputStream == null) {
+                       return response.setStatusCode(404).setStatusText("Not found.");
+               }
+               OutputStream contentOutputStream = response.getContent();
+               try {
+                       StreamCopier.copy(fileInputStream, contentOutputStream);
+               } finally {
+                       Closer.close(fileInputStream);
+                       Closer.close(contentOutputStream);
+               }
+               return response.setStatusCode(200).setStatusText("OK").setContentType(mimeType);
+       }
+}
index 8c325d2..8599a31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - RescuePage.java - Copyright © 2011–2013 David Roden
+ * Sone - RescuePage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 95b0bba..7ec7f9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SearchPage.java - Copyright © 2010–2013 David Roden
+ * Sone - SearchPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 7dfdfe7..15810ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneTemplatePage.java - Copyright © 2010–2013 David Roden
+ * Sone - SoneTemplatePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 39fd1de..cf67052 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - TrustPage.java - Copyright © 2011–2013 David Roden
+ * Sone - TrustPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 72ff2fc..80b3ce6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnbookmarkPage.java - Copyright © 2011–2013 David Roden
+ * Sone - UnbookmarkPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4813239..1ec2d6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnfollowSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnfollowSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 9254a42..057f7b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnlikePage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnlikePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 8491163..0d4432f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnlockSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnlockSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d68d5ca..a5b314f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UntrustPage.java - Copyright © 2011–2013 David Roden
+ * Sone - UntrustPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a1e987a..7621a6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UploadImagePage.java - Copyright © 2011–2013 David Roden
+ * Sone - UploadImagePage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 8adf46d..9ab6612 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ViewPostPage.java - Copyright © 2010–2013 David Roden
+ * Sone - ViewPostPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 74461e3..9b346c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - ViewSonePage.java - Copyright © 2010–2013 David Roden
+ * Sone - ViewSonePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fbba8e0..4da2177 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - WebInterface.java - Copyright © 2010–2013 David Roden
+ * Sone - WebInterface.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,11 +21,7 @@ import static java.util.logging.Logger.getLogger;
 import static net.pterodactylus.util.template.TemplateParser.parse;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
 import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -72,6 +68,7 @@ import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.freenet.L10nFilter;
 import net.pterodactylus.sone.freenet.wot.Identity;
 import net.pterodactylus.sone.freenet.wot.Trust;
+import net.pterodactylus.sone.main.Loaders;
 import net.pterodactylus.sone.main.ReparseFilter;
 import net.pterodactylus.sone.main.SonePlugin;
 import net.pterodactylus.sone.notify.ListNotification;
@@ -129,11 +126,9 @@ import net.pterodactylus.sone.web.ajax.UntrustAjaxPage;
 import net.pterodactylus.sone.web.page.FreenetRequest;
 import net.pterodactylus.sone.web.page.PageToadlet;
 import net.pterodactylus.sone.web.page.PageToadletFactory;
-import net.pterodactylus.util.io.Closer;
 import net.pterodactylus.util.notify.Notification;
 import net.pterodactylus.util.notify.NotificationManager;
 import net.pterodactylus.util.notify.TemplateNotification;
-import net.pterodactylus.util.template.ClassPathTemplateProvider;
 import net.pterodactylus.util.template.CollectionSortFilter;
 import net.pterodactylus.util.template.ContainsFilter;
 import net.pterodactylus.util.template.DateFilter;
@@ -150,7 +145,6 @@ import net.pterodactylus.util.template.TemplateContextFactory;
 import net.pterodactylus.util.template.TemplateProvider;
 import net.pterodactylus.util.template.XmlFilter;
 import net.pterodactylus.util.web.RedirectPage;
-import net.pterodactylus.util.web.StaticPage;
 import net.pterodactylus.util.web.TemplatePage;
 
 import com.google.common.collect.Collections2;
@@ -176,6 +170,9 @@ public class WebInterface {
        /** The logger. */
        private static final Logger logger = getLogger(WebInterface.class.getName());
 
+       /** The loaders for templates, pages, and classpath providers. */
+       private final Loaders loaders;
+
        /** The notification manager. */
        private final NotificationManager notificationManager = new NotificationManager();
 
@@ -246,8 +243,9 @@ public class WebInterface {
         *            The Sone plugin
         */
        @Inject
-       public WebInterface(SonePlugin sonePlugin) {
+       public WebInterface(SonePlugin sonePlugin, Loaders loaders) {
                this.sonePlugin = sonePlugin;
+               this.loaders = loaders;
                formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword();
                soneTextParser = new SoneTextParser(getCore(), getCore());
 
@@ -286,60 +284,45 @@ public class WebInterface {
                templateContextFactory.addFilter("mod", new ModFilter());
                templateContextFactory.addFilter("paginate", new PaginationFilter());
                templateContextFactory.addProvider(TemplateProvider.TEMPLATE_CONTEXT_PROVIDER);
-               templateContextFactory.addProvider(new ClassPathTemplateProvider(WebInterface.class, "/templates/"));
+               templateContextFactory.addProvider(loaders.getTemplateProvider());
                templateContextFactory.addTemplateObject("webInterface", this);
                templateContextFactory.addTemplateObject("formPassword", formPassword);
 
                /* create notifications. */
-               Template newSoneNotificationTemplate = parseTemplate("/templates/notify/newSoneNotification.html");
+               Template newSoneNotificationTemplate = loaders.loadTemplate("/templates/notify/newSoneNotification.html");
                newSoneNotification = new ListNotification<Sone>("new-sone-notification", "sones", newSoneNotificationTemplate, false);
 
-               Template newPostNotificationTemplate = parseTemplate("/templates/notify/newPostNotification.html");
+               Template newPostNotificationTemplate = loaders.loadTemplate("/templates/notify/newPostNotification.html");
                newPostNotification = new ListNotification<Post>("new-post-notification", "posts", newPostNotificationTemplate, false);
 
-               Template localPostNotificationTemplate = parseTemplate("/templates/notify/newPostNotification.html");
+               Template localPostNotificationTemplate = loaders.loadTemplate("/templates/notify/newPostNotification.html");
                localPostNotification = new ListNotification<Post>("local-post-notification", "posts", localPostNotificationTemplate, false);
 
-               Template newReplyNotificationTemplate = parseTemplate("/templates/notify/newReplyNotification.html");
+               Template newReplyNotificationTemplate = loaders.loadTemplate("/templates/notify/newReplyNotification.html");
                newReplyNotification = new ListNotification<PostReply>("new-reply-notification", "replies", newReplyNotificationTemplate, false);
 
-               Template localReplyNotificationTemplate = parseTemplate("/templates/notify/newReplyNotification.html");
+               Template localReplyNotificationTemplate = loaders.loadTemplate("/templates/notify/newReplyNotification.html");
                localReplyNotification = new ListNotification<PostReply>("local-reply-notification", "replies", localReplyNotificationTemplate, false);
 
-               Template mentionNotificationTemplate = parseTemplate("/templates/notify/mentionNotification.html");
+               Template mentionNotificationTemplate = loaders.loadTemplate("/templates/notify/mentionNotification.html");
                mentionNotification = new ListNotification<Post>("mention-notification", "posts", mentionNotificationTemplate, false);
 
-               Template lockedSonesTemplate = parseTemplate("/templates/notify/lockedSonesNotification.html");
+               Template lockedSonesTemplate = loaders.loadTemplate("/templates/notify/lockedSonesNotification.html");
                lockedSonesNotification = new ListNotification<Sone>("sones-locked-notification", "sones", lockedSonesTemplate);
 
-               Template newVersionTemplate = parseTemplate("/templates/notify/newVersionNotification.html");
+               Template newVersionTemplate = loaders.loadTemplate("/templates/notify/newVersionNotification.html");
                newVersionNotification = new TemplateNotification("new-version-notification", newVersionTemplate);
 
-               Template insertingImagesTemplate = parseTemplate("/templates/notify/inserting-images-notification.html");
+               Template insertingImagesTemplate = loaders.loadTemplate("/templates/notify/inserting-images-notification.html");
                insertingImagesNotification = new ListNotification<Image>("inserting-images-notification", "images", insertingImagesTemplate);
 
-               Template insertedImagesTemplate = parseTemplate("/templates/notify/inserted-images-notification.html");
+               Template insertedImagesTemplate = loaders.loadTemplate("/templates/notify/inserted-images-notification.html");
                insertedImagesNotification = new ListNotification<Image>("inserted-images-notification", "images", insertedImagesTemplate);
 
-               Template imageInsertFailedTemplate = parseTemplate("/templates/notify/image-insert-failed-notification.html");
+               Template imageInsertFailedTemplate = loaders.loadTemplate("/templates/notify/image-insert-failed-notification.html");
                imageInsertFailedNotification = new ListNotification<Image>("image-insert-failed-notification", "images", imageInsertFailedTemplate);
        }
 
-       private Template parseTemplate(String resourceName) {
-               InputStream templateInputStream = null;
-               Reader reader = null;
-               try {
-                       templateInputStream = getClass().getResourceAsStream(resourceName);
-                       reader = new InputStreamReader(templateInputStream, "UTF-8");
-                       return parse(reader);
-               } catch (UnsupportedEncodingException uee1) {
-                       throw new RuntimeException("UTF-8 not supported.");
-               } finally {
-                       Closer.close(reader);
-                       Closer.close(templateInputStream);
-               }
-       }
-
        //
        // ACCESSORS
        //
@@ -528,7 +511,7 @@ public class WebInterface {
         */
        public void setFirstStart(boolean firstStart) {
                if (firstStart) {
-                       Template firstStartNotificationTemplate = parseTemplate("/templates/notify/firstStartNotification.html");
+                       Template firstStartNotificationTemplate = loaders.loadTemplate("/templates/notify/firstStartNotification.html");
                        Notification firstStartNotification = new TemplateNotification("first-start-notification", firstStartNotificationTemplate);
                        notificationManager.addNotification(firstStartNotification);
                }
@@ -543,7 +526,7 @@ public class WebInterface {
         */
        public void setNewConfig(boolean newConfig) {
                if (newConfig && !hasFirstStartNotification()) {
-                       Template configNotReadNotificationTemplate = parseTemplate("/templates/notify/configNotReadNotification.html");
+                       Template configNotReadNotificationTemplate = loaders.loadTemplate("/templates/notify/configNotReadNotification.html");
                        Notification configNotReadNotification = new TemplateNotification("config-not-read-notification", configNotReadNotificationTemplate);
                        notificationManager.addNotification(configNotReadNotification);
                }
@@ -574,7 +557,7 @@ public class WebInterface {
                registerToadlets();
 
                /* notification templates. */
-               Template startupNotificationTemplate = parseTemplate("/templates/notify/startupNotification.html");
+               Template startupNotificationTemplate = loaders.loadTemplate("/templates/notify/startupNotification.html");
 
                final TemplateNotification startupNotification = new TemplateNotification("startup-notification", startupNotificationTemplate);
                notificationManager.addNotification(startupNotification);
@@ -587,7 +570,7 @@ public class WebInterface {
                        }
                }, 2, TimeUnit.MINUTES);
 
-               Template wotMissingNotificationTemplate = parseTemplate("/templates/notify/wotMissingNotification.html");
+               Template wotMissingNotificationTemplate = loaders.loadTemplate("/templates/notify/wotMissingNotification.html");
                final TemplateNotification wotMissingNotification = new TemplateNotification("wot-missing-notification", wotMissingNotificationTemplate);
                ticker.scheduleAtFixedRate(new Runnable() {
 
@@ -621,37 +604,37 @@ public class WebInterface {
         */
        private void registerToadlets() {
                Template emptyTemplate = parse(new StringReader(""));
-               Template loginTemplate = parseTemplate("/templates/login.html");
-               Template indexTemplate = parseTemplate("/templates/index.html");
-               Template newTemplate = parseTemplate("/templates/new.html");
-               Template knownSonesTemplate = parseTemplate("/templates/knownSones.html");
-               Template createSoneTemplate = parseTemplate("/templates/createSone.html");
-               Template createPostTemplate = parseTemplate("/templates/createPost.html");
-               Template createReplyTemplate = parseTemplate("/templates/createReply.html");
-               Template bookmarksTemplate = parseTemplate("/templates/bookmarks.html");
-               Template searchTemplate = parseTemplate("/templates/search.html");
-               Template editProfileTemplate = parseTemplate("/templates/editProfile.html");
-               Template editProfileFieldTemplate = parseTemplate("/templates/editProfileField.html");
-               Template deleteProfileFieldTemplate = parseTemplate("/templates/deleteProfileField.html");
-               Template viewSoneTemplate = parseTemplate("/templates/viewSone.html");
-               Template viewPostTemplate = parseTemplate("/templates/viewPost.html");
-               Template deletePostTemplate = parseTemplate("/templates/deletePost.html");
-               Template deleteReplyTemplate = parseTemplate("/templates/deleteReply.html");
-               Template deleteSoneTemplate = parseTemplate("/templates/deleteSone.html");
-               Template imageBrowserTemplate = parseTemplate("/templates/imageBrowser.html");
-               Template createAlbumTemplate = parseTemplate("/templates/createAlbum.html");
-               Template deleteAlbumTemplate = parseTemplate("/templates/deleteAlbum.html");
-               Template deleteImageTemplate = parseTemplate("/templates/deleteImage.html");
-               Template noPermissionTemplate = parseTemplate("/templates/noPermission.html");
-               Template emptyImageTitleTemplate = parseTemplate("/templates/emptyImageTitle.html");
-               Template emptyAlbumTitleTemplate = parseTemplate("/templates/emptyAlbumTitle.html");
-               Template optionsTemplate = parseTemplate("/templates/options.html");
-               Template rescueTemplate = parseTemplate("/templates/rescue.html");
-               Template aboutTemplate = parseTemplate("/templates/about.html");
-               Template invalidTemplate = parseTemplate("/templates/invalid.html");
-               Template postTemplate = parseTemplate("/templates/include/viewPost.html");
-               Template replyTemplate = parseTemplate("/templates/include/viewReply.html");
-               Template openSearchTemplate = parseTemplate("/templates/xml/OpenSearch.xml");
+               Template loginTemplate = loaders.loadTemplate("/templates/login.html");
+               Template indexTemplate = loaders.loadTemplate("/templates/index.html");
+               Template newTemplate = loaders.loadTemplate("/templates/new.html");
+               Template knownSonesTemplate = loaders.loadTemplate("/templates/knownSones.html");
+               Template createSoneTemplate = loaders.loadTemplate("/templates/createSone.html");
+               Template createPostTemplate = loaders.loadTemplate("/templates/createPost.html");
+               Template createReplyTemplate = loaders.loadTemplate("/templates/createReply.html");
+               Template bookmarksTemplate = loaders.loadTemplate("/templates/bookmarks.html");
+               Template searchTemplate = loaders.loadTemplate("/templates/search.html");
+               Template editProfileTemplate = loaders.loadTemplate("/templates/editProfile.html");
+               Template editProfileFieldTemplate = loaders.loadTemplate("/templates/editProfileField.html");
+               Template deleteProfileFieldTemplate = loaders.loadTemplate("/templates/deleteProfileField.html");
+               Template viewSoneTemplate = loaders.loadTemplate("/templates/viewSone.html");
+               Template viewPostTemplate = loaders.loadTemplate("/templates/viewPost.html");
+               Template deletePostTemplate = loaders.loadTemplate("/templates/deletePost.html");
+               Template deleteReplyTemplate = loaders.loadTemplate("/templates/deleteReply.html");
+               Template deleteSoneTemplate = loaders.loadTemplate("/templates/deleteSone.html");
+               Template imageBrowserTemplate = loaders.loadTemplate("/templates/imageBrowser.html");
+               Template createAlbumTemplate = loaders.loadTemplate("/templates/createAlbum.html");
+               Template deleteAlbumTemplate = loaders.loadTemplate("/templates/deleteAlbum.html");
+               Template deleteImageTemplate = loaders.loadTemplate("/templates/deleteImage.html");
+               Template noPermissionTemplate = loaders.loadTemplate("/templates/noPermission.html");
+               Template emptyImageTitleTemplate = loaders.loadTemplate("/templates/emptyImageTitle.html");
+               Template emptyAlbumTitleTemplate = loaders.loadTemplate("/templates/emptyAlbumTitle.html");
+               Template optionsTemplate = loaders.loadTemplate("/templates/options.html");
+               Template rescueTemplate = loaders.loadTemplate("/templates/rescue.html");
+               Template aboutTemplate = loaders.loadTemplate("/templates/about.html");
+               Template invalidTemplate = loaders.loadTemplate("/templates/invalid.html");
+               Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
+               Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
+               Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
 
                PageToadletFactory pageToadletFactory = new PageToadletFactory(sonePlugin.pluginRespirator().getHLSimpleClient(), "/Sone/");
                pageToadlets.add(pageToadletFactory.createPageToadlet(new RedirectPage<FreenetRequest>("", "index.html")));
@@ -700,9 +683,9 @@ public class WebInterface {
                pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("emptyAlbumTitle.html", emptyAlbumTitleTemplate, "Page.EmptyAlbumTitle.Title", this)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new DismissNotificationPage(emptyTemplate, this)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("invalid.html", invalidTemplate, "Page.Invalid.Title", this)));
-               pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage<FreenetRequest>("css/", "/static/css/", "text/css")));
-               pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage<FreenetRequest>("javascript/", "/static/javascript/", "text/javascript")));
-               pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage<FreenetRequest>("images/", "/static/images/", "image/png")));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css")));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript")));
+               pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png")));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new GetImagePage(this)));
                pageToadlets.add(pageToadletFactory.createPageToadlet(new GetTranslationPage(this)));
@@ -795,7 +778,7 @@ public class WebInterface {
                synchronized (soneInsertNotifications) {
                        TemplateNotification templateNotification = soneInsertNotifications.get(sone);
                        if (templateNotification == null) {
-                               templateNotification = new TemplateNotification(parseTemplate("/templates/notify/soneInsertNotification.html"));
+                               templateNotification = new TemplateNotification(loaders.loadTemplate("/templates/notify/soneInsertNotification.html"));
                                templateNotification.set("insertSone", sone);
                                soneInsertNotifications.put(sone, templateNotification);
                        }
@@ -901,72 +884,46 @@ public class WebInterface {
                newSoneNotification.remove(markSoneKnownEvent.sone());
        }
 
-       /**
-        * Notifies the web interface that a {@link Post} was marked as known.
-        *
-        * @param markPostKnownEvent
-        *            The event
-        */
        @Subscribe
        public void markPostKnown(MarkPostKnownEvent markPostKnownEvent) {
-               newPostNotification.remove(markPostKnownEvent.post());
-               localPostNotification.remove(markPostKnownEvent.post());
-               if (!localSoneMentionedInNewPostOrReply(markPostKnownEvent.post())) {
-                       mentionNotification.remove(markPostKnownEvent.post());
-               }
+               removePost(markPostKnownEvent.post());
        }
 
-       /**
-        * Notifies the web interface that a {@link PostReply} was marked as known.
-        *
-        * @param markPostReplyKnownEvent
-        *            The event
-        */
        @Subscribe
        public void markReplyKnown(MarkPostReplyKnownEvent markPostReplyKnownEvent) {
-               PostReply postReply = markPostReplyKnownEvent.postReply();
-               newReplyNotification.remove(postReply);
-               localReplyNotification.remove(postReply);
-               if (postReply.getPost().isPresent() && !localSoneMentionedInNewPostOrReply(postReply.getPost().get())) {
-                       mentionNotification.remove(postReply.getPost().get());
-               }
+               removeReply(markPostReplyKnownEvent.postReply());
        }
 
-       /**
-        * Notifies the web interface that a {@link Sone} was removed.
-        *
-        * @param soneRemovedEvent
-        *            The event
-        */
        @Subscribe
        public void soneRemoved(SoneRemovedEvent soneRemovedEvent) {
                newSoneNotification.remove(soneRemovedEvent.sone());
+               for (Post post : soneRemovedEvent.sone().getPosts()) {
+                       removePost(post);
+               }
+               for (PostReply postReply : soneRemovedEvent.sone().getReplies()) {
+                       removeReply(postReply);
+               }
        }
 
-       /**
-        * Notifies the web interface that a {@link Post} was removed.
-        *
-        * @param postRemovedEvent
-        *            The event
-        */
        @Subscribe
        public void postRemoved(PostRemovedEvent postRemovedEvent) {
-               newPostNotification.remove(postRemovedEvent.post());
-               localPostNotification.remove(postRemovedEvent.post());
-               if (!localSoneMentionedInNewPostOrReply(postRemovedEvent.post())) {
-                       mentionNotification.remove(postRemovedEvent.post());
+               removePost(postRemovedEvent.post());
+       }
+
+       private void removePost(Post post) {
+               newPostNotification.remove(post);
+               localPostNotification.remove(post);
+               if (!localSoneMentionedInNewPostOrReply(post)) {
+                       mentionNotification.remove(post);
                }
        }
 
-       /**
-        * Notifies the web interface that a {@link PostReply} was removed.
-        *
-        * @param postReplyRemovedEvent
-        *            The event
-        */
        @Subscribe
        public void replyRemoved(PostReplyRemovedEvent postReplyRemovedEvent) {
-               PostReply reply = postReplyRemovedEvent.postReply();
+               removeReply(postReplyRemovedEvent.postReply());
+       }
+
+       private void removeReply(PostReply reply) {
                newReplyNotification.remove(reply);
                localReplyNotification.remove(reply);
                if (reply.getPost().isPresent() && !localSoneMentionedInNewPostOrReply(reply.getPost().get())) {
index 42719d3..dea9c3e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - BookmarkAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - BookmarkAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5cb1047..8af6d47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreatePostAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - CreatePostAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3449dec..b63c852 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - CreateReplyAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - CreateReplyAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index acf5f03..6ed222b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeletePostAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DeletePostAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cb33fb9..2ad3b29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteProfileFieldAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - DeleteProfileFieldAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3ea9f7f..e4905f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DeleteReplyAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DeleteReplyAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index aed9cad..4e731e8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DismissNotificationAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - DismissNotificationAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4206e8f..c99c1a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DistrustAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - DistrustAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 238206a..96f3d01 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditAlbumAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - EditAlbumAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 79de200..e11a2b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditImageAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - EditImageAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b4596ad..2a931c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - EditProfileFieldAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - EditProfileFieldAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 64c402a..115b27b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FollowSoneAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - FollowSoneAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ccc51dc..3f6c0d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetLikesAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetLikesAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a25e665..ee4683f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetNotificationsAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - GetNotificationsAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 96002b3..78176cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetPostAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetPostAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 251c784..1445e98 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetReplyAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetReplyAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cc095a2..6c5c0de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetStatusAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetStatusAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 0c78bb6..97706a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetTimesAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetTimesAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free Software
index 5c81d95..2823177 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - GetTranslationPage.java - Copyright © 2010–2013 David Roden
+ * Sone - GetTranslationPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2392b12..a262742 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - JsonPage.java - Copyright © 2010–2013 David Roden
+ * Sone - JsonPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 55a947a..cf57c8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LikeAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - LikeAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cc04338..3a9ea7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSoneAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - LockSoneAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cd026ef..4727686 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MarkAsKnownAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - MarkAsKnownAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index d8781ba..4283f72 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MoveProfileFieldAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - MoveProfileFieldAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3661cb1..1c0689f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - TrustAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - TrustAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 064bedc..769ebcb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnbookmarkAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - UnbookmarkAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a285d20..803464c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnfollowSoneAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnfollowSoneAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 17be966..6afe39b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnlikeAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnlikeAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3a91f81..513ca97 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UnlockSoneAjaxPage.java - Copyright © 2010–2013 David Roden
+ * Sone - UnlockSoneAjaxPage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 229f219..cf8f1a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - UntrustAjaxPage.java - Copyright © 2011–2013 David Roden
+ * Sone - UntrustAjaxPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a67fd04..590ac48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FreenetPage.java - Copyright © 2011–2013 David Roden
+ * Sone - FreenetPage.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 858a219..4a0b788 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FreenetRequest.java - Copyright © 2011–2013 David Roden
+ * Sone - FreenetRequest.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 5e30ca0..7338149 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - FreenetTemplatePage.java - Copyright © 2010–2013 David Roden
+ * Sone - FreenetTemplatePage.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fc58339..c64f2d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PageToadlet.java - Copyright © 2010–2013 David Roden
+ * Sone - PageToadlet.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index a517f0a..0816e89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - PageToadletFactory.java - Copyright © 2010–2013 David Roden
+ * Sone - PageToadletFactory.java - Copyright © 2010–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 0c3eaec..368903f 100644 (file)
@@ -36,7 +36,7 @@ Page.About.License.Title=Licencia
 
 Page.Options.Title=Opciones - Sone
 Page.Options.Page.Title=Opciones
-Page.Options.Page.Description=Estas opciones influencian en la ejecución del plugin de Sone
+Page.Options.Page.Description=Estas opciones influencian en la ejecución del plugin "Sone"
 Page.Options.Section.SoneSpecificOptions.Title=Opciones específicas de Sone
 Page.Options.Section.SoneSpecificOptions.NotLoggedIn=Estas opciones solo están disponibles si has {link}iniciado sesión{/link}.
 Page.Options.Section.SoneSpecificOptions.LoggedIn=Estas opciones solo están disponibles mientras hayas iniciado sesión y solo son válidas para el Sone con el que hayas hecho login.
@@ -94,7 +94,7 @@ Page.Index.Title=Tu Sone - Sone
 Page.Index.Label.Text=Publicar texto:
 Page.Index.Label.Sender=Mensajero:
 Page.Index.Button.Post=Publicar!
-Page.Index.PostList.Title=Publicar Feed
+Page.Index.PostList.Title=Publicaciones
 Page.Index.PostList.Text.NoPostYet=Nadie ha escrito ningún post todavía. Probablemente deberías empezar ahora!
 Page.Index.PostList.Text.FollowSomeSones=O quizás no estás siguiendo ningún Sone? Echa un vistado a la lista de {link}Sones conocidos{/link} y sigue a quienes te parezcan interesantes
 Page.Index.PostList.Text.AutoFollowOption=También tienes la opción de seguir automáticamente cualquier Sone que descubras. Echa un vistado a las {link}opciones{/link} para activar la opción "Seguir automáticamente"!
@@ -344,7 +344,7 @@ View.Sone.Button.LockSone=bloquear
 View.Sone.Button.LockSone.Tooltip=Impide que este Sone sea insertado ahora
 View.Sone.Button.UnfollowSone=dejar de seguir
 View.Sone.Button.FollowSone=seguir
-View.Sone.Status.Modified=Esto Sone fue modificado y espera para ser insertado.
+View.Sone.Status.Modified=Este Sone fue modificado y espera para ser insertado.
 View.Sone.Status.Unknown=Este Sone aun no ha sido recivido.
 View.Sone.Status.Idle=Este Sone está desocupado, i.e. no está siendo descargado ni insertado.
 View.Sone.Status.Downloading=Este Sone está siendo descargado.
@@ -401,8 +401,8 @@ View.Time.AYearAgo=hace un año
 View.Time.XYearsAgo=hace ${year} años
 
 WebInterface.DefaultText.StatusUpdate=Qué estás pensando?
-WebInterface.DefaultText.Message=Escrivir un mensaje…
-WebInterface.DefaultText.Reply=Escrivir una respuesta…
+WebInterface.DefaultText.Message=Escribir un mensaje…
+WebInterface.DefaultText.Reply=Escribir una respuesta…
 WebInterface.DefaultText.FirstName=Primer nombre
 WebInterface.DefaultText.MiddleName=Segundo nombre
 WebInterface.DefaultText.LastName=Apellido
@@ -411,7 +411,7 @@ WebInterface.DefaultText.BirthMonth=Mes
 WebInterface.DefaultText.BirthYear=Año
 WebInterface.DefaultText.FieldName=Nombre del campo
 WebInterface.DefaultText.Option.InsertionDelay=Tiempo a esperar tras la modificación de un Sone antes de insertarlo (en segundos)
-WebInterface.DefaultText.Search=Qué estás buscando?
+WebInterface.DefaultText.Search=Qué quieres buscar?
 WebInterface.DefaultText.CreateAlbum.Name=Título del álbum
 WebInterface.DefaultText.CreateAlbum.Description=Descripción del álbum
 WebInterface.DefaultText.EditAlbum.Title=Título del álbum
@@ -433,7 +433,7 @@ WebInterface.Confirmation.DeleteReplyButton=Si, eliminar!
 WebInterface.SelectBox.Choose=Elegir…
 WebInterface.SelectBox.Yes=Si
 WebInterface.SelectBox.No=No
-WebInterface.ClickToShow.Replies=Clica aquía para mostrar las respuestas ocultas.
+WebInterface.ClickToShow.Replies=Clica aquí para mostrar las respuestas ocultas.
 WebInterface.VersionInformation.CurrentVersion=Versión actual:
 WebInterface.VersionInformation.LatestVersion=Última versión:
 WebInterface.VersionInformation.Homepage=Página de inicio
index c16322c..faf2633 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Matchers.java - Copyright © 2013 David Roden
+ * Sone - Matchers.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index cc5babb..5ee498c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - MemoryDatabaseTest.java - Copyright © 2013 David Roden
+ * Sone - MemoryDatabaseTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 2306931..b6c9cd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSoneCommandTest.java - Copyright © 2013 David Roden
+ * Sone - LockSoneCommandTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index ca615ee..4cabfd1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - LockSoneCommandTest.java - Copyright © 2013 David Roden
+ * Sone - UnlockSoneCommandTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 165d5fd..b0e88ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultIdentityTest.java - Copyright © 2013 David Roden
+ * Sone - DefaultIdentityTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4e2728b..29c371e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - DefaultOwnIdentityTest.java - Copyright © 2013 David Roden
+ * Sone - DefaultOwnIdentityTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index fe3625e..479bee6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - Identities.java - Copyright © 2013 David Roden
+ * Sone - Identities.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index b2d4ed1..6a4e3d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityChangeDetectorTest.java - Copyright © 2013 David Roden
+ * Sone - IdentityChangeDetectorTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 8e1cf6a..c88147c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityChangeEventSenderTest.java - Copyright © 2013 David Roden
+ * Sone - IdentityChangeEventSenderTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 98e187d..692400a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - IdentityLoaderTest.java - Copyright © 2013 David Roden
+ * Sone - IdentityLoaderTest.java - Copyright © 2013–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/test/java/net/pterodactylus/sone/main/DebugLoadersTest.java b/src/test/java/net/pterodactylus/sone/main/DebugLoadersTest.java
new file mode 100644 (file)
index 0000000..c3fa7e9
--- /dev/null
@@ -0,0 +1,89 @@
+package net.pterodactylus.sone.main;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.startsWith;
+import static org.mockito.Mockito.mock;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import net.pterodactylus.sone.web.page.FreenetRequest;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.template.TemplateProvider;
+import net.pterodactylus.util.web.Method;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Response;
+
+import freenet.clients.http.ToadletContext;
+import freenet.support.api.HTTPRequest;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Unit test for {@link DebugLoaders}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class DebugLoadersTest {
+
+       @Rule
+       public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+       private final StringWriter stringWriter = new StringWriter();
+       private final TemplateContext templateContext = new TemplateContext();
+       private Loaders loaders;
+
+       @Before
+       public void setupLoader() throws IOException {
+               String templatePath = temporaryFolder.newFolder("temps").getPath();
+               loaders = new DebugLoaders(templatePath);
+               File templateFile = new File(templatePath, "template.txt");
+               Files.write("<%if foo>foo<%else>bar<%/if>", templateFile, Charsets.UTF_8);
+               new File(templatePath, "templates").mkdir();
+               File secondTemplateFile = new File(templatePath, "templates/template.txt");
+               Files.write("<%if foo>foo<%else>bar<%/if>", secondTemplateFile, Charsets.UTF_8);
+       }
+
+       @Test
+       public void debugLoaderCanLoadTemplatesFromFilesystem() throws IOException {
+               Template template = loaders.loadTemplate("/template.txt");
+               template.render(templateContext, stringWriter);
+               assertThat(stringWriter.toString(), is("bar"));
+       }
+
+       @Test
+       public void staticPageIsServedFromFilesystem() throws URISyntaxException, IOException {
+               Page<FreenetRequest> page = loaders.loadStaticPage("text/", "", "text/plain");
+               URI uri = new URI("http://some.host/text/template.txt");
+               Method method = Method.GET;
+               HTTPRequest httpRequest = mock(HTTPRequest.class);
+               ToadletContext toadletContext = mock(ToadletContext.class);
+               FreenetRequest request = new FreenetRequest(uri, method, httpRequest, toadletContext);
+               OutputStream outputStream = new ByteArrayOutputStream();
+               Response response = new Response(outputStream);
+               page.handleRequest(request, response);
+               assertThat(response.getContentType(), startsWith("text/plain"));
+               assertThat(response.getStatusCode(), is(200));
+       }
+
+       @Test
+       public void templateProviderLocatesTemplatesInFileSystem() {
+               TemplateProvider templateProvider = loaders.getTemplateProvider();
+               Template template = templateProvider.getTemplate(templateContext, "template.txt");
+               template.render(templateContext, stringWriter);
+               assertThat(stringWriter.toString(), is("bar"));
+       }
+
+}
diff --git a/src/test/java/net/pterodactylus/sone/main/DefaultLoadersTest.java b/src/test/java/net/pterodactylus/sone/main/DefaultLoadersTest.java
new file mode 100644 (file)
index 0000000..0f0a9f1
--- /dev/null
@@ -0,0 +1,69 @@
+package net.pterodactylus.sone.main;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.startsWith;
+import static org.mockito.Mockito.mock;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import net.pterodactylus.sone.web.page.FreenetRequest;
+import net.pterodactylus.util.template.Template;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.template.TemplateProvider;
+import net.pterodactylus.util.web.Method;
+import net.pterodactylus.util.web.Page;
+import net.pterodactylus.util.web.Response;
+
+import freenet.clients.http.ToadletContext;
+import freenet.support.api.HTTPRequest;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link DefaultLoaders}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class DefaultLoadersTest {
+
+       private final Loaders loaders = new DefaultLoaders();
+       private final StringWriter stringWriter = new StringWriter();
+       private final TemplateContext templateContext = new TemplateContext();
+
+       @Test
+       public void templateCanBeLoadedFromTheClasspath() {
+               Template template = loaders.loadTemplate("/net/pterodactylus/sone/main/template.txt");
+               template.render(templateContext, stringWriter);
+               assertThat(stringWriter.toString(), is("Template. bar\n"));
+       }
+
+       @Test
+       public void staticPageIsServedFromClasspath() throws IOException, URISyntaxException {
+               Page<FreenetRequest> staticPage = loaders.loadStaticPage("text/", "/net/pterodactylus/sone/main/", "text/plain");
+               URI uri = new URI("http://some.host/text/template.txt");
+               Method method = Method.GET;
+               HTTPRequest httpRequest = mock(HTTPRequest.class);
+               ToadletContext toadletContext = mock(ToadletContext.class);
+               FreenetRequest request = new FreenetRequest(uri, method, httpRequest, toadletContext);
+               OutputStream outputStream = new ByteArrayOutputStream();
+               Response response = new Response(outputStream);
+               staticPage.handleRequest(request, response);
+               assertThat(response.getContentType(), startsWith("text/plain"));
+               assertThat(response.getStatusCode(), is(200));
+       }
+
+       @Test
+       public void templateIsLocatedInClasspath() {
+               TemplateProvider templateProvider = loaders.getTemplateProvider();
+               Template template = templateProvider.getTemplate(templateContext, "about.html");
+               assertThat(template, notNullValue());
+       }
+
+}
diff --git a/src/test/java/net/pterodactylus/sone/template/FilesystemTemplateTest.java b/src/test/java/net/pterodactylus/sone/template/FilesystemTemplateTest.java
new file mode 100644 (file)
index 0000000..cd989eb
--- /dev/null
@@ -0,0 +1,111 @@
+package net.pterodactylus.sone.template;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicReference;
+
+import net.pterodactylus.util.template.Part;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.template.TemplateException;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link FilesystemTemplate}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class FilesystemTemplateTest {
+
+       private final File tempFile;
+       private final FilesystemTemplate filesystemTemplate;
+       private final AtomicReference<StringWriter> stringWriter = new AtomicReference<StringWriter>(new StringWriter());
+       private final TemplateContext templateContext = new TemplateContext();
+
+       public FilesystemTemplateTest() throws IOException {
+               tempFile = File.createTempFile("template-", ".dat");
+               writeTemplate("Text");
+               filesystemTemplate = new FilesystemTemplate(tempFile.getAbsolutePath());
+       }
+
+       private void writeTemplate(String text) throws IOException {
+               Files.write(text + ".<%foreach values value><% value><%/foreach>", tempFile, Charsets.UTF_8);
+       }
+
+       @Before
+       public void setupTemplateContext() {
+               templateContext.set("values", Arrays.asList("a", 1));
+       }
+
+       @Test(expected = FilesystemTemplate.TemplateFileNotFoundException.class)
+       public void loadingTemplateFromNonExistingFileThrowsException() throws IOException {
+               FilesystemTemplate filesystemTemplate = new FilesystemTemplate("/a/b/c.dat");
+               filesystemTemplate.getInitialContext();
+       }
+
+       @Test
+       public void templateCanBeLoadedFromTheFilesystem() {
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("Text.a1"));
+       }
+
+       @Test
+       public void templateCanBeReloaded() throws IOException, InterruptedException {
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("Text.a1"));
+               Thread.sleep(1000);
+               writeTemplate("New");
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("New.a1"));
+       }
+
+       @Test
+       public void templateIsNotReloadedIfNotChanged() {
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("Text.a1"));
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("Text.a1"));
+       }
+
+       private String getRenderedString() {
+               String renderedString = stringWriter.get().toString();
+               stringWriter.set(new StringWriter());
+               return renderedString;
+       }
+
+       @Test
+       public void initialContextIsCopiedToReloadedTemplates() throws IOException, InterruptedException {
+               filesystemTemplate.getInitialContext().set("values", "test");
+               Thread.sleep(1000);
+               writeTemplate("New");
+               assertThat(filesystemTemplate.getInitialContext().get("values"), is((Object) "test"));
+       }
+
+       @Test
+       public void partsAreCopiedToReloadedTemplates() throws InterruptedException, IOException {
+               filesystemTemplate.add(new Part() {
+                       @Override
+                       public void render(TemplateContext templateContext, Writer writer) throws TemplateException {
+                               try {
+                                       writer.write(".Test");
+                               } catch (IOException e) {
+                                       throw new TemplateException(e);
+                               }
+                       }
+               });
+               Thread.sleep(1000);
+               writeTemplate("New");
+               filesystemTemplate.render(templateContext, stringWriter.get());
+               assertThat(getRenderedString(), is("New.a1.Test"));
+       }
+
+}
diff --git a/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java b/src/test/java/net/pterodactylus/sone/template/ImageLinkFilterTest.java
new file mode 100644 (file)
index 0000000..20d2362
--- /dev/null
@@ -0,0 +1,162 @@
+package net.pterodactylus.sone.template;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.pterodactylus.sone.core.Core;
+import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.util.template.HtmlFilter;
+import net.pterodactylus.util.template.TemplateContext;
+import net.pterodactylus.util.template.TemplateContextFactory;
+
+import com.google.common.collect.ImmutableMap;
+import org.hamcrest.Matchers;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link ImageLinkFilterTest}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ImageLinkFilterTest {
+
+       private final Core core = mock(Core.class);
+       private final TemplateContextFactory templateContextFactory = new TemplateContextFactory();
+       private final ImageLinkFilter imageLinkFilter = new ImageLinkFilter(core, templateContextFactory);
+       private final TemplateContext templateContext = null;
+       private final Image image = mock(Image.class);
+
+       @Before
+       public void setupTemplateContextFactory() {
+               templateContextFactory.addFilter("html", new HtmlFilter());
+       }
+
+       @Before
+       public void setupCore() {
+               when(core.getImage("image-id", false)).thenReturn(image);
+       }
+
+       @Before
+       public void setupImage() {
+               when(image.getId()).thenReturn("image-id");
+               when(image.getKey()).thenReturn("image-key");
+               when(image.isInserted()).thenReturn(true);
+               when(image.getWidth()).thenReturn(640);
+               when(image.getHeight()).thenReturn(270);
+               when(image.getTitle()).thenReturn("image title");
+               when(image.getDescription()).thenReturn("image description");
+       }
+
+       @Test
+       public void imageLinkIsGeneratedCorrectlyForNotInsertedImages() {
+               when(image.isInserted()).thenReturn(false);
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>of()));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("class"), is(""));
+               assertThat(imageElement.attr("src"), is("getImage.html?image=image-id"));
+               assertThat(imageElement.attr("title"), is("image title"));
+               assertThat(imageElement.attr("alt"), is("image description"));
+               assertThat(imageElement.attr("width"), is("640"));
+               assertThat(imageElement.attr("height"), is("270"));
+       }
+
+       @Test
+       public void imageLinkIsGeneratedCorrectlyForInsertedImages() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>of()));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("class"), is(""));
+               assertThat(imageElement.attr("src"), is("/image-key?forcedownload=true"));
+               assertThat(imageElement.attr("title"), is("image title"));
+               assertThat(imageElement.attr("alt"), is("image description"));
+               assertThat(imageElement.attr("width"), is("640"));
+               assertThat(imageElement.attr("height"), is("270"));
+       }
+
+       @Test
+       public void imageTitleAndDescriptionAreOverriddenCorrectly() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>of("title", "Test Title")));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("title"), is("Test Title"));
+               assertThat(imageElement.attr("alt"), is("Test Title"));
+       }
+
+       @Test
+       public void imageIsScaledByWidthCorrectly() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>of("max-width", "320")));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("width"), is("320"));
+               assertThat(imageElement.attr("height"), is("135"));
+       }
+
+       @Test
+       public void imageIsScaledByHeightCorrectly() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image, ImmutableMap.<String, Object>of("max-height", "135")));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("width"), is("320"));
+               assertThat(imageElement.attr("height"), is("135"));
+       }
+
+       @Test
+       public void wideImageIsEnlargedCorrectly() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image,
+                               ImmutableMap.<String, Object>of("mode", "enlarge", "max-width", "100", "max-height", "100")));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("width"), is("237"));
+               assertThat(imageElement.attr("height"), is("100"));
+               assertThat(imageElement.attr("style"), containsString("left: -68px"));
+               assertThat(imageElement.attr("style"), containsString("top: 0px"));
+       }
+
+       @Test
+       public void highImageIsEnlargedCorrectly() {
+               when(image.getWidth()).thenReturn(270);
+               when(image.getHeight()).thenReturn(640);
+               String result = String.valueOf(imageLinkFilter.format(templateContext, image,
+                               ImmutableMap.<String, Object>of("mode", "enlarge", "max-width", "100", "max-height", "100")));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("width"), is("100"));
+               assertThat(imageElement.attr("height"), is("237"));
+               assertThat(imageElement.attr("style"), containsString("left: 0px"));
+               assertThat(imageElement.attr("style"), containsString("top: -68px"));
+       }
+
+       @Test
+       public void nullImageIsReturnedAsNull() {
+               assertThat(imageLinkFilter.format(templateContext, null, null), nullValue());
+       }
+
+       @Test
+       public void stringIsUsedToLoadImageFromCore() {
+               String result = String.valueOf(imageLinkFilter.format(templateContext, "image-id", ImmutableMap.<String, Object>of()));
+               Element imageElement = getSingleElement(result);
+               assertThat(imageElement.attr("class"), is(""));
+               assertThat(imageElement.attr("src"), is("/image-key?forcedownload=true"));
+               assertThat(imageElement.attr("title"), is("image title"));
+               assertThat(imageElement.attr("alt"), is("image description"));
+               assertThat(imageElement.attr("width"), is("640"));
+               assertThat(imageElement.attr("height"), is("270"));
+       }
+
+       private Element getSingleElement(String result) {
+               Document document = Jsoup.parseBodyFragment(result);
+               assertThatBodyHasASingleElement(document);
+               return getSingleElement(document);
+       }
+
+       private void assertThatBodyHasASingleElement(Document document) {
+               assertThat(document.body().select("> *"), Matchers.hasSize(1));
+       }
+
+       private Element getSingleElement(Document document) {
+               return document.body().select("> *").get(0);
+       }
+
+}
index 2ac6db7..051c235 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Sone - SoneTextParserTest.java - Copyright © 2011–2013 David Roden
+ * Sone - SoneTextParserTest.java - Copyright © 2011–2015 David Roden
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/test/resources/net/pterodactylus/sone/main/template.txt b/src/test/resources/net/pterodactylus/sone/main/template.txt
new file mode 100644 (file)
index 0000000..c2377d2
--- /dev/null
@@ -0,0 +1 @@
+Template. <%if foo>foo<%else>bar<%/if>
diff --git a/template.txt b/template.txt
new file mode 100644 (file)
index 0000000..a26591c
--- /dev/null
@@ -0,0 +1 @@
+<%if foo>foo<%else>bar<%/if>
\ No newline at end of file