summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org/madore/damlengine/Context.java3
-rw-r--r--org/madore/damlengine/DamlEngine.java24
-rw-r--r--org/madore/damlengine/TodoElement.java1
-rw-r--r--org/madore/damlengine/TodoEntryElement.java7
-rw-r--r--org/madore/damlengine/TodoWeblogSelectElement.java54
-rw-r--r--org/madore/damlengine/TodoWrefAttr.java21
-rw-r--r--org/madore/damlengine/WeblogDatabaseConnection.java30
-rw-r--r--org/madore/damlengine/WeblogPopulate.java26
-rw-r--r--org/madore/damlengine/WeblogSelect.java43
-rw-r--r--org/madore/damlengine/WeblogSummary.java53
10 files changed, 227 insertions, 35 deletions
diff --git a/org/madore/damlengine/Context.java b/org/madore/damlengine/Context.java
index d001389..8b62b6b 100644
--- a/org/madore/damlengine/Context.java
+++ b/org/madore/damlengine/Context.java
@@ -1,6 +1,7 @@
package org.madore.damlengine;
import java.util.ArrayList;
+import java.util.Set;
import org.w3c.dom.*;
public class Context implements Cloneable {
@@ -26,6 +27,8 @@ public class Context implements Cloneable {
public GeneralContext gc;
public static abstract class WeblogSelectionContext {
+ public Set<Integer> sel;
+ public ArrayList<String> xmlData;
}
public static class WeblogMonthSelectionContext
diff --git a/org/madore/damlengine/DamlEngine.java b/org/madore/damlengine/DamlEngine.java
index bf2049d..da49aeb 100644
--- a/org/madore/damlengine/DamlEngine.java
+++ b/org/madore/damlengine/DamlEngine.java
@@ -6,6 +6,7 @@ import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
// import org.xml.sax.EntityResolver;
import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl;
@@ -40,6 +41,22 @@ public final class DamlEngine {
}
}
+ public static final class GetDocumentBuilder {
+ static final DocumentBuilder db;
+ static {
+ final Resolver resolver = new Resolver();
+ final DocumentBuilderFactory dbf = new DocumentBuilderFactoryImpl();
+ dbf.setNamespaceAware(true);
+ dbf.setValidating(false);
+ try {
+ db = dbf.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ db.setEntityResolver(resolver);
+ }
+ }
+
private DamlEngine() { // Forbid instantiation
throw new AssertionError("DamlEngine cannot be instantiated");
}
@@ -73,12 +90,7 @@ public final class DamlEngine {
Context.WeblogSelectionContext wsc)
throws Exception {
- final Resolver resolver = new Resolver();
- final DocumentBuilderFactory dbf = new DocumentBuilderFactoryImpl();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- final DocumentBuilder db = dbf.newDocumentBuilder();
- db.setEntityResolver(resolver);
+ final DocumentBuilder db = GetDocumentBuilder.db;
Document doc = db.parse(fname);
processDocument(doc, wsc);
diff --git a/org/madore/damlengine/TodoElement.java b/org/madore/damlengine/TodoElement.java
index 94867cc..320724c 100644
--- a/org/madore/damlengine/TodoElement.java
+++ b/org/madore/damlengine/TodoElement.java
@@ -61,6 +61,7 @@ public abstract class TodoElement extends TodoItem {
damlFactories.put("smiley-cry", new TodoSmileyElement.Factory(TodoSmileyElement.Type.CRY));
damlFactories.put("smiley-evil", new TodoSmileyElement.Factory(TodoSmileyElement.Type.EVIL));
damlFactories.put("img-a", new TodoImgAElement.Factory());
+ damlFactories.put("weblog-select", new TodoWeblogSelectElement.Factory());
}
protected final Element node;
diff --git a/org/madore/damlengine/TodoEntryElement.java b/org/madore/damlengine/TodoEntryElement.java
index 8b38881..78bffd1 100644
--- a/org/madore/damlengine/TodoEntryElement.java
+++ b/org/madore/damlengine/TodoEntryElement.java
@@ -24,7 +24,8 @@ public final class TodoEntryElement extends TodoDefaultElement {
@Override
public void handleNodeOnly() {
- if ( ! ( caller instanceof TodoWeblogElement ) )
+ if ( ! ( caller instanceof TodoWeblogElement
+ || caller instanceof TodoWeblogSelectElement ) )
throw new IllegalArgumentException("entry node can only be child of weblog node");
Element div = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "div");
@@ -35,11 +36,11 @@ public final class TodoEntryElement extends TodoDefaultElement {
String entryNumberStr = node.getAttributeNS(null, "number");
if ( ! Pattern.matches("^\\d{4}$", entryNumberStr) )
- throw new IllegalArgumentException("title number attribute must be of the form NNNN");
+ throw new IllegalArgumentException("entry number attribute must be of the form NNNN");
String entryDateStr = node.getAttributeNS(null, "date");
Matcher entryDateMatcher = Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})$").matcher(entryDateStr);
if ( ! entryDateMatcher.matches() )
- throw new IllegalArgumentException("title date attribute must be of the form YYYY-MM-DD");
+ throw new IllegalArgumentException("entry date attribute must be of the form YYYY-MM-DD");
String entryYearStr = entryDateMatcher.group(1);
String entryMonthStr = entryDateMatcher.group(2);
String entryDayStr = entryDateMatcher.group(3);
diff --git a/org/madore/damlengine/TodoWeblogSelectElement.java b/org/madore/damlengine/TodoWeblogSelectElement.java
new file mode 100644
index 0000000..145b938
--- /dev/null
+++ b/org/madore/damlengine/TodoWeblogSelectElement.java
@@ -0,0 +1,54 @@
+package org.madore.damlengine;
+
+import java.util.ArrayList;
+import org.w3c.dom.*;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSParser;
+import org.w3c.dom.ls.LSInput;
+
+public final class TodoWeblogSelectElement extends TodoDefaultElement {
+
+ public static class Factory extends TodoElement.Factory {
+ @Override
+ public TodoWeblogSelectElement newItem(Element node,
+ Context ctx,
+ TodoItem caller) {
+ return new TodoWeblogSelectElement(node, ctx, caller);
+ }
+ }
+
+ public TodoWeblogSelectElement(Element node,
+ Context ctx,
+ TodoItem caller) {
+ super(node, ctx, caller);
+ }
+
+ @Override
+ public void handleNodeOnly() {
+ if ( ctx.wsc == null ) {
+ throw new IllegalStateException("weblog-select element encountered with no weblog selection state");
+ }
+ final DOMImplementationLS domi
+ = (DOMImplementationLS)ctx.doc.getImplementation();
+ LSParser par = domi.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
+ ArrayList<TodoElement> toProcess
+ = new ArrayList<TodoElement>(ctx.wsc.xmlData.size());
+ for ( String str : ctx.wsc.xmlData ) {
+ LSInput input = domi.createLSInput();
+ input.setStringData(str);
+ // Xerces2 does not implement parseWithContext() :-(
+ // Node newNode = par.parseWithContext(input, node,
+ // LSParser.ACTION_INSERT_BEFORE);
+ Document temp = par.parse(input);
+ Node newNode = ctx.doc.adoptNode(temp.getDocumentElement());
+ node.getParentNode().insertBefore(newNode, node);
+ TodoElement it
+ = TodoElement.getTodoElement((Element)newNode,
+ this.ctx, this);
+ toProcess.add(it);
+ }
+ node.getParentNode().removeChild(node);
+ this.ownerDeque.registerAtStart(toProcess);
+ }
+
+}
diff --git a/org/madore/damlengine/TodoWrefAttr.java b/org/madore/damlengine/TodoWrefAttr.java
index 60fec1d..df30d99 100644
--- a/org/madore/damlengine/TodoWrefAttr.java
+++ b/org/madore/damlengine/TodoWrefAttr.java
@@ -33,10 +33,8 @@ public class TodoWrefAttr extends TodoAttr {
String wrefNumberStr = wrefMatcher.group(4);
String wrefSupplementStr = wrefMatcher.group(5);
String targetFile = "";
- if ( ctx.wsc != null
- && ctx.wsc instanceof Context.WeblogMonthSelectionContext
- && wrefYearStr.equals(((Context.WeblogMonthSelectionContext)ctx.wsc).year)
- && wrefMonthStr.equals(((Context.WeblogMonthSelectionContext)ctx.wsc).month) )
+ if ( ctx.wsc != null && ctx.wsc.sel != null
+ && ctx.wsc.sel.contains(new Integer(wrefNumberStr)) )
targetFile = "";
else
targetFile = ((ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"))
@@ -48,6 +46,21 @@ public class TodoWrefAttr extends TodoAttr {
this.owner.setAttributeNS(null, "href", target);
if ( ! this.owner.hasAttributeNS(null, "class") )
this.owner.setAttributeNS(null, "class", "weblog-internal-link");
+ if ( wrefSupplementStr.equals("")
+ && ! this.owner.hasAttributeNS(null, "title") ) {
+ WeblogSummary wsum = WeblogSummary.getSummary();
+ if ( wsum != null && wsum.entries != null ) {
+ WeblogSummary.EntrySummary esum
+ = wsum.entries.get(new Integer(wrefNumberStr));
+ if ( esum != null ) {
+ if ( ! ((wrefYearStr+"-"+wrefMonthStr+"-"+wrefDayStr)
+ .equals(esum.date)) )
+ System.err.println("warning: date mismatch for reference to entry "+wrefNumberStr);
+ if ( esum.title != null )
+ this.owner.setAttributeNS(null, "title", esum.title);
+ }
+ }
+ }
}
}
diff --git a/org/madore/damlengine/WeblogDatabaseConnection.java b/org/madore/damlengine/WeblogDatabaseConnection.java
new file mode 100644
index 0000000..a1dfc1f
--- /dev/null
+++ b/org/madore/damlengine/WeblogDatabaseConnection.java
@@ -0,0 +1,30 @@
+package org.madore.damlengine;
+
+import java.util.Properties;
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.postgresql.Driver;
+
+public final class WeblogDatabaseConnection {
+
+ private WeblogDatabaseConnection() { // Forbid instantiation
+ throw new AssertionError("WeblogDatabaseConnection cannot be instantiated");
+ }
+
+ public static Connection conn;
+
+ public static Connection getConnection()
+ throws SQLException {
+ if ( conn == null ) {
+ final String dbUrl = "jdbc:postgresql://localhost/weblog";
+ final Properties dbProps = new Properties();
+ dbProps.setProperty("user", "david");
+ dbProps.setProperty("password", "IHATETHISWHYCANTIUSEUNIXDOMAINSOCKETS");
+ dbProps.setProperty("ssl", "true");
+ dbProps.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory");
+ conn = (new Driver()).connect(dbUrl, dbProps);
+ }
+ return conn;
+ }
+
+}
diff --git a/org/madore/damlengine/WeblogPopulate.java b/org/madore/damlengine/WeblogPopulate.java
index 18e46c3..24c61dc 100644
--- a/org/madore/damlengine/WeblogPopulate.java
+++ b/org/madore/damlengine/WeblogPopulate.java
@@ -1,21 +1,16 @@
package org.madore.damlengine;
-import java.util.Properties;
import java.util.regex.Pattern;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
// import org.xml.sax.EntityResolver;
-import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl;
-import org.apache.xerces.dom.DOMImplementationSourceImpl;
-import org.postgresql.Driver;
public final class WeblogPopulate {
@@ -33,33 +28,20 @@ public final class WeblogPopulate {
public static void main(String[] args)
throws Exception {
- final Resolver resolver = new Resolver();
- final DocumentBuilderFactory dbf = new DocumentBuilderFactoryImpl();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- final DocumentBuilder db = dbf.newDocumentBuilder();
- db.setEntityResolver(resolver);
+ final DocumentBuilder db = DamlEngine.GetDocumentBuilder.db;
if ( args.length == 0 ) {
System.err.println("expecting filename as argument");
}
- final DOMImplementationSource domisrc
- = new DOMImplementationSourceImpl();
final DOMImplementationLS domi
- = (DOMImplementationLS)(domisrc.getDOMImplementation("LS"));
+ = (DOMImplementationLS)(db.getDOMImplementation());
LSSerializer ser = domi.createLSSerializer();
ser.getDomConfig().setParameter("xml-declaration", false);
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
- final String dbUrl = "jdbc:postgresql://localhost/weblog";
- final Properties dbProps = new Properties();
- dbProps.setProperty("user", "david");
- dbProps.setProperty("password", "IHATETHISWHYCANTIUSEUNIXDOMAINSOCKETS");
- dbProps.setProperty("ssl", "true");
- dbProps.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory");
- final Connection conn = (new Driver()).connect(dbUrl, dbProps);
+ final Connection conn = WeblogDatabaseConnection.getConnection();
final PreparedStatement checkSt
= conn.prepareStatement("SELECT sha1 FROM entries WHERE id=?");
@@ -103,7 +85,7 @@ public final class WeblogPopulate {
continue;
Node titleNode = (Node)(texpr.evaluate(ent, XPathConstants.NODE));
String titleTxt = (titleNode != null) ? titleNode.getTextContent() : null;
- String titleXml = ser.writeToString(titleNode);
+ String titleXml = (titleNode != null) ? ser.writeToString(titleNode) : null;
conn.setAutoCommit(false);
if ( exists ) {
System.err.println("Updating entry "+id);
diff --git a/org/madore/damlengine/WeblogSelect.java b/org/madore/damlengine/WeblogSelect.java
new file mode 100644
index 0000000..ad61cbc
--- /dev/null
+++ b/org/madore/damlengine/WeblogSelect.java
@@ -0,0 +1,43 @@
+package org.madore.damlengine;
+
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+public final class WeblogSelect {
+
+ private WeblogSelect() { // Forbid instantiation
+ throw new AssertionError("WeblogSelect cannot be instantiated");
+ }
+
+ public static void main(String[] args)
+ throws Exception {
+
+ String year = "2011";
+ String month = "08";
+
+ final Connection conn = WeblogDatabaseConnection.getConnection();
+
+ final PreparedStatement selSt
+ = conn.prepareStatement("SELECT id , content FROM entries WHERE edate LIKE ? ORDER BY id DESC");
+ selSt.setString(1,year+"-"+month+"-__");
+
+ final ResultSet selRes = selSt.executeQuery();
+ final Context.WeblogSelectionContext wsc
+ = new Context.WeblogMonthSelectionContext(year,month);
+ wsc.sel = new HashSet<Integer>();
+ wsc.xmlData = new ArrayList<String>();
+ while ( selRes.next() ) {
+ int id = selRes.getInt(1);
+ String content = selRes.getString(2);
+ wsc.sel.add(new Integer(id));
+ wsc.xmlData.add(content);
+ }
+
+ DamlEngine.fullProcess("weblog-month-template.daml", System.out, wsc);
+
+ }
+
+}
diff --git a/org/madore/damlengine/WeblogSummary.java b/org/madore/damlengine/WeblogSummary.java
new file mode 100644
index 0000000..ceaf28e
--- /dev/null
+++ b/org/madore/damlengine/WeblogSummary.java
@@ -0,0 +1,53 @@
+package org.madore.damlengine;
+
+import java.util.HashMap;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public final class WeblogSummary {
+
+ public static final class EntrySummary {
+ int id;
+ String date;
+ String title;
+ public EntrySummary(int id, String date, String title) {
+ this.id = id;
+ this.date = date;
+ this.title = title;
+ }
+ }
+
+ public HashMap<Integer,EntrySummary> entries;
+
+ private static WeblogSummary singleton;
+
+ private WeblogSummary() {
+ this.entries = new HashMap<Integer,EntrySummary>();
+ }
+
+ public static WeblogSummary getSummary() {
+ if ( singleton != null )
+ return singleton;
+ singleton = new WeblogSummary();
+ try {
+ final Connection conn = WeblogDatabaseConnection.getConnection();
+ final PreparedStatement selSt
+ = conn.prepareStatement("SELECT id , edate , title FROM entries");
+ final ResultSet selRes = selSt.executeQuery();
+ while ( selRes.next() ) {
+ int id = selRes.getInt(1);
+ String date = selRes.getString(2);
+ String title = selRes.getString(3);
+ singleton.entries.put(new Integer(id), new EntrySummary(id, date, title));
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ // Well, we'll have no summary. Too bad, but better than abort.
+ // singleton = null;
+ }
+ return singleton;
+ }
+
+}