X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=1a1c6df5dfedc63fec66604c0866b85c3ddde3a8;hb=8e73d78985dbf9b12257bcd1408d17cef98394c6;hp=a3c8dc4b5fe5ddbc8c2cd3c22eb339f3a3583c23;hpb=4931b5d6e330389e2b694e1f894f3b17313d54e2;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index a3c8dc4..1a1c6df 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -17,6 +17,7 @@ package net.pterodactylus.sone.core; +import java.io.InputStream; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; @@ -31,11 +32,15 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; +import net.pterodactylus.sone.core.Options.DefaultOption; +import net.pterodactylus.sone.core.Options.Option; +import net.pterodactylus.sone.core.Options.OptionWatcher; import net.pterodactylus.sone.core.SoneException.Type; import net.pterodactylus.sone.data.Post; import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.freenet.wot.WebOfTrustConnector; import net.pterodactylus.util.config.Configuration; import net.pterodactylus.util.config.ConfigurationException; import net.pterodactylus.util.filter.Filter; @@ -52,6 +57,16 @@ import freenet.keys.FreenetURI; */ public class Core extends AbstractService { + /** The default Sones. */ + private static final Set defaultSones = new HashSet(); + + static { + /* Sone of Sone. */ + defaultSones.add("USK@eRHt0ceFsHjRZ11j6dd68RSdIvfd8f9YjJLZ9lnhEyo,iJWjIWh6TkMZm1NY8qBranKTIuwsCPkVPG6T6c6ft-I,AQACAAE/Sone/4"); + /* Sone of Bombe. */ + defaultSones.add("USK@RuW~uAO35Ipne896-1OmaVJNPuYE4ZIB5oZ5ziaU57A,7rV3uiyztXBDt03DCoRiNwiGjgFCJuznM9Okc1opURU,AQACAAE/Sone/29"); + } + /** * Enumeration for the possible states of a {@link Sone}. * @@ -75,20 +90,26 @@ public class Core extends AbstractService { /** The logger. */ private static final Logger logger = Logging.getLogger(Core.class); + /** The options. */ + private final Options options = new Options(); + /** The configuration. */ private Configuration configuration; /** Interface to freenet. */ private FreenetInterface freenetInterface; + /** The WoT connector. */ + private WebOfTrustConnector webOfTrustConnector; + /** The Sone downloader. */ private SoneDownloader soneDownloader; /** The local Sones. */ - private final Set localSones = new HashSet(); + private final Set localSones = Collections.synchronizedSet(new HashSet()); /** Sone inserters. */ - private final Map soneInserters = new HashMap(); + private final Map soneInserters = Collections.synchronizedMap(new HashMap()); /** The Sones’ statuses. */ private final Map soneStatuses = Collections.synchronizedMap(new HashMap()); @@ -96,13 +117,13 @@ public class Core extends AbstractService { /* various caches follow here. */ /** Cache for all known Sones. */ - private final Map soneCache = new HashMap(); + private final Map soneCache = Collections.synchronizedMap(new HashMap()); /** Cache for all known posts. */ - private final Map postCache = new HashMap(); + private final Map postCache = Collections.synchronizedMap(new HashMap()); /** Cache for all known replies. */ - private final Map replyCache = new HashMap(); + private final Map replyCache = Collections.synchronizedMap(new HashMap()); /** * Creates a new core. @@ -116,6 +137,15 @@ public class Core extends AbstractService { // /** + * Returns the options of the Sone plugin. + * + * @return The options of the Sone plugin + */ + public Options getOptions() { + return options; + } + + /** * Sets the configuration of the core. * * @param configuration @@ -142,6 +172,27 @@ public class Core extends AbstractService { } /** + * Returns the Web of Trust connector. + * + * @return The Web of Trust connector + */ + public WebOfTrustConnector getWebOfTrustConnector() { + return webOfTrustConnector; + } + + /** + * Sets the Web of Trust connector. + * + * @param webOfTrustConnector + * The Web of Trust connector + * @return This core (for method chaining) + */ + public Core setWebOfTrustConnector(WebOfTrustConnector webOfTrustConnector) { + this.webOfTrustConnector = webOfTrustConnector; + return this; + } + + /** * Returns the local Sones. * * @return The local Sones @@ -173,7 +224,7 @@ public class Core extends AbstractService { * @return All known sones */ public Collection getKnownSones() { - return soneCache.values(); + return Collections.unmodifiableCollection(soneCache.values()); } /** @@ -182,14 +233,7 @@ public class Core extends AbstractService { * @return All remote Sones */ public Collection getRemoteSones() { - return Filters.filteredCollection(getKnownSones(), new Filter() { - - @Override - @SuppressWarnings("synthetic-access") - public boolean filterObject(Sone object) { - return !localSones.contains(object); - } - }); + return Collections.unmodifiableCollection(getKnownSones()); } /** @@ -322,7 +366,7 @@ public class Core extends AbstractService { * if a Sone error occurs */ public Sone createSone(String name) throws SoneException { - return createSone(name, "Sone-" + name, null, null); + return createSone(name, "Sone", null, null); } /** @@ -414,6 +458,7 @@ public class Core extends AbstractService { } else { addSone(parsedSone); } + setSoneStatus(parsedSone, SoneStatus.idle); } } catch (MalformedURLException mue1) { logger.log(Level.INFO, "Could not create URI from “" + requestUri + "”.", mue1); @@ -423,6 +468,26 @@ public class Core extends AbstractService { } /** + * Loads a Sone from an input stream. + * + * @param soneInputStream + * The input stream to load the Sone from + * @return The parsed Sone, or {@code null} if the Sone could not be parsed + */ + public Sone loadSone(InputStream soneInputStream) { + Sone parsedSone = soneDownloader.parseSone(soneInputStream); + if (parsedSone == null) { + return null; + } + if (parsedSone.getInsertUri() != null) { + addLocalSone(parsedSone); + } else { + addSone(parsedSone); + } + return parsedSone; + } + + /** * Loads and updates the given Sone. * * @param sone @@ -463,6 +528,8 @@ public class Core extends AbstractService { SoneInserter soneInserter = soneInserters.remove(sone); soneInserter.stop(); localSones.remove(sone); + soneStatuses.remove(sone); + soneCache.remove(sone.getId()); } /** @@ -529,8 +596,8 @@ public class Core extends AbstractService { * The post to check for * @return All Sones that like the post */ - public Set getLikes(final Post post) { - return Filters.filteredSet(getSones(), new Filter() { + public Collection getLikes(final Post post) { + return Filters.filteredCollection(getKnownSones(), new Filter() { @Override public boolean filterObject(Sone sone) { @@ -546,8 +613,8 @@ public class Core extends AbstractService { * The reply to check for * @return All Sones that like the reply */ - public Set getLikes(final Reply reply) { - return Filters.filteredSet(getSones(), new Filter() { + public Collection getLikes(final Reply reply) { + return Filters.filteredCollection(getKnownSones(), new Filter() { @Override public boolean filterObject(Sone sone) { @@ -598,11 +665,61 @@ public class Core extends AbstractService { // /** + * Adds some default Sones. + */ + private void addDefaultSones() { + for (String soneUri : defaultSones) { + loadSone(soneUri); + } + } + + /** * Loads the configuration. */ + @SuppressWarnings("unchecked") private void loadConfiguration() { logger.entering(Core.class.getName(), "loadConfiguration()"); + boolean firstStart = configuration.getBooleanValue("FirstStart").getValue(true); + if (firstStart) { + logger.log(Level.INFO, "First start of Sone, adding a couple of default Sones…"); + addDefaultSones(); + try { + configuration.getBooleanValue("FirstStart").setValue(false); + } catch (ConfigurationException ce1) { + logger.log(Level.WARNING, "Could not clear “first start” flag!"); + } + } + + options.addIntegerOption("InsertionDelay", new DefaultOption(60, new OptionWatcher() { + + @Override + public void optionChanged(Option option, Integer oldValue, Integer newValue) { + SoneInserter.setInsertionDelay(newValue); + } + + })); + + options.addBooleanOption("ClearOnNextRestart", new DefaultOption(false)); + options.addBooleanOption("ReallyClearOnNextRestart", new DefaultOption(false)); + + if (firstStart) { + return; + } + + options.getBooleanOption("ClearOnNextRestart").set(configuration.getBooleanValue("Option/ClearOnNextRestart").getValue(null)); + options.getBooleanOption("ReallyClearOnNextRestart").set(configuration.getBooleanValue("Option/ReallyClearOnNextRestart").getValue(null)); + boolean clearConfiguration = options.getBooleanOption("ClearOnNextRestart").get() && options.getBooleanOption("ReallyClearOnNextRestart").get(); + options.getBooleanOption("ClearOnNextRestart").set(null); + options.getBooleanOption("ReallyClearOnNextRestart").set(null); + if (clearConfiguration) { + /* stop loading the configuration. */ + addDefaultSones(); + return; + } + + options.getIntegerOption("InsertionDelay").set(configuration.getIntValue("Option/InsertionDelay").getValue(null)); + /* parse local Sones. */ logger.log(Level.INFO, "Loading Sones…"); int soneId = 0; @@ -620,11 +737,15 @@ public class Core extends AbstractService { String firstName = configuration.getStringValue(sonePrefix + "/Profile/FirstName").getValue(null); String middleName = configuration.getStringValue(sonePrefix + "/Profile/MiddleName").getValue(null); String lastName = configuration.getStringValue(sonePrefix + "/Profile/LastName").getValue(null); + Integer birthDay = configuration.getIntValue(sonePrefix + "/Profile/BirthDay").getValue(null); + Integer birthMonth = configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").getValue(null); + Integer birthYear = configuration.getIntValue(sonePrefix + "/Profile/BirthYear").getValue(null); try { Profile profile = new Profile(); profile.setFirstName(firstName); profile.setMiddleName(middleName); profile.setLastName(lastName); + profile.setBirthDay(birthDay).setBirthMonth(birthMonth).setBirthYear(birthYear); Sone sone = getSone(id).setName(name).setTime(time).setRequestUri(new FreenetURI(requestUri)).setInsertUri(new FreenetURI(insertUri)); sone.setProfile(profile); int postId = 0; @@ -668,17 +789,6 @@ public class Core extends AbstractService { sone.addFriend(friendSone); } - /* load blocked Sone IDs. */ - int blockedSoneCounter = 0; - while (true) { - String blockedSonePrefix = sonePrefix + "/BlockedSone." + blockedSoneCounter++; - String blockedSoneId = configuration.getStringValue(blockedSonePrefix + "/ID").getValue(null); - if (blockedSoneId == null) { - break; - } - sone.addBlockedSoneId(blockedSoneId); - } - /* load liked post IDs. */ int likedPostIdCounter = 0; while (true) { @@ -709,23 +819,6 @@ public class Core extends AbstractService { } while (true); logger.log(Level.INFO, "Loaded %d Sones.", getSones().size()); - /* load all known Sones. */ - int knownSonesCounter = 0; - while (true) { - String knownSonePrefix = "KnownSone." + knownSonesCounter++; - String knownSoneId = configuration.getStringValue(knownSonePrefix + "/ID").getValue(null); - if (knownSoneId == null) { - break; - } - String knownSoneName = configuration.getStringValue(knownSonePrefix + "/Name").getValue(null); - String knownSoneKey = configuration.getStringValue(knownSonePrefix + "/Key").getValue(null); - try { - getSone(knownSoneId).setName(knownSoneName).setRequestUri(new FreenetURI(knownSoneKey)); - } catch (MalformedURLException mue1) { - logger.log(Level.WARNING, "Could not create Sone from requestUri (“" + knownSoneKey + "”)!", mue1); - } - } - /* load all remote Sones. */ for (Sone remoteSone : getRemoteSones()) { loadSone(remoteSone); @@ -740,7 +833,13 @@ public class Core extends AbstractService { private void saveConfiguration() { Set sones = getSones(); logger.log(Level.INFO, "Storing %d Sones…", sones.size()); + try { + /* store the options first. */ + configuration.getIntValue("Option/InsertionDelay").setValue(options.getIntegerOption("InsertionDelay").getReal()); + configuration.getBooleanValue("Option/ClearOnNextRestart").setValue(options.getBooleanOption("ClearOnNextRestart").getReal()); + configuration.getBooleanValue("Option/ReallyClearOnNextRestart").setValue(options.getBooleanOption("ReallyClearOnNextRestart").getReal()); + /* store all Sones. */ int soneId = 0; for (Sone sone : localSones) { @@ -755,6 +854,9 @@ public class Core extends AbstractService { configuration.getStringValue(sonePrefix + "/Profile/FirstName").setValue(profile.getFirstName()); configuration.getStringValue(sonePrefix + "/Profile/MiddleName").setValue(profile.getMiddleName()); configuration.getStringValue(sonePrefix + "/Profile/LastName").setValue(profile.getLastName()); + configuration.getIntValue(sonePrefix + "/Profile/BirthDay").setValue(profile.getBirthDay()); + configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").setValue(profile.getBirthMonth()); + configuration.getIntValue(sonePrefix + "/Profile/BirthYear").setValue(profile.getBirthYear()); int postId = 0; for (Post post : sone.getPosts()) { String postPrefix = sonePrefix + "/Post." + postId++; @@ -786,14 +888,6 @@ public class Core extends AbstractService { /* write null ID as terminator. */ configuration.getStringValue(sonePrefix + "/Friend." + friendId + "/ID").setValue(null); - /* write all blocked Sones. */ - int blockedSoneCounter = 0; - for (String blockedSoneId : sone.getBlockedSoneIds()) { - String blockedSonePrefix = sonePrefix + "/BlockedSone." + blockedSoneCounter++; - configuration.getStringValue(blockedSonePrefix + "/ID").setValue(blockedSoneId); - } - configuration.getStringValue(sonePrefix + "/BlockedSone." + blockedSoneCounter + "/ID").setValue(null); - /* write all liked posts. */ int likedPostIdCounter = 0; for (String soneLikedPostId : sone.getLikedPostIds()) { @@ -814,17 +908,6 @@ public class Core extends AbstractService { /* write null ID as terminator. */ configuration.getStringValue("Sone/Sone." + soneId + "/ID").setValue(null); - /* write all known Sones. */ - int knownSonesCounter = 0; - for (Sone knownSone : getRemoteSones()) { - String knownSonePrefix = "KnownSone." + knownSonesCounter++; - configuration.getStringValue(knownSonePrefix + "/ID").setValue(knownSone.getId()); - configuration.getStringValue(knownSonePrefix + "/Name").setValue(knownSone.getName()); - configuration.getStringValue(knownSonePrefix + "/Key").setValue(knownSone.getRequestUri().toString()); - /* TODO - store all known stuff? */ - } - configuration.getStringValue("KnownSone." + knownSonesCounter + "/ID").setValue(null); - } catch (ConfigurationException ce1) { logger.log(Level.WARNING, "Could not store configuration!", ce1); }