src/org/sonews/storage/DrupalMessage.java
changeset 104 b4c8a2760d6f
parent 103 a788bf0e1080
child 105 d566d08c20d6
     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);