From 4f26d86d308762f4e1a16806042e8bb4c096c2f2 Mon Sep 17 00:00:00 2001
From: "David A. Madore" <david+git@madore.org>
Date: Thu, 9 Oct 2014 16:52:22 +0200
Subject: Support <d:weblog-months-calendar /> element for automatic calendar
 generation.

---
 org/madore/damlengine/TodoElement.java             |   1 +
 .../damlengine/TodoWeblogMonthsCalendar.java       | 114 +++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 org/madore/damlengine/TodoWeblogMonthsCalendar.java

(limited to 'org/madore')

diff --git a/org/madore/damlengine/TodoElement.java b/org/madore/damlengine/TodoElement.java
index 0b2baf5..83275ad 100644
--- a/org/madore/damlengine/TodoElement.java
+++ b/org/madore/damlengine/TodoElement.java
@@ -70,6 +70,7 @@ public abstract class TodoElement extends TodoItem {
 	damlFactories.put("weblog-selection-cat-name", new TodoWeblogSelectionElement.Factory(TodoWeblogSelectionElement.Type.CATEGORY_NAME));
 	damlFactories.put("weblog-selection-single-number", new TodoWeblogSelectionElement.Factory(TodoWeblogSelectionElement.Type.SINGLE_NUMBER));
 	damlFactories.put("weblog-selection-single-title", new TodoWeblogSelectionElement.Factory(TodoWeblogSelectionElement.Type.SINGLE_TITLE));
+	damlFactories.put("weblog-months-calendar", new TodoWeblogMonthsCalendar.Factory());
 	damlFactories.put("cut-here", new TodoCutHere.Factory());
     }
 
diff --git a/org/madore/damlengine/TodoWeblogMonthsCalendar.java b/org/madore/damlengine/TodoWeblogMonthsCalendar.java
new file mode 100644
index 0000000..d9e0573
--- /dev/null
+++ b/org/madore/damlengine/TodoWeblogMonthsCalendar.java
@@ -0,0 +1,114 @@
+package org.madore.damlengine;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+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 TodoWeblogMonthsCalendar extends TodoDefaultElement {
+
+    public static final String[] monthAbbr = {
+	null,
+	"Jan", "Feb", "Mar", "Apr",
+	"May", "Jun", "Jul", "Aug",
+	"Sep", "Oct", "Nov", "Dec",
+    };
+
+    public static class Factory extends TodoElement.Factory {
+	@Override
+	public TodoWeblogMonthsCalendar newItem(Element node,
+						Context ctx,
+						TodoItem caller) {
+	    return new TodoWeblogMonthsCalendar(node, ctx, caller);
+	}
+    }
+
+    public TodoWeblogMonthsCalendar(Element node,
+				    Context ctx,
+				    TodoItem caller) {
+	super(node, ctx, caller);
+    }
+
+    @Override
+    public void handleNodeOnly() {
+	Element table = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "table");
+	node.getParentNode().replaceChild(table, node);
+	table.setAttributeNS(null, "border", "1");
+	table.appendChild(ctx.doc.createTextNode("\n\n"));
+	String targetStdDir = (ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/");
+	try {
+	    final Connection conn = WeblogDatabaseConnection.getConnection();
+	    final PreparedStatement selSt
+		= conn.prepareStatement("SELECT min(edate) , max(edate) FROM entries");
+	    final ResultSet selRes = selSt.executeQuery();
+	    int minedateYear, minedateMonth, maxedateYear, maxedateMonth;
+	    if ( selRes.next() ) {
+		String minedate = selRes.getString(1);
+		String maxedate = selRes.getString(2);
+		Matcher matcher;
+		if ( (matcher=Pattern.compile("(\\d{4})-(\\d{2})-\\d{2}").matcher(minedate)).matches() ) {
+		    minedateYear = Integer.parseInt(matcher.group(1));
+		    minedateMonth = Integer.parseInt(matcher.group(2));
+		} else
+		    throw new IllegalStateException("entry date field must be of the form YYYY-MM-DD");
+		if ( (matcher=Pattern.compile("(\\d{4})-(\\d{2})-\\d{2}").matcher(maxedate)).matches() ) {
+		    maxedateYear = Integer.parseInt(matcher.group(1));
+		    maxedateMonth = Integer.parseInt(matcher.group(2));
+		} else
+		    throw new IllegalStateException("entry date field must be of the form YYYY-MM-DD");
+	    } else
+		throw new IllegalStateException("failed to extract bounding dates");
+	    for ( int year = maxedateYear ; year >= minedateYear ; year-- ) {
+		Element tr = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "tr");
+		table.appendChild(tr);
+		table.appendChild(ctx.doc.createTextNode("\n\n"));
+		Element th = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "th");
+		tr.appendChild(th);
+		th.appendChild(ctx.doc.createTextNode(Integer.toString(year)));
+		tr.appendChild(ctx.doc.createTextNode("\n"));
+		if ( year==minedateYear && minedateMonth > 1 ) {
+		    Element td = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "td");
+		    td.setAttributeNS(null, "colspan",
+				      Integer.toString(minedateMonth-1));
+		    tr.appendChild(td);
+		    tr.appendChild(ctx.doc.createTextNode("\n"));
+		}
+		for ( int month = (year==minedateYear?minedateMonth:1) ;
+		      month <= (year==maxedateYear?maxedateMonth:12) ;
+		      month++ ) {
+		    Element td = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "td");
+		    tr.appendChild(td);
+		    if ( ( ctx.wsc instanceof Context.WeblogMonthSelectionContext )
+			 && year == Integer.parseInt(((Context.WeblogMonthSelectionContext)(ctx.wsc)).year)
+			 && month == Integer.parseInt(((Context.WeblogMonthSelectionContext)(ctx.wsc)).month) )
+			td.setAttributeNS(null, "class", "weblog-calendar-selected-month");
+		    Element a = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "a");
+		    td.appendChild(a);
+		    a.setAttributeNS(null, "href",
+				     targetStdDir + Integer.toString(year) + "-"
+				     + String.format("%02d",month) + ".html");
+		    a.appendChild(ctx.doc.createTextNode(monthAbbr[month] + " " + Integer.toString(year)));
+		    tr.appendChild(ctx.doc.createTextNode("\n"));
+		}
+		if ( year==maxedateYear && maxedateMonth < 12 ) {
+		    Element td = ctx.doc.createElementNS(DamlEngine.XHTML_NS, "td");
+		    td.setAttributeNS(null, "colspan",
+				      Integer.toString(12-maxedateMonth));
+		    tr.appendChild(td);
+		    tr.appendChild(ctx.doc.createTextNode("\n"));
+		}
+	    }
+	} catch (SQLException e) {
+	}
+    }
+
+}
-- 
cgit v1.2.3