KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > business > hibernate > HibernateBookmarkManagerImpl


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  * Created on Jun 18, 2004
20  */

21 package org.apache.roller.business.hibernate;
22
23 import java.io.StringReader JavaDoc;
24 import org.hibernate.Criteria;
25 import org.hibernate.HibernateException;
26 import org.hibernate.Session;
27 import org.hibernate.criterion.Expression;
28 import org.apache.roller.RollerException;
29 import org.apache.roller.pojos.Assoc;
30 import org.apache.roller.pojos.BookmarkData;
31 import org.apache.roller.pojos.FolderAssoc;
32 import org.apache.roller.pojos.FolderData;
33 import org.apache.roller.pojos.WebsiteData;
34 import java.util.Iterator JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.List JavaDoc;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.jdom.Document;
40 import org.jdom.Element;
41 import org.jdom.input.SAXBuilder;
42 import org.apache.roller.model.BookmarkManager;
43 import org.apache.roller.model.RollerFactory;
44 import org.apache.roller.util.Utilities;
45
46
47 /**
48  * Hibernate implementation of the BookmarkManager.
49  */

50 public class HibernateBookmarkManagerImpl implements BookmarkManager {
51     
52     static final long serialVersionUID = 5286654557062382772L;
53     
54     private static Log log = LogFactory.getLog(HibernateBookmarkManagerImpl.class);
55     
56     private HibernatePersistenceStrategy strategy = null;
57     
58     
59     /**
60      * @param pstrategy
61      * @param roller
62      */

63     public HibernateBookmarkManagerImpl(HibernatePersistenceStrategy strat) {
64         log.debug("Instantiating Hibernate Bookmark Manager");
65         
66         this.strategy = strat;
67     }
68     
69     
70     public void saveBookmark(BookmarkData bookmark) throws RollerException {
71         this.strategy.store(bookmark);
72         
73         // update weblog last modified date. date updated by saveWebsite()
74
RollerFactory.getRoller().getUserManager().saveWebsite(bookmark.getWebsite());
75     }
76     
77     
78     public BookmarkData getBookmark(String JavaDoc id) throws RollerException {
79         BookmarkData bd = (BookmarkData)
80         strategy.load(id, BookmarkData.class);
81         // TODO: huh? why do we do this?
82
if (bd != null) bd.setBookmarkManager(this);
83         return bd;
84     }
85     
86     
87     public void removeBookmark(BookmarkData bookmark) throws RollerException {
88         this.strategy.remove(bookmark);
89         
90         // update weblog last modified date. date updated by saveWebsite()
91
RollerFactory.getRoller().getUserManager().saveWebsite(bookmark.getWebsite());
92     }
93     
94     //------------------------------------------------------------ Folder CRUD
95

96     
97     public void saveFolder(FolderData folder) throws RollerException {
98         
99         if(isDuplicateFolderName(folder)) {
100             throw new RollerException("Duplicate folder name");
101         }
102         
103         this.strategy.store(folder);
104         
105         // update weblog last modified date. date updated by saveWebsite()
106
RollerFactory.getRoller().getUserManager().saveWebsite(folder.getWebsite());
107     }
108     
109     
110     public void removeFolder(FolderData folder) throws RollerException {
111         
112         this.strategy.remove(folder);
113         
114         // update weblog last modified date. date updated by saveWebsite()
115
RollerFactory.getRoller().getUserManager().saveWebsite(folder.getWebsite());
116     }
117     
118     
119     /**
120      * Retrieve folder and lazy-load it's sub-folders and bookmarks.
121      */

122     public FolderData getFolder(String JavaDoc id) throws RollerException {
123         return (FolderData)strategy.load(id, FolderData.class);
124     }
125     
126     //------------------------------------------------------------ Operations
127

128     public void importBookmarks(WebsiteData website, String JavaDoc folderName, String JavaDoc opml)
129             throws RollerException {
130         
131         String JavaDoc msg = "importBookmarks";
132         try {
133             // Build JDOC document OPML string
134
SAXBuilder builder = new SAXBuilder();
135             StringReader JavaDoc reader = new StringReader JavaDoc( opml );
136             Document doc = builder.build( reader );
137             
138             FolderData newFolder = getFolder(website, folderName);
139             if (newFolder == null) {
140                 newFolder = new FolderData(
141                         getRootFolder(website), folderName, folderName, website);
142                 this.strategy.store(newFolder);
143             }
144             
145             // Iterate through children of OPML body, importing each
146
Element body = doc.getRootElement().getChild("body");
147             Iterator JavaDoc iter = body.getChildren().iterator();
148             while (iter.hasNext()) {
149                 Element elem = (Element)iter.next();
150                 importOpmlElement( website, elem, newFolder );
151             }
152             
153         } catch (Exception JavaDoc ex) {
154             throw new RollerException(ex);
155         }
156     }
157     
158     // convenience method used when importing bookmarks
159
// NOTE: this method does not commit any changes, that is done by importBookmarks()
160
private void importOpmlElement(
161             WebsiteData website, Element elem, FolderData parent)
162             throws RollerException {
163         String JavaDoc text = elem.getAttributeValue("text");
164         String JavaDoc title = elem.getAttributeValue("title");
165         String JavaDoc desc = elem.getAttributeValue("description");
166         String JavaDoc url = elem.getAttributeValue("url");
167         //String type = elem.getAttributeValue("type");
168
String JavaDoc xmlUrl = elem.getAttributeValue("xmlUrl");
169         String JavaDoc htmlUrl = elem.getAttributeValue("htmlUrl");
170         
171         title = null!=title ? title : text;
172         desc = null!=desc ? desc : title;
173         xmlUrl = null!=xmlUrl ? xmlUrl : url;
174         url = null!=htmlUrl ? htmlUrl : url;
175         
176         if (elem.getChildren().size()==0) {
177             // Leaf element. Store a bookmark
178
// Currently bookmarks must have at least a name and HTML url to be stored. Previous logic was
179
// trying to skip invalid ones, but was letting ones with an xml url and no html url through
180
// which could result in a db exception.
181
// TODO: Consider providing error feedback instead of silently skipping the invalid bookmarks here.
182
if (null != title && null != url) {
183                 BookmarkData bd = new BookmarkData(parent,
184                         title,
185                         desc,
186                         url,
187                         xmlUrl,
188                         new Integer JavaDoc(0),
189                         new Integer JavaDoc(100),
190                         null);
191                 parent.addBookmark(bd);
192                 // TODO: maybe this should be saving the folder?
193
this.strategy.store(bd);
194             }
195         } else {
196             // Store a folder
197
FolderData fd = new FolderData(
198                     parent,
199                     title,
200                     desc,
201                     parent.getWebsite());
202             this.strategy.store(fd);
203             
204             // Import folder's children
205
Iterator JavaDoc iter = elem.getChildren("outline").iterator();
206             while ( iter.hasNext() ) {
207                 Element subelem = (Element)iter.next();
208                 importOpmlElement( website, subelem, fd );
209             }
210         }
211     }
212     
213     //----------------------------------------------------------------
214
public void moveFolderContents(FolderData src, FolderData dest)
215             throws RollerException {
216         
217         if (dest.descendentOf(src)) {
218             throw new RollerException(
219                     "ERROR cannot move parent folder into it's own child");
220         }
221         
222         try {
223             // Add to destination folder
224
LinkedList JavaDoc deleteList = new LinkedList JavaDoc();
225             Iterator JavaDoc srcBookmarks = src.getBookmarks().iterator();
226             while (srcBookmarks.hasNext()) {
227                 BookmarkData bd = (BookmarkData)srcBookmarks.next();
228                 deleteList.add(bd);
229                 
230                 BookmarkData movedBd = new BookmarkData();
231                 movedBd.setData(bd);
232                 movedBd.setId(null);
233                 
234                 dest.addBookmark(movedBd);
235                 this.strategy.store(movedBd);
236             }
237             
238             // Remove from source folder
239
Iterator JavaDoc deleteIter = deleteList.iterator();
240             while (deleteIter.hasNext()) {
241                 BookmarkData bd = (BookmarkData)deleteIter.next();
242                 src.removeBookmark(bd);
243                 // TODO: this won't conflict with the bookmark we store above right?
244
this.strategy.remove(bd);
245             }
246             
247         } catch (Exception JavaDoc ex) {
248             throw new RollerException(ex);
249         }
250     }
251     
252     //----------------------------------------------------------------
253
public void removeFolderContents(FolderData src) throws RollerException {
254         
255         // just go through the folder and remove each bookmark
256
Iterator JavaDoc srcBookmarks = src.getBookmarks().iterator();
257         while (srcBookmarks.hasNext()) {
258             BookmarkData bd = (BookmarkData)srcBookmarks.next();
259             this.strategy.remove(bd);
260         }
261     }
262     
263     //---------------------------------------------------------------- Queries
264

265     public FolderData getFolder(WebsiteData website, String JavaDoc folderPath)
266     throws RollerException {
267         return getFolderByPath(website, null, folderPath);
268     }
269     
270     public String JavaDoc getPath(FolderData folder) throws RollerException {
271         if (null == folder.getParent()) {
272             return "/";
273         } else {
274             String JavaDoc parentPath = getPath(folder.getParent());
275             parentPath = "/".equals(parentPath) ? "" : parentPath;
276             return parentPath + "/" + folder.getName();
277         }
278     }
279     
280     public FolderData getFolderByPath(
281             WebsiteData website, FolderData folder, String JavaDoc path)
282             throws RollerException {
283         final Iterator JavaDoc folders;
284         final String JavaDoc[] pathArray = Utilities.stringToStringArray(path, "/");
285         
286         if (folder == null && (null == path || "".equals(path.trim()))) {
287             throw new RollerException("Bad arguments.");
288         }
289         
290         if (path.trim().equals("/")) {
291             return getRootFolder(website);
292         } else if (folder == null || path.trim().startsWith("/")) {
293             folders = getRootFolder(website).getFolders().iterator();
294         } else {
295             folders = folder.getFolders().iterator();
296         }
297         
298         while (folders.hasNext()) {
299             FolderData possibleMatch = (FolderData)folders.next();
300             if (possibleMatch.getName().equals(pathArray[0])) {
301                 if (pathArray.length == 1) {
302                     return possibleMatch;
303                 } else {
304                     String JavaDoc[] subpath = new String JavaDoc[pathArray.length - 1];
305                     System.arraycopy(pathArray, 1, subpath, 0, subpath.length);
306                     
307                     String JavaDoc pathString= Utilities.stringArrayToString(subpath,"/");
308                     return getFolderByPath(website, possibleMatch, pathString);
309                 }
310             }
311         }
312         
313         // The folder did not match and neither did any subfolders
314
return null;
315     }
316     
317     //----------------------------------------------- FolderAssoc CRUD
318

319     
320     public FolderAssoc retrieveFolderAssoc(String JavaDoc id) throws RollerException {
321         return (FolderAssoc)strategy.load(id, FolderAssoc.class);
322     }
323     
324     public void release() {}
325     
326     /**
327      * @see org.apache.roller.model.BookmarkManager#retrieveBookmarks(
328      * org.apache.roller.pojos.FolderData, boolean)
329      */

330     public List JavaDoc getBookmarks(FolderData folder, boolean subfolders)
331     throws RollerException {
332         try {
333             Session session = ((HibernatePersistenceStrategy) strategy).getSession();
334             List JavaDoc bookmarks = new LinkedList JavaDoc();
335             if (subfolders) {
336                 // get bookmarks in subfolders
337
Criteria assocsQuery = session
338                         .createCriteria(FolderAssoc.class);
339                 assocsQuery.add(Expression.eq("ancestorFolder", folder));
340                 Iterator JavaDoc assocs = assocsQuery.list().iterator();
341                 while (assocs.hasNext()) {
342                     FolderAssoc assoc = (FolderAssoc) assocs.next();
343                     Criteria bookmarksQuery = session
344                             .createCriteria(BookmarkData.class);
345                     bookmarksQuery.add(Expression.eq("folder", assoc
346                             .getFolder()));
347                     Iterator JavaDoc bookmarkIter = bookmarksQuery.list().iterator();
348                     while (bookmarkIter.hasNext()) {
349                         BookmarkData entry = (BookmarkData) bookmarkIter.next();
350                         bookmarks.add(entry);
351                     }
352                 }
353             }
354             
355             // get bookmarks in folder
356
Criteria bookmarksQuery = session
357                     .createCriteria(BookmarkData.class);
358             bookmarksQuery.add(Expression.eq("folder", folder));
359             Iterator JavaDoc bookmarkIter = bookmarksQuery.list().iterator();
360             while (bookmarkIter.hasNext()) {
361                 BookmarkData bookmark = (BookmarkData) bookmarkIter.next();
362                 bookmarks.add(bookmark);
363             }
364             return bookmarks;
365         } catch (HibernateException e) {
366             throw new RollerException(e);
367         }
368     }
369     
370     public FolderData getRootFolder(WebsiteData website) throws RollerException {
371         if (website == null)
372             throw new RollerException("website is null");
373         try {
374             Session session = ((HibernatePersistenceStrategy) strategy).getSession();
375             Criteria criteria = session.createCriteria(FolderAssoc.class);
376             criteria.createAlias("folder", "f");
377             criteria.add(Expression.eq("f.website", website));
378             criteria.add(Expression.isNull("ancestorFolder"));
379             criteria.add(Expression.eq("relation", FolderAssoc.PARENT));
380             List JavaDoc results = criteria.list();
381             if (results.size() > 1) {
382                 // Should not have more than one root
383
throw new RollerException(
384                         "More than one root folder found for website "
385                         + website.getId());
386             } else if (results.size() == 1) {
387                 // Return root
388
return ((FolderAssoc) results.get(0)).getFolder();
389             }
390             return null;
391         } catch (HibernateException e) {
392             throw new RollerException(e);
393         }
394     }
395     
396     public List JavaDoc getAllFolders(WebsiteData website) throws RollerException {
397         if (website == null)
398             throw new RollerException("Website is null");
399         
400         try {
401             Session session = ((HibernatePersistenceStrategy) strategy).getSession();
402             Criteria criteria = session.createCriteria(FolderData.class);
403             criteria.add(Expression.eq("website", website));
404             return criteria.list();
405         } catch (HibernateException e) {
406             throw new RollerException(e);
407         }
408         
409     }
410     
411     /**
412      * @see org.apache.roller.model.BookmarkManager#isDuplicateFolderName(org.apache.roller.pojos.FolderData)
413      */

414     public boolean isDuplicateFolderName(FolderData folder) throws RollerException {
415         // ensure that no sibling folders share the same name
416
boolean isNewFolder = (folder.getId() == null);
417         FolderData parent =
418                 isNewFolder ? (FolderData)folder.getNewParent() : folder.getParent();
419         
420         if (null != parent) {
421             List JavaDoc sameNames;
422             try {
423                 Session session = ((HibernatePersistenceStrategy) strategy).getSession();
424                 Criteria criteria = session.createCriteria(FolderAssoc.class);
425                 criteria.createAlias("folder", "f");
426                 criteria.add(Expression.eq("f.name", folder.getName()));
427                 criteria.add(Expression.eq("ancestorFolder", parent));
428                 criteria.add(Expression.eq("relation", Assoc.PARENT));
429                 sameNames = criteria.list();
430             } catch (HibernateException e) {
431                 throw new RollerException(e);
432             }
433             // If we got some matches
434
if (sameNames.size() > 0) {
435                 // if we're saving a new folder, any matches are dups
436
if (isNewFolder) return true;
437                 // otherwise it's a dup it isn't the same one (one match with the same id).
438
if (!(sameNames.size() == 1 && folder.getId().equals(((FolderAssoc)sameNames.get(0)).getFolder().getId())))
439                     return true;
440             }
441         }
442         return false;
443     }
444     
445     /**
446      * @see org.apache.roller.model.BookmarkManager#getFolderParentAssoc(
447      * org.apache.roller.pojos.FolderData)
448      */

449     public Assoc getFolderParentAssoc(FolderData folder) throws RollerException {
450         try {
451             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
452             Criteria criteria = session.createCriteria(FolderAssoc.class);
453             criteria.add(Expression.eq("folder", folder));
454             criteria.add(Expression.eq("relation", Assoc.PARENT));
455             List JavaDoc parents = criteria.list();
456             if (parents.size() > 1) {
457                 throw new RollerException("ERROR: more than one parent");
458             } else if (parents.size() == 1) {
459                 return (Assoc) parents.get(0);
460             } else {
461                 return null;
462             }
463         } catch (HibernateException e) {
464             throw new RollerException(e);
465         }
466     }
467     
468     /**
469      * @see org.apache.roller.model.BookmarkManager#getFolderChildAssocs(
470      * org.apache.roller.pojos.FolderData)
471      */

472     public List JavaDoc getFolderChildAssocs(FolderData folder) throws RollerException {
473         try {
474             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
475             Criteria criteria = session.createCriteria(FolderAssoc.class);
476             criteria.add(Expression.eq("ancestorFolder", folder));
477             criteria.add(Expression.eq("relation", Assoc.PARENT));
478             return criteria.list();
479         } catch (HibernateException e) {
480             throw new RollerException(e);
481         }
482     }
483     
484     /**
485      * @see org.apache.roller.model.BookmarkManager#getAllFolderDecscendentAssocs(
486      * org.apache.roller.pojos.FolderData)
487      */

488     public List JavaDoc getAllFolderDecscendentAssocs(FolderData folder) throws RollerException {
489         try {
490             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
491             Criteria criteria = session.createCriteria(FolderAssoc.class);
492             criteria.add(Expression.eq("ancestorFolder", folder));
493             return criteria.list();
494         } catch (HibernateException e) {
495             throw new RollerException(e);
496         }
497     }
498     
499     /**
500      * @see org.apache.roller.model.BookmarkManager#getFolderAncestorAssocs(
501      * org.apache.roller.pojos.FolderData)
502      */

503     public List JavaDoc getFolderAncestorAssocs(FolderData folder) throws RollerException {
504         try {
505             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
506             Criteria criteria = session.createCriteria(FolderAssoc.class);
507             criteria.add(Expression.eq("folder", folder));
508             return criteria.list();
509         } catch (HibernateException e) {
510             throw new RollerException(e);
511         }
512     }
513     
514     /**
515      * @see org.apache.roller.model.BookmarkManager#isFolderInUse(org.apache.roller.pojos.FolderData)
516      */

517     public boolean isFolderInUse(FolderData folder) throws RollerException {
518         try {
519             // We consider a folder to be "in use" if it contains any bookmarks or has
520
// any children.
521

522             // We first determine the number of bookmark entries.
523
// NOTE: This seems to be an attempt to optimize, rather than just use getBookmarks(),
524
// but I'm not sure that this optimization is really worthwhile, and it ignores
525
// caching in the case that the (lazy) getBookmarks has been done already. --agangolli
526
// TODO: condider changing to just use getBookmarks().size()
527

528             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
529             Criteria criteria = session.createCriteria(BookmarkData.class);
530             criteria.add(Expression.eq("folder", folder));
531             criteria.setMaxResults(1);
532             int entryCount = criteria.list().size();
533             
534             // Return true if we have bookmarks or (, failing that, then checking) if we have children
535
return (entryCount > 0 || folder.getFolders().size() > 0);
536         } catch (HibernateException e) {
537             throw new RollerException(e);
538         }
539     }
540     
541     public boolean isDescendentOf(FolderData child, FolderData ancestor)
542     throws RollerException {
543         boolean ret = false;
544         try {
545             Session session = ((HibernatePersistenceStrategy)strategy).getSession();
546             Criteria criteria = session.createCriteria(FolderAssoc.class);
547             criteria.add(Expression.eq("folder", child));
548             criteria.add(Expression.eq("ancestorFolder", ancestor));
549             ret = criteria.list().size() > 0;
550         } catch (HibernateException e) {
551             throw new RollerException(e);
552         }
553         return ret;
554     }
555 }
556
Popular Tags