001: /*
002: * Copyright (c) 2001 - 2005 ivata limited.
003: * All rights reserved.
004: * -----------------------------------------------------------------------------
005: * ivata groupware may be redistributed under the GNU General Public
006: * License as published by the Free Software Foundation;
007: * version 2 of the License.
008: *
009: * These programs are free software; you can redistribute them and/or
010: * modify them under the terms of the GNU General Public License
011: * as published by the Free Software Foundation; version 2 of the License.
012: *
013: * These programs are distributed in the hope that they will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: *
017: * See the GNU General Public License in the file LICENSE.txt for more
018: * details.
019: *
020: * If you would like a copy of the GNU General Public License write to
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place - Suite 330
024: * Boston, MA 02111-1307, USA.
025: *
026: *
027: * To arrange commercial support and licensing, contact ivata at
028: * http://www.ivata.com/contact.jsp
029: * -----------------------------------------------------------------------------
030: * $Log: CommentTreeNodeRenderer.java,v $
031: * Revision 1.2 2005/04/09 17:19:48 colinmacleod
032: * Changed copyright text to GPL v2 explicitly.
033: *
034: * Revision 1.1.1.1 2005/03/10 17:52:07 colinmacleod
035: * Restructured ivata op around Hibernate/PicoContainer.
036: * Renamed ivata groupware.
037: *
038: * Revision 1.5 2004/11/12 18:16:06 colinmacleod
039: * Ordered imports.
040: *
041: * Revision 1.4 2004/11/12 15:57:16 colinmacleod
042: * Removed dependencies on SSLEXT.
043: * Moved Persistence classes to ivata masks.
044: *
045: * Revision 1.3 2004/07/13 19:47:29 colinmacleod
046: * Moved project to POJOs from EJBs.
047: * Applied PicoContainer to services layer (replacing session EJBs).
048: * Applied Hibernate to persistence layer (replacing entity EJBs).
049: *
050: * Revision 1.2 2004/03/21 21:16:29 colinmacleod
051: * Shortened name to ivata op.
052: *
053: * Revision 1.1.1.1 2004/01/27 20:58:45 colinmacleod
054: * Moved ivata openportal to SourceForge..
055: *
056: * Revision 1.3 2003/11/18 09:57:52 jano
057: * commiting all forgoten staff
058: *
059: * Revision 1.2 2003/10/15 14:16:54 colin
060: * fixing for XDoclet
061: *
062: * Revision 1.2 2003/02/27 07:53:01 colin
063: * added missing setUserName on dateFormatter
064: *
065: * Revision 1.1 2003/02/24 19:33:33 colin
066: * moved to jsp
067: *
068: * Revision 1.4 2003/02/04 17:43:46 colin
069: * copyright notice
070: *
071: * Revision 1.3 2003/01/24 19:30:27 peter
072: * added pageContext to initialize parameters, URL rewriting
073: *
074: * Revision 1.2 2002/09/05 13:23:24 colin
075: * changed library user rights from canUser... to can...
076: *
077: * Revision 1.1 2002/08/15 09:48:49 colin
078: * first version
079: * -----------------------------------------------------------------------------
080: */
081: package com.ivata.groupware.web.tree.comment;
082:
083: import java.util.Properties;
084:
085: import javax.servlet.http.HttpServletRequest;
086: import javax.servlet.http.HttpSession;
087: import javax.servlet.jsp.JspException;
088: import javax.servlet.jsp.JspWriter;
089: import javax.servlet.jsp.PageContext;
090:
091: import com.ivata.groupware.admin.security.server.SecuritySession;
092: import com.ivata.groupware.admin.setting.Settings;
093: import com.ivata.groupware.admin.setting.SettingsDataTypeException;
094: import com.ivata.groupware.business.library.comment.CommentDO;
095: import com.ivata.groupware.business.library.right.LibraryRights;
096: import com.ivata.groupware.util.SettingDateFormatter;
097: import com.ivata.groupware.web.tree.DefaultTreeNodeRenderer;
098: import com.ivata.groupware.web.tree.TreeNode;
099: import com.ivata.mask.util.SystemException;
100: import com.ivata.mask.web.format.CharacterEntityFormat;
101: import com.ivata.mask.web.format.DateFormatterException;
102: import com.ivata.mask.web.format.FormatConstants;
103: import com.ivata.mask.web.format.HTMLFormatter;
104: import com.ivata.mask.web.format.LineBreakFormat;
105:
106: /**
107: * <p>Create at tree node renderer for library item comments. This
108: * renderer uses
109: * the same theme sections as <code>DefaultTreeNodeRenderer</code>
110: * though it
111: * sets
112: * new properties to be evaluated in a separate theme.</p>
113: *
114: * @since 2002-07-07
115: * @author Colin MacLeod
116: * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
117: * @version $Revision: 1.2 $
118: * @see DefaultTreeNodeRenderer
119: */
120: public class CommentTreeNodeRenderer extends DefaultTreeNodeRenderer {
121:
122: /**
123: * <p>Applied to the content of the tree tag</p>
124: */
125: private CharacterEntityFormat characterEntityFormat = new CharacterEntityFormat();
126:
127: /**
128: * <p>Used to format the modified by field.</p>
129: */
130: private SettingDateFormatter dateFormatter;
131:
132: /**
133: * <p>Used to check whether or not the current user can edit the
134: * current
135: * node.</p>
136: */
137: private LibraryRights libraryRights;
138:
139: /**
140: * <p>Used to convert line breaks in plain text comments.</p>
141: */
142: private LineBreakFormat lineBreakFormat = new LineBreakFormat();
143:
144: /**
145: * <p>Used to initialize get the spacer width.</p>
146: */
147: private Settings settings;
148: /**
149: * <p>Stores the number of the top level comment (top level meaning a
150: * comment
151: * which is not a reply to another comment). This is used to set the
152: * css
153: * class.</p>
154: */
155: int threadNumber = 0;
156: SecuritySession securitySession;
157:
158: /**
159: * Constructor.
160: */
161: public CommentTreeNodeRenderer(SecuritySession securitySession,
162: SettingDateFormatter dateFormatter,
163: LibraryRights libraryRights, Settings settings) {
164: this .securitySession = securitySession;
165: this .dateFormatter = dateFormatter;
166: this .libraryRights = libraryRights;
167: this .settings = settings;
168: }
169:
170: /**
171: * <p>Overridden to close the table which surrounds comment trees.</p>
172: *
173: * @param session the current session which can be used to retrieve
174: * settings.
175: * @param request the current servlet request which can be used to
176: * retrieve
177: * settings.
178: * @param out jsp writer which can be used to output HTML.
179: * @throws JspException if there is an error parsing the theme or
180: * writing the
181: * output.
182: * who experience an error on finalization.
183: */
184: public void finalize(final HttpSession session,
185: final HttpServletRequest request, final JspWriter out)
186: throws JspException {
187: try {
188: out.print(getTreeTag().getTheme().parseSection(
189: "finalizeCommentTree", new Properties()));
190: } catch (java.io.IOException e) {
191: throw new JspException(e);
192: }
193:
194: super .finalize(session, request, out);
195: }
196:
197: /**
198: * <p>Access the internal date formatter to change the date or time
199: * format
200: * applied.</p>
201: *
202: * @return the formatter which is used internally to convert the
203: * modified field
204: * to a string.
205: */
206: public final SettingDateFormatter getDateFormatter() {
207: return dateFormatter;
208: }
209:
210: /**
211: * <p>This method has been overriden to initialize the settings in the
212: * internal
213: * date formatter, and to parse the comment surrounding table.</p>
214: *
215: * @param session the current session which can be used to retrieve
216: * settings.
217: * @param request the current servlet request which can be used to
218: * retrieve
219: * settings.
220: * @param out jsp writer which can be used to output HTML.
221: * @param pageContext the current PageContext
222: * @throws JspException if there is an error parsing the theme or
223: * writing the
224: * output.
225: * who experience an error on initialization.
226: */
227: public void initialize(final HttpSession session,
228: final HttpServletRequest request, final JspWriter out,
229: final PageContext pageContext) throws JspException {
230: try {
231: out.print(getTreeTag().getTheme().parseSection(
232: "initializeCommentTree", new Properties()));
233: } catch (java.io.IOException e) {
234: throw new JspException(e);
235: }
236:
237: super .initialize(session, request, out, pageContext);
238:
239: // if we apply it, we'll want the line break format to do its job ;-)
240: lineBreakFormat.setConvertLineBreaks(true);
241: }
242:
243: /**
244: * <p>Overridden to add the comment text property.</p>
245: *
246: * @param treeNode the current node in the tree being drawn.
247: * @param level the depth of this node within the tree, with 0 being
248: * root.
249: * @param properties all the properties are already defined. New
250: * properties
251: * should be added to this instance and returned.
252: * @return all of the properties which should be evaluated in the
253: * client theme
254: * section.
255: * @throws JspException if there is a format error with the date.
256: */
257: public Properties setAdditionalProperties(final TreeNode treeNode,
258: final int level, final Properties properties)
259: throws JspException {
260: // make the right formatter for the occasion
261: HTMLFormatter formatter = new HTMLFormatter();
262: CommentDO commentDO = (CommentDO) treeNode;
263:
264: // see if the user is allowed to edit this comment
265: try {
266: if (libraryRights.canAmendComment(securitySession,
267: commentDO)) {
268: properties.setProperty("canUserEdit", "true");
269: }
270: } catch (SystemException e) {
271: throw new RuntimeException(e);
272: }
273:
274: // if this is a plain text message, convert character entities and line
275: // breaks
276: if (commentDO.getFormat() == FormatConstants.FORMAT_TEXT) {
277: formatter.add(characterEntityFormat);
278: formatter.add(lineBreakFormat);
279: }
280:
281: properties.setProperty("commentSubject", formatter
282: .format(commentDO.getSubject()));
283: properties.setProperty("commentText", formatter
284: .format(commentDO.getText()));
285: properties.setProperty("commentUserName", commentDO
286: .getCreatedBy().getName());
287:
288: try {
289: properties.setProperty("commentModified", dateFormatter
290: .format(commentDO.getModified()));
291: } catch (DateFormatterException e1) {
292: throw new RuntimeException(e1);
293: }
294:
295: // how large the spacer is depends on the level
296: try {
297: properties.setProperty("spacer", new Integer(level
298: * settings.getIntegerSetting(securitySession,
299: "libraryCommentSpacer",
300: securitySession.getUser()).intValue())
301: .toString());
302: } catch (SettingsDataTypeException e) {
303: throw new JspException(e);
304: } catch (SystemException e) {
305: throw new JspException(e);
306: }
307:
308: // the css style for this row depends on the whether the thread number
309: // is odd or even, and whether the reply number within that thread is
310: // odd or even too.
311: String threadClass;
312:
313: if ((threadNumber % 2) == 0) {
314: if ((level % 2) == 0) {
315: threadClass = "commentEvenThreadEvenReply";
316: } else {
317: threadClass = "commentEvenThreadOddReply";
318: }
319: } else if ((level % 2) == 0) {
320: threadClass = "commentOddThreadEvenReply";
321: } else {
322: threadClass = "commentOddThreadOddReply";
323: }
324:
325: properties.setProperty("threadClass", threadClass);
326:
327: // if this is a top level comment, then increase the thread counter
328: if (level == 0) {
329: ++threadNumber;
330: }
331:
332: return properties;
333: }
334: }
|