1 package org.unitedfront2.domain.communication;
2
3 import java.io.Serializable;
4 import java.util.List;
5
6 import org.apache.commons.lang.builder.EqualsBuilder;
7 import org.apache.commons.lang.builder.HashCodeBuilder;
8 import org.apache.commons.lang.builder.ToStringBuilder;
9 import org.unitedfront2.dao.BlogDao;
10 import org.unitedfront2.domain.Deletable;
11 import org.unitedfront2.domain.Domain;
12 import org.unitedfront2.domain.Identifiable;
13 import org.unitedfront2.domain.Storable;
14 import org.unitedfront2.domain.accesscontrol.AbstractResource;
15 import org.unitedfront2.domain.accesscontrol.AccessControl;
16 import org.unitedfront2.domain.accesscontrol.AccessDeniedException;
17
18 /**
19 * ブログを表すドメインモデルです。
20 *
21 * @invariant ${this.writeAccessControl} is
22 * {@link org.unitedfront2.domain.accesscontrol.OwnerOnly}
23 * @invariant ${this.readAccessControl} is ${this.overview.readAccessControl}
24 * @invariant ${this.writeAccessControl} is ${this.overview.writeAccessControl}
25 * @invariant ブログ記事が存在するブログは削除できない。
26 * @author kurokkie
27 *
28 */
29 public class Blog extends AbstractResource implements Serializable,
30 Identifiable<Blog>, Storable, Deletable, Domain {
31
32 /** シリアル番号 */
33 private static final long serialVersionUID = 5187863597884559866L;
34
35 /** ID */
36 private Integer id;
37
38 /**
39 * コード
40 *
41 * @invariant 一意な値
42 */
43 private String code;
44
45 /** 概要 */
46 private Message overview;
47
48 /** コメント投稿に対するアクセス制御 */
49 private AccessControl commentAccessControl;
50
51 /** ブログ記事リスト */
52 private transient List<BlogEntry> entries;
53
54 /** ブログ記事総数 */
55 private transient int count;
56
57 /** ブログデータアクセスオブジェクト */
58 private transient BlogDao blogDao;
59
60 public Blog() {
61 super();
62 }
63
64 public Blog(String code, Message overview, Integer ownerId,
65 AccessControl readAccessControl, AccessControl writeAccessControl,
66 AccessControl commeAccessControl) {
67 super(ownerId, readAccessControl, writeAccessControl);
68 this.code = code;
69 this.overview = overview;
70 this.commentAccessControl = commeAccessControl;
71 }
72
73 public Blog(Integer id, String code, Message overview, Integer ownerId,
74 AccessControl readAccessControl, AccessControl writeAccessControl,
75 AccessControl commeAccessControl) {
76 this(code, overview, ownerId, readAccessControl, writeAccessControl,
77 commeAccessControl);
78 this.id = id;
79 }
80
81 @Override
82 protected boolean buildEqualsBuilder(EqualsBuilder eb, Object other) {
83 if (!(other instanceof Blog)) {
84 return false;
85 }
86 Blog castOther = (Blog) other;
87 eb.append(id, castOther.id)
88 .append(code, castOther.code)
89 .append(overview, castOther.overview);
90 if (!super.buildEqualsBuilder(eb, other)) {
91 return false;
92 }
93 eb.append(commentAccessControl, castOther.commentAccessControl);
94 return true;
95 }
96
97 @Override
98 protected void buildHashCodeBuilder(HashCodeBuilder hcb) {
99 hcb.append(id).append(code).append(overview);
100 super.buildHashCodeBuilder(hcb);
101 hcb.append(commentAccessControl);
102 }
103
104 @Override
105 protected void buildToStringBuilder(ToStringBuilder tsb) {
106 tsb.append("id", id).append("code", code).append("overview", overview);
107 super.buildToStringBuilder(tsb);
108 tsb.append("commentAccessControl", commentAccessControl);
109 }
110
111 /**
112 * @throws BlogCodeUsedByOtherException 指定したコードが他のブログで既に使用されている
113 */
114 @Override
115 public void store() throws BlogCodeUsedByOtherException {
116 Blog foundByCode = blogDao.findByCode(code);
117 if (foundByCode != null && !foundByCode.identify(this)) {
118 String message = "The code '" + code
119 + "' has already been used by other.";
120 logger.warn(message);
121 throw new BlogCodeUsedByOtherException(message);
122 }
123 if (this.id == null) {
124 blogDao.register(this);
125 } else {
126 blogDao.update(this);
127 }
128 }
129
130 @Override
131 public boolean identify(Blog blog) {
132 if (id == null) {
133 return false;
134 }
135 return id.equals(blog.getId());
136 }
137
138 /**
139 * 指定した範囲のブログ記事を復元します。記事番号は0から始まる整数で、ID の降順になります。
140 *
141 * @param no 開始点となる記事番号
142 * @param num 件数
143 */
144 public void retrieveEntries(int no, int num) {
145 entries = blogDao.findBlogEntries(id, no, num);
146 }
147
148 /**
149 * 全てのブログ記事を復元します。
150 */
151 public void retrieveEntries() {
152 int count = blogDao.countBlogEntry(id);
153 entries = blogDao.findBlogEntries(id, 0, count);
154 }
155
156 /**
157 * ブログ記事総件数を復元します。
158 */
159 public void retrieveCount() {
160 count = blogDao.countBlogEntry(id);
161 }
162
163 /**
164 * ブログ記事を投稿します。指定したブログ記事を保存し、このブログと関連付けます。
165 *
166 * @param blogEntry ブログ記事
167 */
168 public void post(BlogEntry blogEntry) {
169 blogEntry.store();
170 blogDao.registerBlogEntry(id, blogEntry.getId());
171 }
172
173 /**
174 * 匿名ユーザで投稿アクセスを試みます。
175 *
176 * @throws AccessDeniedException アクセス拒否
177 */
178 public void commentAccess() throws AccessDeniedException {
179 commentAccessControl.access(this);
180 }
181
182 /**
183 * 投稿アクセスを試みます。
184 *
185 * @param userId ユーザ ID
186 * @throws AccessDeniedException アクセス拒否
187 */
188 public void commentAccess(int userId) throws AccessDeniedException {
189 commentAccessControl.access(this, userId);
190 }
191
192 /**
193 * 匿名ユーザに投稿アクセス権限があるか判定します。
194 *
195 * @return 権限があれば <code>true</code> 、なければ <code>false</code>
196 */
197 public boolean canComment() {
198 try {
199 commentAccess();
200 return true;
201 } catch (AccessDeniedException e) {
202 return false;
203 }
204 }
205
206 /**
207 * 投稿アクセス権限があるか判定します。
208 *
209 * @param userId ユーザ ID
210 * @return 権限があれば <code>true</code> 、なければ <code>false</code>
211 */
212 public boolean canComment(int userId) {
213 try {
214 commentAccess(userId);
215 return true;
216 } catch (AccessDeniedException e) {
217 return false;
218 }
219 }
220
221 /**
222 * @throws BlogEntryExistException ブログ記事が存在している
223 */
224 @Override
225 public void delete() throws BlogEntryExistException {
226 int count = blogDao.countBlogEntry(id);
227 if (count > 0) {
228 String message = "The blog [ID=" + id + "] has " + count
229 + " entries.";
230 logger.warn(message);
231 throw new BlogEntryExistException(message);
232 }
233 blogDao.delete(id);
234 }
235
236 public Integer getId() {
237 return id;
238 }
239
240 public void setId(Integer id) {
241 this.id = id;
242 }
243
244 public String getCode() {
245 return code;
246 }
247
248 public void setCode(String code) {
249 this.code = code;
250 }
251
252 public Message getOverview() {
253 return overview;
254 }
255
256 public void setOverview(Message overview) {
257 this.overview = overview;
258 }
259
260 public AccessControl getCommentAccessControl() {
261 return commentAccessControl;
262 }
263
264 public void setCommentAccessControl(AccessControl commentAccessControl) {
265 this.commentAccessControl = commentAccessControl;
266 }
267
268 public List<BlogEntry> getEntries() {
269 return entries;
270 }
271
272 public int getCount() {
273 return count;
274 }
275
276 public Profile getOwnerProfile() {
277 return getOwner().getProfile();
278 }
279
280 public void setBlogDao(BlogDao blogDao) {
281 this.blogDao = blogDao;
282 }
283 }