1 package org.columba.mail.folder.command; 17 18 import java.awt.Color ; 19 import java.awt.Font ; 20 import java.io.ByteArrayInputStream ; 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.lang.reflect.Array ; 25 import java.net.MalformedURLException ; 26 import java.net.URL ; 27 import java.nio.charset.Charset ; 28 import java.text.DateFormat ; 29 import java.text.ParsePosition ; 30 import java.text.SimpleDateFormat ; 31 import java.util.Date ; 32 import java.util.List ; 33 import java.util.logging.Logger ; 34 35 import org.columba.api.command.ICommandReference; 36 import org.columba.api.command.IWorkerStatusController; 37 import org.columba.core.command.Command; 38 import org.columba.core.command.StatusObservableImpl; 39 import org.columba.core.command.Worker; 40 import org.columba.core.config.Config; 41 import org.columba.core.io.DiskIO; 42 import org.columba.core.io.StreamUtils; 43 import org.columba.core.print.cCmUnit; 44 import org.columba.core.print.cDocument; 45 import org.columba.core.print.cHGroup; 46 import org.columba.core.print.cHTMLPart; 47 import org.columba.core.print.cLine; 48 import org.columba.core.print.cParagraph; 49 import org.columba.core.print.cPrintObject; 50 import org.columba.core.print.cPrintVariable; 51 import org.columba.core.print.cVGroup; 52 import org.columba.core.util.TempFileStore; 53 import org.columba.core.xml.XmlElement; 54 import org.columba.mail.command.IMailFolderCommandReference; 55 import org.columba.mail.config.MailConfig; 56 import org.columba.mail.folder.IMailbox; 57 import org.columba.mail.gui.message.viewer.AttachmentModel; 58 import org.columba.mail.parser.text.HtmlParser; 59 import org.columba.mail.util.MailResourceLoader; 60 import org.columba.ristretto.coder.Base64DecoderInputStream; 61 import org.columba.ristretto.coder.CharsetDecoderInputStream; 62 import org.columba.ristretto.coder.QuotedPrintableDecoderInputStream; 63 import org.columba.ristretto.message.Header; 64 import org.columba.ristretto.message.MimeHeader; 65 import org.columba.ristretto.message.MimePart; 66 import org.columba.ristretto.message.MimeTree; 67 import org.columba.ristretto.message.StreamableMimePart; 68 69 70 75 public class PrintMessageCommand extends Command { 76 77 78 private static final Logger LOG = Logger.getLogger("org.columba.mail.folder.command"); 79 80 private cPrintObject mailHeader; 81 private cPrintObject mailFooter; 82 private DateFormat mailDateFormat; 83 private String [] headerKeys = {"From", "To", "Date", "Subject"}; 84 private String dateHeaderKey = "Date"; private String attHeaderKey = "attachment"; 86 private Charset charset; 87 88 89 private MimeHeader bodyHeader; 90 private InputStream bodyStream; 91 97 public PrintMessageCommand(ICommandReference reference, Charset charset) { 98 super(reference); 99 this.charset = charset; 100 101 cParagraph columbaParagraph = new cParagraph(); 103 columbaParagraph.setText("The Columba Project"); 104 columbaParagraph.setColor(Color.lightGray); 105 columbaParagraph.setFontStyle(Font.BOLD); 106 107 cParagraph link = new cParagraph(); 108 link.setText(" - http://www.columbamail.org"); 109 link.setTextAlignment(cParagraph.LEFT); 110 link.setLeftMargin(columbaParagraph.getSize(new cCmUnit(100)).getWidth()); 111 link.setColor(Color.lightGray); 112 113 cPrintVariable date = new cPrintVariable(); 114 date.setCodeString("%DATE_TODAY%"); 115 date.setTextAlignment(cParagraph.RIGHT); 116 date.setColor(Color.lightGray); 117 118 cHGroup headerText = new cHGroup(); 119 headerText.add(columbaParagraph); 120 headerText.add(link); 121 headerText.add(date); 122 123 cLine headerLine = new cLine(); 124 125 headerLine.setThickness(1); 126 headerLine.setColor(Color.lightGray); 127 headerLine.setTopMargin(new cCmUnit(0.1)); 128 129 cVGroup header = new cVGroup(); 130 header.add(headerText); 131 header.add(headerLine); 132 header.setBottomMargin(new cCmUnit(0.5)); 133 134 mailHeader = header; 135 136 cPrintVariable footer = new cPrintVariable(); 138 footer.setTextAlignment(cParagraph.CENTER); 139 footer.setCodeString("%PAGE_NR% / %PAGE_COUNT%"); 140 footer.setTopMargin(new cCmUnit(0.5)); 141 footer.setColor(Color.lightGray); 142 143 mailFooter = footer; 144 145 mailDateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, 147 DateFormat.MEDIUM); 148 } 149 150 public cPrintObject getMailHeader() { 151 return mailHeader; 152 } 153 154 public cPrintObject getMailFooter() { 155 return mailFooter; 156 } 157 158 public String [] getHeaderKeys() { 159 return headerKeys; 160 } 161 162 public DateFormat getMailDateFormat() { 163 return mailDateFormat; 164 } 165 166 169 public void updatedGUI() throws Exception { 170 } 171 172 178 public void execute(IWorkerStatusController worker) 179 throws Exception { 180 184 IMailFolderCommandReference r = (IMailFolderCommandReference) getReference(); 185 186 Object [] uids = r.getUids(); 188 IMailbox srcFolder = (IMailbox) r.getSourceFolder(); 189 190 ((StatusObservableImpl) srcFolder.getObservable()).setWorker(worker); 192 193 for (int j = 0; j < uids.length; j++) { 195 Object uid = uids[j]; 196 LOG.info("Printing UID=" + uid); 197 198 Header header = srcFolder.getHeaderFields(uids[j], getHeaderKeys()); 199 200 setupMessageBodyPart(uid, srcFolder, worker); 201 202 203 204 205 cDocument messageDoc = new cDocument(); 207 messageDoc.setHeader(getMailHeader()); 208 messageDoc.setFooter(getMailFooter()); 209 210 String [] headerKeys = getHeaderKeys(); 211 cParagraph hKey; 212 cParagraph hValue; 213 cHGroup hLine; 214 Object value; 215 216 for (int i = 0; i < Array.getLength(headerKeys); i++) { 218 hKey = new cParagraph(); 219 220 hKey.setText(MailResourceLoader.getString("header", 223 headerKeys[i].toLowerCase())); 224 hKey.setFontStyle(Font.BOLD); 225 226 hValue = new cParagraph(); 227 228 233 value = header.get(headerKeys[i]); 239 240 if (headerKeys[i].equalsIgnoreCase(dateHeaderKey)) { 241 SimpleDateFormat formatter = new SimpleDateFormat ( 243 "d MMM yyyy HH:mm:ss Z"); 244 String dateStr = (String ) value; 245 246 ParsePosition pos = new ParsePosition (dateStr.indexOf(',') + 1); 249 Date d = formatter.parse((String ) value, pos); 250 251 if (d != null) { 252 hValue.setText(getMailDateFormat().format(d)); 253 } else { 254 hValue.setText((String ) value); 256 } 257 } else { 258 hValue.setText((String ) value); 259 } 260 261 hValue.setLeftMargin(new cCmUnit(3.0)); 262 263 hLine = new cHGroup(); 264 hLine.add(hKey); 265 hLine.add(hValue); 266 267 messageDoc.appendPrintObject(hLine); 268 } 269 270 AttachmentModel attMod = new AttachmentModel(); 272 attMod.setCollection(srcFolder.getMimePartTree(uid)); 273 274 List attachments = attMod.getDisplayedMimeParts(); 275 276 for (int i = 0; i < attachments.size(); i++) { 277 StreamableMimePart mp = (StreamableMimePart) attachments.get(i); 278 if (mp.getHeader().getFileName() != null) { 279 hKey = new cParagraph(); 282 hKey.setText(MailResourceLoader.getString("header", 283 attHeaderKey)); 284 hKey.setFontStyle(Font.BOLD); 285 286 hValue = new cParagraph(); 287 hValue.setText(mp.getHeader().getFileName()); 288 hValue.setLeftMargin(new cCmUnit(3.0)); 289 290 hLine = new cHGroup(); 291 hLine.add(hKey); 292 hLine.add(hValue); 293 294 messageDoc.appendPrintObject(hLine); 295 } 296 } 297 298 String mimesubtype = bodyHeader.getMimeType().getSubtype(); 300 301 if (mimesubtype.equals("html")) { 302 messageDoc.appendPrintObject(getHTMLBodyPrintObject()); 303 } else { 304 messageDoc.appendPrintObject(getPlainBodyPrintObject()); 305 } 306 307 messageDoc.print(); 309 } 310 311 } 313 314 324 private cPrintObject getPlainBodyPrintObject() 325 throws IOException { 326 String decodedBody = getDecodedMessageBody(); 328 329 cParagraph printBody = new cParagraph(); 331 printBody.setTopMargin(new cCmUnit(1.0)); 332 printBody.setText(decodedBody); 333 334 return printBody; 335 } 336 337 342 protected boolean isScalingAllowed() { 343 XmlElement options = Config.getInstance().get("options").getElement("/options"); 344 XmlElement printer = null; 345 346 if (options != null) { 347 printer = options.getElement("/printer"); 348 } 349 350 if (printer == null) { 352 LOG.info("printer config node not found - creating new"); 354 printer = new XmlElement("printer"); 355 printer.addAttribute("allow_scaling", "true"); 356 357 if (options != null) { 359 LOG.info("storing new printer config node"); 360 options.addElement(printer); 361 } 362 } 363 364 return Boolean.valueOf(printer.getAttribute("allow_scaling", "true")) 365 .booleanValue(); 366 } 367 368 377 private cPrintObject getHTMLBodyPrintObject() 378 throws IOException { 379 String decodedBody = getDecodedMessageBody(); 381 382 String validated = HtmlParser.validateHTMLString(decodedBody); 384 385 try { 386 File tempFile = TempFileStore.createTempFileWithSuffix("html"); 388 DiskIO.saveStringInFile(tempFile, validated); 389 390 URL url = tempFile.toURL(); 391 392 boolean allowScaling = isScalingAllowed(); 393 cHTMLPart htmlBody = new cHTMLPart(allowScaling); 394 395 htmlBody.setTopMargin(new cCmUnit(1.0)); 397 htmlBody.setHTML(url); 398 399 return htmlBody; 400 } catch (MalformedURLException e) { 401 LOG.warning("Error loading html for print: " + e.getMessage()); 402 403 return null; 404 } catch (IOException e) { 405 LOG.warning("Error loading html for print: " + e.getMessage()); 406 407 return null; 408 } 409 } 410 411 419 private String getDecodedMessageBody() 420 throws IOException { 421 int encoding = bodyHeader.getContentTransferEncoding(); 422 423 switch (encoding) { 424 case MimeHeader.QUOTED_PRINTABLE: { 425 bodyStream = new QuotedPrintableDecoderInputStream(bodyStream); 426 427 break; 428 } 429 430 case MimeHeader.BASE64: { 431 bodyStream = new Base64DecoderInputStream(bodyStream); 432 433 break; 434 } 435 } 436 437 if (charset == null) { 439 try { 440 charset = Charset.forName(bodyHeader.getContentParameter("charset")); 442 } catch (Exception ex) { 443 charset = Charset.forName(System.getProperty("file.encoding")); 445 } 446 } 447 448 bodyStream = new CharsetDecoderInputStream(bodyStream, charset); 449 450 return StreamUtils.readCharacterStream(bodyStream).toString(); 451 } 452 453 465 private void setupMessageBodyPart(Object uid, IMailbox srcFolder, 466 IWorkerStatusController worker) throws Exception { 467 XmlElement html = MailConfig.getInstance().getMainFrameOptionsConfig() 469 .getRoot().getElement("/options/html"); 470 471 MimeTree mimePartTree = srcFolder.getMimePartTree(uid); 473 474 MimePart bodyPart = null; 475 476 if (Boolean.valueOf(html.getAttribute("prefer")).booleanValue()) { 477 bodyPart = mimePartTree.getFirstTextPart("html"); 478 } else { 479 bodyPart = mimePartTree.getFirstTextPart("plain"); 480 } 481 482 if (bodyPart == null) { 483 bodyHeader = new MimeHeader(); 484 bodyStream = new ByteArrayInputStream (new byte[0]); 485 } else { 486 bodyHeader = bodyPart.getHeader(); 487 bodyStream = srcFolder.getMimePartBodyStream(uid, bodyPart.getAddress()); 488 } 489 } 490 491 } 492 | Popular Tags |