File Source: JPAWeblogManagerImpl.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.business.jpa;
20
21 import java.util.ArrayList;
22 import java.util.Calendar;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.Date;
26 import java.util.Hashtable;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.text.SimpleDateFormat;
31 import java.util.TreeMap;
32 import java.sql.Timestamp;
33 import javax.persistence.FlushModeType;
34 import javax.persistence.NoResultException;
35 import javax.persistence.Query;
36
37 import org.apache.commons.collections.comparators.ReverseComparator;
38 import org.apache.commons.lang.StringUtils;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy;
42
43 import org.apache.roller.weblogger.WebloggerException;
44 import org.apache.roller.weblogger.business.Weblogger;
45 import org.apache.roller.weblogger.business.WeblogManager;
46 import org.apache.roller.weblogger.pojos.WeblogEntryComment;
47 import org.apache.roller.weblogger.pojos.WeblogHitCount;
48 import org.apache.roller.weblogger.pojos.WeblogReferrer;
49 import org.apache.roller.weblogger.pojos.StatCount;
50 import org.apache.roller.weblogger.pojos.TagStat;
51 import org.apache.roller.weblogger.pojos.TagStatComparator;
52 import org.apache.roller.weblogger.pojos.TagStatCountComparator;
53 import org.apache.roller.weblogger.pojos.WeblogCategory;
54 import org.apache.roller.weblogger.pojos.WeblogEntry;
55 import org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate;
56 import org.apache.roller.weblogger.pojos.WeblogEntryTag;
57 import org.apache.roller.weblogger.pojos.Weblog;
58 import org.apache.roller.weblogger.pojos.WeblogEntryAttribute;
59 import org.apache.roller.weblogger.pojos.StatCountCountComparator;
60 import org.apache.roller.weblogger.pojos.User;
61 import org.apache.roller.util.DateUtil;
62
63 /*
64 * JPAWeblogManagerImpl.java
65 *
66 * Created on May 31, 2006, 4:08 PM
67 *
68 */
69 @com.google.inject.Singleton
70 public class JPAWeblogManagerImpl implements WeblogManager {
71
/*
P/P * Method: org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl__static_init
*
* Postconditions:
* init'ed(log)
* reverseComparator == &new ReverseComparator(JPAWeblogManagerImpl__static_init#1)
* init'ed(statCountCountReverseComparator)
* init'ed(tagStatCountReverseComparator)
* tagStatNameComparator == &new TagStatComparator(JPAWeblogManagerImpl__static_init#2)
* new ReverseComparator(JPAWeblogManagerImpl__static_init#1) num objects == 1
* new TagStatComparator(JPAWeblogManagerImpl__static_init#2) num objects == 1
*/
72 protected static Log log = LogFactory.getLog(
73 JPAWeblogManagerImpl.class);
74
75 private final Weblogger roller;
76 private final JPAPersistenceStrategy strategy;
77
78 // cached mapping of entryAnchors -> entryIds
79 private Hashtable entryAnchorToIdMap = new Hashtable();
80
81 /* inline creation of reverse comparator, anonymous inner class */
82 private static final Comparator reverseComparator = new ReverseComparator();
83
84 private static final Comparator tagStatNameComparator = new TagStatComparator();
85
86 private static final Comparator tagStatCountReverseComparator =
87 Collections.reverseOrder(TagStatCountComparator.getInstance());
88
89 private static final Comparator statCountCountReverseComparator =
90 Collections.reverseOrder(StatCountCountComparator.getInstance());
91
92
93 @com.google.inject.Inject
/*
P/P * Method: void org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl(Weblogger, JPAPersistenceStrategy)
*
* Preconditions:
* log != null
*
* Postconditions:
* this.entryAnchorToIdMap == &new Hashtable(JPAWeblogManagerImpl#1)
* this.roller == roller
* init'ed(this.roller)
* this.strategy == strategy
* init'ed(this.strategy)
* new Hashtable(JPAWeblogManagerImpl#1) num objects == 1
*/
94 protected JPAWeblogManagerImpl(Weblogger roller, JPAPersistenceStrategy strategy) {
95 log.debug("Instantiating JPA Weblog Manager");
96 this.roller = roller;
97 this.strategy = strategy;
98 }
99
100 /**
101 * @inheritDoc
102 */
103 public void saveWeblogCategory(WeblogCategory cat) throws WebloggerException {
/*
P/P * Method: void saveWeblogCategory(WeblogCategory)
*
* Preconditions:
* cat != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* getUserManager(...).strategy.emf@104 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@113 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWebsite(...)@118 != null
*
* Test Vectors:
* javax.persistence.EntityManager:find(...)@216: Inverse{null}, Addr_Set{null}
* org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@111: Addr_Set{null}, Inverse{null}
*/
104 boolean exists = getWeblogCategory(cat.getId()) != null;
105 if (!exists) {
+ 106 if (isDuplicateWeblogCategoryName(cat)) {
107 throw new WebloggerException("Duplicate category name, cannot save category");
108 }
109 // Newly added object. If it has a parent,
110 // maintain relationship from both sides
111 WeblogCategory parent = cat.getParent();
112 if(parent != null) {
113 parent.getWeblogCategories().add(cat);
114 }
115 }
116
117 // update weblog last modified date. date updated by saveWebsite()
118 roller.getUserManager().saveWebsite(cat.getWebsite());
119 this.strategy.store(cat);
120 }
121
122 /**
123 * @inheritDoc
124 */
125 public void removeWeblogCategory(WeblogCategory cat)
126 throws WebloggerException {
/*
P/P * Method: void removeWeblogCategory(WeblogCategory)
*
* Preconditions:
* cat != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* getUserManager(...).strategy.emf@132 != null
* java.util.List:size(...)@127 <= 0
* org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@140 != null
* org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@146 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@136 != null
* ...
*
* Test Vectors:
* org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@140: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@146: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@134: Addr_Set{null}, Inverse{null}
*/
127 if(cat.retrieveWeblogEntries(true).size() > 0) {
128 throw new WebloggerException("Cannot remove category with entries");
129 }
130
131 // remove cat
132 this.strategy.remove(cat);
133 //relationship management for the other side
134 WeblogCategory parent = cat.getParent();
135 if(parent != null) {
136 parent.getWeblogCategories().remove(cat);
137 }
138
139 // update website default cats if needed
140 if(cat.getWebsite().getBloggerCategory().equals(cat)) {
141 WeblogCategory rootCat = this.getRootWeblogCategory(cat.getWebsite());
142 cat.getWebsite().setBloggerCategory(rootCat);
143 this.strategy.store(cat.getWebsite());
144 }
145
146 if(cat.getWebsite().getDefaultCategory().equals(cat)) {
147 WeblogCategory rootCat = this.getRootWeblogCategory(cat.getWebsite());
148 cat.getWebsite().setDefaultCategory(rootCat);
149 this.strategy.store(cat.getWebsite());
150 }
151
152 // update weblog last modified date. date updated by saveWebsite()
153 roller.getUserManager().saveWebsite(
154 cat.getWebsite());
155 }
156
157 /**
158 * @inheritDoc
159 */
160 public void moveWeblogCategory(WeblogCategory srcCat, WeblogCategory destCat)
161 throws WebloggerException {
162
163 // TODO: this check should be made before calling this method?
/*
P/P * Method: void moveWeblogCategory(WeblogCategory, WeblogCategory)
*
* Preconditions:
* destCat != null
* log != null
* srcCat != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@164 == 0
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@175 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@178 != null
*
* Test Vectors:
* java.lang.String:equals(...)@180: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@173: Addr_Set{null}, Inverse{null}
*/
164 if (destCat.descendentOf(srcCat)) {
165 throw new WebloggerException(
166 "ERROR cannot move parent category into it's own child");
167 }
168
169 log.debug("Moving category "+srcCat.getPath() +
170 " under "+destCat.getPath());
171
172
173 WeblogCategory oldParent = srcCat.getParent();
174 if(oldParent != null) {
175 oldParent.getWeblogCategories().remove(srcCat);
176 }
177 srcCat.setParent(destCat);
178 destCat.getWeblogCategories().add(srcCat);
179
180 if("/".equals(destCat.getPath())) {
181 srcCat.setPath("/"+srcCat.getName());
182 } else {
183 srcCat.setPath(destCat.getPath() + "/" + srcCat.getName());
184 }
185 saveWeblogCategory(srcCat);
186
187 // the main work to be done for a category move is to update the
188 // path attribute of the category and all descendent categories
189 updatePathTree(srcCat);
190 }
191
192
193 // updates the paths of all descendents of the given category
194 private void updatePathTree(WeblogCategory cat)
195 throws WebloggerException {
196
/*
P/P * Method: void updatePathTree(WeblogCategory)
*
* Preconditions:
* cat != null
* log != null
* (soft) this.roller != null
* (soft) this.roller.userManager != null
* (soft) this.roller.userManager.strategy != null
* (soft) this.roller.userManager.strategy.threadLocalEntityManager != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@202 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@200 != null
*
* Test Vectors:
* java.lang.String:equals(...)@207: {0}, {1}
* java.util.Iterator:hasNext(...)@201: {0}, {1}
*/
197 log.debug("Updating path tree for category "+cat.getPath());
198
199 WeblogCategory childCat = null;
200 Iterator childCats = cat.getWeblogCategories().iterator();
201 while(childCats.hasNext()) {
202 childCat = (WeblogCategory) childCats.next();
203
204 log.debug("OLD child category path was "+childCat.getPath());
205
206 // update path and save
207 if("/".equals(cat.getPath())) {
208 childCat.setPath("/" + childCat.getName());
209 } else {
210 childCat.setPath(cat.getPath() + "/" + childCat.getName());
211 }
212 saveWeblogCategory(childCat);
213
214 log.debug("NEW child category path is "+ childCat.getPath());
215
216 // then make recursive call to update this cats children
217 updatePathTree(childCat);
218 }
219 }
220
221 /**
222 * @inheritDoc
223 */
224 public void moveWeblogCategoryContents(WeblogCategory srcCat,
225 WeblogCategory destCat)
226 throws WebloggerException {
227
228 // TODO: this check should be made before calling this method?
/*
P/P * Method: void moveWeblogCategoryContents(WeblogCategory, WeblogCategory)
*
* Preconditions:
* destCat != null
* srcCat != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@241 != null
* org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@257 != null
* org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@250 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@229 == 0
* org.apache.roller.weblogger.pojos.WeblogCategory:getId(...)@250 != null
* ...
*
* Test Vectors:
* java.lang.String:equals(...)@250: {1}, {0}
* java.lang.String:equals(...)@257: {1}, {0}
* java.util.Iterator:hasNext(...)@240: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@250: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@257: {0}, {1}
*/
229 if (destCat.descendentOf(srcCat)) {
230 throw new WebloggerException(
231 "ERROR cannot move parent category into it's own child");
232 }
233
234 // get all entries in category and subcats
235 List results = srcCat.retrieveWeblogEntries(true);
236
237 // Loop through entries in src cat, assign them to dest cat
238 Iterator iter = results.iterator();
239 Weblog website = destCat.getWebsite();
240 while (iter.hasNext()) {
241 WeblogEntry entry = (WeblogEntry) iter.next();
242 entry.setCategory(destCat);
243 entry.setWebsite(website);
244 this.strategy.store(entry);
245 }
246
247 // Make sure website's default and bloggerapi categories
248 // are valid after the move
249
250 if (srcCat.getWebsite().getDefaultCategory().getId()
251 .equals(srcCat.getId())
252 || srcCat.getWebsite().getDefaultCategory().descendentOf(srcCat)) {
253 srcCat.getWebsite().setDefaultCategory(destCat);
254 this.strategy.store(srcCat.getWebsite());
255 }
256
257 if (srcCat.getWebsite().getBloggerCategory().getId()
258 .equals(srcCat.getId())
259 || srcCat.getWebsite().getBloggerCategory().descendentOf(srcCat)) {
260 srcCat.getWebsite().setBloggerCategory(destCat);
261 this.strategy.store(srcCat.getWebsite());
262 }
263 }
264
265 /**
266 * @inheritDoc
267 */
268 public void saveComment(WeblogEntryComment comment) throws WebloggerException {
/*
P/P * Method: void saveComment(WeblogEntryComment)
*
* Preconditions:
* comment != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* getUserManager(...).strategy.emf@269 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@272 != null
* org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@272 != null
*/
269 this.strategy.store(comment);
270
271 // update weblog last modified date. date updated by saveWebsite()
272 roller.getUserManager()
273 .saveWebsite(comment.getWeblogEntry().getWebsite());
274 }
275
276 /**
277 * @inheritDoc
278 */
279 public void removeComment(WeblogEntryComment comment) throws WebloggerException {
/*
P/P * Method: void removeComment(WeblogEntryComment)
*
* Preconditions:
* comment != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* getUserManager(...).strategy.emf@280 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@283 != null
* org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@283 != null
*/
280 this.strategy.remove(comment);
281
282 // update weblog last modified date. date updated by saveWebsite()
283 roller.getUserManager()
284 .saveWebsite(comment.getWeblogEntry().getWebsite());
285 }
286
287 /**
288 * @inheritDoc
289 */
290 // TODO: perhaps the createAnchor() and queuePings() items should go outside this method?
291 public void saveWeblogEntry(WeblogEntry entry) throws WebloggerException {
292
/*
P/P * Method: void saveWeblogEntry(WeblogEntry)
*
* Preconditions:
* entry != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) org/apache/roller/weblogger/business/WebloggerFactory.webloggerProvider != null
* (soft) org/apache/roller/weblogger/business/WebloggerFactory.webloggerProvider.webloggerInstance != null
* (soft) org/apache/roller/weblogger/business/jpa/JPAAutoPingManagerImpl.logger != null
* (soft) org/apache/roller/weblogger/business/jpa/JPAPingQueueManagerImpl.log != null
* (soft) org/apache/roller/weblogger/config/WebloggerRuntimeConfig.log != null
* (soft) org/apache/roller/weblogger/pojos/AutoPing.pcInheritedFieldCount <= 232-3
* (soft) this.roller != null
* ...
*
* Presumptions:
* getAutopingManager(...).strategy.emf@318 != null
* getUserManager(...).strategy.emf@318 != null
* java.lang.System:currentTimeMillis(...)@310 <= 18_446_744_073_709_491_615
* org.apache.roller.weblogger.pojos.WeblogEntry:getAddedTags(...)@297 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getAnchor(...)@293 != null
* ...
*
* Test Vectors:
* java.lang.String:equals(...)@293: {0}, {1}
* java.lang.String:equals(...)@310: {0}, {1}
* java.sql.Timestamp:after(...)@310: {0}, {1}
* java.util.Iterator:hasNext(...)@297: {0}, {1}
* java.util.Iterator:hasNext(...)@302: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogEntry:getAnchor(...)@293: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.pojos.WeblogEntry:isPublished(...)@321: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogEntry:isPublished(...)@326: {0}, {1}
*/
293 if (entry.getAnchor() == null || entry.getAnchor().trim().equals("")) {
294 entry.setAnchor(this.createAnchor(entry));
295 }
296
297 for(Iterator it = entry.getAddedTags().iterator(); it.hasNext();) {
298 String name = (String) it.next();
299 updateTagCount(name, entry.getWebsite(), 1);
300 }
301
302 for(Iterator it = entry.getRemovedTags().iterator(); it.hasNext();) {
303 String name = (String) it.next();
304 updateTagCount(name, entry.getWebsite(), -1);
305 }
306
307 // if the entry was published to future, set status as SCHEDULED
308 // we only consider an entry future published if it is scheduled
309 // more than 1 minute into the future
310 if ("PUBLISHED".equals(entry.getStatus()) &&
311 entry.getPubTime().after(new Date(System.currentTimeMillis() + 60000))) {
312 entry.setStatus(WeblogEntry.SCHEDULED);
313 }
314
315 // Store value object (creates new or updates existing)
316 entry.setUpdateTime(new Timestamp(new Date().getTime()));
317
318 this.strategy.store(entry);
319
320 // update weblog last modified date. date updated by saveWebsite()
321 if(entry.isPublished()) {
322 roller.getUserManager()
323 .saveWebsite(entry.getWebsite());
324 }
325
326 if(entry.isPublished()) {
327 // Queue applicable pings for this update.
328 roller.getAutopingManager()
329 .queueApplicableAutoPings(entry);
330 }
331 }
332
333 /**
334 * @inheritDoc
335 */
336 public void removeWeblogEntry(WeblogEntry entry)
337 throws WebloggerException {
338
/*
P/P * Method: void removeWeblogEntry(WeblogEntry)
*
* Preconditions:
* entry != null
* this.entryAnchorToIdMap != null
* this.roller != null
* this.roller.userManager != null
* this.roller.userManager.strategy != null
* this.roller.userManager.strategy.threadLocalEntityManager != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* getUserManager(...).strategy.emf@390 != null
* java.util.Iterator:next(...)@346 != null
* java.util.Iterator:next(...)@371 != null
* javax.persistence.Query:getResultList(...)@344 != null
* javax.persistence.Query:getResultList(...)@924 != null
* ...
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@345: {0}, {1}
* java.util.Iterator:hasNext(...)@364: {0}, {1}
* java.util.Iterator:hasNext(...)@370: {0}, {1}
* java.util.Iterator:hasNext(...)@380: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogEntry:getEntryAttributes(...)@379: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.pojos.WeblogEntry:getTags(...)@369: Addr_Set{null}, Inverse{null}
*/
339 String entryAnchor = entry.getAnchor();
340 Weblog website = entry.getWebsite();
341
342 Query q = strategy.getNamedQuery("WeblogReferrer.getByWeblogEntry");
343 q.setParameter(1, entry);
344 List referers = q.getResultList();
345 for (Iterator iter = referers.iterator(); iter.hasNext();) {
346 WeblogReferrer referer = (WeblogReferrer) iter.next();
347 this.strategy.remove(referer.getClass(), referer.getId());
348 }
349 // TODO: can we eliminate this unnecessary flush with OpenJPA 1.0
350 this.strategy.flush();
351
352 // remove comments
353 List comments = getComments(
354 null, // website
355 entry,
356 null, // search String
357 null, // startDate
358 null, // endDate
359 null, // status
360 true, // reverse chrono order (not that it matters)
361 0, // offset
362 -1); // no limit
363 Iterator commentsIT = comments.iterator();
364 while (commentsIT.hasNext()) {
365 this.strategy.remove((WeblogEntryComment) commentsIT.next());
366 }
367
368 // remove tags aggregates
369 if (entry.getTags() != null) {
370 for (Iterator it = entry.getTags().iterator(); it.hasNext(); ) {
371 WeblogEntryTag tag = (WeblogEntryTag) it.next();
372 updateTagCount(tag.getName(), entry.getWebsite(), -1);
373 it.remove();
374 this.strategy.remove(tag);
375 }
376 }
377
378 // remove attributes
379 if (entry.getEntryAttributes() != null) {
380 for (Iterator it = entry.getEntryAttributes().iterator(); it.hasNext(); ) {
381 WeblogEntryAttribute att = (WeblogEntryAttribute) it.next();
382 it.remove();
383 this.strategy.remove(att);
384 }
385 }
386 // TODO: can we eliminate this unnecessary flush with OpenJPA 1.0
387 this.strategy.flush();
388
389 // remove entry
390 this.strategy.remove(entry);
391
392 // update weblog last modified date. date updated by saveWebsite()
393 roller.getUserManager().saveWebsite(website);
394
395 // remove entry from cache mapping
396 this.entryAnchorToIdMap.remove(website.getHandle() + ":" + entryAnchor);
397 }
398
399 public List getNextPrevEntries(WeblogEntry current, String catName,
400 String locale, int maxEntries, boolean next)
401 throws WebloggerException {
/*
P/P * Method: List getNextPrevEntries(WeblogEntry, String, String, int, bool)
*
* Preconditions:
* current != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@407 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@432 != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* catName: Addr_Set{null}, Inverse{null}
* locale: Addr_Set{null}, Inverse{null}
* next: {0}, {1}
* java.lang.String:equals(...)@406: {1}, {0}
* java.lang.String:equals(...)@431: {1}, {0}
*/
402 Query query = null;
403 List results = null;
404 WeblogCategory category = null;
405
406 if (catName != null && !catName.trim().equals("/")) {
+ 407 category = getWeblogCategoryByPath(current.getWebsite(), null,
408 catName);
409 }
410
411 List params = new ArrayList();
412 int size = 0;
413 StringBuffer queryString = new StringBuffer();
414 StringBuffer whereClause = new StringBuffer();
415 queryString.append("SELECT e FROM WeblogEntry e WHERE ");
416
417 params.add(size++, current.getWebsite());
418 whereClause.append("e.website = ?" + size);
419
420 params.add(size++, WeblogEntry.PUBLISHED);
421 whereClause.append(" AND e.status = ?" + size);
422
423 if (next) {
424 params.add(size++, current.getPubTime());
425 whereClause.append(" AND e.pubTime > ?" + size);
426 } else {
427 params.add(size++, current.getPubTime());
428 whereClause.append(" AND e.pubTime < ?" + size);
429 }
430
431 if (catName != null && !catName.trim().equals("/")) {
432 category = getWeblogCategoryByPath(current.getWebsite(), catName);
433 if (category != null) {
434 params.add(size++, category);
435 whereClause.append(" AND e.category = ?" + size);
436 } else {
+ 437 throw new WebloggerException("Cannot find category: " + catName);
438 }
439 }
440
441 if(locale != null) {
442 params.add(size++, locale + '%');
443 whereClause.append(" AND e.locale like ?" + size);
444 }
445
446 if (next) {
447 whereClause.append(" ORDER BY e.pubTime ASC");
448 } else {
449 whereClause.append(" ORDER BY e.pubTime DESC");
450 }
451 query = strategy.getDynamicQuery(queryString.toString() + whereClause.toString());
452 for (int i=0; i<params.size(); i++) {
453 query.setParameter(i+1, params.get(i));
454 }
455 query.setMaxResults(maxEntries);
456
457 return query.getResultList();
458 }
459
460 /**
461 * @inheritDoc
462 */
463 public WeblogCategory getRootWeblogCategory(Weblog website)
464 throws WebloggerException {
/*
P/P * Method: WeblogCategory getRootWeblogCategory(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
465 if (website == null)
466 throw new WebloggerException("website is null");
467
468 Query q = strategy.getNamedQuery(
469 "WeblogCategory.getByWebsite&ParentNull");
470 q.setParameter(1, website);
471 try {
472 return (WeblogCategory)q.getSingleResult();
473 } catch (NoResultException e) {
474 return null;
475 }
476 }
477
478 /**
479 * @inheritDoc
480 */
481 public List getWeblogCategories(Weblog website, boolean includeRoot)
482 throws WebloggerException {
/*
P/P * Method: List getWeblogCategories(Weblog, bool)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* includeRoot: {0}, {1}
*/
483 if (website == null)
484 throw new WebloggerException("website is null");
485
486 if (includeRoot) return getWeblogCategories(website);
487
488 Query q = strategy.getNamedQuery(
489 "WeblogCategory.getByWebsite&ParentNotNull");
490 q.setParameter(1, website);
491 return q.getResultList();
492 }
493
494 /**
495 * @inheritDoc
496 */
497 public List getWeblogCategories(Weblog website)
498 throws WebloggerException {
/*
P/P * Method: List getWeblogCategories(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
499 if (website == null)
500 throw new WebloggerException("website is null");
501
502 Query q = strategy.getNamedQuery(
503 "WeblogCategory.getByWebsite");
504 q.setParameter(1, website);
505 return q.getResultList();
506 }
507
508 /**
509 * @inheritDoc
510 */
511 public List getWeblogEntries(
512 Weblog website,
513 User user,
514 Date startDate,
515 Date endDate,
516 String catName,
517 List tags,
518 String status,
519 String text,
520 String sortby,
521 String sortOrder,
522 String locale,
523 int offset,
524 int length) throws WebloggerException {
525
/*
P/P * Method: List getWeblogEntries(Weblog, User, Date, Date, String, List, String, String, String, String, String, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* init'ed(java.lang.Boolean.TRUE)
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* endDate: Addr_Set{null}, Inverse{null}
* length: {-1}, {-231..-2, 0..232-1}
* locale: Addr_Set{null}, Inverse{null}
* offset: {0}, {-231..-1, 1..232-1}
* sortOrder: Addr_Set{null}, Inverse{null}
* sortby: Addr_Set{null}, Inverse{null}
* startDate: Addr_Set{null}, Inverse{null}
* status: Addr_Set{null}, Inverse{null}
* tags: Addr_Set{null}, Inverse{null}
* text: Addr_Set{null}, Inverse{null}
* ...
*/
526 WeblogCategory cat = null;
527 if (StringUtils.isNotEmpty(catName) && website != null) {
528 cat = getWeblogCategoryByPath(website, catName);
529 if (cat == null) catName = null;
530 }
531 if (catName != null && catName.trim().equals("/")) {
532 catName = null;
533 }
534
535 List params = new ArrayList();
536 int size = 0;
537 StringBuffer queryString = new StringBuffer();
538
539 //queryString.append("SELECT e FROM WeblogEntry e WHERE ");
540 if (tags == null || tags.size()==0) {
541 queryString.append("SELECT e FROM WeblogEntry e WHERE ");
542 } else {
543 queryString.append("SELECT e FROM WeblogEntry e JOIN e.tags t WHERE ");
544 queryString.append("(");
545 for(int i = 0; i < tags.size(); i++) {
546 if (i != 0) queryString.append(" OR ");
547 params.add(size++, tags.get(i));
548 queryString.append(" t.name = ?").append(size);
549 }
550 queryString.append(") AND ");
551 }
552
553 if (website != null) {
+ 554 params.add(size++, website.getId());
555 queryString.append("e.website.id = ?").append(size);
556 } else {
+ 557 params.add(size++, Boolean.TRUE);
558 queryString.append("e.website.enabled = ?").append(size);
559 }
560
561 /*if (tags != null && tags.size() > 0) {
562 // A JOIN with WeblogEntryTag in parent quert will cause a DISTINCT in SELECT clause
563 // WeblogEntry has a clob field and many databases do not link DISTINCT for CLOB fields
564 // Hence as a workaround using corelated EXISTS query.
565 queryString.append(" AND EXISTS (SELECT t FROM WeblogEntryTag t WHERE "
566 + " t.weblogEntry = e AND t.name IN (");
567 final String PARAM_SEPERATOR = ", ";
568 for(int i = 0; i < tags.size(); i++) {
569 params.add(size++, tags.get(i));
570 queryString.append("?").append(size).append(PARAM_SEPERATOR);
571 }
572 // Remove the trailing PARAM_SEPERATOR
573 queryString.delete(queryString.length() - PARAM_SEPERATOR.length(),
574 queryString.length());
575
576 // Close the brace FOR IN clause and EXIST clause
577 queryString.append(" ) )");
578 }*/
579
580 if (user != null) {
+ 581 params.add(size++, user.getId());
582 queryString.append(" AND e.creator.id = ?").append(size);
583 }
584
585 if (startDate != null) {
586 Timestamp start = new Timestamp(startDate.getTime());
+ 587 params.add(size++, start);
588 queryString.append(" AND e.pubTime >= ?").append(size);
589 }
590
591 if (endDate != null) {
592 Timestamp end = new Timestamp(endDate.getTime());
+ 593 params.add(size++, end);
594 queryString.append(" AND e.pubTime <= ?").append(size);
595 }
596
+ 597 if (cat != null && website != null) {
+ 598 params.add(size++, cat.getId());
599 queryString.append(" AND e.category.id = ?").append(size);
600 }
601
602 if (status != null) {
+ 603 params.add(size++, status);
604 queryString.append(" AND e.status = ?").append(size);
605 }
606
607 if (locale != null) {
+ 608 params.add(size++, locale + '%');
609 queryString.append(" AND e.locale like ?").append(size);
610 }
611
612 if (text != null) {
+ 613 params.add(size++, '%' + text + '%');
614 queryString.append(" AND ( e.text LIKE ?").append(size);
615 queryString.append(" OR e.summary LIKE ? ").append(size);
616 queryString.append(" OR e.title LIKE ?").append(size);
617 queryString.append(") ");
618 }
619
620 if (sortby != null && sortby.equals("updateTime")) {
621 queryString.append(" ORDER BY e.updateTime ");
622 } else {
623 queryString.append(" ORDER BY e.pubTime ");
624 }
625
626 if (sortOrder != null && sortOrder.equals(ASCENDING)) {
627 queryString.append("ASC ");
628 } else {
629 queryString.append("DESC ");
630 }
631
632
633 Query query = strategy.getDynamicQuery(queryString.toString());
634 for (int i=0; i<params.size(); i++) {
635 query.setParameter(i+1, params.get(i));
636 }
637
638 if (offset != 0) {
639 query.setFirstResult(offset);
640 }
641 if (length != -1) {
642 query.setMaxResults(length);
643 }
644
645 return query.getResultList();
646 }
647
648 /**
649 * @inheritDoc
650 */
651 public List getWeblogEntriesPinnedToMain(Integer max)
652 throws WebloggerException {
/*
P/P * Method: List getWeblogEntriesPinnedToMain(Integer)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* init'ed(java.lang.Boolean.TRUE)
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* max: Addr_Set{null}, Inverse{null}
*/
653 Query query = strategy.getNamedQuery(
654 "WeblogEntry.getByPinnedToMain&statusOrderByPubTimeDesc");
655 query.setParameter(1, Boolean.TRUE);
656 query.setParameter(2, WeblogEntry.PUBLISHED);
657 if (max != null) {
658 query.setMaxResults(max.intValue());
659 }
660 return query.getResultList();
661 }
662
663 public void removeWeblogEntryAttribute(String name, WeblogEntry entry)
664 throws WebloggerException {
/*
P/P * Method: void removeWeblogEntryAttribute(String, WeblogEntry)
*
* Preconditions:
* entry != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@666 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getEntryAttributes(...)@665 != null
* org.apache.roller.weblogger.pojos.WeblogEntryAttribute:getName(...)@667 != null
*
* Test Vectors:
* java.lang.String:equals(...)@667: {0}, {1}
* java.util.Iterator:hasNext(...)@665: {0}, {1}
*/
665 for (Iterator it = entry.getEntryAttributes().iterator(); it.hasNext();) {
666 WeblogEntryAttribute entryAttribute = (WeblogEntryAttribute) it.next();
667 if (entryAttribute.getName().equals(name)) {
668 //Remove it from database
669 this.strategy.remove(entryAttribute);
670 //Remove it from the collection
671 it.remove();
672 }
673 }
674 }
675
676 public void removeWeblogEntryTag(String name, WeblogEntry entry)
677 throws WebloggerException {
/*
P/P * Method: void removeWeblogEntryTag(String, WeblogEntry)
*
* Preconditions:
* entry != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@679 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getTags(...)@678 != null
* org.apache.roller.weblogger.pojos.WeblogEntryTag:getName(...)@680 != null
*
* Test Vectors:
* java.lang.String:equals(...)@680: {0}, {1}
* java.util.Iterator:hasNext(...)@678: {0}, {1}
*/
678 for (Iterator it = entry.getTags().iterator(); it.hasNext();) {
679 WeblogEntryTag tag = (WeblogEntryTag) it.next();
680 if (tag.getName().equals(name)) {
681 //Call back the entity to adjust its internal state
682 entry.onRemoveTag(name);
683 //Remove it from database
684 this.strategy.remove(tag);
685 //Remove it from the collection
686 it.remove();
687 }
688 }
689 }
690
691 /**
692 * @inheritDoc
693 */
694 public WeblogEntry getWeblogEntryByAnchor(Weblog website,
695 String anchor) throws WebloggerException {
696
/*
P/P * Method: WeblogEntry getWeblogEntryByAnchor(Weblog, String)
*
* Preconditions:
* anchor != null
* this.entryAnchorToIdMap != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) log != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.Hashtable:containsKey(...)@708: {0}, {1}
* javax.persistence.EntityManager:find(...)@216: Addr_Set{null}, Inverse{null}
*/
697 if (website == null)
698 throw new WebloggerException("Website is null");
699
700 if (anchor == null)
701 throw new WebloggerException("Anchor is null");
702
703 // mapping key is combo of weblog + anchor
704 String mappingKey = website.getHandle()+":"+anchor;
705
706 // check cache first
707 // NOTE: if we ever allow changing anchors then this needs updating
708 if(this.entryAnchorToIdMap.containsKey(mappingKey)) {
709
710 WeblogEntry entry = this.getWeblogEntry((String) this.entryAnchorToIdMap.get(mappingKey));
711 if(entry != null) {
712 log.debug("entryAnchorToIdMap CACHE HIT - "+mappingKey);
713 return entry;
714 } else {
715 // mapping hit with lookup miss? mapping must be old, remove it
716 this.entryAnchorToIdMap.remove(mappingKey);
717 }
718 }
719
720 // cache failed, do lookup
721 Query q = strategy.getNamedQuery(
722 "WeblogEntry.getByWebsite&AnchorOrderByPubTimeDesc");
723 q.setParameter(1, website);
724 q.setParameter(2, anchor);
725 WeblogEntry entry = null;
726 try {
727 entry = (WeblogEntry)q.getSingleResult();
728 } catch (NoResultException e) {
729 entry = null;
730 }
731
732 // add mapping to cache
733 if(entry != null) {
734 log.debug("entryAnchorToIdMap CACHE MISS - "+mappingKey);
735 this.entryAnchorToIdMap.put(mappingKey, entry.getId());
736 }
737 return entry;
738 }
739
740 /**
741 * @inheritDoc
742 */
743 // TODO: this method should be removed and it's functionality moved to getWeblogEntries()
744 public List getWeblogEntries(WeblogCategory cat, boolean subcats)
745 throws WebloggerException {
/*
P/P * Method: List getWeblogEntries(WeblogCategory, bool)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) cat != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* subcats: {1}, {0}
*/
746 List results = null;
747
748 if (!subcats) {
749 Query q = strategy.getNamedQuery(
750 "WeblogEntry.getByStatus&Category");
751 q.setParameter(1, WeblogEntry.PUBLISHED);
752 q.setParameter(2, cat);
753 results = q.getResultList();
754 } else {
755 Query q = strategy.getNamedQuery(
756 "WeblogEntry.getByStatus&Category.pathLike&Website");
757 q.setParameter(1, WeblogEntry.PUBLISHED);
758 q.setParameter(2, cat.getPath() + '%');
759 q.setParameter(3, cat.getWebsite());
760 results = q.getResultList();
761 }
762
763 return results;
764 }
765
766 /**
767 * @inheritDoc
768 */
769 public String createAnchor(WeblogEntry entry) throws WebloggerException {
770 // Check for uniqueness of anchor
/*
P/P * Method: String createAnchor(WeblogEntry)
*
* Preconditions:
* entry != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* javax.persistence.Query:getResultList(...)@784 != null
*
* Postconditions:
* java.lang.StringBuilder:toString(...)._tainted == 0
* init'ed(return_value)
*
* Test Vectors:
* java.util.List:size(...)@786: {1..232-1}, {-231..0}
*/
771 String base = entry.createAnchorBase();
772 String name = base;
773 int count = 0;
774
775 while (true) {
776 if (count > 0) {
777 name = base + count;
778 }
779
780 Query q = strategy.getNamedQuery(
781 "WeblogEntry.getByWebsite&Anchor");
782 q.setParameter(1, entry.getWebsite());
783 q.setParameter(2, name);
784 List results = q.getResultList();
785
786 if (results.size() < 1) {
787 break;
788 } else {
+ 789 count++;
790 }
791 }
792 return name;
793 }
794
795 /**
796 * @inheritDoc
797 */
798 public boolean isDuplicateWeblogCategoryName(WeblogCategory cat)
799 throws WebloggerException {
800
801 // ensure that no sibling categories share the same name
/*
P/P * Method: bool isDuplicateWeblogCategoryName(WeblogCategory)
*
* Preconditions:
* cat != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* org.apache.roller.weblogger.pojos.WeblogCategory:getWebsite(...)@804 != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@802: Addr_Set{null}, Inverse{null}
*/
802 WeblogCategory parent = cat.getParent();
803 if (null != parent) {
804 return (getWeblogCategoryByPath(
805 cat.getWebsite(), cat.getPath()) != null);
806 }
807
808 return false;
809 }
810
811 /**
812 * @inheritDoc
813 */
814 public boolean isWeblogCategoryInUse(WeblogCategory cat)
815 throws WebloggerException {
816
/*
P/P * Method: bool isWeblogCategoryInUse(WeblogCategory)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) cat != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Iterator:next(...)@827 != null
* javax.persistence.Query:getResultList(...)@819 != null
* org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@833 != null
* org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@837 != null
* org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@825 != null
* ...
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@826: {0}, {1}
* java.util.List:size(...)@819: {-231..0}, {1..232-1}
* org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@833: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@837: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogCategory:isInUse(...)@828: {0}, {1}
*/
817 Query q = strategy.getNamedQuery("WeblogEntry.getByCategory");
818 q.setParameter(1, cat);
819 int entryCount = q.getResultList().size();
820
821 if (entryCount > 0) {
822 return true;
823 }
824
825 Iterator cats = cat.getWeblogCategories().iterator();
826 while (cats.hasNext()) {
827 WeblogCategory childCat = (WeblogCategory)cats.next();
828 if (childCat.isInUse()) {
829 return true;
830 }
831 }
832
833 if (cat.getWebsite().getBloggerCategory().equals(cat)) {
834 return true;
835 }
836
837 if (cat.getWebsite().getDefaultCategory().equals(cat)) {
838 return true;
839 }
840
841 return false;
842 }
843
844 /**
845 * @inheritDoc
846 */
847 public List getComments(
848 Weblog website,
849 WeblogEntry entry,
850 String searchString,
851 Date startDate,
852 Date endDate,
853 String status,
854 boolean reverseChrono,
855 int offset,
856 int length) throws WebloggerException {
857
/*
P/P * Method: List getComments(Weblog, WeblogEntry, String, Date, Date, String, bool, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* endDate: Addr_Set{null}, Inverse{null}
* entry: Addr_Set{null}, Inverse{null}
* length: {-1}, {-231..-2, 0..232-1}
* offset: {0}, {-231..-1, 1..232-1}
* reverseChrono: {0}, {1}
* searchString: Addr_Set{null}, Inverse{null}
* startDate: Addr_Set{null}, Inverse{null}
* status: Addr_Set{null}, Inverse{null}
* website: Addr_Set{null}, Inverse{null}
* java.lang.String:equals(...)@892: {0}, {1}
* ...
*/
858 List params = new ArrayList();
859 int size = 0;
860 StringBuffer queryString = new StringBuffer();
861 queryString.append("SELECT c FROM WeblogEntryComment c ");
862
863 StringBuffer whereClause = new StringBuffer();
864 if (entry != null) {
865 params.add(size++, entry);
866 whereClause.append("c.weblogEntry = ?").append(size);
867 } else if (website != null) {
868 params.add(size++, website);
869 whereClause.append("c.weblogEntry.website = ?").append(size);
870 }
871
872 if (searchString != null) {
873 params.add(size++, "%" + searchString + "%");
874 appendConjuctionToWhereclause(whereClause, "(c.url LIKE ?")
875 .append(size).append(" OR c.content LIKE ?").append(size).append(")");
876 }
877
878 if (startDate != null) {
879 Timestamp start = new Timestamp(startDate.getTime());
880 params.add(size++, start);
881 appendConjuctionToWhereclause(whereClause, "c.postTime >= ?").append(size);
882 }
883
884 if (endDate != null) {
885 Timestamp end = new Timestamp(endDate.getTime());
886 params.add(size++, end);
887 appendConjuctionToWhereclause(whereClause, "c.postTime <= ?").append(size);
888 }
889
890 if (status != null) {
891 String comparisionOperator;
892 if("ALL_IGNORE_SPAM".equals(status)) {
893 // we want all comments, except spam
894 // so that means where status != SPAM
895 status = WeblogEntryComment.SPAM;
896 comparisionOperator = " <> ";
897 } else {
898 comparisionOperator = " = ";
899 }
900 params.add(size++, status);
901 appendConjuctionToWhereclause(whereClause, "c.status ")
902 .append(comparisionOperator).append('?').append(size);
903 }
904
905 if(whereClause.length() != 0) {
906 queryString.append(" WHERE ").append(whereClause);
907 }
908 if (reverseChrono) {
909 queryString.append(" ORDER BY c.postTime DESC");
910 } else {
911 queryString.append(" ORDER BY c.postTime ASC");
912 }
913
914 Query query = strategy.getDynamicQuery(queryString.toString());
915 if (offset != 0) {
916 query.setFirstResult(offset);
917 }
918 if (length != -1) {
919 query.setMaxResults(length);
920 }
921 for (int i=0; i<params.size(); i++) {
922 query.setParameter(i+1, params.get(i));
923 }
924 return query.getResultList();
925
926 }
927
928
929 /**
930 * @inheritDoc
931 */
932 public int removeMatchingComments(
933 Weblog website,
934 WeblogEntry entry,
935 String searchString,
936 Date startDate,
937 Date endDate,
938 String status) throws WebloggerException {
939
940 // TODO dynamic bulk delete query: I'd MUCH rather use a bulk delete,
941 // but MySQL says "General error, message from server: "You can't
942 // specify target table 'roller_comment' for update in FROM clause"
943
/*
P/P * Method: int removeMatchingComments(Weblog, WeblogEntry, String, Date, Date, String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.roller != null
* (soft) this.roller.userManager != null
* (soft) this.roller.userManager.strategy != null
* (soft) this.roller.userManager.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Iterator:next(...)@949 != null
* javax.persistence.Query:getResultList(...)@924 != null
*
* Postconditions:
* return_value >= 0
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@948: {0}, {1}
*/
944 List comments = getComments(
945 website, entry, searchString, startDate, endDate,
946 status, true, 0, -1);
947 int count = 0;
948 for (Iterator it = comments.iterator(); it.hasNext();) {
949 WeblogEntryComment comment = (WeblogEntryComment) it.next();
950 removeComment(comment);
+ 951 count++;
952 }
953 return count;
954 }
955
956
957 /**
958 * @inheritDoc
959 */
960 public WeblogCategory getWeblogCategory(String id)
961 throws WebloggerException {
/*
P/P * Method: WeblogCategory getWeblogCategory(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
962 return (WeblogCategory) this.strategy.load(
963 WeblogCategory.class, id);
964 }
965
966 //--------------------------------------------- WeblogCategory Queries
967
968 /**
969 * @inheritDoc
970 */
971 public WeblogCategory getWeblogCategoryByPath(Weblog website,
972 String categoryPath) throws WebloggerException {
/*
P/P * Method: WeblogCategory getWeblogCategoryByPath(Weblog, String)
*
* Preconditions:
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
* (soft) website != null
*
* Postconditions:
* init'ed(return_value)
*/
973 return getWeblogCategoryByPath(website, null, categoryPath);
974 }
975
976 /**
977 * @inheritDoc
978 */
979 // TODO: ditch this method in favor of getWeblogCategoryByPath(weblog, path)
980 public WeblogCategory getWeblogCategoryByPath(Weblog website,
981 WeblogCategory category, String path) throws WebloggerException {
982
/*
P/P * Method: WeblogCategory getWeblogCategoryByPath(Weblog, WeblogCategory, String)
*
* Preconditions:
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
* (soft) website != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* path: Addr_Set{null}, Inverse{null}
* java.lang.String:equals(...)@983: {0}, {1}
* java.lang.String:startsWith(...)@989: {1}, {0}
*/
983 if (path == null || path.trim().equals("/")) {
984 return getRootWeblogCategory(website);
985 } else {
986 String catPath = path;
987
988 // all cat paths must begin with a '/'
989 if(!catPath.startsWith("/")) {
990 catPath = "/"+catPath;
991 }
992
993 // now just do simple lookup by path
994 Query q = strategy.getNamedQuery(
995 "WeblogCategory.getByPath&Website");
996 q.setParameter(1, catPath);
997 q.setParameter(2, website);
998 try {
999 return (WeblogCategory)q.getSingleResult();
1000 } catch (NoResultException e) {
1001 return null;
1002 }
1003 }
1004 }
1005
1006 /**
1007 * @inheritDoc
1008 */
1009 public WeblogEntryComment getComment(String id) throws WebloggerException {
/*
P/P * Method: WeblogEntryComment getComment(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
1010 return (WeblogEntryComment) this.strategy.load(WeblogEntryComment.class, id);
1011 }
1012
1013 /**
1014 * @inheritDoc
1015 */
1016 public WeblogEntry getWeblogEntry(String id) throws WebloggerException {
/*
P/P * Method: WeblogEntry getWeblogEntry(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
1017 return (WeblogEntry)strategy.load(WeblogEntry.class, id);
1018 }
1019
1020 /**
1021 * @inheritDoc
1022 */
1023 public Map getWeblogEntryObjectMap(
1024 Weblog website,
1025 Date startDate,
1026 Date endDate,
1027 String catName,
1028 List tags,
1029 String status,
1030 String locale,
1031 int offset,
1032 int length) throws WebloggerException {
/*
P/P * Method: Map getWeblogEntryObjectMap(Weblog, Date, Date, String, List, String, String, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* return_value == &new TreeMap(getWeblogEntryMap#1)
* new TreeMap(getWeblogEntryMap#1) num objects == 1
*/
1033 return getWeblogEntryMap(
1034 website,
1035 startDate,
1036 endDate,
1037 catName,
1038 tags,
1039 status,
1040 false,
1041 locale,
1042 offset,
1043 length);
1044 }
1045
1046 /**
1047 * @inheritDoc
1048 */
1049 public Map getWeblogEntryStringMap(
1050 Weblog website,
1051 Date startDate,
1052 Date endDate,
1053 String catName,
1054 List tags,
1055 String status,
1056 String locale,
1057 int offset,
1058 int length
1059 ) throws WebloggerException {
/*
P/P * Method: Map getWeblogEntryStringMap(Weblog, Date, Date, String, List, String, String, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* return_value == &new TreeMap(getWeblogEntryMap#1)
* new TreeMap(getWeblogEntryMap#1) num objects == 1
*/
1060 return getWeblogEntryMap(
1061 website,
1062 startDate,
1063 endDate,
1064 catName,
1065 tags,
1066 status,
1067 true,
1068 locale,
1069 offset,
1070 length);
1071 }
1072
1073 private Map getWeblogEntryMap(
1074 Weblog website,
1075 Date startDate,
1076 Date endDate,
1077 String catName,
1078 List tags,
1079 String status,
1080 boolean stringsOnly,
1081 String locale,
1082 int offset,
1083 int length) throws WebloggerException {
1084
/*
P/P * Method: Map getWeblogEntryMap(Weblog, Date, Date, String, List, String, bool, String, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Calendar:getInstance(...)@1102 != null
* java.util.Iterator:next(...)@1109 != null
* javax.persistence.Query:getResultList(...)@645 != null
* org.apache.roller.util.DateUtil:get8charDateFormat(...)@1107 != null
*
* Postconditions:
* return_value == &new TreeMap(getWeblogEntryMap#1)
* new TreeMap(getWeblogEntryMap#1) num objects == 1
*
* Test Vectors:
* stringsOnly: {0}, {1}
* website: Addr_Set{null}, Inverse{null}
* java.util.Iterator:hasNext(...)@1108: {0}, {1}
* java.util.TreeMap:get(...)@1112: Inverse{null}, Addr_Set{null}
* java.util.TreeMap:get(...)@1115: Inverse{null}, Addr_Set{null}
*/
1085 TreeMap map = new TreeMap(reverseComparator);
1086
1087 List entries = getWeblogEntries(
1088 website,
1089 null, // user
1090 startDate,
1091 endDate,
1092 catName,
1093 tags,
1094 status,
1095 null, // text
1096 null, // sortBy
1097 null, // sortOrder
1098 locale,
1099 offset,
1100 length);
1101
1102 Calendar cal = Calendar.getInstance();
1103 if (website != null) {
1104 cal.setTimeZone(website.getTimeZoneInstance());
1105 }
1106
1107 SimpleDateFormat formatter = DateUtil.get8charDateFormat();
1108 for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) {
1109 WeblogEntry entry = (WeblogEntry) wbItr.next();
1110 Date sDate = DateUtil.getNoonOfDay(entry.getPubTime(), cal);
1111 if (stringsOnly) {
1112 if (map.get(sDate) == null)
1113 map.put(sDate, formatter.format(sDate));
1114 } else {
1115 List dayEntries = (List) map.get(sDate);
1116 if (dayEntries == null) {
1117 dayEntries = new ArrayList();
1118 map.put(sDate, dayEntries);
1119 }
1120 dayEntries.add(entry);
1121 }
1122 }
1123 return map;
1124 }
1125
1126 /**
1127 * @inheritDoc
1128 */
1129 public List getMostCommentedWeblogEntries(Weblog website,
1130 Date startDate, Date endDate, int offset,
1131 int length) throws WebloggerException {
/*
P/P * Method: List getMostCommentedWeblogEntries(Weblog, Date, Date, int, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Iterator:next(...)@1176 != null
* javax.persistence.Query:getResultList(...)@1173 != null
* row.length@1176 >= 4
*
* Postconditions:
* return_value == &new ArrayList(getMostCommentedWeblogEntries#8)
* new ArrayList(getMostCommentedWeblogEntries#8) num objects == 1
*
* Test Vectors:
* endDate: Inverse{null}, Addr_Set{null}
* length: {-1}, {-231..-2, 0..232-1}
* offset: {0}, {-231..-1, 1..232-1}
* startDate: Addr_Set{null}, Inverse{null}
* website: Addr_Set{null}, Inverse{null}
* java.util.Iterator:hasNext(...)@1175: {0}, {1}
*/
1132 Query query = null;
1133 List queryResults = null;
1134 if (endDate == null) endDate = new Date();
1135
1136 if (website != null) {
1137 if (startDate != null) {
1138 Timestamp start = new Timestamp(startDate.getTime());
1139 Timestamp end = new Timestamp(endDate.getTime());
1140 query = strategy.getNamedQuery(
1141 "WeblogEntryComment.getMostCommentedWeblogEntryByWebsite&EndDate&StartDate");
1142 query.setParameter(1, website);
1143 query.setParameter(2, end);
1144 query.setParameter(3, start);
1145 } else {
1146 Timestamp end = new Timestamp(endDate.getTime());
1147 query = strategy.getNamedQuery(
1148 "WeblogEntryComment.getMostCommentedWeblogEntryByWebsite&EndDate");
1149 query.setParameter(1, website);
1150 query.setParameter(2, end);
1151 }
1152 } else {
1153 if (startDate != null) {
1154 Timestamp start = new Timestamp(startDate.getTime());
1155 Timestamp end = new Timestamp(endDate.getTime());
1156 query = strategy.getNamedQuery(
1157 "WeblogEntryComment.getMostCommentedWeblogEntryByEndDate&StartDate");
1158 query.setParameter(1, end);
1159 query.setParameter(2, start);
1160 } else {
1161 Timestamp end = new Timestamp(endDate.getTime());
1162 query = strategy.getNamedQuery(
1163 "WeblogEntryComment.getMostCommentedWeblogEntryByEndDate");
1164 query.setParameter(1, end);
1165 }
1166 }
1167 if (offset != 0) {
1168 query.setFirstResult(offset);
1169 }
1170 if (length != -1) {
1171 query.setMaxResults(length);
1172 }
1173 queryResults = query.getResultList();
1174 List results = new ArrayList();
1175 for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
1176 Object[] row = (Object[]) iter.next();
+ 1177 results.add(new StatCount(
1178 (String)row[1], // entry id
1179 (String)row[2], // entry anchor
1180 (String)row[3], // entry title
1181 "statCount.weblogEntryCommentCountType", // stat desc
1182 ((Long)row[0]).longValue())); // count
1183 }
1184 // Original query ordered by desc count.
1185 // JPA QL doesn't allow queries to be ordered by agregates; do it in memory
1186 Collections.sort(results, statCountCountReverseComparator);
1187
1188 return results;
1189 }
1190
1191 /**
1192 * @inheritDoc
1193 */
1194 public WeblogEntry getNextEntry(WeblogEntry current,
1195 String catName, String locale) throws WebloggerException {
/*
P/P * Method: WeblogEntry getNextEntry(WeblogEntry, String, String)
*
* Preconditions:
* current != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.List:size(...)@1198: {-231..0}, {1..232-1}
*/
1196 WeblogEntry entry = null;
1197 List entryList = getNextPrevEntries(current, catName, locale, 1, true);
1198 if (entryList != null && entryList.size() > 0) {
1199 entry = (WeblogEntry)entryList.get(0);
1200 }
1201 return entry;
1202 }
1203
1204 /**
1205 * @inheritDoc
1206 */
1207 public WeblogEntry getPreviousEntry(WeblogEntry current,
1208 String catName, String locale) throws WebloggerException {
/*
P/P * Method: WeblogEntry getPreviousEntry(WeblogEntry, String, String)
*
* Preconditions:
* current != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* java.util.List:size(...)@1211: {-231..0}, {1..232-1}
*/
1209 WeblogEntry entry = null;
1210 List entryList = getNextPrevEntries(current, catName, locale, 1, false);
1211 if (entryList != null && entryList.size() > 0) {
1212 entry = (WeblogEntry)entryList.get(0);
1213 }
1214 return entry;
1215 }
1216
1217 /**
1218 * @inheritDoc
1219 */
/*
P/P * Method: void release()
*/
1220 public void release() {}
1221
1222 /**
1223 * @inheritDoc
1224 */
1225 public void applyCommentDefaultsToEntries(Weblog website)
1226 throws WebloggerException {
/*
P/P * Method: void applyCommentDefaultsToEntries(Weblog)
*
* Preconditions:
* log != null
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* javax.persistence.EntityManager:createNamedQuery(...)@301 != null
*
* Test Vectors:
* org.apache.commons.logging.Log:isDebugEnabled(...)@1227: {0}, {1}
*/
1227 if (log.isDebugEnabled()) {
1228 log.debug("applyCommentDefaults");
1229 }
1230
1231 // TODO: Non-standard JPA bulk update, using parameter values in set clause
1232 Query q = strategy.getNamedUpdate(
1233 "WeblogEntry.updateAllowComments&CommentDaysByWebsite");
1234 q.setParameter(1, website.getDefaultAllowComments());
1235 q.setParameter(2, new Integer(website.getDefaultCommentDays()));
1236 q.setParameter(3, website);
1237 q.executeUpdate();
1238 }
1239
1240 /**
1241 * @inheritDoc
1242 */
1243 public List getPopularTags(Weblog website, Date startDate, int limit)
1244 throws WebloggerException {
/*
P/P * Method: List getPopularTags(Weblog, Date, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* (int) (java.lang.Math:floor(...)@1299 + 1) in -231..232-1
* java.util.Iterator:next(...)@1282 != null
* java.util.Iterator:next(...)@1298 != null
* javax.persistence.Query:getResultList(...)@1274 != null
* row.length@1282 >= 2
*
* Postconditions:
* return_value == &new ArrayList(getPopularTags#3)
* new ArrayList(getPopularTags#3) num objects == 1
*
* Test Vectors:
* limit: {-1}, {-231..-2, 0..232-1}
* startDate: Addr_Set{null}, Inverse{null}
* website: Addr_Set{null}, Inverse{null}
* java.util.Iterator:hasNext(...)@1281: {0}, {1}
* java.util.Iterator:hasNext(...)@1297: {0}, {1}
*/
1245 Query query = null;
1246 List queryResults = null;
1247
1248 if (website != null) {
1249 if (startDate != null) {
1250 Timestamp start = new Timestamp(startDate.getTime());
1251 query = strategy.getNamedQuery(
1252 "WeblogEntryTagAggregate.getPopularTagsByWebsite&StartDate");
1253 query.setParameter(1, website);
1254 query.setParameter(2, start);
1255 } else {
1256 query = strategy.getNamedQuery(
1257 "WeblogEntryTagAggregate.getPopularTagsByWebsite");
1258 query.setParameter(1, website);
1259 }
1260 } else {
1261 if (startDate != null) {
1262 Timestamp start = new Timestamp(startDate.getTime());
1263 query = strategy.getNamedQuery(
1264 "WeblogEntryTagAggregate.getPopularTagsByWebsiteNull&StartDate");
1265 query.setParameter(1, start);
1266 } else {
1267 query = strategy.getNamedQuery(
1268 "WeblogEntryTagAggregate.getPopularTagsByWebsiteNull");
1269 }
1270 }
1271 if (limit != -1) {
1272 query.setMaxResults(limit);
1273 }
1274 queryResults = query.getResultList();
1275
1276 double min = Integer.MAX_VALUE;
1277 double max = Integer.MIN_VALUE;
1278
1279 List results = new ArrayList(limit);
1280
1281 for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
1282 Object[] row = (Object[]) iter.next();
1283 TagStat t = new TagStat();
1284 t.setName((String) row[0]);
+ 1285 t.setCount(((Number) row[1]).intValue());
1286
1287 min = Math.min(min, t.getCount());
1288 max = Math.max(max, t.getCount());
1289 results.add(t);
1290 }
1291
1292 min = Math.log(1+min);
1293 max = Math.log(1+max);
1294
1295 double range = Math.max(.01, max - min) * 1.0001;
1296
1297 for (Iterator iter = results.iterator(); iter.hasNext(); ) {
1298 TagStat t = (TagStat) iter.next();
1299 t.setIntensity((int) (1 + Math.floor(5 * (Math.log(1+t.getCount()) - min) / range)));
1300 }
1301
1302 // sort results by name, because query had to sort by total
1303 Collections.sort(results, tagStatNameComparator);
1304
1305 return results;
1306 }
1307
1308 /**
1309 * @inheritDoc
1310 */
1311 public List getTags(Weblog website, String sortBy,
1312 String startsWith, int limit) throws WebloggerException {
/*
P/P * Method: List getTags(Weblog, String, String, int)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Iterator:next(...)@1352 != null
* javax.persistence.Query:getResultList(...)@1348 != null
* row.length@1352 >= 2
*
* Postconditions:
* return_value == &new ArrayList(getTags#6)
* new ArrayList(getTags#6) num objects == 1
*
* Test Vectors:
* limit: {-1}, {-231..-2, 0..232-1}
* sortBy: Inverse{null}, Addr_Set{null}
* startsWith: Addr_Set{null}, Inverse{null}
* website: Addr_Set{null}, Inverse{null}
* java.lang.String:equals(...)@1334: {0}, {1}
* java.lang.String:length(...)@1329: {0}, {1..232-1}
* java.util.Iterator:hasNext(...)@1351: {0}, {1}
*/
1313 Query query = null;
1314 List queryResults = null;
1315 boolean sortByName = sortBy == null || !sortBy.equals("count");
1316
1317 List params = new ArrayList();
1318 int size = 0;
1319 StringBuffer queryString = new StringBuffer();
1320 queryString.append("SELECT w.name, SUM(w.total) FROM WeblogEntryTagAggregate w WHERE ");
1321
1322 if (website != null) {
1323 params.add(size++, website.getId());
1324 queryString.append(" w.weblog.id = ?").append(size);
1325 } else {
1326 queryString.append(" w.weblog IS NULL");
1327 }
1328
1329 if (startsWith != null && startsWith.length() > 0) {
1330 params.add(size++, startsWith + '%');
1331 queryString.append(" AND w.name LIKE ?" + size);
1332 }
1333
1334 if (sortBy != null && sortBy.equals("count")) {
1335 sortBy = "w.total DESC";
1336 } else {
1337 sortBy = "w.name";
1338 }
1339 queryString.append(" GROUP BY w.name, w.total ORDER BY " + sortBy);
1340
1341 query = strategy.getDynamicQuery(queryString.toString());
1342 for (int i=0; i<params.size(); i++) {
1343 query.setParameter(i+1, params.get(i));
1344 }
1345 if (limit != -1) {
1346 query.setMaxResults(limit);
1347 }
1348 queryResults = query.getResultList();
1349
1350 List results = new ArrayList();
1351 for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
1352 Object[] row = (Object[]) iter.next();
1353 TagStat ce = new TagStat();
1354 ce.setName((String) row[0]);
1355 // The JPA query retrieves SUM(w.total) always as long
+ 1356 ce.setCount(((Long) row[1]).intValue());
1357 results.add(ce);
1358 }
1359
1360 if (sortByName) {
1361 Collections.sort(results, tagStatNameComparator);
1362 } else {
1363 Collections.sort(results, tagStatCountReverseComparator);
1364 }
1365
1366 return results;
1367 }
1368
1369
1370 /**
1371 * @inheritDoc
1372 */
1373 public boolean getTagComboExists(List tags, Weblog weblog) throws WebloggerException{
1374
/*
P/P * Method: bool getTagComboExists(List, Weblog)
*
* Preconditions:
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.lang.String:length(...)@1394 - java.lang.StringBuffer:length(...)@1394 in -232+1..231
* java.util.List:size(...)@1385 <= 232-2
* java.util.List:size(...)@1388 <= 232-2
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* tags: Addr_Set{null}, Inverse{null}
* weblog: Addr_Set{null}, Inverse{null}
* java.util.List:size(...)@1375: {-231..-1, 1..232-1}, {0}
*/
1375 if(tags == null || tags.size() == 0) {
1376 return false;
1377 }
1378
1379 StringBuffer queryString = new StringBuffer();
1380 queryString.append("SELECT DISTINCT w.name ");
1381 queryString.append("FROM WeblogEntryTagAggregate w WHERE w.name IN (");
1382 //?1) AND w.weblog = ?2");
1383 //Append tags as parameter markers to avoid potential escaping issues
1384 //The IN clause would be of form (?1, ?2, ?3, ..)
1385 ArrayList params = new ArrayList(tags.size() + 1);
+ 1386 final String PARAM_SEPERATOR = ", ";
1387 int i;
1388 for (i=0; i < tags.size(); i++) {
1389 queryString.append('?').append(i+1).append(PARAM_SEPERATOR);
1390 params.add(tags.get(i));
1391 }
1392
1393 // Remove the trailing PARAM_SEPERATOR
1394 queryString.delete(queryString.length() - PARAM_SEPERATOR.length(),
1395 queryString.length());
1396 // Close the brace of IN clause
1397 queryString.append(')');
1398
1399 if(weblog != null) {
1400 queryString.append(" AND w.weblog = ?").append(i+1);
1401 params.add(weblog);
1402 } else {
1403 queryString.append(" AND w.weblog IS NULL");
1404 }
1405
1406 Query q = strategy.getDynamicQuery(queryString.toString());
1407 for (int j=0; j<params.size(); j++) {
1408 q.setParameter(j+1, params.get(j));
1409 }
1410 List results = q.getResultList();
1411
1412 //TODO: DatamapperPort: Since we are only interested in knowing whether
1413 //results.size() == tags.size(). This query can be optimized to just fetch COUNT
1414 //instead of objects as done currently
1415 return (results != null && results.size() == tags.size());
1416 }
1417
1418 /**
1419 * @inheritDoc
1420 */
1421 public void updateTagCount(String name, Weblog website, int amount)
1422 throws WebloggerException {
/*
P/P * Method: void updateTagCount(String, Weblog, int)
*
* Preconditions:
* amount != 0
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* amount + org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate:getTotal(...)@1464 in -231..232-1
* amount + org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate:getTotal(...)@1484 in -231..232-1
* javax.persistence.EntityManager:createNamedQuery(...)@301 != null
*
* Test Vectors:
* amount: {-231..-1}, {1..232-1}
*/
1423 if(amount == 0) {
1424 throw new WebloggerException("Tag increment amount cannot be zero.");
1425 }
1426
1427 if(website == null) {
1428 throw new WebloggerException("Website cannot be NULL.");
1429 }
1430
1431 // The reason why add order lastUsed desc is to make sure we keep picking the most recent
1432 // one in the case where we have multiple rows (clustered environment)
1433 // eventually that second entry will have a very low total (most likely 1) and
1434 // won't matter
1435 Query weblogQuery = strategy.getNamedQuery(
1436 "WeblogEntryTagAggregate.getByName&WebsiteOrderByLastUsedDesc");
1437 weblogQuery.setParameter(1, name);
1438 weblogQuery.setParameter(2, website);
1439 WeblogEntryTagAggregate weblogTagData;
1440 try {
1441 weblogTagData = (WeblogEntryTagAggregate)weblogQuery.getSingleResult();
1442 } catch (NoResultException e) {
1443 weblogTagData = null;
1444 }
1445
1446 Query siteQuery = strategy.getNamedQuery(
1447 "WeblogEntryTagAggregate.getByName&WebsiteNullOrderByLastUsedDesc");
1448 siteQuery.setParameter(1, name);
1449 WeblogEntryTagAggregate siteTagData;
1450 try {
1451 siteTagData = (WeblogEntryTagAggregate)siteQuery.getSingleResult();
1452 } catch (NoResultException e) {
1453 siteTagData = null;
1454 }
1455 Timestamp lastUsed = new Timestamp((new Date()).getTime());
1456
1457 // create it only if we are going to need it.
1458 if (weblogTagData == null && amount > 0) {
1459 weblogTagData = new WeblogEntryTagAggregate(null, website, name, amount);
1460 weblogTagData.setLastUsed(lastUsed);
1461 strategy.store(weblogTagData);
1462
1463 } else if (weblogTagData != null) {
1464 weblogTagData.setTotal(weblogTagData.getTotal() + amount);
1465 weblogTagData.setLastUsed(lastUsed);
1466 strategy.store(weblogTagData);
1467 // Why use update query when only one object needs update?
1468 // Query update = strategy.getNamedUpdate(
1469 // "WeblogEntryTagAggregate.updateAddToTotalByName&Weblog");
1470 // update.setParameter(1, new Long(amount));
1471 // update.setParameter(2, lastUsed);
1472 // update.setParameter(3, weblogTagData.getName());
1473 // update.setParameter(4, website);
1474 // update.executeUpdate();
1475 }
1476
1477 // create it only if we are going to need it.
1478 if (siteTagData == null && amount > 0) {
1479 siteTagData = new WeblogEntryTagAggregate(null, null, name, amount);
1480 siteTagData.setLastUsed(lastUsed);
1481 strategy.store(siteTagData);
1482
1483 } else if(siteTagData != null) {
1484 siteTagData.setTotal(siteTagData.getTotal() + amount);
1485 siteTagData.setLastUsed(lastUsed);
1486 strategy.store(siteTagData);
1487 // Why use update query when only one object needs update?
1488 // Query update = strategy.getNamedUpdate(
1489 // "WeblogEntryTagAggregate.updateAddToTotalByName&WeblogNull");
1490 // update.setParameter(1, new Long(amount));
1491 // update.setParameter(2, siteTagData.getName());
1492 // update.executeUpdate();
1493 }
1494
1495 // delete all bad counts
1496 Query removeq = strategy.getNamedUpdate(
1497 "WeblogEntryTagAggregate.removeByTotalLessEqual");
1498 removeq.setParameter(1, new Integer(0));
1499 removeq.executeUpdate();
1500 }
1501
1502 /**
1503 * @inheritDoc
1504 */
1505 public WeblogHitCount getHitCount(String id) throws WebloggerException {
1506
1507 // do lookup
/*
P/P * Method: WeblogHitCount getHitCount(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
1508 return (WeblogHitCount) strategy.load(WeblogHitCount.class, id);
1509 }
1510
1511 /**
1512 * @inheritDoc
1513 */
1514 public WeblogHitCount getHitCountByWeblog(Weblog weblog)
1515 throws WebloggerException {
/*
P/P * Method: WeblogHitCount getHitCountByWeblog(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
1516 Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
1517 q.setParameter(1, weblog);
1518 try {
1519 return (WeblogHitCount)q.getSingleResult();
1520 } catch (NoResultException e) {
1521 return null;
1522 }
1523 }
1524
1525 /**
1526 * @inheritDoc
1527 */
1528 public List getHotWeblogs(int sinceDays, int offset, int length)
1529 throws WebloggerException {
1530
1531 // figure out start date
/*
P/P * Method: List getHotWeblogs(int, int, int)
*
* Preconditions:
* sinceDays <= 231
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.Calendar:getInstance(...)@1532 != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* length: {-1}, {-231..-2, 0..232-1}
* offset: {0}, {-231..-1, 1..232-1}
*/
1532 Calendar cal = Calendar.getInstance();
1533 cal.setTime(new Date());
1534 cal.add(Calendar.DATE, -1 * sinceDays);
1535 Date startDate = cal.getTime();
1536
1537 Query query = strategy.getNamedQuery(
1538 "WeblogHitCount.getByWeblogEnabledTrueAndActiveTrue&DailyHitsGreaterThenZero&WeblogLastModifiedGreaterOrderByDailyHitsDesc");
1539 query.setParameter(1, startDate);
1540
1541 // Was commented out due to https://glassfish.dev.java.net/issues/show_bug.cgi?id=2084
1542 // TODO: determine if this is still an issue. Is it a problem with other JPA implementations?
1543 if (offset != 0) {
1544 query.setFirstResult(offset);
1545 }
1546 if (length != -1) {
1547 query.setMaxResults(length);
1548 }
1549 return query.getResultList();
1550 }
1551
1552
1553 /**
1554 * @inheritDoc
1555 */
1556 public void saveHitCount(WeblogHitCount hitCount) throws WebloggerException {
/*
P/P * Method: void saveHitCount(WeblogHitCount)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*/
1557 this.strategy.store(hitCount);
1558 }
1559
1560
1561 /**
1562 * @inheritDoc
1563 */
1564 public void removeHitCount(WeblogHitCount hitCount) throws WebloggerException {
/*
P/P * Method: void removeHitCount(WeblogHitCount)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*/
1565 this.strategy.remove(hitCount);
1566 }
1567
1568
1569 /**
1570 * @inheritDoc
1571 */
1572 public void incrementHitCount(Weblog weblog, int amount)
1573 throws WebloggerException {
1574
/*
P/P * Method: void incrementHitCount(Weblog, int)
*
* Preconditions:
* amount != 0
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* weblog != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* amount + org.apache.roller.weblogger.pojos.WeblogHitCount:getDailyHits(...)@1599 in -231..232-1
*
* Test Vectors:
* amount: {-231..-1}, {1..232-1}
*/
1575 if(amount == 0) {
1576 throw new WebloggerException("Tag increment amount cannot be zero.");
1577 }
1578
1579 if(weblog == null) {
1580 throw new WebloggerException("Website cannot be NULL.");
1581 }
1582
1583 Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
1584 q.setParameter(1, weblog);
1585 WeblogHitCount hitCount = null;
1586 try {
1587 hitCount = (WeblogHitCount)q.getSingleResult();
1588 } catch (NoResultException e) {
1589 hitCount = null;
1590 }
1591
1592 // create it if it doesn't exist
1593 if(hitCount == null && amount > 0) {
1594 hitCount = new WeblogHitCount();
1595 hitCount.setWeblog(weblog);
1596 hitCount.setDailyHits(amount);
1597 strategy.store(hitCount);
1598 } else if(hitCount != null) {
1599 hitCount.setDailyHits(hitCount.getDailyHits() + amount);
1600 strategy.store(hitCount);
1601 }
1602 }
1603
1604 /**
1605 * @inheritDoc
1606 */
1607 public void resetAllHitCounts() throws WebloggerException {
/*
P/P * Method: void resetAllHitCounts()
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* javax.persistence.EntityManager:createNamedQuery(...)@301 != null
*/
1608 Query q = strategy.getNamedUpdate("WeblogHitCount.updateDailyHitCountZero");
1609 q.executeUpdate();
1610 }
1611
1612 /**
1613 * @inheritDoc
1614 */
1615 public void resetHitCount(Weblog weblog) throws WebloggerException {
/*
P/P * Method: void resetHitCount(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* javax.persistence.Query:getSingleResult(...)@1620 != null
*/
1616 Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
1617 q.setParameter(1, weblog);
1618 WeblogHitCount hitCount = null;
1619 try {
1620 hitCount = (WeblogHitCount)q.getSingleResult();
1621 hitCount.setDailyHits(0);
1622 strategy.store(hitCount);
1623 } catch (NoResultException e) {
1624 // ignore: no hit count for weblog
1625 }
1626
1627 }
1628
1629 /**
1630 * @inheritDoc
1631 */
1632 public long getCommentCount() throws WebloggerException {
/*
P/P * Method: long getCommentCount()
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.List:get(...)@1637 != null
* javax.persistence.Query:getResultList(...)@1636 != null
*
* Postconditions:
* init'ed(return_value)
*/
1633 Query q = strategy.getNamedQuery(
1634 "WeblogEntryComment.getCountAllDistinctByStatus");
1635 q.setParameter(1, WeblogEntryComment.APPROVED);
1636 List results = q.getResultList();
1637 return ((Long)results.get(0)).longValue();
1638 }
1639
1640 /**
1641 * @inheritDoc
1642 */
1643 public long getCommentCount(Weblog website) throws WebloggerException {
/*
P/P * Method: long getCommentCount(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.List:get(...)@1649 != null
* javax.persistence.Query:getResultList(...)@1648 != null
*
* Postconditions:
* init'ed(return_value)
*/
1644 Query q = strategy.getNamedQuery(
1645 "WeblogEntryComment.getCountDistinctByWebsite&Status");
1646 q.setParameter(1, website);
1647 q.setParameter(2, WeblogEntryComment.APPROVED);
1648 List results = q.getResultList();
1649 return ((Long)results.get(0)).longValue();
1650 }
1651
1652 /**
1653 * @inheritDoc
1654 */
1655 public long getEntryCount() throws WebloggerException {
/*
P/P * Method: long getEntryCount()
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.List:get(...)@1660 != null
* javax.persistence.Query:getResultList(...)@1659 != null
*
* Postconditions:
* init'ed(return_value)
*/
1656 Query q = strategy.getNamedQuery(
1657 "WeblogEntry.getCountDistinctByStatus");
1658 q.setParameter(1, "PUBLISHED");
1659 List results = q.getResultList();
1660 return ((Long)results.get(0)).longValue();
1661 }
1662
1663 /**
1664 * @inheritDoc
1665 */
1666 public long getEntryCount(Weblog website) throws WebloggerException {
/*
P/P * Method: long getEntryCount(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Presumptions:
* java.util.List:get(...)@1672 != null
* javax.persistence.Query:getResultList(...)@1671 != null
*
* Postconditions:
* init'ed(return_value)
*/
1667 Query q = strategy.getNamedQuery(
1668 "WeblogEntry.getCountDistinctByStatus&Website");
1669 q.setParameter(1, "PUBLISHED");
1670 q.setParameter(2, website);
1671 List results = q.getResultList();
1672 return ((Long)results.get(0)).longValue();
1673 }
1674
1675 /**
1676 * Appends given expression to given whereClause. If whereClause already
1677 * has other conditions, an " AND " is also appended before appending
1678 * the expression
1679 * @param whereClause The given where Clauuse
1680 * @param expression The given expression
1681 * @return the whereClause.
1682 */
1683 private static StringBuffer appendConjuctionToWhereclause(StringBuffer whereClause,
1684 String expression) {
/*
P/P * Method: StringBuffer appendConjuctionToWhereclause(StringBuffer, String)
*
* Preconditions:
* whereClause != null
* (soft) expression != null
*
* Postconditions:
* return_value == whereClause
* return_value != null
* whereClause._tainted == old whereClause._tainted | One-of{expression._tainted, old whereClause._tainted}
* init'ed(whereClause._tainted)
*
* Test Vectors:
* java.lang.String:length(...)@1685: {0}, {1..232-1}
* java.lang.StringBuffer:length(...)@1685: {0}, {-231..-1, 1..232-1}
*/
1685 if(whereClause.length() != 0 && expression.length() != 0) {
1686 whereClause.append(" AND ");
1687 }
1688 return whereClause.append(expression);
1689 }
1690
1691 }
SofCheck Inspector Build Version : 2.18479
| JPAWeblogManagerImpl.java |
2009-Jan-02 14:25:16 |
| JPAWeblogManagerImpl.class |
2009-Sep-04 03:12:31 |