Remove the shell stuff, make objects mutable.
[Sone.git] / src / main / java / net / pterodactylus / sone / data / Post.java
1 /*
2  * FreenetSone - StatusUpdate.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
28 /**
29  * A post is a short message that a user writes in his Sone to let other users
30  * know what is going on.
31  *
32  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
33  */
34 public class Post {
35
36         /** The GUID of the post. */
37         private final UUID id;
38
39         /** The Sone this post belongs to. */
40         private Sone sone;
41
42         /** The time of the post (in milliseconds since Jan 1, 1970 UTC). */
43         private long time;
44
45         /** The text of the post. */
46         private String text;
47
48         /** The replies that have been loaded for this post. */
49         private final Set<Reply> replies = new HashSet<Reply>();
50
51         /**
52          * Creates a new post.
53          *
54          * @param sone
55          *            The Sone this post belongs to
56          * @param text
57          *            The text of the post
58          */
59         public Post(Sone sone, String text) {
60                 this(sone, System.currentTimeMillis(), text);
61         }
62
63         /**
64          * Creates a new post.
65          *
66          * @param sone
67          *            The Sone this post belongs to
68          * @param time
69          *            The time of the post (in milliseconds since Jan 1, 1970 UTC)
70          * @param text
71          *            The text of the post
72          */
73         public Post(Sone sone, long time, String text) {
74                 this(UUID.randomUUID().toString(), sone, time, text);
75         }
76
77         /**
78          * Creates a new post.
79          *
80          * @param id
81          *            The ID of the post
82          * @param sone
83          *            The Sone this post belongs to
84          * @param time
85          *            The time of the post (in milliseconds since Jan 1, 1970 UTC)
86          * @param text
87          *            The text of the post
88          */
89         public Post(String id, Sone sone, long time, String text) {
90                 this.id = UUID.fromString(id);
91                 this.sone = sone;
92                 this.time = time;
93                 this.text = text;
94         }
95
96         //
97         // ACCESSORS
98         //
99
100         /**
101          * Returns the ID of the post.
102          *
103          * @return The ID of the post
104          */
105         public String getId() {
106                 return id.toString();
107         }
108
109         /**
110          * Returns the Sone this post belongs to.
111          *
112          * @return The Sone of this post
113          */
114         public Sone getSone() {
115                 return sone;
116         }
117
118         /**
119          * Sets the Sone of this post.
120          *
121          * @param sone
122          *            The Sone of this post
123          * @return This post (for method chaining)
124          */
125         public Post setSone(Sone sone) {
126                 this.sone = sone;
127                 return this;
128         }
129
130         /**
131          * Returns the time of the post.
132          *
133          * @return The time of the post (in milliseconds since Jan 1, 1970 UTC)
134          */
135         public long getTime() {
136                 return time;
137         }
138
139         /**
140          * Sets the time of this post.
141          *
142          * @param time
143          *            The time of this post (in milliseconds since Jan 1, 1970 UTC)
144          * @return This post (for method chaining)
145          */
146         public Post setTime(long time) {
147                 this.time = time;
148                 return this;
149         }
150
151         /**
152          * Returns the text of the post.
153          *
154          * @return The text of the post
155          */
156         public String getText() {
157                 return text;
158         }
159
160         /**
161          * Sets the text of this post.
162          *
163          * @param text
164          *            The text of this post
165          * @return This post (for method chaining)
166          */
167         public Post setText(String text) {
168                 this.text = text;
169                 return this;
170         }
171
172         /**
173          * Returns all replies to this post in unspecified order.
174          *
175          * @return All replies to this post
176          */
177         public List<Reply> getReplies() {
178                 List<Reply> sortedReplies = new ArrayList<Reply>(replies);
179                 Collections.sort(sortedReplies, new Comparator<Reply>() {
180
181                         @Override
182                         public int compare(Reply leftReply, Reply rightReply) {
183                                 return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, leftReply.getTime() - rightReply.getTime()));
184                         }
185
186                 });
187                 return sortedReplies;
188         }
189
190         /**
191          * Adds a reply to this post. The reply will not be added if its
192          * {@link Reply#getPost() post} is not equal to this post.
193          *
194          * @param reply
195          *            The reply to add
196          */
197         public void addReply(Reply reply) {
198                 if (reply.getPost().equals(this)) {
199                         replies.add(reply);
200                 }
201         }
202
203         /**
204          * Removes a reply from this post.
205          *
206          * @param reply
207          *            The reply to remove
208          */
209         public void removeReply(Reply reply) {
210                 if (reply.getPost().equals(this)) {
211                         replies.remove(reply);
212                 }
213         }
214
215         //
216         // OBJECT METHODS
217         //
218
219         /**
220          * {@inheritDoc}
221          */
222         @Override
223         public int hashCode() {
224                 return id.hashCode() ^ sone.hashCode() ^ (int) (time >> 32) ^ (int) (time & 0xffffffff) ^ text.hashCode();
225         }
226
227         /**
228          * {@inheritDoc}
229          */
230         @Override
231         public boolean equals(Object object) {
232                 if (!(object instanceof Post)) {
233                         return false;
234                 }
235                 Post post = (Post) object;
236                 return post.id.equals(id) && post.sone.equals(sone) && (post.time == time) && post.text.equals(text);
237         }
238
239         /**
240          * {@inheritDoc}
241          */
242         @Override
243         public String toString() {
244                 return getClass().getName() + "[id=" + id + ",sone=" + sone + ",time=" + time + ",text=" + text + ",replies(" + replies.size() + ")]";
245         }
246
247 }