From: David ‘Bombe’ Roden Date: Mon, 10 Jan 2011 19:16:25 +0000 (+0100) Subject: Merge branch 'next' into image-management X-Git-Tag: beta-freefall-0.6.2-1~137 X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=commitdiff_plain;h=0157d6ead52bd7c3052b368bed7026075be7cb33;hp=a474ae28d3820854e9a8d8ea5b9f3a44b06fa737 Merge branch 'next' into image-management --- diff --git a/src/main/java/net/pterodactylus/sone/data/Album.java b/src/main/java/net/pterodactylus/sone/data/Album.java new file mode 100644 index 0000000..76015c8 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/Album.java @@ -0,0 +1,291 @@ +/* + * Sone - Album.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 . + */ + +package net.pterodactylus.sone.data; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import net.pterodactylus.util.validation.Validation; + +/** + * Container for images that can also contain nested {@link Album}s. + * + * @author David ‘Bombe’ Roden + */ +public class Album implements Fingerprintable { + + /** The ID of this album. */ + private final String id; + + /** The Sone this album belongs to. */ + private final Sone sone; + + /** Nested albums. */ + private final List albums = new ArrayList(); + + /** The images in this album. */ + private final List images = new ArrayList(); + + /** The parent album. */ + private Album parent; + + /** The name of this album. */ + private String name; + + /** The description of this album. */ + private String description; + + /** + * Creates a new album with a random ID. + * + * @param sone + * The Sone this album belongs to + */ + public Album(Sone sone) { + this(UUID.randomUUID().toString(), sone); + } + + /** + * Creates a new album with the given ID. + * + * @param id + * The ID of the album + * @param sone + * The Sone this album belongs to + */ + public Album(String id, Sone sone) { + Validation.begin().isNotNull("Album ID", id).isNotNull("Album Owner", sone).check(); + this.id = id; + this.sone = sone; + } + + // + // ACCESSORS + // + + /** + * Returns the ID of this album. + * + * @return The ID of this album + */ + public String getId() { + return id; + } + + /** + * Returns the Sone this album belongs to. + * + * @return The Sone this album belongs to + */ + public Sone getSone() { + return sone; + } + + /** + * Returns the nested albums. + * + * @return The nested albums + */ + public List getNestedAlbums() { + return new ArrayList(albums); + } + + /** + * Adds an album to this album. + * + * @param album + * The album to add + */ + public void addAlbum(Album album) { + Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.sone, sone).isNull("Album Parent", album.parent).check(); + albums.add(album); + album.setParent(this); + } + + /** + * Removes an album from this album. + * + * @param album + * The album to remove + */ + public void removeAlbum(Album album) { + Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.sone, sone).isEqual("Album Parent", album.parent, this).check(); + albums.remove(album); + album.removeParent(); + } + + /** + * Returns the images in this album. + * + * @return The images in this album + */ + public List getImages() { + return new ArrayList(images); + } + + /** + * Adds the given image to this album. + * + * @param image + * The image to add + */ + public void addImage(Image image) { + Validation.begin().isNotNull("Image", image).check().isEqual("Image Owner", image.getSone(), sone).check(); + images.add(image); + } + + /** + * Removes the given image from this album. + * + * @param image + * The image to remove + */ + public void removeImage(Image image) { + Validation.begin().isNotNull("Image", image).check().isEqual("Image Owner", image.getSone(), sone).check(); + images.remove(image); + } + + /** + * Returns the parent album of this album. + * + * @return The parent album of this album, or {@code null} if this album + * does not have a parent + */ + public Album getParent() { + return parent; + } + + /** + * Sets the parent album of this album. + * + * @param parent + * The new parent album of this album + * @return This album + */ + protected Album setParent(Album parent) { + Validation.begin().isNotNull("Album Parent", parent).check(); + this.parent = parent; + return this; + } + + /** + * Removes the parent album of this album. + * + * @return This album + */ + protected Album removeParent() { + Validation.begin().isNotNull("Album Parent", parent).check(); + this.parent = null; + return this; + } + + /** + * Returns the name of this album. + * + * @return The name of this album + */ + public String getName() { + return name; + } + + /** + * Sets the name of this album. + * + * @param name + * The name of this album + * @return This album + */ + public Album setName(String name) { + Validation.begin().isNotNull("Album Name", name).check(); + this.name = name; + return this; + } + + /** + * Returns the description of this album. + * + * @return The description of this album + */ + public String getDescription() { + return description; + } + + /** + * Sets the description of this album. + * + * @param description + * The description of this album + * @return This album + */ + public Album setDescription(String description) { + Validation.begin().isNotNull("Album Description", description).check(); + this.description = description; + return this; + } + + // + // FINGERPRINTABLE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public String getFingerprint() { + StringBuilder fingerprint = new StringBuilder(); + fingerprint.append("Album("); + fingerprint.append("ID(").append(id).append(')'); + fingerprint.append("Name(").append(name).append(')'); + fingerprint.append("Description(").append(description).append(')'); + + /* add nested albums. */ + fingerprint.append("Albums("); + for (Album album : albums) { + fingerprint.append(album.getFingerprint()); + } + fingerprint.append(')'); + + /* add images. */ + fingerprint.append("Images("); + for (Image image : images) { + fingerprint.append(image.getFingerprint()); + } + fingerprint.append(')'); + + fingerprint.append(')'); + return fingerprint.toString(); + } + + // + // OBJECT METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object object) { + if (!(object instanceof Album)) { + return false; + } + Album album = (Album) object; + return sone.equals(album.sone) && id.equals(album.id); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/data/Fingerprintable.java b/src/main/java/net/pterodactylus/sone/data/Fingerprintable.java new file mode 100644 index 0000000..013e0b3 --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/Fingerprintable.java @@ -0,0 +1,36 @@ +/* + * Sone - Fingerprintable.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 . + */ + +package net.pterodactylus.sone.data; + +/** + * Interface for objects that can create a fingerprint of themselves, e.g. to + * detect modifications. The fingerprint should only contain original + * information; derived information should not be included. + * + * @author David ‘Bombe’ Roden + */ +public interface Fingerprintable { + + /** + * Returns the fingerprint of this object. + * + * @return The fingerprint of this object + */ + public String getFingerprint(); + +} diff --git a/src/main/java/net/pterodactylus/sone/data/Image.java b/src/main/java/net/pterodactylus/sone/data/Image.java new file mode 100644 index 0000000..6b7b1dd --- /dev/null +++ b/src/main/java/net/pterodactylus/sone/data/Image.java @@ -0,0 +1,220 @@ +/* + * Sone - Image.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 . + */ + +package net.pterodactylus.sone.data; + +import java.util.UUID; + +import net.pterodactylus.util.validation.Validation; + +/** + * Container for image metadata. + * + * @author David ‘Bombe’ Roden + */ +public class Image implements Fingerprintable { + + /** The ID of the image. */ + private final String id; + + /** The Sone the image belongs to. */ + private final Sone sone; + + /** The key of the image. */ + private final String key; + + /** The creation time of the image. */ + private final long creationTime; + + /** The width of the image. */ + private final int width; + + /** The height of the image. */ + private final int height; + + /** The title of the image. */ + private String title; + + /** The description of the image. */ + private String description; + + /** + * Creates a new image. + * + * @param sone + * The Sone the image belongs to + * @param key + * The key of the image + * @param creationTime + * The creation time of the image + * @param width + * The width of the image + * @param height + * The height of the image + */ + public Image(Sone sone, String key, long creationTime, int width, int height) { + this(UUID.randomUUID().toString(), sone, key, creationTime, width, height); + } + + /** + * Creates a new image. + * + * @param id + * The ID of the image + * @param sone + * The Sone the image belongs to + * @param key + * The key of the image + * @param creationTime + * The creation time of the image + * @param width + * The width of the image + * @param height + * The height of the image + */ + public Image(String id, Sone sone, String key, long creationTime, int width, int height) { + Validation.begin().isNotNull("Image ID", id).isNotNull("Image Owner", sone).isNotNull("Image Key", key).isGreater("Image Creation Time", creationTime, 0).isGreater("Image Width", width, 0).isGreater("Image Height", height, 0).check(); + this.id = id; + this.sone = sone; + this.key = key; + this.creationTime = creationTime; + this.width = width; + this.height = height; + } + + // + // ACCESSORS + // + + /** + * Returns the ID of this image. + * + * @return The ID of this image + */ + public String getId() { + return id; + } + + /** + * Returns the Sone this image belongs to. + * + * @return The Sone this image belongs to + */ + public Sone getSone() { + return sone; + } + + /** + * Returns the key of this image. + * + * @return The key of this image + */ + public String getKey() { + return key; + } + + /** + * Returns the creation time of this image. + * + * @return The creation time of this image (in milliseconds since 1970, Jan + * 1, UTC) + */ + public long getCreationTime() { + return creationTime; + } + + /** + * Returns the width of this image. + * + * @return The width of this image (in pixels) + */ + public int getWidth() { + return width; + } + + /** + * Returns the height of this image. + * + * @return The height of this image (in pixels) + */ + public int getHeight() { + return height; + } + + /** + * Returns the title of this image. + * + * @return The title of this image + */ + public String getTitle() { + return title; + } + + /** + * Sets the title of this image. + * + * @param title + * The title of this image + * @return This image + */ + public Image setTitle(String title) { + Validation.begin().isNotNull("Image Title", title).check(); + this.title = title; + return this; + } + + /** + * Returns the description of this image. + * + * @return The description of this image + */ + public String getDescription() { + return description; + } + + /** + * Sets the description of this image. + * + * @param description + * The description of this image + * @return This image + */ + public Image setDescription(String description) { + Validation.begin().isNotNull("Image Description", description).check(); + this.description = description; + return this; + } + + // + // FINGERPRINTABLE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + public String getFingerprint() { + StringBuilder fingerprint = new StringBuilder(); + fingerprint.append("Image("); + fingerprint.append("ID(").append(id).append(')'); + fingerprint.append("Title(").append(title).append(')'); + fingerprint.append("Description(").append(description).append(')'); + fingerprint.append(')'); + return fingerprint.toString(); + } + +} diff --git a/src/main/java/net/pterodactylus/sone/data/Sone.java b/src/main/java/net/pterodactylus/sone/data/Sone.java index 7d4f7ef..91b1c10 100644 --- a/src/main/java/net/pterodactylus/sone/data/Sone.java +++ b/src/main/java/net/pterodactylus/sone/data/Sone.java @@ -30,6 +30,7 @@ import java.util.logging.Logger; import net.pterodactylus.sone.freenet.wot.Identity; import net.pterodactylus.sone.template.SoneAccessor; import net.pterodactylus.util.logging.Logging; +import net.pterodactylus.util.validation.Validation; import freenet.keys.FreenetURI; /** @@ -40,7 +41,7 @@ import freenet.keys.FreenetURI; * * @author David ‘Bombe’ Roden */ -public class Sone { +public class Sone implements Fingerprintable { /** comparator that sorts Sones by their nice name. */ public static final Comparator NICE_NAME_COMPARATOR = new Comparator() { @@ -99,6 +100,9 @@ public class Sone { /** The IDs of all liked replies. */ private final Set likedReplyIds = Collections.synchronizedSet(new HashSet()); + /** The albums of this Sone. */ + private final List albums = Collections.synchronizedList(new ArrayList()); + /** * Creates a new Sone. * @@ -581,13 +585,44 @@ public class Sone { } /** - * Returns a fingerprint of this Sone. The fingerprint only depends on data - * that is actually stored when a Sone is inserted. The fingerprint can be - * used to detect changes in Sone data and can also be used to detect if - * previous changes are reverted. + * Returns the albums of this Sone. + * + * @return The albums of this Sone + */ + public List getAlbums() { + return Collections.unmodifiableList(albums); + } + + /** + * Adds an album to this Sone. * - * @return The fingerprint of this Sone + * @param album + * The album to add */ + public synchronized void addAlbum(Album album) { + Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check(); + albums.add(album); + } + + /** + * Removes an album from this Sone. + * + * @param album + * The album to remove + */ + public synchronized void removeAlbum(Album album) { + Validation.begin().isNotNull("Album", album).check().isEqual("Album Owner", album.getSone(), this).check(); + albums.remove(album); + } + + // + // FINGERPRINTABLE METHODS + // + + /** + * {@inheritDoc} + */ + @Override public synchronized String getFingerprint() { StringBuilder fingerprint = new StringBuilder(); fingerprint.append("Profile("); @@ -641,6 +676,12 @@ public class Sone { } fingerprint.append(')'); + fingerprint.append("Albums("); + for (Album album : albums) { + fingerprint.append(album.getFingerprint()); + } + fingerprint.append(')'); + return fingerprint.toString(); } diff --git a/src/main/resources/templates/insert/include/album.xml b/src/main/resources/templates/insert/include/album.xml new file mode 100644 index 0000000..cd845da --- /dev/null +++ b/src/main/resources/templates/insert/include/album.xml @@ -0,0 +1,23 @@ + + <% album.id|xml> + <% album.name|xml> + <% album.description|xml> + + <%foreach album.albums album> + <%include insert/include/album.xml> + <%/foreach> + + + <%foreach album.images image> + + <% image.id|xml> + <% image.creationTime|xml> + <% image.key|xml> + <% image.width|xml> + <% image.height|xml> + <% image.title|xml> + <% image.description|xml> + + <%/foreach> + + diff --git a/src/main/resources/templates/insert/sone.xml b/src/main/resources/templates/insert/sone.xml index 7d3c8aa..1f12d90 100644 --- a/src/main/resources/templates/insert/sone.xml +++ b/src/main/resources/templates/insert/sone.xml @@ -52,4 +52,10 @@ <%/foreach> + + <%foreach currentSone.albums album> + <%include insert/include/album.xml> + <%/foreach> + +