KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ivata > groupware > business > library > LibraryImpl


1 /*
2  * Copyright (c) 2001 - 2005 ivata limited.
3  * All rights reserved.
4  * -----------------------------------------------------------------------------
5  * ivata groupware may be redistributed under the GNU General Public
6  * License as published by the Free Software Foundation;
7  * version 2 of the License.
8  *
9  * These programs are free software; you can redistribute them and/or
10  * modify them under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; version 2 of the License.
12  *
13  * These programs are distributed in the hope that they will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License in the file LICENSE.txt for more
18  * details.
19  *
20  * If you would like a copy of the GNU General Public License write to
21  *
22  * Free Software Foundation, Inc.
23  * 59 Temple Place - Suite 330
24  * Boston, MA 02111-1307, USA.
25  *
26  *
27  * To arrange commercial support and licensing, contact ivata at
28  * http://www.ivata.com/contact.jsp
29  * -----------------------------------------------------------------------------
30  * $Log: LibraryImpl.java,v $
31  * Revision 1.5 2005/04/29 02:48:16 colinmacleod
32  * Data bugfixes.
33  * Changed primary key back to Integer.
34  *
35  * Revision 1.4 2005/04/26 15:21:54 colinmacleod
36  * Renamed Faq to FAQ.
37  *
38  * Revision 1.3 2005/04/10 20:09:44 colinmacleod
39  * Added new themes.
40  * Changed id type to String.
41  * Changed i tag to em and b tag to strong.
42  * Improved PicoContainerFactory with NanoContainer scripts.
43  *
44  * Revision 1.2 2005/04/09 17:19:44 colinmacleod
45  * Changed copyright text to GPL v2 explicitly.
46  *
47  * Revision 1.1.1.1 2005/03/10 17:51:54 colinmacleod
48  * Restructured ivata op around Hibernate/PicoContainer.
49  * Renamed ivata groupware.
50  *
51  * Revision 1.11 2004/11/12 18:16:06 colinmacleod
52  * Ordered imports.
53  *
54  * Revision 1.10 2004/11/12 15:57:15 colinmacleod
55  * Removed dependencies on SSLEXT.
56  * Moved Persistence classes to ivata masks.
57  *
58  * Revision 1.9 2004/09/30 14:59:06 colinmacleod
59  * Added methods to sanitize the entire library and update the search index.
60  *
61  * Revision 1.8 2004/08/01 11:45:19 colinmacleod
62  * Restructured search engine into separate subproject.
63  *
64  * Revision 1.7 2004/07/31 10:26:38 colinmacleod
65  * Fixed comment tree.
66  *
67  * Revision 1.6 2004/07/29 20:51:33 colinmacleod
68  * Set the page order (page numbers) before adding/amending library items.
69  *
70  * Revision 1.5 2004/07/19 22:01:31 colinmacleod
71  * Changed recent items from collection to list.
72  *
73  * Revision 1.4 2004/07/18 22:30:35 colinmacleod
74  * Synchronized lists and collections.
75  *
76  * Revision 1.3 2004/07/18 21:59:14 colinmacleod
77  * Removed Person from User - now you need to use addressbook/persistence manager to find the person (makes the app run faster.)
78  *
79  * Revision 1.2 2004/07/13 19:47:28 colinmacleod
80  * Moved project to POJOs from EJBs.
81  * Applied PicoContainer to services layer (replacing session EJBs).
82  * Applied Hibernate to persistence layer (replacing entity EJBs).
83  *
84  * Revision 1.1 2004/03/27 10:31:25 colinmacleod
85  * Split off business logic from remote facades to POJOs.
86  * -----------------------------------------------------------------------------
87  */

88 package com.ivata.groupware.business.library;
89
90 import java.text.MessageFormat JavaDoc;
91 import java.util.Collections JavaDoc;
92 import java.util.Comparator JavaDoc;
93 import java.util.Iterator JavaDoc;
94 import java.util.List JavaDoc;
95 import java.util.Vector JavaDoc;
96
97 import javax.mail.MethodNotSupportedException JavaDoc;
98
99 import org.apache.log4j.Logger;
100
101 import com.ivata.groupware.admin.security.server.SecuritySession;
102 import com.ivata.groupware.admin.security.user.UserDO;
103 import com.ivata.groupware.admin.setting.Settings;
104 import com.ivata.groupware.business.BusinessLogic;
105 import com.ivata.groupware.business.addressbook.AddressBook;
106 import com.ivata.groupware.business.addressbook.person.PersonDO;
107 import com.ivata.groupware.business.library.comment.CommentDO;
108 import com.ivata.groupware.business.library.faq.FAQDO;
109 import com.ivata.groupware.business.library.faq.category.FAQCategoryDO;
110 import com.ivata.groupware.business.library.item.LibraryItemConstants;
111 import com.ivata.groupware.business.library.item.LibraryItemDO;
112 import com.ivata.groupware.business.library.page.PageDO;
113 import com.ivata.groupware.business.library.topic.TopicDO;
114 import com.ivata.groupware.business.mail.Mail;
115 import com.ivata.groupware.business.mail.session.MailSession;
116 import com.ivata.groupware.business.search.SearchEngine;
117 import com.ivata.groupware.container.persistence.QueryPersistenceManager;
118 import com.ivata.groupware.container.persistence.TimestampDOHandling;
119 import com.ivata.groupware.web.format.SanitizerFormat;
120 import com.ivata.mask.Mask;
121 import com.ivata.mask.MaskFactory;
122 import com.ivata.mask.persistence.PersistenceException;
123 import com.ivata.mask.persistence.PersistenceSession;
124 import com.ivata.mask.util.StringHandling;
125 import com.ivata.mask.util.SystemException;
126 import com.ivata.mask.validation.ValidationError;
127 import com.ivata.mask.validation.ValidationErrors;
128 import com.ivata.mask.validation.ValidationException;
129 import com.ivata.mask.web.format.CharacterEntityFormat;
130 import com.ivata.mask.web.format.FormatConstants;
131 import com.ivata.mask.web.format.HTMLFormatter;
132 import com.ivata.mask.web.format.LineBreakFormat;
133
134 /**
135  * @author Colin MacLeod
136  * <a HREF='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
137  * @since Mar 26, 2004
138  * @version $Revision: 1.5 $
139  */

140 public class LibraryImpl extends BusinessLogic implements Library {
141
142
143     /**
144      * <p>This class is used to sort the comments.</p>
145      */

146     private class CommentComparator implements Comparator JavaDoc {
147
148         /**
149          * <p>Compare two objects (in this case, both are instances of Comment.</p>
150          */

151         public int compare(final Object JavaDoc o1,
152             final Object JavaDoc o2) {
153             CommentDO comment1 = (CommentDO) o1;
154             CommentDO comment2 = (CommentDO) o2;
155             long test1 = comment1.getModified().getTime();
156             long test2 = comment2.getModified().getTime();
157
158             // note: purposely don't allow an equals case here!! If two are
159
// equal, then only one will appear in the final set
160
return (test1 > test2) ? -1 : 1;
161         }
162     }
163
164
165     /**
166      * <p>This class is used to sort the library item rights.</p>
167      */

168     private class LibraryItemComparator implements Comparator JavaDoc {
169
170         /**
171          * <p>Compare two objects (in this case, both are instances of
172          * {@link com.ivata.groupware.business.library.item.right.LibraryItemRightLocal
173          * LibraryItemRightLocal}) and return which is the higher priority.</p>
174          *
175          * @param o1 first instance of {@link
176          * com.ivata.groupware.business.library.item.right.LibraryItemRightLocal
177          * LibraryItemRightLocal} to be compared.
178          * @param o2 second instance of {@link
179          * com.ivata.groupware.business.library.item.right.LibraryItemRightLocal
180          * LibraryItemRightLocal} to be compared.
181          * @return a negative integer, zero, or a positive integer as the first argument
182          * comes after, same as, or before the second.
183          */

184         public int compare(final Object JavaDoc o1,
185             final Object JavaDoc o2) {
186             LibraryItemDO itemRight1 = (LibraryItemDO) o1;
187             LibraryItemDO itemRight2 = (LibraryItemDO) o2;
188             long test1 = itemRight1.getModified().getTime();
189             long test2 = itemRight2.getModified().getTime();
190
191             // note: purposely don't allow an equals case here!! If two are
192
// equal, then only one will appear in the final set
193
return (test1 > test2) ? -1 : 1;
194         }
195     }
196     /**
197      * <p>
198      * <strong>Log4J</strong> logger.
199      * </p>
200      */

201     private static Logger log = Logger.getLogger(Library.class);
202     private AddressBook addressBook;
203     private HTMLFormatter formatter;
204     private Mail mail;
205     /**
206      * Persistence manger used to store/retrieve data objects.
207      */

208     private QueryPersistenceManager persistenceManager;
209     private SearchEngine searchEngine;
210     private Settings settings;
211     private MaskFactory maskFactory;
212     /**
213      * Construct a new address book.
214      *
215      * @param persistenceManager used to store objects in db.
216      */

217     public LibraryImpl(QueryPersistenceManager persistenceManager,
218             AddressBook addressBook,
219             Mail mail,
220             Settings settings,
221             SearchEngine searchEngine,
222             HTMLFormatter formatter,
223             MaskFactory maskFactory) {
224         this.persistenceManager = persistenceManager;
225         this.addressBook = addressBook;
226         this.mail = mail;
227         this.settings = settings;
228         this.searchEngine = searchEngine;
229         this.formatter = formatter;
230         this.maskFactory = maskFactory;
231     }
232
233     /**
234      * <p>Add a new comment to the system. The user supplied is checked, to make
235      * sure she has the necessary permission to add the comment, then the comment
236      * is added and the new primary key value (id) is returned.</p>
237      *
238      * @throws BusinessException if the user
239      * provided is not entitled to add this topic.
240      * @throws BusinessException
241      * if either the <code>subject</code>, <code>subject</code> or
242      * <code>item id</code> fields are <code>null</code>.
243      * @param securitySession mail session used to post notifications about the new
244      * comment.
245      * @param commentParam data object containing all values of the new
246      * object to add.
247      * @param replyToId the unique identifier of the comment this is a reply to,
248      * or <code>null</code> if this is the first comment in a thread.
249      * @return new value of the comment as it is now in the system.
250      */

251     public CommentDO addComment(final SecuritySession securitySession,
252             final CommentDO commentParam)
253             throws SystemException {
254         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
255         try {
256             // before creating the event, check we have reasonable data
257
ValidationErrors errors = validate(securitySession, commentParam);
258             if (!errors.isEmpty()) {
259                 throw new ValidationException(errors);
260             }
261             TimestampDOHandling.add(securitySession, commentParam);
262             CommentDO comment = (CommentDO) persistenceManager.add(
263                     persistenceSession,
264                     commentParam);
265
266             LibraryItemDO item = comment.getItem();
267             searchEngine.updateIndex(securitySession,
268                     item.getId(),
269                     LibraryItemDO.class.getName(),
270                     item.getTopic().getId().toString(),
271                     comment.getId(),
272                     CommentDO.class.getName(),
273                     comment.getText(),
274                     comment.getFormat());
275             return comment;
276         } catch (Exception JavaDoc e) {
277             persistenceSession.cancel();
278             throw new SystemException(e);
279         } finally {
280             persistenceSession.close();
281         }
282     }
283     /**
284      * <p>Add a new library item to the system. The <code>created</code> and
285      * <code>modified</code> timestamps are set automatically by this method
286      * (any values in <code>item</code> are ignored). The <code>user</code>,
287      * <code>createdBy<code> and <code>modifiedBy<code> fields are set to the
288      * user name you provide.</p>
289      *
290      * <p>For the topic, the <code>topicId</code> field is taken from the
291      * data object: settings for the caption and image are
292      * ignored.</p>
293      *
294      * @param userName the name of the user who wants to add the item. This is
295      * used to check user rights.
296      * @param itemParam a data object containing all the details
297      * of the item to add.
298      * @param securitySession mail session used to post notifications about the new
299      * library item.
300      * @param comment the comment used in revision control
301      * @exception com.ivata.groupware.ejb.entity.InvalidFieldValueException
302      * if a field has an incorrect value.
303      * @exception com.ivata.groupware.ejb.entity.MandatoryFieldException
304      * if a mandatory field has no value.
305      * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
306      * provided is not entitled to add this item.
307      * @return the new item data object, with the details as they
308      * now are in the adressbook.
309      */

310     public LibraryItemDO addItem(final SecuritySession securitySession,
311             final LibraryItemDO itemParam,
312             final String JavaDoc comment)
313             throws SystemException {
314         LibraryItemDO item = itemParam;
315         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
316         try {
317             // before creating the event, check we have reasonable data
318
ValidationErrors errors = validate(securitySession, item);
319             if (!errors.isEmpty()) {
320                 throw new ValidationException(errors);
321             }
322
323             // set the page order, and set all ids null (to create new pages)
324
if (item.getPages() != null) {
325                 Iterator JavaDoc pagesIterator = item.getPages().iterator();
326                 int pageNumber = 0;
327                 while (pagesIterator.hasNext()) {
328                     PageDO page = (PageDO) pagesIterator.next();
329                     // only new pages allowed!
330
page.setId(null);
331                     page.setNumber(new Integer JavaDoc(pageNumber++));
332                 }
333             }
334
335             TimestampDOHandling.add(securitySession, item);
336             item = (LibraryItemDO) persistenceManager.add(persistenceSession, item);
337             updateSearchIndexForItem(securitySession, item);
338
339 /*
340             DirectoryDO parentDirectory = (DirectoryDO)
341                 persistenceManager.findByPrimaryKey(persistenceSession,
342                 DirectoryDO.class, DirectoryConstants.LIBRARY_DIRECTORY);
343             // create the directory for attachments and doc versions
344             DirectoryDO attachmentsDirectory = new DirectoryDO();
345             attachmentsDirectory.setName(item.getId().toString());
346             attachmentsDirectory.setParent(parentDirectory);
347 // TODO attachmentsDirectory = drive.addDirectory(securitySession, attachmentsDirectory);
348
349             DirectoryDO versionsDirectory = new DirectoryDO();
350             versionsDirectory.setName("versions");
351             versionsDirectory.setParent(attachmentsDirectory);
352 // TODO versionsDirectory = drive.addDirectory(securitySession, versionsDirectory);
353
354
355             // commit this ITEM do CVS as XML file
356             DriveFileDO driveFile = new DriveFileDO();
357
358             String tmpItemFilePath;
359             try {
360                 tmpItemFilePath = item.saveToFile();
361             } catch(IOException e) {
362                 log.error("Saving to file.", e);
363                 throw new SystemException(e);
364             }
365             File tmpFile = new File(tmpItemFilePath);
366
367             driveFile.setDirectory(versionsDirectory);
368             driveFile.setName("document.xml");
369             driveFile.setMimeType("text/xml");
370             driveFile.setSize(new Integer((int)(tmpFile.length())));
371             FileRevisionDO fileRevision = new FileRevisionDO();
372             fileRevision.setComment(StringHandling.getNotNull(comment, "new revision"));
373             driveFile.setHeadRevision(fileRevision);
374
375             // drive.checkAndCreate("library" + File.separator + this.getId() + File.separator + "versions" + File.separator, item.getCreatedBy());
376 // TODO drive.commitFile(securitySession, driveFile, tmpItemFilePath);
377             // delete tmp file
378             tmpFile.delete();
379             tmpFile = null;
380 */

381         } catch (Exception JavaDoc e) {
382             persistenceSession.cancel();
383             throw new SystemException(e);
384         } finally {
385             persistenceSession.close();
386         }
387         notifyForSubmission(securitySession, item, true);
388         return item;
389     }
390     /**
391      * <p>Add a new topic to the system. The user supplied is checked, to make
392      * sure she has the necessary permission to add the topic, then the topic
393      * is added and the new primary key value (id) is returned.</p>
394      *
395      * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
396      * provided is not entitled to add this topic.
397      * @exception com.ivata.groupware.ejb.entity.InvalidFieldValueException
398      * if either the <code>caption</code> or <code>image</code> fields are
399      * <code>null</code>.
400      * @param userName the user who is trying to add the topic (to check the
401      * user right permissions).
402      * @param topic details of new TOPIC.
403      *
404      * @return TopicDO which was added.
405      */

406     public TopicDO addTopic(final SecuritySession securitySession,
407             final TopicDO topic)
408             throws SystemException {
409         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
410         try {
411             // before creating the event, check we have reasonable data
412
ValidationErrors errors = validate(securitySession, topic);
413             if (!errors.isEmpty()) {
414                 throw new ValidationException(errors);
415             }
416             return (TopicDO) persistenceManager.add(persistenceSession, topic);
417         } catch (Exception JavaDoc e) {
418             persistenceSession.cancel();
419             throw new SystemException(e);
420         } finally {
421             persistenceSession.close();
422         }
423     }
424
425     /**
426      * <p>Amend an existing comment in the system. The user supplied is
427      * checked, to make sure she has the necessary permission to amend the
428      * comment, then the comment is changed and the current comment values
429      * are returned, as they now are in the database.</p>
430      *
431      * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
432      * provided is not entitled to add this topic.
433      * @exception com.ivata.groupware.ejb.entity.MandatoryFieldException
434      * if the <code>id</code> field is <code>null</code>.
435      * @param userName the user who is trying to add the comment (to check the
436      * user right permissions).
437      * @param comment data object containing all values of the
438      * object to amend.
439      * @param securitySession mail session used to post notifications about the amended
440      * comment.
441      * @return new value of the comment as it is now in the system.
442      */

443     public CommentDO amendComment(final SecuritySession securitySession,
444             final CommentDO comment)
445             throws SystemException {
446         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
447         try {
448             // before changing the event, check we have reasonable data
449
ValidationErrors errors = validate(securitySession, comment);
450             if (!errors.isEmpty()) {
451                 throw new ValidationException(errors);
452             }
453             TimestampDOHandling.amend(securitySession, comment);
454             persistenceManager.amend(persistenceSession, comment);
455
456             LibraryItemDO item = comment.getItem();
457             searchEngine.updateIndex(securitySession, item.getId(),
458                     LibraryItemDO.class.getName(),
459                     item.getTopic().getId().toString(),
460                     comment.getId(),
461                     CommentDO.class.getName(),
462                     comment.getText(),
463                     comment.getFormat());
464             return comment;
465         } catch (Exception JavaDoc e) {
466             persistenceSession.cancel();
467             throw new SystemException(e);
468         } finally {
469             persistenceSession.close();
470         }
471     }
472     /**
473      * <p>Amend an existing library item in the system. The
474      * <code>modified</code> timestamp is set automatically by this method
475      * (any values in <code>item</code> are ignored). Values for the
476      * <code>created</code> timestamp are not changed.</p>
477      *
478      * <p>The <code>modifiedBy<code> field is set to the user name you
479      * provide.</p>
480      *
481      * <p>For the topic, the <code>topicId</code> field is taken from the
482      * data object: settings for the caption and image are
483      * ignored.</p>
484      *
485      * @param userName the name of the user who wants to amend the item. This is
486      * used to check user rights.
487      * @param item a data object containing all the details
488      * of the item to amend.
489      * @param securitySession mail server used to post notifications about the amended
490      * library item.
491      * @param comment the comment used in revision control
492      * @exception com.ivata.groupware.ejb.entity.MandatoryFieldException
493      * if a mandatory field has no value.
494      * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
495      * provided is not entitled to add this item.
496      * @return the new item data object, with the details as they
497      * now are in the adressbook.
498      */

499     public LibraryItemDO amendItem(final SecuritySession securitySession,
500             final LibraryItemDO item,
501             final String JavaDoc comment)
502             throws SystemException {
503         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
504         try {
505             // before changing the event, check we have reasonable data
506
ValidationErrors errors = validate(securitySession, item);
507             if (!errors.isEmpty()) {
508                 throw new ValidationException(errors);
509             }
510             // set the page order
511
if (item.getPages() != null) {
512                 Iterator JavaDoc pagesIterator = item.getPages().iterator();
513                 int pageNumber = 0;
514                 while (pagesIterator.hasNext()) {
515                     PageDO page = (PageDO) pagesIterator.next();
516                     page.setNumber(new Integer JavaDoc(pageNumber++));
517                 }
518             }
519             TimestampDOHandling.amend(securitySession, item);
520             persistenceManager.amend(persistenceSession, item);
521             updateSearchIndexForItem(securitySession, item);
522
523             /*TODO
524             DirectoryDO attachmentsDirectory = (DirectoryDO)
525                     persistenceManager.find(persistenceSession,
526                     "driveDirectoryByParentIdName",
527                     new Object[] {DirectoryConstants.LIBRARY_DIRECTORY, item.getId().toString()});
528             DirectoryDO versionsDirectory = (DirectoryDO)
529                     persistenceManager.find(persistenceSession,
530                     "driveDirectoryByParentIdName",
531                     new Object[] {attachmentsDirectory.getId(), "versions"});
532
533             String tmpItemFilePath;
534             try {
535                 tmpItemFilePath = item.saveToFile();
536             } catch (IOException e) {
537                 throw new SystemException(e);
538             }
539             File tmpFile = new File(tmpItemFilePath);
540
541             // commit the new version
542             DriveFileDO driveFile = new DriveFileDO();
543
544             driveFile.setDirectory(versionsDirectory);
545             driveFile.setName("document.xml");
546             driveFile.setMimeType("text/xml");
547             driveFile.setSize(new Integer((int)tmpFile.length()));
548             FileRevisionDO fileRevision = new FileRevisionDO();
549             fileRevision.setComment(StringHandling.getNotNull(comment, "new revision"));
550             driveFile.setHeadRevision(fileRevision);
551
552             drive.commitFile(securitySession, driveFile, tmpItemFilePath);
553             // delete tmp file
554             tmpFile.delete();
555             tmpFile = null;
556             */

557
558             notifyForSubmission(securitySession, item, false);
559             return item;
560         } catch (Exception JavaDoc e) {
561             persistenceSession.cancel();
562             throw new SystemException(e);
563         } finally {
564             persistenceSession.close();
565         }
566     }
567     /**
568      * <p>Amend an existing topic in the system. The user supplied is checked,
569      * to make sure she has the necessary permission to amend the topic, then
570      * the topic is changed.</p>
571      *
572      * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
573      * provided is not entitled to amend this topic.
574      * @exception com.ivata.groupware.ejb.entity.InvalidFieldValueException
575      * if the id provided is <code>null</code>.
576      * @param userName the user who is trying to add the topic (to check the
577      * user right permissions).
578      * @param topic details of TOPIC.
579      *
580      * @return TopicDO which was amend
581      */

582     public TopicDO amendTopic(final SecuritySession securitySession,
583             final TopicDO topic)
584             throws SystemException {
585         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
586         try {
587             // before changing the event, check we have reasonable data
588
ValidationErrors errors = validate(securitySession, topic);
589             if (!errors.isEmpty()) {
590                 throw new ValidationException(errors);
591             }
592             persistenceManager.amend(persistenceSession, topic);
593             return topic;
594         } catch (Exception JavaDoc e) {
595             persistenceSession.cancel();
596             throw new SystemException(e);
597         } finally {
598             persistenceSession.close();
599         }
600     }
601
602     /**
603      * <p>
604      * Find out how many comments exists in total for a library item.
605      * </p>
606      *
607      * @param itemId unique identifier for the item to count comments for.
608      * @return Total number of comments for the library item specified.
609      */

610     public int countCommentsForItem(final SecuritySession securitySession,
611             final Integer JavaDoc itemId)
612             throws SystemException {
613         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
614         try {
615             Integer JavaDoc count = persistenceManager.findInteger(persistenceSession,
616                     "libraryCountCommentByItemId",
617                     new Object JavaDoc [] {itemId});
618             return (count == null) ? 0 : count.intValue();
619         } catch (Exception JavaDoc e) {
620             persistenceSession.cancel();
621             throw new SystemException(e);
622         } finally {
623             persistenceSession.close();
624         }
625     }
626     /**
627      * <p>Locate a list of top-level comments in a specificy item. Note:
628      * this does not include comments which are replies - only top-level
629      * comments</p>
630      *
631      * @param itemId the unique identifier of comment item to locate.
632      * @return data object containing all values of the
633      * object as they are now in the system.
634      */

635     public List JavaDoc findCommentByItem(final
636             SecuritySession securitySession,
637             final Integer JavaDoc itemId)
638             throws SystemException {
639         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
640         try {
641             return persistenceManager.find(persistenceSession,
642                     "libraryCommentByItemId",
643                     new Object JavaDoc [] {itemId});
644         } catch (Exception JavaDoc e) {
645             persistenceSession.cancel();
646             throw new SystemException(e);
647         } finally {
648             persistenceSession.close();
649         }
650     }
651     /**
652      * <p>Locate a list of comments in the system by their parents.</p>
653      *
654      * @param parentId the unique identifier of parent comment to locate.
655      * @return data object containing all values of the
656      * object as they are now in the system.
657      */

658     public List JavaDoc findCommentByParent(final
659             SecuritySession securitySession,
660             final Integer JavaDoc parentId)
661             throws SystemException {
662         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
663         try {
664             return persistenceManager.find(persistenceSession,
665                     "libraryCommentByParentId",
666                     new Object JavaDoc [] {parentId});
667         } catch (Exception JavaDoc e) {
668             persistenceSession.cancel();
669             throw new SystemException(e);
670         } finally {
671             persistenceSession.close();
672         }
673     }
674
675     /**
676      * <p>Locate a comment in the system by its unique identifier, and return
677      * all the comment values.</p>
678      *
679      * @exception com.ivata.groupware.ejb.entity.MandatoryFieldException
680      * if the <code>id</code> field is <code>null</code>.
681      * @param id the unique identifier of the comment to locate.
682      * @return data object containing all values of the
683      * object as they are now in the system.
684      */

685     public CommentDO findCommentByPrimaryKey(final SecuritySession securitySession,
686             final Integer JavaDoc id)
687             throws SystemException {
688         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
689         try {
690             return (CommentDO) persistenceManager.findByPrimaryKey(persistenceSession,
691                     CommentDO.class, id);
692         } catch (Exception JavaDoc e) {
693             persistenceSession.cancel();
694             throw new SystemException(e);
695         } finally {
696             persistenceSession.close();
697         }
698     }
699
700     /**
701      * <p>Find an item in the library by its unique identifier.</p>
702      *
703      * @param id the unique identifier of the library item to find.
704      * @return the library item data object which matches this id,
705      * with the details as they now are in the library.
706      */

707     public LibraryItemDO findItemByPrimaryKey(final SecuritySession securitySession,
708             final Integer JavaDoc id)
709             throws SystemException {
710         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
711         try {
712             return (LibraryItemDO) persistenceManager.findByPrimaryKey(persistenceSession,
713                     LibraryItemDO.class, id);
714         } catch (Exception JavaDoc e) {
715             persistenceSession.cancel();
716             throw new SystemException(e);
717         } finally {
718             persistenceSession.close();
719         }
720     }
721
722     /**
723      * <p>This merhod searches for an item by revision.</p>
724      *
725      * @param rev revision number
726      * @param userName user who is doing this
727      * @return
728      */

729     public LibraryItemDO findItemByRevision(final SecuritySession securitySession,
730             final String JavaDoc itemId,
731             final String JavaDoc rev)
732             throws SystemException {
733         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
734         try {
735             // let's find actual version
736
LibraryItemDO item = (LibraryItemDO)
737                 persistenceManager.findByPrimaryKey(persistenceSession,
738                     LibraryItemDO.class, itemId);
739
740             /*TODO
741             // let's find revision
742             DriveLocalHome driveHome = (DriveLocalHome)
743                 ApplicationServer.findLocalHome("DriveLocal",
744                     DriveLocalHome.class);
745             DriveLocal drive = driveHome.create();
746
747             DriveFileDO versionsFileDO =
748                 drive.findFileByPathFileName("/library/" + item.getId().toString() + "/versions", "document.xml", userName);
749             FileContentDO fileContent = drive.getFileRevision(versionsFileDO.getId(), rev, userName);
750
751             // convert xml file to ItemDO
752             item = itemHome.convertFileToItem(fileContent);
753             */

754             return item;
755         } catch (Exception JavaDoc e) {
756             persistenceSession.cancel();
757             throw new SystemException(e);
758         } finally {
759             persistenceSession.close();
760         }
761     }
762
763     /**
764      * <p>Find items sorted by modification date/time, to the count provided in
765      * the parameter. If there are less items in the library than
766      * <code>count</code>, then all library items are returned.</p>
767      *
768      * <p>The items are filtered using a view, so that only those items with the
769      * <code>access</code> level indicated are shown for the user requested.</p>
770      *
771      * @param count the total number of items to return. Specify
772      * <code>null</code> to return all items.
773      * @param userName the user to display results for. The results filtered so
774      * that only those items are return which the user is entitled to see.
775      * @param access the access level which the user should see. This is defined
776      * as one of the constants in {@link
777      * com.ivata.groupware.business.addressbook.person.user.group.right.RightConstants
778      * RightConstants}.
779      * @param topicId unique identifier of the topic to filter items for, or all
780      * topics, if <code>null</code>.
781      * @return a <code>Collection</code> of all of the item as {@link
782      * LibraryItemDO item dependent value}
783      * instances.
784      */

785     public List JavaDoc findRecentItems(final SecuritySession securitySession,
786             final Integer JavaDoc count,
787             final Integer JavaDoc access,
788             final Integer JavaDoc topicId)
789             throws SystemException {
790         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
791         try {
792             if (topicId == null) {
793                 return Collections.synchronizedList(persistenceManager.find(persistenceSession,
794                         "libraryItemRecent", new Object JavaDoc[]{}, count, new Integer JavaDoc(0)));
795             } else {
796                 return Collections.synchronizedList(persistenceManager.find(persistenceSession,
797                         "libraryItemRecentByTopic", new Object JavaDoc[]{topicId}, count,
798                         new Integer JavaDoc(0)));
799             }
800         } catch (Exception JavaDoc e) {
801             persistenceSession.cancel();
802             throw new SystemException(e);
803         } finally {
804             persistenceSession.close();
805         }
806     }
807     /**
808      * <p>when we need to find library item by meeting ID</p>
809      *
810      * @return libraryItemDO
811      */

812     /* public LibraryItemDO findItemByMeetingId(String id) {
813             LibraryItemDO item = null;
814
815             // check we have an id
816             if (id == null) {
817                 throw new EJBException("Please specify an id to find. Cannot find an item with a null id.");
818             }
819             try {
820                 LibraryItemDOHome itemHome = (LibraryItemDOHome)
821                     ApplicationServer.findLocalHome("LibraryItemDO",
822                         LibraryItemDOHome.class);
823                 MeetingLocalHome meetingHome = (MeetingLocalHome)
824                     ApplicationServer.findLocalHome("MeetingLocal",
825                         MeetingLocalHome.class);
826                 MeetingLocal meeting = meetingHome.findByPrimaryKey(id);
827                 LibraryItemDO item = itemHome.findByPrimaryKey(meeting.getLibraryItem().getId());
828
829                 item = item.getDO();
830             } catch (NamingException e) {
831                 throw new EJBException(e);
832             } catch (FinderException e) {
833                 throw new EJBException(e);
834             }
835             return item;
836         }*/

837
838     /**
839      * <p>Find Topic by primary keyand return <code>TopicDO.</code></p>
840      *
841      * @param id of Topic which we are trying yo find
842      * @return TopicDO which is containing all details of finded Topic
843      */

844     public TopicDO findTopicByPrimaryKey(final SecuritySession securitySession,
845             final Integer JavaDoc id)
846            throws SystemException {
847         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
848         try {
849             return (TopicDO) persistenceManager.findByPrimaryKey(persistenceSession,
850                     TopicDO.class, id);
851         } catch (Exception JavaDoc e) {
852             persistenceSession.cancel();
853             throw new SystemException(e);
854         } finally {
855             persistenceSession.close();
856         }
857     }
858
859     /**
860      * <p>Find all topics with the given access rights for the user name
861      * provided.</p>
862      *
863      * @param userName the user to display results for. The results filtered so
864      * that only those topics are return which the user is entitled to access.
865      * @param access the access level which the user should see. This is defined
866      * as one of the constants in {@link
867      * com.ivata.groupware.business.addressbook.person.user.group.right.RightConstants
868      * RightConstants}.
869      * @param detail, at this moment we are trying to find Topics for :
870      * - add, amend, delete and view LIBRARY ITEMS
871      * - amend, delete and view TOPICS
872      * @return a <code>List</code> containing two <code>Map</code>s. The map
873      * in element <code>0</code> contains a <code>Map</code> of all of the
874      * topic captions. The map in element <code>1</code> contains a
875      * <code>Map</code> of all of the topic images. In each <code>Map</code>,
876      * the key is topic id.
877      */

878     public List JavaDoc findTopics(final SecuritySession securitySession)
879             throws SystemException {
880         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
881         try {
882             return Collections.synchronizedList(persistenceManager.findAll(persistenceSession,
883                     TopicDO.class));
884         } catch (Exception JavaDoc e) {
885             persistenceSession.cancel();
886             throw new SystemException(e);
887         } finally {
888             persistenceSession.close();
889         }
890     }
891
892     /**
893      * <p>Find all comments to which there has been no reply.</p>
894      * @param userName
895      * @param count
896      * @return
897      */

898     public List JavaDoc findUnacknowledgedComments(final SecuritySession securitySession,
899             final Integer JavaDoc count)
900             throws SystemException {
901         PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
902         try {
903             return Collections.synchronizedList(
904                     persistenceManager.find(persistenceSession,
905                     "libraryCommentByUserNameUnacknowledged",
906                     new Object JavaDoc[] {securitySession.getUser().getName(),
907                             Boolean.FALSE}, count, new Integer JavaDoc(0)));
908         } catch (Exception JavaDoc e) {
909             persistenceSession.cancel();
910             throw new SystemException(e);
911         } finally {
912             persistenceSession.close();
913         }
914     }
915
916     /**
917      * <p>Helper method. Notify everyone who can view a certain topic of a new
918      * submission. This could be a new library item or a new comment.</p>
919      *
920      * @param submission instance of either <code>LibraryItemDO</code> or
921      * <code>CommentDO</code>.
922      * @param isNew set to <code>true</code> if this is a new submission,
923      * otherwise false.
924      * @param userName the user who has entered the new item or comment.
925      * @param securitySession mail session used to post notifications.
926      * @throws NotificationException if the mail cannot be sent for any reason.
927      */

928     private void notifyForSubmission(final SecuritySession securitySession,
929             final Object JavaDoc submission,
930             final boolean isNew)
931             throws NotificationException, PersistenceException {
932         // prerequisite: ignore any submission which didn't supply a valid mail object
933
if (securitySession == null) {
934             // just return: in codetutorial.com, for example, we don't want
935
// notifications
936
return;
937         }
938         PersistenceSession persistenceSession =
939             persistenceManager.openSession(securitySession);
940         String JavaDoc senderAddress = null;
941         List JavaDoc recipientAddresses = null;
942         List JavaDoc to = null;
943         List JavaDoc cc = null;
944         try {
945             UserDO user = securitySession.getUser();
946
947             String JavaDoc URL = settings.getStringSetting(securitySession,
948                 "pathContext", user);
949
950             Integer JavaDoc topicId; // topic of the item
951
UserDO originalAuthor = null; // person who wrote original item/comment
952
UserDO author; // author of this submission
953
senderAddress = "\"ivata groupware library\" <" // email address for replies
954
+ settings.getStringSetting(securitySession,
955                     "emailLibrary",
956                     user) + ">";
957             String JavaDoc content; // content of the message
958
String JavaDoc subject; // subject of the comment or title of the item
959

960             // let's look at the submission item
961
// itself, to find out spcifically who this is addressed to
962
if (LibraryItemDO.class.isInstance(submission)) {
963                 LibraryItemDO item = (LibraryItemDO) submission;
964                 String JavaDoc settingName = "libraryNotificationContentItem";
965
966                 topicId = item.getTopic().getId();
967                 author = item.getCreatedBy();
968                 subject = item.getTitle();
969                 URL += "/display.jsp?id=" + item.getId();
970                 // if this is a change, rather than a new submission, append "Amend"
971
// to the setting name
972
if (!isNew) {
973                     settingName += "Amend";
974                     author = item.getModifiedBy();
975                 }
976                 String JavaDoc[] arguments = {
977                         author.getName(),
978                         item.getTitle(),
979                         item.getSummary(),
980                         URL};
981                 String JavaDoc setting = settings.getStringSetting(securitySession,
982                     settingName, user);
983
984                 if (setting == null) {
985                     throw new SystemException("ERROR in Library.notifyForSubmission: "
986                             + "the administrator must set the system setting '"
987                             + settingName
988                             + "'");
989                 }
990                 content = MessageFormat.format(setting, arguments);
991             } else {
992                 // check this really _is_ a comment
993
if (!CommentDO.class.isInstance(submission)) {
994                     throw new SystemException("ERROR in Library: cannot notify on "
995                             + "submission of class '"
996                             + submission.getClass()
997                             + "'");
998                 }
999                 CommentDO comment = (CommentDO) submission;
1000
1001                topicId = comment.getItem().getTopic().getId();
1002                author = comment.getCreatedBy();
1003                subject = comment.getSubject();
1004
1005                // if this is a reply to another comment, the original author is
1006
// the author of that comment
1007
String JavaDoc settingName, replyTitle, replySummary, commentText;
1008
1009                int formatOfOrigComment = -1;
1010                int formatOfComment = comment.getFormat();
1011
1012                if (comment.getParent() != null) {
1013                    originalAuthor = comment.getParent().getCreatedBy();
1014                    settingName = "libraryNotificationContentComment";
1015                    replyTitle = comment.getParent().getSubject();
1016                    replySummary = comment.getParent().getText();
1017                    formatOfOrigComment = comment.getParent().getFormat();
1018                    // for case that comment was changed
1019
// carefull user could change not his comment
1020
if (!isNew) {
1021                        settingName += "Amend";
1022                        if (!author.getId().equals(user.getId())) {
1023                            settingName += "Strange";
1024                            author = user;
1025                            originalAuthor = comment.getCreatedBy();
1026                            replyTitle = comment.getSubject();
1027                        }
1028                    }
1029                } else {
1030                    // otherwise the original author is the author of the
1031
// item
1032
originalAuthor = comment.getItem().getCreatedBy();
1033                    settingName = "libraryNotificationContentItemReply";
1034                    replyTitle = comment.getItem().getTitle();
1035                    replySummary = comment.getItem().getSummary();
1036                    formatOfOrigComment = FormatConstants.FORMAT_HTML;
1037                    // for case that comment was changed
1038
if (!isNew) {
1039                        settingName += "Amend";
1040                        if (!author.getId().equals(user.getId())) {
1041                            author = user;
1042                            settingName = "libraryNotificationContentCommentAmendStrange";
1043                            originalAuthor = comment.getCreatedBy();
1044                            replyTitle = comment.getSubject();
1045                        }
1046                    }
1047                }
1048                commentText = comment.getText();
1049                LineBreakFormat lineBreakFormat = new LineBreakFormat();
1050
1051                lineBreakFormat.setConvertLineBreaks(true);
1052                formatter.add(new CharacterEntityFormat());
1053                formatter.add(lineBreakFormat);
1054                if (formatOfComment == FormatConstants.FORMAT_TEXT) {
1055                    // if this is a plain text message, do HTML paragraph
1056
commentText = formatter.format(commentText);
1057                }
1058                if (formatOfOrigComment == FormatConstants.FORMAT_TEXT) {
1059                    // if this is a plain text message, do HTML paragraph
1060
replySummary = formatter.format(replySummary);
1061                }
1062                URL += "/display.jsp?id=" + comment.getItem().getId() + "#comments";
1063                String JavaDoc[] arguments = {
1064                        author.getName(),
1065                        originalAuthor.getName(),
1066                        replyTitle,
1067                        replySummary,
1068                        comment.getSubject(),
1069                        commentText, URL};
1070                String JavaDoc setting = settings.getStringSetting(securitySession,
1071                    settingName,
1072                    user);
1073
1074                if (setting == null) {
1075                    throw new SystemException("ERROR in Library.notifyForSubmission: "
1076                        + "the administrator must set the system setting '"
1077                        + settingName
1078                        + "'");
1079                }
1080                content = MessageFormat.format(setting, arguments);
1081            }
1082            // next thing to do is construct a set of all of the recipients of
1083
// the message
1084
// TODO: users should subscribe
1085
List JavaDoc recipients = persistenceManager.findAll(persistenceSession,
1086                UserDO.class);
1087
1088
1089            // now remove the author from the recipients
1090
recipients.remove(author);
1091            // if there is an original author, remove her from the recipients too
1092
PersonDO originalAuthorPerson = null;
1093            if (originalAuthor != null) {
1094                recipients.remove(originalAuthor);
1095                originalAuthorPerson = addressBook.findPersonByUserName(securitySession,
1096                        originalAuthor.getName());
1097            }
1098            // since we are using the remote mail interface, we need to convert
1099
// the emailAddressses here
1100
recipientAddresses = new Vector JavaDoc(recipients.size());
1101
1102            for (Iterator JavaDoc i = recipients.iterator(); i.hasNext();) {
1103                UserDO thisUser = (UserDO) i.next();
1104                // only add enabled users
1105
PersonDO thisPerson = addressBook.findPersonByUserName(securitySession,
1106                        thisUser.getName());
1107                String JavaDoc address = thisPerson.getEmailAddress();
1108
1109                if (user.isEnabled()
1110                        && !user.isDeleted()
1111                        && (address != null)) {
1112                    recipientAddresses.add(address);
1113                }
1114            }
1115            String JavaDoc address;
1116
1117            // if there is an original author, we'll use that person as the 'to'
1118
// recipient and make everyone else a cc
1119
if ((originalAuthor != null) &&
1120                (!originalAuthor.isDeleted()) &&
1121                ((address = originalAuthorPerson.getEmailAddress()) != null)) {
1122                to = new Vector JavaDoc();
1123                to.add(address);
1124                cc = recipientAddresses;
1125            } else {
1126                to = recipientAddresses;
1127                cc = null;
1128            }
1129            String JavaDoc contentType = settings.getStringSetting(securitySession,
1130                "libraryNotificationContentType", user);
1131            if (!to.isEmpty()
1132                && (securitySession instanceof MailSession)) {
1133                mail.send((MailSession) securitySession, senderAddress, to, cc,
1134                    null, subject, content, contentType, false);
1135            }
1136        } catch (Exception JavaDoc e) {
1137            persistenceSession.cancel();
1138            List JavaDoc allRecipients = new Vector JavaDoc();
1139            if (to != null) {
1140                allRecipients.addAll(to);
1141            }
1142            if (cc != null) {
1143                allRecipients.addAll(cc);
1144            }
1145            throw new NotificationException(e, senderAddress, allRecipients);
1146        } finally {
1147            persistenceSession.close();
1148        }
1149    }
1150    /**
1151     * <p>Remove an existing comment from the system. The user supplied is
1152     * checked, to make sure she has the necessary permission to remove the
1153     * comment, then the comment is removed.</p>
1154     *
1155     * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
1156     * provided is not entitled to add this topic.
1157     * @exception com.ivata.groupware.ejb.entity.MandatoryFieldException
1158     * if the <code>id</code> field is <code>null</code>.
1159     * @param userName the user who is trying to add the comment (to check the
1160     * user right permissions).
1161     * @param comment data object containing all values of the
1162     * object to amend. Only the <code>id</code> field is read.
1163     */

1164    public void removeComment(final SecuritySession securitySession,
1165            final CommentDO comment)
1166            throws SystemException {
1167        PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
1168        try {
1169            persistenceManager.remove(persistenceSession,
1170                    comment.getClass(), comment.getId());
1171        } catch (Exception JavaDoc e) {
1172            persistenceSession.cancel();
1173            throw new SystemException(e);
1174        } finally {
1175            persistenceSession.close();
1176        }
1177    }
1178    /**
1179     * <p>Remove a library item to the system. The item with the id specified in
1180     * <code>item</code> is removed.</p>
1181     *
1182     * @param userName the name of the user who wants to add the item. This is
1183     * used to check user rights.
1184     * @param item a data object containing all the details
1185     * of the item to remove. Only the <code>id</code> from this object is
1186     * actually used.
1187     * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
1188     * provided is not entitled to add this item.
1189     */

1190    public void removeItem(final SecuritySession securitySession,
1191            final LibraryItemDO item)
1192            throws SystemException {
1193        PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
1194        try {
1195            /* TODO
1196            searchEngine.removeFromIndex(securitySession,
1197                    LibraryItemDO.class.getName(),
1198                    item.getId(), item.getTopic().getId().toString());
1199*/

1200            persistenceManager.remove(persistenceSession,
1201                    item.getClass(), item.getId());
1202
1203/*TODO // remove the directory with attachments (if any)
1204                // remove attachments and versions recursively
1205                DirectoryDO directory = (DirectoryDO)
1206                    persistenceManager.findInstance(persistenceSession,
1207                        "libraryDirectoryByParentIdName",
1208                        new Object[] {
1209                                DirectoryConstants.LIBRARY_DIRECTORY,
1210                                item.getId().toString()});
1211
1212                drive.removeDirectory(securitySession, directory);
1213*/

1214        } catch (Exception JavaDoc e) {
1215            persistenceSession.cancel();
1216            throw new SystemException(e);
1217        } finally {
1218            persistenceSession.close();
1219        }
1220    }
1221
1222    /**
1223     * <p>Remove a topic from the system. The user supplied is checked,
1224     * to make sure she has the necessary permission to remove the topic, then
1225     * the topic is removed.</p>
1226     *
1227     * @exception com.ivata.groupware.ejb.entity.UserRightException if the user
1228     * provided is not entitled to remove this topic.
1229     * @exception com.ivata.groupware.ejb.entity.InvalidFieldValueException
1230     * if the id provided is <code>null</code> or doesn't exist.
1231     * @param userName the user who is trying to add the topic (to check the
1232     * user right permissions).
1233     * @param topic topic which we are going to remove.
1234     */

1235    public void removeTopic(final SecuritySession securitySession,
1236            final TopicDO topic)
1237            throws SystemException {
1238        PersistenceSession persistenceSession = persistenceManager.openSession(securitySession);
1239        try {
1240            persistenceManager.remove(persistenceSession,
1241                    topic.getClass(), topic.getId());
1242        } catch (Exception JavaDoc e) {
1243            persistenceSession.cancel();
1244            throw new SystemException(e);
1245        } finally {
1246            persistenceSession.close();
1247        }
1248    }
1249    /**
1250     * <p>
1251     * TODO
1252     * </p>
1253     *
1254     * @param itemId
1255     * @param revision
1256     * @param userName
1257     * @return
1258     */

1259    public LibraryItemDO revertItemToRevision(final SecuritySession securitySession,
1260            final String JavaDoc itemId,
1261            final String JavaDoc revision,
1262            final String JavaDoc comment)
1263            throws SystemException {
1264        throw new SystemException(new MethodNotSupportedException JavaDoc("ERROR: revertItemToRevision not implemented."));
1265/*TODO LibraryItemDO revisedItemDO = null;
1266
1267        try {
1268            if (itemId == null) {
1269                throw new InvalidFieldValueException("You must specify an identifier to revert a library item");
1270            }
1271            // find the current version
1272            LibraryItemDO item = itemHome.findByPrimaryKey(itemId);
1273
1274            DriveLocalHome driveHome = (DriveLocalHome)
1275                ApplicationServer.findLocalHome("DriveLocal",
1276                    DriveLocalHome.class);
1277            DriveLocal drive = driveHome.create();
1278
1279            // fidn Id of file
1280            DriveFileDO versionsFileDO =
1281                drive.findFileByPathFileName("/library/" + itemId.toString() + "/versions", "document.xml", userName);
1282
1283            // find that head revision in CVS
1284            FileContentDO fileContent = drive.getFileRevision(versionsFileDO.getId(), revision, userName);
1285
1286            // convert xml file to ItemDO
1287            revisedItemDO = itemHome.convertFileToItem(fileContent);
1288            // try to find that TOPIC, if not we will stay on actual
1289            try {
1290                TopicDO topic = topicHome.findByPrimaryKey(revisedItemDO.getTopicId());
1291            } catch (FinderException e) {
1292                revisedItemDO.setTopicId(item.getTopic().getId());
1293            }
1294            // if user changed topic we have to ask if user has right to add to that topic
1295            // if he didn't changed topic so we have to ask if he has right amend in that topic
1296            boolean canAmend = false;
1297
1298            if (item.getTopic().getId().equals(revisedItemDO.getTopicId())) {
1299                canAmend = rights.canAmendInTopic(userName, item.getTopic().getId());
1300            } else {
1301                canAmend = rights.canAddToTopic(userName, revisedItemDO.getTopicId());
1302            }
1303            if (!canAmend && !userName.equals(item.getCreatedBy().getIntranetUserName())) {
1304                TopicDO topic = topicHome.findByPrimaryKey(item.getTopic().getId());
1305
1306                throw new UserRightException("You do not have the necessary rights to amend an item in '" +
1307                        topic.getCaption() +
1308                        "'");
1309            }
1310
1311            // let's do the business
1312            revisedItemDO.setModifiedBy(userName);
1313            revisedItemDO.setCreated(item.getCreated());
1314            revisedItemDO = item.setDO(revisedItemDO, comment);
1315
1316            // submit the new version:
1317            Integer attachmentsDirectoryId =
1318                directoryHome.findByParentIdName(DirectoryConstants.LIBRARY_DIRECTORY, item.getId().toString()).getId();
1319            Integer versionsDirectoryId =
1320                directoryHome.findByParentIdName(attachmentsDirectoryId, "versions").getId();
1321
1322
1323            String tmpItemFilePath = item.convertItemToFile(revisedItemDO);
1324
1325            // commit the new version
1326            DriveFileDO driveFile = new DriveFileDO();
1327            File tmpFile = new File(tmpItemFilePath);
1328
1329            driveFile.setDirectoryId(versionsDirectoryId);
1330            driveFile.setFileName("document.xml");
1331            driveFile.setMimeType("text/xml");
1332            driveFile.setSize(new Integer((int)tmpFile.length()));
1333            FileRevisionDO fileRevision = new FileRevisionDO();
1334            fileRevision.setComment(StringHandling.getNotNull(comment, "new revision"));
1335            driveFile.setHeadRevision(fileRevision);
1336
1337
1338
1339            drive.commitFile(driveFile, revisedItemDO.getModifiedBy(), tmpItemFilePath);
1340            // delete tmp file
1341            tmpFile.delete();tmpFile = null;
1342
1343            notifyForSubmission(securitySession, userName, item, false);
1344        } catch (NamingException e) {
1345            throw new EJBException(e);
1346        } catch (CreateException e) {
1347            throw new EJBException(e);
1348        } catch (FinderException e) {
1349            throw new EJBException(e);
1350        }
1351        return revisedItemDO;
1352*/

1353    }
1354
1355    /**
1356     * <p>
1357     * Sanitize all library contents.
1358     * </p>
1359     *
1360     * @param item
1361     * @param persistenceSession
1362     */

1363    public void sanitize(SecuritySession securitySession)
1364            throws SystemException {
1365        PersistenceSession persistenceSession = persistenceManager
1366            .openSession(securitySession);
1367        SanitizerFormat sanitizer = new SanitizerFormat();
1368        sanitizer.setOnlyBodyContents(true);
1369
1370        try {
1371            List JavaDoc allItems = Collections.synchronizedList(persistenceManager.findAll(persistenceSession,
1372                    LibraryItemDO.class));
1373            Iterator JavaDoc itemIterator = allItems.iterator();
1374            while (itemIterator.hasNext()) {
1375                sanitizeItem((LibraryItemDO) itemIterator.next(), persistenceSession,
1376                        sanitizer);
1377            }
1378            List JavaDoc allComments = Collections.synchronizedList(persistenceManager.findAll(persistenceSession,
1379                    CommentDO.class));
1380            Iterator JavaDoc commentIterator = allComments.iterator();
1381            List JavaDoc commentsToRemove = new Vector JavaDoc();
1382            while (commentIterator.hasNext()) {
1383                CommentDO comment = (CommentDO) commentIterator.next();
1384                if (comment.getFormat() == FormatConstants.FORMAT_HTML) {
1385                    if (log.isDebugEnabled()) {
1386                        log.debug("Sanitize text for comment id "
1387                                + comment.getId()
1388                                + " - subject '"
1389                                + comment.getSubject()
1390                                + "'");
1391                    }
1392                    String JavaDoc newText = sanitizer.format(comment.getText());
1393                    if (StringHandling.isNullOrEmpty(newText)) {
1394                        commentsToRemove.add(comment);
1395                    } else {
1396                        comment.setText(newText);
1397                        persistenceManager.amend(persistenceSession, comment);
1398                    }
1399                } else {
1400                    if (log.isDebugEnabled()) {
1401                        log.debug("Ignoring non-HTML text for comment id "
1402                                + comment.getId()
1403                                + " - subject '"
1404                                + comment.getSubject()
1405                                + "'");
1406                    }
1407
1408                }
1409            }
1410            commentIterator = commentsToRemove.iterator();
1411            while (commentIterator.hasNext()) {
1412                CommentDO comment = (CommentDO) commentIterator.next();
1413                persistenceManager.remove(persistenceSession, comment);
1414            }
1415        } catch (Exception JavaDoc e) {
1416            persistenceSession.cancel();
1417            throw new SystemException(e);
1418        } finally {
1419            persistenceSession.close();
1420        }
1421
1422    }
1423
1424    /**
1425     * <p>
1426     * Private helper to clean up the HTML in an item.
1427     * </p>
1428     *
1429     * @param item The item to sanitize the HTML for.
1430     * @param persistenceSession Used to update the changed items.
1431     * @param sanitizer This sanitizer does all the hard work.
1432     */

1433    private void sanitizeItem(final LibraryItemDO item,
1434            final PersistenceSession persistenceSession,
1435            final SanitizerFormat sanitizer)
1436            throws PersistenceException {
1437        if (log.isDebugEnabled()) {
1438            log.debug("Sanitize text for item id "
1439                    + item.getId()
1440                    + " - title '"
1441                    + item.getTitle()
1442                    + "'");
1443        }
1444        item.setSummary(sanitizer.format(item.getSummary()));
1445
1446        // update the index for the pages
1447
if (item.getPages() != null) {
1448            Iterator JavaDoc pagesIterator = item.getPages().iterator();
1449            // page number for debugging
1450
int pageNumber = 0;
1451            List JavaDoc pagesToRemove = new Vector JavaDoc();
1452            while (pagesIterator.hasNext()) {
1453                if (log.isDebugEnabled()) {
1454                    log.debug("Sanitize text for item id "
1455                            + item.getId()
1456                            + " - page "
1457                            + ++pageNumber);
1458                }
1459                PageDO page = (PageDO) pagesIterator.next();
1460                String JavaDoc newText = sanitizer.format(page.getText());
1461                // remove empty pages
1462
if (StringHandling.isNullOrEmpty(newText)) {
1463                    pagesToRemove.add(page);
1464                } else {
1465                    page.setText(newText);
1466                    persistenceManager.amend(persistenceSession, page);
1467                }
1468            }
1469            pagesIterator = pagesToRemove.iterator();
1470            while(pagesIterator.hasNext()) {
1471                PageDO page = (PageDO) pagesIterator.next();
1472                persistenceManager.remove(persistenceSession, page);
1473                item.getPages().remove(page);
1474            }
1475
1476        }
1477        // update the index for the faqs
1478
if (item.getFAQCategories() != null) {
1479            Iterator JavaDoc fAQCategoriesIterator = item.getFAQCategories().iterator();
1480            while (fAQCategoriesIterator.hasNext()) {
1481                FAQCategoryDO faqCategory = (FAQCategoryDO) fAQCategoriesIterator.next();
1482
1483                if (log.isDebugEnabled()) {
1484                    log.debug("Sanitize text for item id "
1485                            + item.getId()
1486                            + " - faq category "
1487                            + faqCategory.getName());
1488                }
1489                faqCategory.setDescription(sanitizer.format(faqCategory.getDescription()));
1490
1491
1492                if (faqCategory.getFAQs() != null) {
1493                    Iterator JavaDoc faqIterator = faqCategory.getFAQs().iterator();
1494                    while (faqIterator.hasNext()) {
1495                        FAQDO faq = (FAQDO) faqIterator.next();
1496                        faq.setAnswer(sanitizer.format(faq.getAnswer()));
1497                        persistenceManager.amend(persistenceSession, faq);
1498                    }
1499                }
1500                persistenceManager.amend(persistenceSession, faqCategory);
1501            }
1502        }
1503        persistenceManager.amend(persistenceSession, item);
1504
1505    }
1506
1507    /**
1508     * <p>
1509     * Re-index all library contents (items and comments) in the search engine.
1510     * This is useful after an upgrade, if the search functionality has changed.
1511     * </p>
1512     */

1513    public void updateSearchIndex (SecuritySession securitySession)
1514            throws SystemException {
1515        PersistenceSession persistenceSession = persistenceManager
1516                .openSession(securitySession);
1517        try {
1518            List JavaDoc allItems = Collections.synchronizedList(persistenceManager.findAll(persistenceSession,
1519                    LibraryItemDO.class));
1520            Iterator JavaDoc itemIterator = allItems.iterator();
1521            while (itemIterator.hasNext()) {
1522                updateSearchIndexForItem(securitySession,
1523                        (LibraryItemDO) itemIterator.next());
1524            }
1525            List JavaDoc allComments = Collections.synchronizedList(persistenceManager.findAll(persistenceSession,
1526                    CommentDO.class));
1527            Iterator JavaDoc commentIterator = allComments.iterator();
1528            while (commentIterator.hasNext()) {
1529                CommentDO comment = (CommentDO) commentIterator.next();
1530                LibraryItemDO item = comment.getItem();
1531                searchEngine.updateIndex(securitySession, item.getId(),
1532                        LibraryItemDO.class.getName(),
1533                        item.getTopic().getId().toString(),
1534                        comment.getId(),
1535                        CommentDO.class.getName(),
1536                        comment.getText(),
1537                        comment.getFormat());
1538            }
1539        } catch (Exception JavaDoc e) {
1540            persistenceSession.cancel();
1541            throw new SystemException(e);
1542        } finally {
1543            persistenceSession.close();
1544        }
1545    }
1546
1547    /**
1548     * <p>
1549     * Private helper to update the search index for an item which was added
1550     * or amended. This method goes thro' all the faq categories and pages,
1551     * and updates the index for each.
1552     * </p>
1553     *
1554     * @param item The item to update the search index for.
1555     * @throws SystemException See {@link
1556     * com.ivata.groupware.business.search.Search#updateIndex Search.updateIndex}
1557     */

1558    private void updateSearchIndexForItem(final SecuritySession securitySession,
1559            final LibraryItemDO item)
1560            throws SystemException {
1561        if (log.isDebugEnabled()) {
1562            log.debug("Update search index for item id "
1563                    + item.getId()
1564                    + " - title '"
1565                    + item.getTitle()
1566                    + "'");
1567        }
1568
1569        // update the title and summary
1570
searchEngine.updateIndex(securitySession, item.getId(),
1571                LibraryItemDO.class.getName(),
1572                item.getTopic().getId().toString(),
1573                item.getId(),
1574                LibraryItemDO.class.getName(),
1575                item.getTitle()
1576                    + " "
1577                    + item.getSummary(),
1578                FormatConstants.FORMAT_HTML);
1579
1580        // update the index for the pages
1581
if (item.getPages() != null) {
1582            Iterator JavaDoc pagesIterator = item.getPages().iterator();
1583            // page number for debugging
1584
int pageNumber = 0;
1585            while (pagesIterator.hasNext()) {
1586                if (log.isDebugEnabled()) {
1587                    log.debug("Update search index for item id "
1588                            + item.getId()
1589                            + " - page "
1590                            + ++pageNumber);
1591                }
1592                PageDO page = (PageDO) pagesIterator.next();
1593                searchEngine.updateIndex(securitySession, item.getId(),
1594                        LibraryItemDO.class.getName(),
1595                        item.getTopic().getId().toString(),
1596                        page.getId(),
1597                        PageDO.class.getName(),
1598                        page.getText(),
1599                        FormatConstants.FORMAT_HTML);
1600            }
1601        }
1602        // update the index for the faqs
1603
if (item.getFAQCategories() != null) {
1604            Iterator JavaDoc fAQCategoriesIterator = item.getFAQCategories().iterator();
1605            while (fAQCategoriesIterator.hasNext()) {
1606                FAQCategoryDO faqCategory = (FAQCategoryDO) fAQCategoriesIterator.next();
1607
1608                if (log.isDebugEnabled()) {
1609                    log.debug("Update search index for item id "
1610                            + item.getId()
1611                            + " - faq category "
1612                            + faqCategory.getName());
1613                }
1614
1615                searchEngine.updateIndex(securitySession, item.getId(),
1616                        LibraryItemDO.class.getName(),
1617                        item.getTopic().getId().toString(),
1618                        faqCategory.getId(),
1619                        FAQCategoryDO.class.getName(),
1620                        faqCategory.getName()
1621                            + " "
1622                            + faqCategory.getDescription(),
1623                        FormatConstants.FORMAT_HTML);
1624
1625                if (faqCategory.getFAQs() != null) {
1626                    Iterator JavaDoc faqIterator = faqCategory.getFAQs().iterator();
1627                    while (faqIterator.hasNext()) {
1628                        FAQDO faq = (FAQDO) faqIterator.next();
1629
1630                        searchEngine.updateIndex(securitySession, item.getId(),
1631                                LibraryItemDO.class.getName(),
1632                                item.getTopic().getId().toString(),
1633                                faq.getId(),
1634                                FAQDO.class.getName(),
1635                                faq.getQuestion()
1636                                    + " "
1637                                    + faq.getAnswer(),
1638                                FormatConstants.FORMAT_HTML);
1639                    }
1640                }
1641            }
1642        }
1643    }
1644    /**
1645     * <p>Confirm all of the elements of the comment are valid before it
1646     * is submitted.</p>
1647     *
1648     * @param comment data object to check for consistency and
1649     * completeness.
1650     * @return a collection of validation errors if any of the
1651     * mandatory fields are missing, or if fields contain invalid values.
1652     */

1653    public ValidationErrors validate(final SecuritySession securitySession,
1654            final CommentDO comment) {
1655        if (log.isDebugEnabled()) {
1656            log.debug("START validating "
1657                    + comment);
1658        }
1659
1660        ValidationErrors errors = new ValidationErrors();
1661        Mask mask = maskFactory.getMask(CommentDO.class);
1662
1663        if (comment.getItem() == null) {
1664            errors.add(new ValidationError(
1665                    "submitComment",
1666                    Library.BUNDLE_PATH,
1667                    mask.getField("item"),
1668                    "errors.required"));
1669        }
1670        if (StringHandling.isNullOrEmpty(comment.getSubject())) {
1671            errors.add(new ValidationError(
1672                    "submitComment",
1673                    Library.BUNDLE_PATH,
1674                    mask.getField("subject"),
1675                    "errors.required"));
1676        }
1677        if (StringHandling.isNullOrEmpty(comment.getText())) {
1678            errors.add(new ValidationError(
1679                    "submitComment",
1680                    Library.BUNDLE_PATH,
1681                    mask.getField("text"),
1682                    "errors.required"));
1683        }
1684        if (comment.getCreatedBy() == null) {
1685            errors.add(new ValidationError(
1686                    "submitComment",
1687                    Library.BUNDLE_PATH,
1688                    mask.getField("createdBy"),
1689                    "errors.required"));
1690        }
1691
1692        if (log.isDebugEnabled()) {
1693            log.debug("END validating "
1694                    + comment
1695                    + "- errors: "
1696                    + errors);
1697        }
1698        return errors;
1699    }
1700    /**
1701     * <p>Confirm all of the elements of the item are present and valid,
1702     * before the item is submitted.</p>
1703     *
1704     * @param item data object to check for consistency and
1705     * completeness.
1706     * @return a collection of validation errors if any of the
1707     * mandatory fields are missing, or if fields contain invalid values.
1708     */

1709    public ValidationErrors validate(final SecuritySession securitySession,
1710            final LibraryItemDO item) {
1711        if (log.isDebugEnabled()) {
1712            log.debug("START validating "
1713                    + item);
1714        }
1715
1716        ValidationErrors errors = new ValidationErrors();
1717        Mask mask = maskFactory.getMask(LibraryItemDO.class);
1718
1719        if (StringHandling.isNullOrEmpty(item.getSummary())) {
1720            errors.add(new ValidationError(
1721                    "submit",
1722                    Library.BUNDLE_PATH,
1723                    mask.getField("summary"),
1724                    "errors.required"));
1725        }
1726        if (StringHandling.isNullOrEmpty(item.getTitle())) {
1727            errors.add(new ValidationError(
1728                    "submit",
1729                    Library.BUNDLE_PATH,
1730                    mask.getField("title"),
1731                    "errors.required"));
1732        }
1733        if (item.getTopic() == null) {
1734            errors.add(new ValidationError(
1735                    "submit",
1736                    Library.BUNDLE_PATH,
1737                    mask.getField("topic"),
1738                    "errors.required"));
1739        }
1740        if (item.getType() == null) {
1741            errors.add(new ValidationError(
1742                    "submit",
1743                    Library.BUNDLE_PATH,
1744                    mask.getField("type"),
1745                    "errors.required"));
1746        }
1747        // if this is a faq, it must have faq categories
1748
if (LibraryItemConstants.ITEM_FAQ.equals(item.getType())) {
1749            boolean noCategoryName = false;
1750
1751            for (Iterator JavaDoc i = item.getFAQCategories().iterator(); i.hasNext();) {
1752                FAQCategoryDO faqCategory = (FAQCategoryDO) i.next();
1753                String JavaDoc categoryName = faqCategory.getName();
1754
1755                if (!noCategoryName && StringHandling.isNullOrEmpty(categoryName)) {
1756                    errors.add(new ValidationError(
1757                            "submitFaq",
1758                            Library.BUNDLE_PATH,
1759                            mask.getField("category"),
1760                            "errors.required"));
1761                    // we only want to show the error once
1762
noCategoryName = true;
1763                }
1764                for (Iterator JavaDoc j = faqCategory.getFAQs().iterator(); j.hasNext();) {
1765                    FAQDO faq = (FAQDO) j.next();
1766
1767                    if (StringHandling.isNullOrEmpty(faq.getQuestion())) {
1768                        errors.add(new ValidationError(
1769                                "submitFaq",
1770                                Library.BUNDLE_PATH,
1771                                mask.getField("question"),
1772                                "errors.required"));
1773                        break;
1774                    }
1775                }
1776            }
1777        }
1778
1779        if (log.isDebugEnabled()) {
1780            log.debug("END validating "
1781                    + item
1782                    + "- errors: "
1783                    + errors);
1784        }
1785        return errors;
1786    }
1787
1788    /**
1789     * <p>Confirm all of the elements of the topic are present and valid,
1790     * before the topic is submitted.</p>
1791     *
1792     * @param topic data object to check for consistency and
1793     * completeness.
1794     * @return a collection of validation errors if any of the
1795     * mandatory fields are missing, or if fields contain invalid values.
1796     */

1797    public ValidationErrors validate(final SecuritySession securitySession,
1798            final TopicDO topic) {
1799        ValidationErrors errors = new ValidationErrors();
1800        Mask mask = maskFactory.getMask(TopicDO.class);
1801
1802        if (StringHandling.isNullOrEmpty(topic.getCaption())) {
1803            errors.add(new ValidationError(
1804                    "topicModify",
1805                    Library.BUNDLE_PATH,
1806                    mask.getField("caption"),
1807                    "errors.required"));
1808        }
1809        return errors;
1810    }
1811
1812}
1813
Popular Tags