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