1.1 --- a/src/org/sonews/storage/DrupalMessage.java Thu Oct 20 10:50:58 2011 +0200
1.2 +++ b/src/org/sonews/storage/DrupalMessage.java Fri Oct 21 17:35:29 2011 +0200
1.3 @@ -42,13 +42,19 @@
1.4 import javax.mail.internet.MimeBodyPart;
1.5 import javax.mail.internet.MimeMessage;
1.6 import javax.mail.internet.MimeMultipart;
1.7 +import javax.xml.parsers.DocumentBuilder;
1.8 +import javax.xml.parsers.DocumentBuilderFactory;
1.9 +import javax.xml.parsers.ParserConfigurationException;
1.10 import javax.xml.transform.Transformer;
1.11 import javax.xml.transform.TransformerException;
1.12 import javax.xml.transform.TransformerFactory;
1.13 +import javax.xml.transform.dom.DOMSource;
1.14 import javax.xml.transform.stream.StreamResult;
1.15 import javax.xml.transform.stream.StreamSource;
1.16 import org.sonews.daemon.NNTPConnection;
1.17 import org.sonews.util.io.Resource;
1.18 +import org.w3c.dom.Document;
1.19 +import org.xml.sax.SAXException;
1.20
1.21 /**
1.22 * This is MimeMessage which enables custom Message-ID header
1.23 @@ -71,14 +77,32 @@
1.24 private String messageID;
1.25 private Long parentID;
1.26 private Long groupID;
1.27 + private TransformerFactory transformerFactory;
1.28 + private DocumentBuilderFactory documentBuilderFactory;
1.29 +
1.30 + /**
1.31 + * Initializes XML factories (Transformer, DocumentBuilder).
1.32 + */
1.33 + private void initFactories() {
1.34 + transformerFactory = TransformerFactory.newInstance();
1.35 + documentBuilderFactory = DocumentBuilderFactory.newInstance();
1.36 + /**
1.37 + * Komentáře nás nepotřebujeme
1.38 + * (a museli bychom je brát v úvahu při dělení odstavců:
1.39 + * v současné verzi XSLT odstavcovače by nám případný komentář
1.40 + * rozdělil text na dva odstavce, přestože to má být odstavec jede).
1.41 + */
1.42 + documentBuilderFactory.setIgnoringComments(true);
1.43 + }
1.44
1.45 /**
1.46 * Constructs MIME message from SQL result.
1.47 * @param rs ResultSet containing message data. No {@link ResultSet#next()} will be called, just values from current row will be read.
1.48 * @param constructBody true if whole message should be constructed | false if we need only message headers (body will be dummy).
1.49 */
1.50 - public DrupalMessage(ResultSet rs, String myDomain, boolean constructBody) throws SQLException, UnsupportedEncodingException, MessagingException, TransformerException, IOException {
1.51 + public DrupalMessage(ResultSet rs, String myDomain, boolean constructBody) throws SQLException, UnsupportedEncodingException, MessagingException, TransformerException, IOException, ParserConfigurationException, SAXException {
1.52 super(Session.getDefaultInstance(System.getProperties()));
1.53 + initFactories();
1.54
1.55 groupID = rs.getLong("group_id");
1.56 addHeader("Message-id", constructMessageId(rs.getInt("id"), groupID, rs.getString("group_name"), myDomain));
1.57 @@ -135,9 +159,10 @@
1.58 */
1.59 public DrupalMessage(Article article) throws MessagingException {
1.60 super(Session.getDefaultInstance(System.getProperties()), serializeArticle(article));
1.61 + initFactories();
1.62
1.63 String[] parentHeaders = getHeader("In-Reply-To");
1.64 - if (parentHeaders.length == 1) {
1.65 + if (parentHeaders != null && parentHeaders.length == 1) {
1.66 String parentMessageID = parentHeaders[0];
1.67 parentID = parseArticleID(parentMessageID);
1.68 groupID = parseGroupID(parentMessageID);
1.69 @@ -162,8 +187,7 @@
1.70
1.71 private String readPlainText(ResultSet rs, String xhtmlText) {
1.72 try {
1.73 - TransformerFactory tf = TransformerFactory.newInstance();
1.74 - Transformer textTransformer = tf.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeTextPart.xsl")));
1.75 + Transformer textTransformer = transformerFactory.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeTextPart.xsl")));
1.76
1.77 StringReader input = new StringReader(xhtmlText);
1.78 StringWriter output = new StringWriter(xhtmlText.length());
1.79 @@ -179,34 +203,37 @@
1.80 }
1.81 }
1.82
1.83 - private String readXhtmlText(String text, String subject, long parentId, String urlBase, String wwwRead, String wwwPost) throws TransformerException, IOException {
1.84 + private DOMSource readDOM(String xml) throws ParserConfigurationException, SAXException, IOException {
1.85 + DocumentBuilder db = documentBuilderFactory.newDocumentBuilder();
1.86 + Document d = db.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
1.87 + return new DOMSource(d);
1.88 + }
1.89 +
1.90 + private String readXhtmlText(String text, String subject, long parentId, String urlBase, String wwwRead, String wwwPost) throws TransformerException, IOException, ParserConfigurationException, SAXException {
1.91 /**
1.92 * TODO:
1.93 - * - znovupoužívat XSL transformér
1.94 + * - znovupoužívat XSL transformér (nejen v instanci)
1.95 * - používat cache, ukládat si vygenerované články
1.96 */
1.97 String inputText = makeSimpleXHTML(text);
1.98
1.99 - TransformerFactory tf = TransformerFactory.newInstance();
1.100 - Transformer paragraphTransformer = tf.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeXhtmlPart-make-paragraphs.xsl")));
1.101 + Transformer paragraphTransformer = transformerFactory.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeXhtmlPart-make-paragraphs.xsl")));
1.102
1.103 String paragraphedText;
1.104 boolean tidyWasUsed = false;
1.105 try {
1.106 - StringReader input = new StringReader(inputText);
1.107 StringWriter output = new StringWriter(2 * inputText.length());
1.108 - paragraphTransformer.transform(new StreamSource(input), new StreamResult(output));
1.109 + paragraphTransformer.transform(readDOM(inputText), new StreamResult(output));
1.110 paragraphedText = output.toString();
1.111 } catch (Exception e) {
1.112 log.log(Level.FINER, "HTML input was shitty – Tidy had to be called.", e);
1.113 - StringReader input = new StringReader(tidyXhtml(inputText));
1.114 StringWriter output = new StringWriter(2 * inputText.length());
1.115 - paragraphTransformer.transform(new StreamSource(input), new StreamResult(output));
1.116 + paragraphTransformer.transform(readDOM(tidyXhtml(inputText)), new StreamResult(output));
1.117 paragraphedText = output.toString();
1.118 tidyWasUsed = true;
1.119 }
1.120
1.121 - Transformer xhtmlTransformer = tf.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeXhtmlPart.xsl")));
1.122 + Transformer xhtmlTransformer = transformerFactory.newTransformer(new StreamSource(Resource.getAsStream("helpers/mimeXhtmlPart.xsl")));
1.123 xhtmlTransformer.setParameter("isRoot", (parentId == 0));
1.124 xhtmlTransformer.setParameter("title", subject);
1.125 xhtmlTransformer.setParameter("urlBase", urlBase);