Always return the replies sorted by time, oldest first.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / SoneShell.java
1 /*
2  * Sone - SoneShell.java - Copyright © 2010 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone.data;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Set;
25 import java.util.UUID;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import net.pterodactylus.util.logging.Logging;
30 import freenet.keys.FreenetURI;
31
32 /**
33  * {@link Shell} around a {@link Sone} that has not yet been retrieved.
34  *
35  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
36  */
37 public class SoneShell extends Sone implements Shell<Sone> {
38
39         /** The logger. */
40         private static final Logger logger = Logging.getLogger(SoneShell.class);
41
42         /** The shell creator. */
43         public static final ShellCreator<Sone> creator = new ShellCreator<Sone>() {
44
45                 @Override
46                 public Shell<Sone> createShell(String id) {
47                         return new SoneShell().setId(id);
48                 }
49         };
50
51         /** A GUID for this Sone. */
52         private UUID id;
53
54         /** The name of this Sone. */
55         private String name;
56
57         /** The URI under which the Sone is stored in Freenet. */
58         private FreenetURI requestUri;
59
60         /** The profile of this Sone. */
61         private Profile profile;
62
63         /** All friend Sones. */
64         private final Set<Sone> friendSones = new HashSet<Sone>();
65
66         /** All posts. */
67         private final List<Post> posts = new ArrayList<Post>();
68
69         /** All replies. */
70         private final Set<Reply> replies = new HashSet<Reply>();
71
72         /**
73          * Creates a new Sone shell.
74          */
75         public SoneShell() {
76                 super(null, null, null);
77         }
78
79         //
80         // ACCESSORS
81         //
82
83         /**
84          * Returns the ID of this Sone.
85          *
86          * @return The ID of this Sone
87          */
88         @Override
89         public String getId() {
90                 return id.toString();
91         }
92
93         /**
94          * Sets the ID of the Sone.
95          *
96          * @param id
97          *            The ID of the Sone
98          * @return This Sone shell (for method chaining)
99          */
100         public SoneShell setId(String id) {
101                 try {
102                         this.id = UUID.fromString(id);
103                 } catch (IllegalArgumentException iae1) {
104                         logger.log(Level.WARNING, "Invalid ID: “" + id + "”.", iae1);
105                         this.id = UUID.randomUUID();
106                 }
107                 return this;
108         }
109
110         /**
111          * Returns the name of this Sone.
112          *
113          * @return The name of this Sone
114          */
115         @Override
116         public String getName() {
117                 return name;
118         }
119
120         /**
121          * Sets the name of the Sone.
122          *
123          * @param name
124          *            The name of the Sone
125          * @return This Sone shell (for method chaining)
126          */
127         public SoneShell setName(String name) {
128                 this.name = name;
129                 return this;
130         }
131
132         /**
133          * Returns the request URI of this Sone.
134          *
135          * @return The request URI of this Sone
136          */
137         @Override
138         public FreenetURI getRequestUri() {
139                 return requestUri;
140         }
141
142         /**
143          * Sets the request URI of the Sone.
144          *
145          * @param requestUri
146          *            The request URI of the Sone
147          * @return This Sone shell (for method chaining)
148          */
149         public SoneShell setRequestUri(FreenetURI requestUri) {
150                 this.requestUri = requestUri;
151                 return this;
152         }
153
154         /**
155          * Returns a copy of the profile. If you want to update values in the
156          * profile of this Sone, update the values in the returned {@link Profile}
157          * and use {@link #setProfile(Profile)} to change the profile in this Sone.
158          *
159          * @return A copy of the profile
160          */
161         @Override
162         public Profile getProfile() {
163                 return new Profile(profile);
164         }
165
166         /**
167          * {@inheritDoc}
168          */
169         @Override
170         public void setProfile(Profile profile) {
171                 this.profile = profile;
172         }
173
174         /**
175          * Returns all friend Sones of this Sone.
176          *
177          * @return The friend Sones of this Sone
178          */
179         @Override
180         public Set<Sone> getFriendSones() {
181                 return Collections.unmodifiableSet(friendSones);
182         }
183
184         /**
185          * Returns whether this Sone has the given Sone as a friend Sone.
186          *
187          * @param friendSone
188          *            The friend Sone to check for
189          * @return {@code true} if this Sone has the given Sone as a friend,
190          *         {@code false} otherwise
191          */
192         @Override
193         public boolean hasFriendSone(Sone friendSone) {
194                 return friendSones.contains(friendSone);
195         }
196
197         /**
198          * Adds the given Sone as a friend Sone.
199          *
200          * @param friendSone
201          *            The friend Sone to add
202          * @return This Sone (for method chaining)
203          */
204         @Override
205         public Sone addFriendSone(Sone friendSone) {
206                 friendSones.add(friendSone);
207                 return this;
208         }
209
210         /**
211          * Removes the given Sone as a friend Sone.
212          *
213          * @param friendSone
214          *            The friend Sone to remove
215          * @return This Sone (for method chaining)
216          */
217         @Override
218         public Sone removeFriendSone(Sone friendSone) {
219                 friendSones.remove(friendSone);
220                 return this;
221         }
222
223         /**
224          * Returns the list of posts of this Sone.
225          *
226          * @return All posts of this Sone
227          */
228         @Override
229         public List<Post> getPosts() {
230                 return Collections.unmodifiableList(posts);
231         }
232
233         /**
234          * Adds the given post to this Sone. The post will not be added if its
235          * {@link Post#getSone() Sone} is not this Sone.
236          *
237          * @param post
238          *            The post to add
239          */
240         @Override
241         public void addPost(Post post) {
242                 posts.add(post);
243         }
244
245         /**
246          * Removes the given post from this Sone.
247          *
248          * @param post
249          *            The post to remove
250          */
251         @Override
252         public void removePost(Post post) {
253                 posts.remove(post);
254         }
255
256         /**
257          * Returns all replies this Sone made.
258          *
259          * @return All replies this Sone made
260          */
261         @Override
262         public Set<Reply> getReplies() {
263                 return Collections.unmodifiableSet(replies);
264         }
265
266         /**
267          * Adds a reply to this Sone. If the given reply was not made by this Sone,
268          * nothing is added to this Sone.
269          *
270          * @param reply
271          *            The reply to add
272          */
273         @Override
274         public void addReply(Reply reply) {
275                 replies.add(reply);
276         }
277
278         /**
279          * Removes a reply from this Sone.
280          *
281          * @param reply
282          *            The reply to remove
283          */
284         @Override
285         public void removeReply(Reply reply) {
286                 replies.remove(reply);
287         }
288
289         //
290         // INTERFACE Shell
291         //
292
293         /**
294          * {@inheritDoc}
295          */
296         @Override
297         public boolean canUnshell() {
298                 return (id != null) && (name != null) && (requestUri != null) && (profile != null);
299         }
300
301         /**
302          * {@inheritDoc}
303          */
304         @Override
305         public Sone getShelled() {
306                 if (canUnshell()) {
307                         Sone sone = new Sone(id, name, requestUri);
308                         sone.setProfile(profile);
309                         for (Sone friendSone : friendSones) {
310                                 sone.addFriendSone(friendSone);
311                         }
312                         for (Post post : posts) {
313                                 sone.addPost(post);
314                         }
315                         for (Reply reply : replies) {
316                                 sone.addReply(reply);
317                         }
318                         return sone;
319                 }
320                 return this;
321         }
322
323 }