--- /dev/null
+/*
+ * Sone - Database.java - Copyright © 2011 David Roden
+ *
+ * This 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.database;
+
+import java.util.Collection;
+
+import net.pterodactylus.sone.data.Sone;
+
+/**
+ * Interface for Sone’s database.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public interface Database {
+
+ /**
+ * Returns whether the given Sone is a local Sone.
+ *
+ * @param sone
+ * The Sone to check
+ * @return {@code true} if the given Sone is a local Sone, {@code false}
+ * otherwise
+ * @throws IllegalArgumentException
+ * if {@code sone} is {@code null}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public boolean isLocalSone(Sone sone) throws DatabaseException;
+
+ /**
+ * Returns whether the given Sone ID belongs to a local Sone.
+ *
+ * @param id
+ * The Sone ID to check
+ * @return {@code true} if the given Sone ID belongs to a local Sone,
+ * {@code false} otherwise
+ * @throws IllegalArgumentException
+ * if {@code id} is {@code null}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public boolean isLocalSone(String id) throws DatabaseException;
+
+ /**
+ * Returns whether the given Sone is a remote Sone.
+ *
+ * @param sone
+ * The Sone to check
+ * @return {@code true} if the given Sone is a remote Sone, {@code false}
+ * otherwise
+ * @throws IllegalArgumentException
+ * if {@code sone} is {@code null}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public boolean isRemoteSone(Sone sone) throws DatabaseException;
+
+ /**
+ * Returns whether the given Sone ID belongs to a remote Sone.
+ *
+ * @param id
+ * The Sone ID to check
+ * @return {@code true} if the given Sone ID belongs to a remote Sone,
+ * {@code false} otherwise
+ * @throws IllegalArgumentException
+ * if {@code id} is {@code null}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public boolean isRemoteSone(String id) throws DatabaseException;
+
+ /**
+ * Returns the Sone with the given ID, creating a new Sone if a Sone with
+ * the given ID does not exist and {@code create} is {@code true}. When
+ * searching for a Sone with the given IDs, local Sones are preferred.
+ *
+ * @param id
+ * The ID of the new Sone
+ * @param create
+ * {@code true} to create a new Sone if a Sone with the given ID
+ * does not exist, {@code false} to return {@code null} if a Sone
+ * with the given ID does not exist
+ * @return The created Sone
+ * @throws IllegalArgumentException
+ * if {@code id} is {@code null}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public Sone getSone(String id, boolean create) throws DatabaseException;
+
+ /**
+ * Returns all known Sones.
+ *
+ * @return All known Sones
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public Collection<Sone> getSones() throws DatabaseException;
+
+ /**
+ * Returns all known local Sones.
+ *
+ * @return All known local Sones
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public Collection<Sone> getLocalSones() throws DatabaseException;
+
+ /**
+ * Returns all known remote Sones.
+ *
+ * @return All known remote Sones
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public Collection<Sone> getRemoteSones() throws DatabaseException;
+
+ /**
+ * Returns the local Sone with the given ID, creating it if it doesn’t exist
+ * and {@code create} is {@code true}.
+ *
+ * @param id
+ * The ID of the Sone
+ * @param create
+ * {@code true} to create a Sone if no Sone with the given ID
+ * exists yet, {@code false} to return {@code null}
+ * @return The existing Sone, the created Sone, or {@code null}
+ * @throws DatabaseException
+ * if adatabase error occurs
+ */
+ public Sone getLocalSone(String id, boolean create) throws DatabaseException;
+
+ /**
+ * Returns the remote Sone with the given ID, creating it if it doesn’t
+ * exist and {@code create} is {@code true}.
+ *
+ * @param id
+ * The ID of the Sone
+ * @param create
+ * {@code true} to create a Sone if no Sone with the given ID
+ * exists yet, {@code false} to return {@code null}
+ * @return The existing Sone, the created Sone, or {@code null}
+ * @throws DatabaseException
+ * if adatabase error occurs
+ */
+ public Sone getRemoteSone(String id, boolean create) throws DatabaseException;
+
+ /**
+ * Stores the given Sone. The given Sone has to be an object that was
+ * returned by a previous call to {@link #getSone(String, boolean)}.
+ *
+ * @param sone
+ * The Sone to store
+ * @throws IllegalArgumentException
+ * if {@code sone} is {@code null}, or the Sone was not
+ * retrieved by a call to {@link #getSone(String, boolean)}
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public void saveSone(Sone sone) throws DatabaseException;
+
+ /**
+ * Removes the given Sone from the database.
+ *
+ * @param sone
+ * The Sone to remove
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public void removeSone(Sone sone) throws DatabaseException;
+
+ /**
+ * Removes the Sone with the given ID from the database.
+ *
+ * @param id
+ * The ID of the Sone to remove
+ * @throws DatabaseException
+ * if a database error occurs
+ */
+ public void removeSone(String id) throws DatabaseException;
+
+}
+++ /dev/null
-/*
- * Sone - SoneDatabase.java - Copyright © 2011 David Roden
- *
- * This 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.database;
-
-import net.pterodactylus.sone.data.Sone;
-
-/**
- * Interface for the Sone database.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public interface SoneDatabase {
-
- /**
- * Returns the Sone with the given ID, creating a new Sone if a Sone with
- * the given ID does not exist and {@code create} is {@code true}.
- *
- * @param id
- * The ID of the new Sone
- * @param create
- * {@code true} to create a new Sone if a Sone with the given ID
- * does not exist, {@code false} to return {@code null} if a Sone
- * with the given ID does not exist
- * @return The created Sone
- * @throws IllegalArgumentException
- * if {@code id} is {@code null}
- * @throws DatabaseException
- * if a database error occurs
- */
- public Sone getSone(String id, boolean create) throws DatabaseException;
-
- /**
- * Stores the given Sone. The given Sone has to be an object that was
- * returned by a previous call to {@link #getSone(String, boolean)}.
- *
- * @param sone
- * The Sone to store
- * @throws IllegalArgumentException
- * if {@code sone} is {@code null}, or the Sone was not
- * retrieved by a call to {@link #getSone(String, boolean)}
- * @throws DatabaseException
- * if a database error occurs
- */
- public void saveSone(Sone sone) throws DatabaseException;
-
-}
--- /dev/null
+/*
+ * Sone - MemoryDatabase.java - Copyright © 2011 David Roden
+ *
+ * This 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.database.memory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.pterodactylus.sone.core.Core;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.Database;
+import net.pterodactylus.sone.database.DatabaseException;
+import net.pterodactylus.util.collection.SetBuilder;
+import net.pterodactylus.util.validation.Validation;
+
+/**
+ * In-memory implementation of {@link Database} that stores all its data in a
+ * {@link Map}. This is roughly equivalent to what {@link Core} does today and
+ * is mainly used while Sone is transitioning to using a real database.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class MemoryDatabase implements Database {
+
+ /** The local SSones. */
+ private final Map<String, Sone> localSones = new HashMap<String, Sone>();
+
+ /** The remote Sones. */
+ private final Map<String, Sone> remoteSones = new HashMap<String, Sone>();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLocalSone(Sone sone) throws DatabaseException {
+ Validation.begin().isNotNull("Sone", sone).check();
+ return isLocalSone(sone.getId());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isLocalSone(String id) throws DatabaseException {
+ Validation.begin().isNotNull("Sone ID", id).check();
+ synchronized (localSones) {
+ return localSones.containsKey(id);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRemoteSone(Sone sone) throws DatabaseException {
+ Validation.begin().isNotNull("Sone", sone).check();
+ return isRemoteSone(sone.getId());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRemoteSone(String id) throws DatabaseException {
+ Validation.begin().isNotNull("Sone ID", id).check();
+ synchronized (remoteSones) {
+ return remoteSones.containsKey(id);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone getSone(String id, boolean create) throws DatabaseException {
+ if (isLocalSone(id)) {
+ return getLocalSone(id, create);
+ }
+ return getRemoteSone(id, create);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Sone> getSones() throws DatabaseException {
+ return new SetBuilder<Sone>().addAll(getLocalSones()).addAll(getRemoteSones()).get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Sone> getLocalSones() throws DatabaseException {
+ synchronized (localSones) {
+ return Collections.unmodifiableCollection(localSones.values());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Sone> getRemoteSones() throws DatabaseException {
+ synchronized (remoteSones) {
+ return Collections.unmodifiableCollection(remoteSones.values());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone getLocalSone(String id, boolean create) throws DatabaseException {
+ Validation.begin().isNotNull("Sone ID", id).check();
+ synchronized (localSones) {
+ if (!localSones.containsKey(id)) {
+ localSones.put(id, new Sone(id));
+ }
+ return localSones.get(id);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Sone getRemoteSone(String id, boolean create) throws DatabaseException {
+ Validation.begin().isNotNull("Sone ID", id).check();
+ synchronized (remoteSones) {
+ if (!remoteSones.containsKey(id)) {
+ remoteSones.put(id, new Sone(id));
+ }
+ return remoteSones.get(id);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void saveSone(Sone sone) throws DatabaseException {
+ if (isLocalSone(sone)) {
+ synchronized (localSones) {
+ localSones.put(sone.getId(), sone);
+ }
+ } else {
+ synchronized (remoteSones) {
+ Validation.begin().is("Sone is from this database", remoteSones.containsKey(sone.getId())).check();
+ remoteSones.put(sone.getId(), sone);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeSone(Sone sone) throws DatabaseException {
+ Map<String, Sone> sones = isLocalSone(sone) ? localSones : remoteSones;
+ synchronized (sones) {
+ sones.remove(sone.getId());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeSone(String id) throws DatabaseException {
+ Map<String, Sone> sones = isLocalSone(id) ? localSones : remoteSones;
+ synchronized (sones) {
+ sones.remove(id);
+ }
+ }
+
+}
+++ /dev/null
-/*
- * Sone - MemorySoneDatabase.java - Copyright © 2011 David Roden
- *
- * This 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.database.memory;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import net.pterodactylus.sone.core.Core;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.DatabaseException;
-import net.pterodactylus.sone.database.SoneDatabase;
-import net.pterodactylus.util.validation.Validation;
-
-/**
- * In-memory implementation of {@link SoneDatabase} that stores all its data in
- * a {@link Map}. This is roughly equivalent to what {@link Core} does today and
- * is mainly used while Sone is transitioning to using a real database.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class MemorySoneDatabase implements SoneDatabase {
-
- /** The Sones. */
- private final Map<String, Sone> sones = new HashMap<String, Sone>();
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Sone getSone(String id, boolean create) throws DatabaseException {
- Validation.begin().isNotNull("Sone ID", id).check();
- synchronized (sones) {
- if (!sones.containsKey(id)) {
- sones.put(id, new Sone(id));
- }
- return sones.get(id);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void saveSone(Sone sone) throws DatabaseException {
- synchronized (sones) {
- Validation.begin().isNotNull("Sone", sone).check().is("Sone is an in-memory Sone", sones.containsKey(sone.getId())).check();
- }
- /* this is a no-op. */
- }
-
-}