001: /***
002: * jwma Java WebMail
003: * Copyright (c) 2000-2003 jwma team
004: *
005: * jwma is free software; you can distribute and use this source
006: * under the terms of the BSD-style license received along with
007: * the distribution.
008: ***/package dtw.webmail.model;
009:
010: import java.util.*;
011: import java.net.*;
012: import java.text.*;
013: import java.io.ByteArrayInputStream;
014:
015: import org.apache.log4j.Logger;
016:
017: import dtw.webmail.*;
018: import dtw.webmail.util.MessageSortCriterias;
019: import dtw.webmail.util.StringUtil;
020: import dtw.webmail.util.MD5;
021: import dtw.webmail.util.config.ConfigurationChangeListener;
022: import dtw.webmail.util.config.PostOffice;
023: import dtw.webmail.plugin.RandomAppendPlugin;
024: import dtw.webmail.plugin.ContactManagementPlugin;
025:
026: import javax.servlet.http.HttpSession;
027:
028: import net.wimpi.text.Processor;
029:
030: /**
031: * Class implementing the JwmaHtmlHelper.
032: * <p>Actually represents an utility class that helps
033: * to keep complex logic out of the views.
034: *
035: * @author Dieter Wimberger
036: * @version 0.9.7 07/02/2003
037: */
038: public class JwmaHtmlHelperImpl implements JwmaHtmlHelper {
039:
040: //logging
041: private static Logger log = Logger
042: .getLogger(JwmaHtmlHelperImpl.class);
043: private static HashMap c_DateFormats;
044:
045: //prepare cached dateformat instances
046: static {
047: Locale[] locales = JwmaKernel.getReference().getConfiguration()
048: .getI18N().listViewLocales();
049: c_DateFormats = new HashMap((int) (locales.length * 1.4));
050: for (int i = 0; i < locales.length; i++) {
051: SimpleDateFormat dfs = (SimpleDateFormat) DateFormat
052: .getDateInstance(DateFormat.SHORT, locales[i]);
053: SimpleDateFormat dfm = (SimpleDateFormat) DateFormat
054: .getDateInstance(DateFormat.MEDIUM, locales[i]);
055: SimpleDateFormat dfl = (SimpleDateFormat) DateFormat
056: .getDateInstance(DateFormat.LONG, locales[i]);
057: SimpleDateFormat[] formats = { dfs, dfm, dfl };
058: c_DateFormats.put(locales[i], formats);
059: }
060: }
061:
062: public JwmaHtmlHelperImpl() {
063: }//constructor
064:
065: public String getControllerUrl() {
066: return JwmaKernel.getReference().getMainControllerUrl();
067: }//getControllerUrl
068:
069: public String getSendMailControllerUrl() {
070: return JwmaKernel.getReference().getSendMailControllerUrl();
071: }//getSendMailControllerUrl
072:
073: public String getContactsControllerUrl() {
074: return JwmaKernel.getReference().getContactsControllerUrl();
075: }//getContactsControllerUrl
076:
077: public String getPostOfficeSelect(String postoffice) {
078: boolean def = true;
079: if (postoffice != null && postoffice.length() > 0) {
080: def = false;
081: }
082: StringBuffer buf = new StringBuffer(
083: "<select name=\"postoffice\">");
084: for (Iterator iter = JwmaKernel.getReference()
085: .getConfiguration().getPostOffices(); iter.hasNext();) {
086:
087: PostOffice po = (PostOffice) iter.next();
088: buf.append(" <option value=\"").append(po.getName())
089: .append("\"");
090: if (def) {
091: if (po.isDefault()) {
092: buf.append(" selected");
093: }
094: } else {
095: if (MD5.hash(po.getName()).equals(postoffice)) {
096: buf.append(" selected");
097: }
098: }
099: buf.append(">");
100: buf.append(po.getName());
101: buf.append("</option>");
102: }
103: buf.append("</select>");
104: return buf.toString();
105: }//getPostOfficeSelect
106:
107: public String getPathHierarchyNavigator(JwmaStoreInfo info,
108: JwmaFolder folder) {
109: String clickurl = "<a href=\""
110: + getControllerUrl()
111: + "?acton=folder&todo=display&path={0}\">{1}</a>";
112:
113: String fname = "";
114: String sep = info.getFolderSeparator() + "";
115: //JwmaKernel.getReference().debugLog().write("Path="+path+";ClickUrl="+clickurl);
116: StringBuffer fpath = new StringBuffer();
117: StringBuffer hierarchy = new StringBuffer();
118: StringTokenizer strtok = new StringTokenizer(folder.getPath(),
119: sep, false);
120: int i = 0;
121:
122: while (strtok.hasMoreElements()) {
123: fname = strtok.nextToken();
124: if (i > 0) {
125: fpath.append(sep);
126: hierarchy.append(sep);
127: }
128: fpath.append(URLEncoder.encode(fname));
129: if (strtok.countTokens() == 0) {
130: //redirect to folder
131: hierarchy
132: .append("<a href=\"")
133: .append(getControllerUrl())
134: .append(
135: "?acton=session&todo=redirect&view=folder\">")
136: .append(fname).append("</a>");
137: } else {
138: Object[] args = { fpath, fname };
139: hierarchy.append(MessageFormat.format(clickurl, args));
140: }
141: i++;
142: }
143: return hierarchy.toString();
144: }//getPathNavigator
145:
146: public String getFolderDisplayAction(JwmaFolder folder) {
147: if (folder == null) {
148: return "nullfolder";
149: } else {
150: return getControllerUrl()
151: + "?acton=folder&todo=display&path="
152: + URLEncoder.encode(folder.getPath());
153: }
154: }//getFolderDisplayAction
155:
156: public String getFolderDisplayAction(JwmaInboxInfo info) {
157: return getFolderDisplayAction((JwmaFolder) info);
158: }//getFolderDisplayAction
159:
160: public String getFolderDisplayAction(JwmaTrashInfo info) {
161: return getFolderDisplayAction((JwmaFolder) info);
162: }//getFolderDisplayAction
163:
164: public String getDestinationsSelect(JwmaFolder[] folders) {
165: StringBuffer buf = new StringBuffer(
166: "<select name=\"destination\">");
167: for (int i = 0; i < folders.length; i++) {
168: buf.append(" <option value=\"" + folders[i].getPath()
169: + "\">" + folders[i].getPath() + "</option>");
170: }
171: buf.append("</select>");
172: return buf.toString();
173: }//getDestinationsSelection
174:
175: public String getLanguageSelect(JwmaPreferences prefs) {
176: StringBuffer buf = new StringBuffer(
177: "<select name=\"language\">");
178: Locale[] locales = JwmaKernel.getReference().getConfiguration()
179: .getI18N().listViewLocales();
180:
181: for (int i = 0; i < locales.length; i++) {
182: buf.append(" <option value=\"").append(
183: locales[i].getLanguage()).append("\"");
184: if (locales[i].equals(prefs.getLocale())) {
185: buf.append(" selected");
186: }
187: buf.append(">");
188: buf.append(locales[i].getDisplayName(locales[i]));
189: buf.append("</option>");
190: }
191: buf.append("</select>");
192: return buf.toString();
193: }//getLanguageSelect
194:
195: public String getSortCriteriaSelect(JwmaPreferences prefs,
196: String eventhandler, ResourceBundle viewcontent) {
197: StringBuffer buf = new StringBuffer(
198: "<select name=\"criteria\" ");
199:
200: if (eventhandler != null) {
201: buf.append(eventhandler);
202: }
203: buf.append(">\n");
204:
205: int[] criterianums = MessageSortCriterias.EXUI_CRITERIAS;
206: int last = prefs.getMessageSortCriteria();
207: String[] names = MessageSortCriterias.EXUI_CRITERIAS_STR;
208:
209: for (int i = 0; i < criterianums.length; i++) {
210: buf.append(" <option value=\"").append(criterianums[i])
211: .append("\"");
212: if (criterianums[i] == last) {
213: buf.append(" selected");
214: }
215: buf.append(">");
216: buf.append(viewcontent.getString(names[i]));
217: buf.append("</option>");
218: }
219: buf.append("</select>");
220: return buf.toString();
221: }//getSortingCriteriaSelect
222:
223: public String getFrequentSelect(JwmaContacts contacts,
224: String eventhandler) {
225: //String[] fnicks = book.listNicknames(true);
226: JwmaContact[] frequent = contacts.listFrequentRecipients();
227: if (frequent == null || frequent.length == 0) {
228: return "";
229: }
230: StringBuffer buf = new StringBuffer(
231: "<select name=\"frequent\" ");
232:
233: if (eventhandler != null) {
234: buf.append(eventhandler);
235: }
236: buf.append(">\n");
237: buf
238: .append("<option value=\"\" selected>Select frequent</option>\n");
239: for (int i = 0; i < frequent.length; i++) {
240: JwmaContact ct = frequent[i];
241: String nickname = ct.getNickname();
242: if (nickname == null || nickname.length() == 0) {
243: nickname = new StringBuffer(ct.getLastname()).append(
244: ", ").append(ct.getFirstname()).toString();
245: }
246: buf.append(" <option value=\"").append(ct.getFirstname())
247: .append(" ").append(ct.getLastname()).append("<")
248: .append(ct.getEmail()).append(">").append("\">")
249: .append(nickname).append("</option>\n");
250: }
251: buf.append("</select>\n");
252: return buf.toString();
253: }//getFrequentSelect
254:
255: public String getCategoriesSelect(JwmaContact ct,
256: String[] categories, ResourceBundle viewcontent) {
257:
258: StringBuffer buf = new StringBuffer(
259: "<select name=\"category\">\n");
260: if (categories != null && categories.length > 0) {
261: for (int i = 0; i < categories.length; i++) {
262: buf
263: .append(" <option value=\"")
264: .append(categories[i])
265: .append("\"")
266: .append(
267: ((categories[i]
268: .equals(ct.getCategory())) ? " selected>"
269: : ">")).append(categories[i])
270: .append("</option>\n");
271: }
272: }
273: String newcat = viewcontent.getString("contact.newcategory");
274: buf.append(" <option value=\"").append(newcat).append("\">")
275: .append(newcat).append("</option>\n");
276:
277: buf.append("</select>\n");
278: return buf.toString();
279: }//getCategoriesSelect
280:
281: public String getMessageProcessorSelect(JwmaPreferences prefs) {
282: String[] procs = JwmaKernel.getReference()
283: .listMessageProcessors();
284: StringBuffer buf = new StringBuffer(
285: "<select name=\"msgprocessor\">\n");
286: //add options
287: for (int i = 0; i < procs.length; i++) {
288: Processor proc = JwmaKernel.getReference()
289: .getMessageProcessor(procs[i]);
290: buf
291: .append(" <option value=\"")
292: .append(procs[i])
293: .append("\"")
294: .append(
295: ((procs[i].equals(prefs
296: .getMessageProcessorName())) ? " selected>"
297: : ">")).append(
298: proc.getDescription(prefs.getLocale()))
299: .append("</option>\n");
300: }
301: buf.append("</select>\n");
302: return buf.toString();
303: }//getMessageProcessorSelect
304:
305: public String getRandomAppendTypesSelect(JwmaPreferences prefs,
306: JwmaMailIdentity mid) {
307: RandomAppendPlugin rap = JwmaKernel.getReference()
308: .getRandomAppendPlugin();
309: String[] rndapp = null;
310:
311: if (rap == null) {
312: rndapp = new String[1];
313: rndapp[0] = RandomAppendPlugin.TYPE_NONE;
314: } else {
315: rndapp = rap.listAppendTypes(prefs.getLocale());
316: }
317:
318: StringBuffer buf = new StringBuffer(
319: "<select name=\"rndappendtype\">\n");
320: //add options
321: for (int i = 0; i < rndapp.length; i++) {
322: buf
323: .append(" <option value=\"")
324: .append(rndapp[i])
325: .append("\"")
326: .append(
327: ((rndapp[i].equals(mid
328: .getRandomAppendType())) ? " selected>"
329: : ">")).append(rndapp[i]).append(
330: "</option>\n");
331: }
332: buf.append("</select>\n");
333:
334: return buf.toString();
335: }//getRandomAppendSelect
336:
337: public String getDateFormatSelect(JwmaPreferences prefs) {
338: Date d = new Date();
339: SimpleDateFormat[] formats = (SimpleDateFormat[]) c_DateFormats
340: .get(prefs.getLocale());
341: String actualpattern = ((SimpleDateFormat) prefs
342: .getDateFormat()).toPattern();
343: StringBuffer buf = new StringBuffer(
344: "<select name=\"dfpattern\">\n");
345: //add options
346: for (int i = 0; i < 3; i++) {
347: SimpleDateFormat sdf = formats[i];
348: String pattern = sdf.toPattern();
349: buf.append(" <option value=\"").append(pattern).append(
350: "\"").append(
351: ((pattern.equals(actualpattern)) ? " selected>"
352: : ">")).append(sdf.format(d)).append(" (")
353: .append(pattern).append(")").append("</option>\n");
354: }
355: buf.append("</select>\n");
356:
357: return buf.toString();
358: }//getDateFormatSelect
359:
360: public String getMailIdentitySelect(JwmaPreferences prefs) {
361: JwmaMailIdentity[] mids = prefs.listMailIdentities();
362: StringBuffer buf = new StringBuffer(
363: "<select name=\"mailidentity\">\n");
364: //add options
365: //buf.append(" <option value=\"\" selected>Use</option>\n");
366: for (int i = 0; i < mids.length; i++) {
367: buf
368: .append(" <option value=\"")
369: .append(mids[i].getUID())
370: .append("\"")
371: .append(
372: ((prefs.getMailIdentity().equals(mids[i])) ? " selected>"
373: : ">")).append(mids[i].getName())
374: .append(" (").append(mids[i].getFrom()).append(")")
375: .append("</option>\n");
376: }
377: buf.append("</select>\n");
378: return buf.toString();
379: }//getMailIdentitySelect
380:
381: public String getGroupMembersSelect(JwmaContactGroup group) {
382: JwmaContact[] cts = group.listContacts();
383: StringBuffer buf = new StringBuffer(
384: "<select name=\"contact.member.id\" size=\"10\" multiple>\n");
385: //add options
386: //buf.append(" <option value=\"\" selected>Use</option>\n");
387: for (int i = 0; i < cts.length; i++) {
388: buf.append(" <option value=\"").append(cts[i].getUID())
389: .append("\">").append(cts[i].getLastname()).append(
390: ", ").append(cts[i].getFirstname()).append(
391: " ").append(cts[i].getMiddlename()).append(
392: " (").append(cts[i].getEmail()).append(")")
393: .append("</option>\n");
394: }
395: buf.append("</select>\n");
396: return buf.toString();
397: }//getGroupMembersSelect
398:
399: public String getNonMembersSelect(JwmaContactGroup group,
400: JwmaContacts ctdb) {
401: JwmaContact[] cts = ctdb.listContacts();
402: JwmaContactGroupImpl grp = (JwmaContactGroupImpl) group;
403: StringBuffer buf = new StringBuffer(
404: "<select name=\"contact.nomember.id\" size=\"10\" multiple>\n");
405: //add options
406: //buf.append(" <option value=\"\" selected>Use</option>\n");
407: for (int i = 0; i < cts.length; i++) {
408: if (!grp.containsContact(cts[i].getUID())) {
409: buf.append(" <option value=\"")
410: .append(cts[i].getUID()).append("\">").append(
411: cts[i].getLastname()).append(", ")
412: .append(cts[i].getFirstname()).append(" ")
413: .append(cts[i].getMiddlename()).append(" (")
414: .append(cts[i].getEmail()).append(")").append(
415: "</option>\n");
416: }
417: }
418: buf.append("</select>\n");
419: return buf.toString();
420: }//getNonMembersSelect
421:
422: public String displayPartInlined(HttpSession session,
423: JwmaMessagePart part, JwmaPreferences prefs,
424: ResourceBundle viewcontent) {
425:
426: StringBuffer sbuf = new StringBuffer();
427: JwmaMessagePartImpl msgpart = (JwmaMessagePartImpl) part;
428: log.debug("displaying part inlined type="
429: + msgpart.getContentType());
430: try {
431: //handle by type
432: if (msgpart.isMimeType("text/plain")) {
433: //log.debug("textcontent="+msgpart.getTextContent());
434: sbuf.append("<pre>");
435: sbuf.append(prefs.getMessageProcessor().process(
436: msgpart.getTextContent()));
437: sbuf.append("</pre>");
438: } else if (msgpart.isMimeType("image/*")) {
439: sbuf.append("<img border=\"0\" src=\"").append(
440: JwmaKernel.getReference()
441: .getMainControllerUrl()).append(
442: "?acton=message&todo=displaypart&number=")
443: .append(part.getPartNumber()).append("\">");
444: } else if (msgpart.isMimeType("text/directory")
445: || msgpart.isMimeType("application/directory")) {
446: ContactManagementPlugin cmp = JwmaKernel.getReference()
447: .getContactManagementPlugin();
448: String ctype = StringUtil.split(msgpart
449: .getContentType(), ";")[0].toLowerCase();
450: if (cmp.isSupportedContactImportType(ctype)) {
451: //log.debug("displayPartInlined()::Contact:"+msgpart.getTextContent());
452: JwmaContact ct = cmp.importContact(
453: new ByteArrayInputStream(msgpart
454: .getTextContent().getBytes()),
455: ctype);
456:
457: session.putValue("jwma.contacts.import", ct);
458:
459: sbuf
460: .append(
461: "<img border=\"0\" src=\"images/address.png\">")
462: .append(ct.getLastname())
463: .append(",")
464: .append(ct.getFirstname())
465: .append(" <a href=\"")
466: .append(
467: JwmaKernel.getReference()
468: .getContactsControllerUrl())
469: .append("?acton=contact&todo=import")
470: .append("\">")
471: .append(
472: viewcontent
473: .getString("contacts.import"))
474: .append("</a>");
475: } else {
476: sbuf
477: .append(getPartDescription(msgpart,
478: viewcontent));
479: }
480:
481: } else {
482: sbuf.append(getPartDescription(msgpart, viewcontent));
483: }
484:
485: return sbuf.toString();
486: } catch (Exception ex) {
487: log.debug("displayPartInlined()", ex);
488: return viewcontent.getString("message.part.failedinline");
489: }
490: }//displayPartInlined
491:
492: public String getPartDescription(JwmaMessagePart part,
493: ResourceBundle viewcontent) {
494:
495: StringBuffer sbuf = new StringBuffer("<p>");
496: sbuf
497: .append("<b>")
498: .append(viewcontent.getString("message.part.number"))
499: .append(part.getPartNumber())
500: .append("</b> (<i>")
501: .append(part.getContentType())
502: .append("</i>)")
503: .append("<br>\n")
504: .append("<b>")
505: .append(viewcontent.getString("message.part.filename"))
506: .append(":</b>")
507: .append("<a href=\"")
508: .append(getControllerUrl())
509: .append(
510: "?acton=message&todo=displaypart&number=")
511: .append(part.getPartNumber()).append("\">").append(
512: part.getName()).append("</a>(<i>").append(
513: getSizeString(part.getSize())).append(
514: "</i>)<br>\n").append("</p>\n");
515: return sbuf.toString();
516: }//getPartDescription
517:
518: public String getSizeString(int size) {
519: int steps = 0;
520: while (size > 1024) {
521: size = size / 1024;
522: steps++;
523: }
524: if (steps == 0) {
525: return size + " bytes";
526: } else if (steps == 1) {
527: return size + " kB";
528: } else if (steps == 2) {
529: return size + " MB";
530: } else {
531: return "Huge ;)";
532: }
533: }//getSizeString
534:
535: public String getAlphabeticFilter(JwmaContacts contacts,
536: ResourceBundle viewcontent) {
537: StringBuffer sbuf = new StringBuffer();
538: JwmaContactsImpl cts = (JwmaContactsImpl) contacts;
539:
540: //1. add the selector that will show all contacts
541: if (cts.getContactFilter().toString().equals("")) {
542: sbuf
543: .append(
544: viewcontent
545: .getString("contacts.filter.alphabetic.none"))
546: .append(" - ");
547: } else {
548: sbuf
549: .append("<a href=\"")
550: .append(
551: JwmaKernel.getReference()
552: .getContactsControllerUrl())
553: .append(
554: "?acton=database&todo=setfilter&filtertype=alphabetic&filter=")
555: .append("none")
556: .append("\">")
557: .append(
558: viewcontent
559: .getString("contacts.filter.alphabetic.none"))
560: .append("</a> - ");
561: }
562:
563: //2. add the selectors for the first characters of all lastnames
564: for (Iterator iter = cts.getLastnameStarts(); iter.hasNext();) {
565: String firstchar = (String) iter.next();
566: if (cts.getContactFilter().toString().equalsIgnoreCase(
567: firstchar)) {
568: sbuf.append(firstchar).append(" ");
569: } else {
570: sbuf
571: .append("<a href=\"")
572: .append(
573: JwmaKernel.getReference()
574: .getContactsControllerUrl())
575: .append(
576: "?acton=database&todo=setfilter&filtertype=alphabetic&filter=")
577: .append(firstchar).append("\">").append(
578: firstchar).append("</a> ");
579: }
580: }
581: return sbuf.toString();
582: }//getAlphabeticFilter
583:
584: public String getCategoryFilterSelect(JwmaContacts ctdb,
585: String eventhandler, ResourceBundle viewcontent) {
586:
587: JwmaContactsImpl ctdbimpl = (JwmaContactsImpl) ctdb;
588: String[] categories = ctdbimpl.listContactCategories();
589:
590: StringBuffer buf = new StringBuffer("<select name=\"filter\" ")
591: .append(eventhandler).append(">\n");
592:
593: boolean selected = false;
594: boolean selectednow = true;
595: if (categories != null && categories.length > 0) {
596: for (int i = 0; i < categories.length; i++) {
597: if (categories[i].equals(ctdbimpl.getCategoryFilter())) {
598: selected = true;
599: selectednow = true;
600: } else {
601: selectednow = false;
602: }
603: buf.append(" <option value=\"").append(categories[i])
604: .append("\"").append(
605: ((selectednow) ? " selected>" : ">"))
606: .append(categories[i]).append("</option>\n");
607: }
608: }
609:
610: buf.append(" <option value=\"none\"").append(
611: ((selected) ? ">" : " selected>")).append(
612: viewcontent.getString("contacts.filter.category.all"))
613: .append("</option>\n");
614:
615: buf.append("</select>\n");
616: return buf.toString();
617: }//getCategoryFilterSelect
618:
619: }//class JwmaHtmlHelperImpl
|