File Source: JPABookmarkManagerImpl.java
1
2 /*
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. The ASF licenses this file to You
5 * under the Apache License, Version 2.0 (the "License"); you may not
6 * use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License. For additional information regarding
16 * copyright in this work, please see the NOTICE file in the top level
17 * directory of this distribution.
18 */
19 package org.apache.roller.weblogger.business.jpa;
20
21 import java.io.StringReader;
22 import java.util.Iterator;
23 import java.util.List;
24 import javax.persistence.NoResultException;
25 import javax.persistence.Query;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy;
30 import org.apache.roller.weblogger.WebloggerException;
31 import org.apache.roller.weblogger.business.BookmarkManager;
32 import org.apache.roller.weblogger.business.Weblogger;
33 import org.apache.roller.weblogger.pojos.WeblogBookmark;
34 import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder;
35 import org.apache.roller.weblogger.pojos.Weblog;
36 import org.jdom.Document;
37 import org.jdom.Element;
38 import org.jdom.input.SAXBuilder;
39
40 /*
41 * JPABookmarkManagerImpl.java
42 *
43 * Created on May 31, 2006, 3:49 PM
44 *
45 */
46 @com.google.inject.Singleton
47 public class JPABookmarkManagerImpl implements BookmarkManager {
48
49 private final Weblogger roller;
50 private final JPAPersistenceStrategy strategy;
51
52
53 /**
54 * The logger instance for this class.
55 */
/*
P/P * Method: org.apache.roller.weblogger.business.jpa.JPABookmarkManagerImpl__static_init
*
* Presumptions:
* org.apache.commons.logging.LogFactory:getFactory(...)@56 != null
*
* Postconditions:
* init'ed(log)
*/
56 private static Log log = LogFactory
57 .getFactory().getInstance(JPABookmarkManagerImpl.class);
58
59 /**
60 * Creates a new instance of JPABookmarkManagerImpl
61 */
62 @com.google.inject.Inject
/*
P/P * Method: void org.apache.roller.weblogger.business.jpa.JPABookmarkManagerImpl(Weblogger, JPAPersistenceStrategy)
*
* Preconditions:
* log != null
*
* Postconditions:
* this.roller == roller
* init'ed(this.roller)
* this.strategy == strategy
* init'ed(this.strategy)
*/
63 protected JPABookmarkManagerImpl(Weblogger roller, JPAPersistenceStrategy strategy) {
64 log.debug("Instantiating JPA Bookmark Manager");
65 this.roller = roller;
66 this.strategy = strategy;
67 }
68
69
70 public void saveBookmark(WeblogBookmark bookmark) throws WebloggerException {
/*
P/P * Method: void saveBookmark(WeblogBookmark)
*
* Preconditions:
* bookmark != 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@77 != null
* org.apache.roller.weblogger.pojos.WeblogBookmark:getFolder(...)@74 != null
* org.apache.roller.weblogger.pojos.WeblogBookmark:getWebsite(...)@80 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getBookmarks(...)@74 != null
*
* Test Vectors:
* javax.persistence.EntityManager:find(...)@216: Inverse{null}, Addr_Set{null}
*/
71 boolean exists = getBookmark(bookmark.getId()) != null;
72 if (!exists) {
73 // New object make sure that relationship is set on managed copy of other side
74 bookmark.getFolder().getBookmarks().add(bookmark);
75 }
76
77 this.strategy.store(bookmark);
78
79 // update weblog last modified date (date is updated by saveWebsite())
80 roller.getUserManager().
81 saveWebsite(bookmark.getWebsite());
82 }
83
84 public WeblogBookmark getBookmark(String id) throws WebloggerException {
/*
P/P * Method: WeblogBookmark getBookmark(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
85 return (WeblogBookmark) strategy.load(WeblogBookmark.class, id);
86 }
87
88 public void removeBookmark(WeblogBookmark bookmark) throws WebloggerException {
89 //Now remove it from database
/*
P/P * Method: void removeBookmark(WeblogBookmark)
*
* Preconditions:
* bookmark != 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@90 != null
* org.apache.roller.weblogger.pojos.WeblogBookmark:getFolder(...)@92 != null
* org.apache.roller.weblogger.pojos.WeblogBookmark:getWebsite(...)@94 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getBookmarks(...)@92 != null
*/
90 this.strategy.remove(bookmark);
91 //Remove the bookmark from its parent folder
92 bookmark.getFolder().getBookmarks().remove(bookmark);
93 // update weblog last modified date. date updated by saveWebsite()
94 roller.getUserManager()
95 .saveWebsite(bookmark.getWebsite());
96 }
97
98 public void saveFolder(WeblogBookmarkFolder folder) throws WebloggerException {
99
/*
P/P * Method: void saveFolder(WeblogBookmarkFolder)
*
* Preconditions:
* folder != 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@113 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getFolders(...)@109 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getWebsite(...)@116 != null
*
* Test Vectors:
* javax.persistence.EntityManager:find(...)@216: Inverse{null}, Addr_Set{null}
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getId(...)@100: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getParent(...)@107: Addr_Set{null}, Inverse{null}
*/
100 if(folder.getId() == null || this.getFolder(folder.getId()) == null) {
101 // New folder, so make sure name is unique
+ 102 if (isDuplicateFolderName(folder)) {
103 throw new WebloggerException("Duplicate folder name");
104 }
105
106 // And If it has a parent, maintain relationship from both sides
107 WeblogBookmarkFolder parent = folder.getParent();
108 if(parent != null) {
109 parent.getFolders().add(folder);
110 }
111 }
112
113 this.strategy.store(folder);
114
115 // update weblog last modified date. date updated by saveWebsite()
116 roller.getUserManager().saveWebsite(folder.getWebsite());
117 }
118
119 public void removeFolder(WeblogBookmarkFolder folder) throws WebloggerException {
/*
P/P * Method: void removeFolder(WeblogBookmarkFolder)
*
* Preconditions:
* folder != 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@120 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getFolders(...)@123 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getWebsite(...)@127 != null
*
* Test Vectors:
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getParent(...)@121: Addr_Set{null}, Inverse{null}
*/
120 this.strategy.remove(folder);
121 WeblogBookmarkFolder parent = folder.getParent();
122 if (parent != null) {
123 parent.getFolders().remove(folder);
124 }
125
126 // update weblog last modified date. date updated by saveWebsite()
127 roller.getUserManager().
128 saveWebsite(folder.getWebsite());
129 }
130
131 public void moveFolder(WeblogBookmarkFolder srcFolder, WeblogBookmarkFolder destFolder)
132 throws WebloggerException {
133
134 // TODO: this check should be made before calling this method?
/*
P/P * Method: void moveFolder(WeblogBookmarkFolder, WeblogBookmarkFolder)
*
* Preconditions:
* destFolder != null
* log != null
* srcFolder != 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.WeblogBookmarkFolder:descendentOf(...)@135 == 0
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getFolders(...)@146 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getFolders(...)@149 != null
*
* Test Vectors:
* java.lang.String:equals(...)@151: {0}, {1}
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getParent(...)@144: Addr_Set{null}, Inverse{null}
*/
135 if (destFolder.descendentOf(srcFolder)) {
136 throw new WebloggerException(
137 "ERROR cannot move parent folder into it's own child");
138 }
139
140 log.debug("Moving folder " + srcFolder.getPath() + " under " +
141 destFolder.getPath());
142
143 // Manage relationships
144 WeblogBookmarkFolder oldParent = srcFolder.getParent();
145 if(oldParent != null) {
146 oldParent.getFolders().add(srcFolder);
147 }
148 srcFolder.setParent(destFolder);
149 destFolder.getFolders().add(srcFolder);
150
151 if("/".equals(destFolder.getPath())) {
152 srcFolder.setPath("/"+srcFolder.getName());
153 } else {
154 srcFolder.setPath(destFolder.getPath() + "/" + srcFolder.getName());
155 }
156 saveFolder(srcFolder);
157
158 // the main work to be done for a category move is to update the
159 // path attribute of the category and all descendent categories
160 updatePathTree(srcFolder);
161 }
162
163 // updates the paths of all descendents of the given folder
164 private void updatePathTree(WeblogBookmarkFolder folder) throws WebloggerException {
165
/*
P/P * Method: void updatePathTree(WeblogBookmarkFolder)
*
* Preconditions:
* folder != 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(...)@171 != null
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getFolders(...)@169 != null
*
* Test Vectors:
* java.lang.String:equals(...)@176: {0}, {1}
* java.util.Iterator:hasNext(...)@170: {0}, {1}
*/
166 log.debug("Updating path tree for folder "+folder.getPath());
167
168 WeblogBookmarkFolder childFolder = null;
169 Iterator childFolders = folder.getFolders().iterator();
170 while(childFolders.hasNext()) {
171 childFolder = (WeblogBookmarkFolder) childFolders.next();
172
173 log.debug("OLD child folder path was "+childFolder.getPath());
174
175 // update path and save
176 if("/".equals(folder.getPath())) {
177 childFolder.setPath("/" + childFolder.getName());
178 } else {
179 childFolder.setPath(folder.getPath() + "/" +
180 childFolder.getName());
181 }
182 saveFolder(childFolder);
183
184 log.debug("NEW child folder path is "+ childFolder.getPath());
185
186 // then make recursive call to update this folders children
187 updatePathTree(childFolder);
188 }
189 }
190
191
192 /**
193 * Retrieve folder and lazy-load it's sub-folders and bookmarks.
194 */
195 public WeblogBookmarkFolder getFolder(String id) throws WebloggerException {
/*
P/P * Method: WeblogBookmarkFolder getFolder(String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
196 return (WeblogBookmarkFolder) strategy.load(WeblogBookmarkFolder.class, id);
197 }
198
199
200 public void importBookmarks(
201 Weblog website, String folderName, String opml)
202 throws WebloggerException {
/*
P/P * Method: void importBookmarks(Weblog, String, String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
* (soft) website != null
*
* Presumptions:
* java.util.Iterator:next(...)@222 != null
* org.jdom.Document:getRootElement(...)@219 != null
* org.jdom.Element:getChild(...)@219 != null
* org.jdom.Element:getChildren(...)@220 != null
* org.jdom.input.SAXBuilder:build(...)@208 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@221: {0}, {1}
*/
+ 203 String msg = "importBookmarks";
204 try {
205 // Build JDOC document OPML string
206 SAXBuilder builder = new SAXBuilder();
207 StringReader reader = new StringReader( opml );
208 Document doc = builder.build( reader );
209
210 WeblogBookmarkFolder newFolder = getFolder(website, folderName);
211 if (newFolder == null) {
212 newFolder = new WeblogBookmarkFolder(
213 getRootFolder(website),
214 folderName, folderName, website);
215 this.strategy.store(newFolder);
216 }
217
218 // Iterate through children of OPML body, importing each
219 Element body = doc.getRootElement().getChild("body");
220 Iterator iter = body.getChildren().iterator();
221 while (iter.hasNext()) {
222 Element elem = (Element)iter.next();
223 importOpmlElement( website, elem, newFolder );
224 }
225
226 } catch (Exception ex) {
227 throw new WebloggerException(ex);
228 }
229 }
230
231 // convenience method used when importing bookmarks
232 // NOTE: this method does not commit any changes;
233 // that is done by importBookmarks()
234 private void importOpmlElement(
235 Weblog website, Element elem, WeblogBookmarkFolder parent)
236 throws WebloggerException {
/*
P/P * Method: void importOpmlElement(Weblog, Element, WeblogBookmarkFolder)
*
* Preconditions:
* elem != null
* (soft) parent != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@284 != null
* org.jdom.Element:getChildren(...)@250 != null
* org.jdom.Element:getChildren(...)@282 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@283: {0}, {1}
* java.util.List:size(...)@250: {-231..-1, 1..232-1}, {0}
*/
237 String text = elem.getAttributeValue("text");
238 String title = elem.getAttributeValue("title");
239 String desc = elem.getAttributeValue("description");
240 String url = elem.getAttributeValue("url");
241 //String type = elem.getAttributeValue("type");
242 String xmlUrl = elem.getAttributeValue("xmlUrl");
243 String htmlUrl = elem.getAttributeValue("htmlUrl");
244
245 title = null!=title ? title : text;
246 desc = null!=desc ? desc : title;
247 xmlUrl = null!=xmlUrl ? xmlUrl : url;
248 url = null!=htmlUrl ? htmlUrl : url;
249
250 if (elem.getChildren().size()==0) {
251 // Leaf element. Store a bookmark
252 // Currently bookmarks must have at least a name and
253 // HTML url to be stored. Previous logic was
254 // trying to skip invalid ones, but was letting ones
255 // with an xml url and no html url through
256 // which could result in a db exception.
257 // TODO: Consider providing error feedback instead of
258 // silently skipping the invalid bookmarks here.
259 if (null != title && null != url) {
260 WeblogBookmark bd = new WeblogBookmark(parent,
261 title,
262 desc,
263 url,
264 xmlUrl,
265 new Integer(0),
266 new Integer(100),
267 null);
268 parent.addBookmark(bd);
269 // TODO: maybe this should be saving the folder?
270 this.strategy.store(bd);
271 }
272 } else {
273 // Store a folder
274 WeblogBookmarkFolder fd = new WeblogBookmarkFolder(
275 parent,
276 title,
277 desc,
278 parent.getWebsite());
279 this.strategy.store(fd);
280
281 // Import folder's children
282 Iterator iter = elem.getChildren("outline").iterator();
283 while ( iter.hasNext() ) {
284 Element subelem = (Element)iter.next();
285 importOpmlElement( website, subelem, fd );
286 }
287 }
288 }
289
290
291 public WeblogBookmarkFolder getFolder(Weblog website, String path)
292 throws WebloggerException {
293
/*
P/P * Method: WeblogBookmarkFolder getFolder(Weblog, String)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) this.strategy.emf != null
* (soft) website != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* path: Addr_Set{null}, Inverse{null}
* java.lang.String:equals(...)@294: {0}, {1}
* java.lang.String:startsWith(...)@300: {1}, {0}
*/
294 if (path == null || path.trim().equals("/")) {
295 return getRootFolder(website);
296 } else {
297 String folderPath = path;
298
299 // all folder paths must begin with a '/'
300 if(!folderPath.startsWith("/")) {
301 folderPath = "/"+folderPath;
302 }
303
304 // now just do simple lookup by path
305 Query query = strategy.getNamedQuery("WeblogBookmarkFolder.getByWebsite&Path");
306 query.setParameter(1, website);
307 query.setParameter(2, folderPath);
308 try {
309 return (WeblogBookmarkFolder)query.getSingleResult();
310 } catch (NoResultException e) {
311 return null;
312 }
313 }
314 }
315
316 /**
317 * @see org.apache.roller.weblogger.model.BookmarkManager#retrieveBookmarks(
318 * org.apache.roller.weblogger.pojos.WeblogBookmarkFolder, boolean)
319 */
320 public List getBookmarks(WeblogBookmarkFolder folder, boolean subfolders)
321 throws WebloggerException {
/*
P/P * Method: List getBookmarks(WeblogBookmarkFolder, bool)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* (soft) folder != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* subfolders: {1}, {0}
*/
322 Query query = null;
323 List results = null;
324
325 if(!subfolders) {
326 // if no subfolders then this is an equals query
327 query = strategy.getNamedQuery("BoomarkData.getByFolder");
328 query.setParameter(1, folder);
329 results = query.getResultList();
330 } else {
331 // if we are doing subfolders then do a case sensitive
332 // query using folder path
333 query = strategy.getNamedQuery(
334 "BoomarkData.getByFolder.pathLike&Folder.website");
335 query.setParameter(1, folder.getPath() + '%');
336 query.setParameter(2, folder.getWebsite());
337 results = query.getResultList();
338 }
339
340 return results;
341 }
342
343 public WeblogBookmarkFolder getRootFolder(Weblog website)
344 throws WebloggerException {
/*
P/P * Method: WeblogBookmarkFolder getRootFolder(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
345 if (website == null)
346 throw new WebloggerException("website is null");
347
348 Query q = strategy.getNamedQuery("WeblogBookmarkFolder.getByWebsite&ParentNull");
349 q.setParameter(1, website);
350 try {
351 return (WeblogBookmarkFolder)q.getSingleResult();
352 } catch (NoResultException e) {
353 return null;
354 }
355 }
356
357 public List getAllFolders(Weblog website)
358 throws WebloggerException {
/*
P/P * Method: List getAllFolders(Weblog)
*
* Preconditions:
* this.strategy != null
* this.strategy.threadLocalEntityManager != null
* website != null
* (soft) this.strategy.emf != null
*
* Postconditions:
* init'ed(return_value)
*/
359 if (website == null)
360 throw new WebloggerException("Website is null");
361
362 Query q = strategy.getNamedQuery("WeblogBookmarkFolder.getByWebsite");
363 q.setParameter(1, website);
364 return q.getResultList();
365 }
366
367
368 /**
369 * make sure the given folder doesn't already exist.
370 */
371 private boolean isDuplicateFolderName(WeblogBookmarkFolder folder)
372 throws WebloggerException {
373
374 // ensure that no sibling categories share the same name
/*
P/P * Method: bool isDuplicateFolderName(WeblogBookmarkFolder)
*
* Preconditions:
* folder != null
* (soft) this.strategy != null
* (soft) this.strategy.emf != null
* (soft) this.strategy.threadLocalEntityManager != null
*
* Presumptions:
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getWebsite(...)@377 != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getParent(...)@375: Addr_Set{null}, Inverse{null}
*/
375 WeblogBookmarkFolder parent = folder.getParent();
376 if (null != parent) {
377 return (getFolder(folder.getWebsite(), folder.getPath()) != null);
378 }
379
380 return false;
381 }
382
383
/*
P/P * Method: void release()
*/
384 public void release() {}
385
386 }
SofCheck Inspector Build Version : 2.18479
| JPABookmarkManagerImpl.java |
2009-Jan-02 14:25:38 |
| JPABookmarkManagerImpl.class |
2009-Sep-04 03:12:31 |