diff options
author | David A. Madore <david+git@madore.org> | 2011-08-31 17:23:45 +0200 |
---|---|---|
committer | David A. Madore <david+git@madore.org> | 2011-08-31 17:23:45 +0200 |
commit | 1565d0be33cb4d83ee6fa63081bf09ae0a68693d (patch) | |
tree | 723b4a70005e326dd56a71c3cb6cd632cb47ed7d | |
parent | 9d7354465ab229641c2da9cfe93584e1c21c6fd8 (diff) | |
download | damlengine-1565d0be33cb4d83ee6fa63081bf09ae0a68693d.tar.gz damlengine-1565d0be33cb4d83ee6fa63081bf09ae0a68693d.tar.bz2 damlengine-1565d0be33cb4d83ee6fa63081bf09ae0a68693d.zip |
RSS feed generator.
-rw-r--r-- | org/madore/damlengine/DamlEngine.java | 4 | ||||
-rw-r--r-- | org/madore/damlengine/WeblogDatabaseConnection.java | 1 | ||||
-rw-r--r-- | org/madore/damlengine/WeblogRSS.java | 152 |
3 files changed, 157 insertions, 0 deletions
diff --git a/org/madore/damlengine/DamlEngine.java b/org/madore/damlengine/DamlEngine.java index 070cbab..e54ee86 100644 --- a/org/madore/damlengine/DamlEngine.java +++ b/org/madore/damlengine/DamlEngine.java @@ -19,6 +19,10 @@ public final class DamlEngine { public static final String XML_NS = XMLConstants.XML_NS_URI; public static final String XHTML_NS = "http://www.w3.org/1999/xhtml"; public static final String DAML_NS = "http://www.madore.org/~david/NS/daml/"; + public static final String RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + public static final String RSS10_NS = "http://purl.org/rss/1.0/"; + public static final String DUBLINCORE_NS = "http://purl.org/dc/elements/1.1/"; + public static final String SYNDICATION_NS = "http://purl.org/rss/1.0/modules/syndication/"; public static final class DamlNSMapping implements NamespaceContext { // This is used for XPath resolution (_not_ for parsing the document). diff --git a/org/madore/damlengine/WeblogDatabaseConnection.java b/org/madore/damlengine/WeblogDatabaseConnection.java index a1dfc1f..c88f5a8 100644 --- a/org/madore/damlengine/WeblogDatabaseConnection.java +++ b/org/madore/damlengine/WeblogDatabaseConnection.java @@ -23,6 +23,7 @@ public final class WeblogDatabaseConnection { dbProps.setProperty("ssl", "true"); dbProps.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory"); conn = (new Driver()).connect(dbUrl, dbProps); + conn.createStatement().execute("SET TIME ZONE 0"); } return conn; } diff --git a/org/madore/damlengine/WeblogRSS.java b/org/madore/damlengine/WeblogRSS.java new file mode 100644 index 0000000..c08991c --- /dev/null +++ b/org/madore/damlengine/WeblogRSS.java @@ -0,0 +1,152 @@ +package org.madore.damlengine; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import javax.xml.parsers.DocumentBuilder; +import org.w3c.dom.*; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSParser; +import org.w3c.dom.ls.LSSerializer; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSOutput; + +public final class WeblogRSS { + + private WeblogRSS() { // Forbid instantiation + throw new AssertionError("WeblogRSS cannot be instantiated"); + } + + public static void main(String[] args) + throws Exception { + + final Connection conn = WeblogDatabaseConnection.getConnection(); + + final PreparedStatement selSt + = conn.prepareStatement("SELECT id , edate , to_char(cdate,'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') , lang , title , content FROM entries ORDER BY id DESC LIMIT 15"); + + final ResultSet selRes = selSt.executeQuery(); + + final DocumentBuilder db = DamlEngine.GetDocumentBuilder.db; + + final DOMImplementationLS domi + = (DOMImplementationLS)(db.getDOMImplementation()); + LSSerializer ser = domi.createLSSerializer(); + ser.getDomConfig().setParameter("xml-declaration", true); + LSParser par = domi.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + + final LSOutput out = domi.createLSOutput(); + out.setByteStream(System.out); + out.setEncoding("UTF-8"); + + Document rssDoc = db.newDocument(); + Element rssRoot = rssDoc.createElementNS(DamlEngine.RDF_NS, "rdf:RDF"); + rssDoc.appendChild(rssRoot); + // rssDoc.appendChild(rssDoc.createTextNode("\n")); + + rssRoot.setAttributeNS(DamlEngine.XMLNS_NS, "xmlns:rdf", DamlEngine.RDF_NS); + rssRoot.setAttributeNS(DamlEngine.XMLNS_NS, "xmlns", DamlEngine.RSS10_NS); + rssRoot.setAttributeNS(DamlEngine.XMLNS_NS, "xmlns:dc", DamlEngine.DUBLINCORE_NS); + rssRoot.setAttributeNS(DamlEngine.XMLNS_NS, "xmlns:sy", DamlEngine.SYNDICATION_NS); + rssRoot.setAttributeNS(DamlEngine.XML_NS, "xml:lang", "en"); + rssRoot.appendChild(rssDoc.createTextNode("\n")); + + Element channel = rssDoc.createElementNS(DamlEngine.RSS10_NS, "channel"); + rssRoot.appendChild(channel); + rssRoot.appendChild(rssDoc.createTextNode("\n")); + channel.setAttributeNS(DamlEngine.RDF_NS, "rdf:about", "http://www.madore.org/~david/weblog/"); + channel.appendChild(rssDoc.createTextNode("\n")); + + Element chanTitle = rssDoc.createElementNS(DamlEngine.RSS10_NS, "title"); + channel.appendChild(chanTitle); + channel.appendChild(rssDoc.createTextNode("\n")); + chanTitle.appendChild(rssDoc.createTextNode("David Madore's WebLog")); + Element syUpdatePeriod = rssDoc.createElementNS(DamlEngine.SYNDICATION_NS, "sy:updatePeriod"); + channel.appendChild(syUpdatePeriod); + channel.appendChild(rssDoc.createTextNode("\n")); + syUpdatePeriod.appendChild(rssDoc.createTextNode("hourly")); + Element syUpdateFrequency = rssDoc.createElementNS(DamlEngine.SYNDICATION_NS, "sy:updateFrequency"); + channel.appendChild(syUpdateFrequency); + channel.appendChild(rssDoc.createTextNode("\n")); + syUpdateFrequency.appendChild(rssDoc.createTextNode("3")); + Element syUpdateBase = rssDoc.createElementNS(DamlEngine.SYNDICATION_NS, "sy:updateBase"); + channel.appendChild(syUpdateBase); + channel.appendChild(rssDoc.createTextNode("\n")); + syUpdateBase.appendChild(rssDoc.createTextNode("2003-05-01T10:00:00Z")); + Element chanItems = rssDoc.createElementNS(DamlEngine.RSS10_NS, "items"); + channel.appendChild(chanItems); + channel.appendChild(rssDoc.createTextNode("\n")); + chanItems.appendChild(rssDoc.createTextNode("\n")); + Element itemsSeq = rssDoc.createElementNS(DamlEngine.RDF_NS, "rdf:Seq"); + chanItems.appendChild(itemsSeq); + chanItems.appendChild(rssDoc.createTextNode("\n")); + itemsSeq.appendChild(rssDoc.createTextNode("\n")); + + while ( selRes.next() ) { + int id = selRes.getInt(1); + String date = selRes.getString(2); + String cdate = selRes.getString(3); + String lang = selRes.getString(4); + String title = selRes.getString(5); + String contentXml = selRes.getString(6); + Matcher matcher = Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})$").matcher(date); + if ( ! matcher.matches() ) + throw new IllegalArgumentException("entry "+id+" has badly formed date"); + String yearStr = matcher.group(1); + String monthStr = matcher.group(2); + // String dayStr = matcher.group(3); + String numberStr = String.format("%04d",id); + String aboutUri = "http://www.madore.org/~david/weblog/" + + "#d." + date + "." + numberStr; + String linkUri = "http://www.madore.org/~david/weblog/" + + yearStr + "-" + monthStr + ".html" + + "#d." + date + "." + numberStr; + Element li = rssDoc.createElementNS(DamlEngine.RDF_NS, "rdf:li"); + itemsSeq.appendChild(li); + itemsSeq.appendChild(rssDoc.createTextNode("\n")); + li.setAttributeNS(DamlEngine.RDF_NS, "rdf:resource", + aboutUri); + Element item = rssDoc.createElementNS(DamlEngine.RSS10_NS, "item"); + rssRoot.appendChild(item); + rssRoot.appendChild(rssDoc.createTextNode("\n")); + item.setAttributeNS(DamlEngine.RDF_NS, "rdf:about", + aboutUri); + item.setAttributeNS(DamlEngine.XML_NS, "xml:lang", lang); + item.appendChild(rssDoc.createTextNode("\n")); + Element itemTitle = rssDoc.createElementNS(DamlEngine.RSS10_NS, "title"); + item.appendChild(itemTitle); + item.appendChild(rssDoc.createTextNode("\n")); + itemTitle.appendChild(rssDoc.createTextNode(title)); + Element itemLink = rssDoc.createElementNS(DamlEngine.RSS10_NS, "link"); + item.appendChild(itemLink); + item.appendChild(rssDoc.createTextNode("\n")); + itemLink.appendChild(rssDoc.createTextNode(linkUri)); + Element itemDate = rssDoc.createElementNS(DamlEngine.DUBLINCORE_NS, "dc:date"); + item.appendChild(itemDate); + item.appendChild(rssDoc.createTextNode("\n")); + itemDate.appendChild(rssDoc.createTextNode(cdate)); + LSInput input = domi.createLSInput(); + input.setStringData(contentXml); + Document temp = par.parse(input); + String contentStr = temp.getDocumentElement().getTextContent(); + int bound; + try { + bound = Character.offsetByCodePoints(contentStr, 0, 160); + } catch (IndexOutOfBoundsException e) { + bound = contentStr.length(); + } + String descrStr = contentStr.substring(0, bound).replace("\n"," "); + Element itemDescr = rssDoc.createElementNS(DamlEngine.RSS10_NS, "description"); + item.appendChild(itemDescr); + item.appendChild(rssDoc.createTextNode("\n")); + itemDescr.appendChild(rssDoc.createTextNode(descrStr)); + } + + ser.write(rssDoc, out); + out.getByteStream().write("\n".getBytes("UTF-8")); + + } + +} |