[Bedework-commit] timezones r30 - in trunk: . .settings lib olson
olson/src olson/src/org olson/src/org/bedework
olson/src/org/bedework/timezones
olson/src/org/bedework/timezones/olson resources
tzsvr/src/org/bedework/timezones/server tzsvr/war/WEB-INF/classes
tzutil/src/org/bedework/timezones/tzutil
svnadmin at bedework.org
svnadmin at bedework.org
Thu Jul 24 15:43:30 EDT 2008
Author: douglm
Date: 2008-07-24 15:43:24 -0400 (Thu, 24 Jul 2008)
New Revision: 30
Added:
trunk/lib/backport-util-concurrent-3.0.jar
trunk/lib/ehcache-1.5.0.jar
trunk/lib/jsr107cache-1.0.jar
trunk/lib/rpiutil-3.5.jar
trunk/olson/
trunk/olson/src/
trunk/olson/src/org/
trunk/olson/src/org/bedework/
trunk/olson/src/org/bedework/timezones/
trunk/olson/src/org/bedework/timezones/olson/
trunk/olson/src/org/bedework/timezones/olson/Parser.java
trunk/olson/src/org/bedework/timezones/olson/ParserSource.java
trunk/olson/src/org/bedework/timezones/olson/Process.java
trunk/olson/src/org/bedework/timezones/olson/RuleSet.java
trunk/olson/src/org/bedework/timezones/olson/TzData.java
trunk/olson/src/org/bedework/timezones/olson/Zone.java
trunk/resources/
trunk/resources/log4j.xml
trunk/resources/tzregistry.xml
trunk/tzsvr/war/WEB-INF/classes/ehcache.xml
Removed:
trunk/lib/rpiutil-3.2.jar
Modified:
trunk/.classpath
trunk/.settings/org.eclipse.jdt.core.prefs
trunk/tzsvr/src/org/bedework/timezones/server/GetMethod.java
trunk/tzsvr/src/org/bedework/timezones/server/TzServer.java
trunk/tzsvr/src/org/bedework/timezones/server/TzServerUtil.java
trunk/tzsvr/war/WEB-INF/classes/servlet.properties
trunk/tzutil/src/org/bedework/timezones/tzutil/Reader.java
trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneChange.java
trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneDef.java
trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneInfo.java
trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneProvider.java
trunk/tzutil/src/org/bedework/timezones/tzutil/TzUtil.java
trunk/tzutil/src/org/bedework/timezones/tzutil/VtoXml.java
trunk/tzutil/src/org/bedework/timezones/tzutil/XmlToV.java
Log:
More work on timezone database population tool and server
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/.classpath 2008-07-24 19:43:24 UTC (rev 30)
@@ -1,15 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="tzsvr/src"/>
+ <classpathentry kind="src" path="olson/src"/>
<classpathentry kind="src" path="tzutil/src"/>
<classpathentry kind="lib" path="lib/derby.jar"/>
<classpathentry kind="lib" path="lib/geronimo-stax-api_1.0_spec-1.0.jar"/>
- <classpathentry kind="lib" path="lib/ical4j-head.jar"/>
+ <classpathentry kind="lib" path="lib/ical4j-head.jar" sourcepath="/iCal4j/source"/>
<classpathentry kind="lib" path="lib/log4j-1.2.8.jar"/>
- <classpathentry kind="lib" path="lib/rpiutil-3.2.jar"/>
<classpathentry kind="lib" path="lib/servletapi-2.4.jar"/>
<classpathentry kind="lib" path="lib/wstx-asl-3.9.0.jar"/>
+ <classpathentry kind="lib" path="lib/commons-httpclient-3.0.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="lib" path="lib/commons-httpclient-3.0.jar"/>
+ <classpathentry kind="lib" path="lib/ehcache-1.5.0.jar" sourcepath="/home/douglm/drop2/db/ehcache/ehcache-1.5.0/ehcache-1.5.0-sources"/>
+ <classpathentry kind="lib" path="lib/rpiutil-3.5.jar"/>
<classpathentry kind="output" path="bin/timezones"/>
</classpath>
Modified: trunk/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/.settings/org.eclipse.jdt.core.prefs 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/.settings/org.eclipse.jdt.core.prefs 2008-07-24 19:43:24 UTC (rev 30)
@@ -1,4 +1,4 @@
-#Tue Apr 15 15:22:42 EDT 2008
+#Sun Jun 29 00:40:52 EDT 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@@ -111,7 +111,7 @@
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.compact_else_if=true
-org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation=8
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
Added: trunk/lib/backport-util-concurrent-3.0.jar
===================================================================
(Binary files differ)
Property changes on: trunk/lib/backport-util-concurrent-3.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/lib/ehcache-1.5.0.jar
===================================================================
(Binary files differ)
Property changes on: trunk/lib/ehcache-1.5.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/lib/jsr107cache-1.0.jar
===================================================================
(Binary files differ)
Property changes on: trunk/lib/jsr107cache-1.0.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: trunk/lib/rpiutil-3.2.jar
===================================================================
(Binary files differ)
Added: trunk/lib/rpiutil-3.5.jar
===================================================================
(Binary files differ)
Property changes on: trunk/lib/rpiutil-3.5.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/olson/src/org/bedework/timezones/olson/Parser.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/Parser.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/Parser.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,50 @@
+package org.bedework.timezones.olson;
+
+public class Parser {
+ private ParserSource psrc;
+
+ private boolean debug;
+
+ public TzData parseFile(String fileName,
+ boolean debug) throws Throwable {
+ this.debug = debug;
+ psrc = new ParserSource(fileName, debug);
+
+ TzData tzd = new TzData();
+
+ while (psrc.nextTokens()) {
+ if (psrc.tokenEquals("Zone", 0)) {
+ parseZone();
+ } else {
+ error("Unknown entry type " + psrc.getCurLine());
+ }
+ }
+ return tzd;
+ }
+
+ /**
+ *
+ * @return Zone
+ */
+ public Zone parseZone() {
+ if (debug) {
+ trace("parseZone entry");
+ }
+
+ Zone z = new Zone(psrc);
+
+ if (!z.parse()) {
+ return null;
+ }
+
+ return z;
+ }
+
+ private void trace(String val) {
+ System.out.println("DEBUG: " + val);
+ }
+
+ private void error(String val) {
+ System.err.println(val);
+ }
+}
Added: trunk/olson/src/org/bedework/timezones/olson/ParserSource.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/ParserSource.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/ParserSource.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,241 @@
+package org.bedework.timezones.olson;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
+
+import org.bedework.timezones.olson.TzData.TimeData;
+
+/** Source for parsing datafiles
+ *
+ * @author Mike Douglass
+ */
+public class ParserSource {
+ private LineNumberReader lnr;
+ private boolean atEof;
+ private String curLine;
+
+ private String[] curTokens;
+
+ private boolean debug;
+
+ public ParserSource(String fileName,
+ boolean debug) throws Throwable {
+ this.debug = debug;
+ Reader rdr = new FileReader(new File(fileName));
+
+ lnr = new LineNumberReader(rdr);
+ }
+
+ public boolean atEof() {
+ return atEof;
+ }
+
+ public String getCurLine() {
+ return curLine;
+ }
+
+ public String getToken(int pos) {
+ if ((curTokens == null) || (curTokens.length <= pos)) {
+ return null;
+ }
+
+ return curTokens[pos];
+ }
+
+ public boolean tokenEquals(String val, int pos) {
+ if ((curTokens == null) || (curTokens.length <= pos)) {
+ return false;
+ }
+
+ return val.equals(curTokens[pos]);
+ }
+
+ /** The indicated token should represent a time
+ *
+ * @param pos
+ * @return TimeData seconds
+ */
+ public TimeData tokenTime(int pos) {
+ if ((curTokens == null) || (curTokens.length <= pos)) {
+ return null;
+ }
+
+ return getTime(curTokens[pos]);
+ }
+
+ /** Return a number or null
+ *
+ * @param pos
+ * @return Integer or null if not a number
+ */
+ public Integer number(int pos) {
+ if ((curTokens == null) || (curTokens.length <= pos)) {
+ return null;
+ }
+
+ try {
+ Integer res = Integer.valueOf(curTokens[pos]);
+
+ return res;
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ }
+
+ private static class Token {
+ String val;
+ int pos;
+
+ Token(String val) {
+ this.val = val;
+ this.pos = 0;
+ }
+
+ boolean ifMatch(String val) {
+ if (atEnd()) {
+ return false;
+ }
+
+ int len = val.length();
+ if (!val.regionMatches(pos, val, 0, len)) {
+ return false;
+ }
+
+ pos += len;
+ return true;
+ }
+
+ int number2() {
+ int res = Integer.valueOf(val.substring(pos, 2));
+
+ pos += 2;
+
+ return res;
+ }
+
+ boolean atEnd() {
+ if (pos >= val.length()) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ /** Has form:
+ * <pre>
+ * [-]hours[:minutes[:seconds]][w|s|g|u|z]
+ * </pre>
+ * Final code signifies wall (the default), standard, or UTC
+ *
+ * @param val
+ * @return int number of seconds
+ */
+ private TimeData getTime(String val) {
+ TimeData td = new TimeData();
+
+ Token tk = new Token(val);
+
+ boolean neg = tk.ifMatch("-");
+
+ td.seconds = tk.number2() * 60 * 60;
+
+ if (tk.ifMatch(":")) {
+ td.seconds += (tk.number2() * 60);
+ if (tk.ifMatch(":")) {
+ td.seconds += tk.number2();
+ }
+ }
+
+ if (neg) {
+ td.seconds = -td.seconds;
+ }
+
+ if (tk.atEnd()) {
+ td.typeCode = TimeData.timeWall;
+ } else if (tk.ifMatch("w")) {
+ td.typeCode = TimeData.timeWall;
+ } else if (tk.ifMatch("s")) {
+ td.typeCode = TimeData.timeStandard;
+ } else if (tk.ifMatch("u")) {
+ td.typeCode = TimeData.timeUtc;
+ } else if (tk.ifMatch("z")) {
+ td.typeCode = TimeData.timeUtc;
+ } else if (tk.ifMatch("g")) {
+ td.typeCode = TimeData.timeUtc;
+ } else {
+ error("Bad time " + curLine);
+ }
+
+ return td;
+ }
+
+ /** Break the current line into an array of tokens.
+ * Return null for no tokens.
+ *
+ * @return String[] tokens.
+ */
+ private String[] tokenize(String val) {
+ if (val == null) {
+ return null;
+ }
+
+ if (val.startsWith("#") || (val.length() == 0)) {
+ return null;
+ }
+
+ String[] res = val.split("\\s");
+ if ((res == null) || (res.length == 0)) {
+ return null;
+ }
+
+ for (int i = 0; i < res.length; i++) {
+ if (res[i].startsWith("#")) {
+ // Comment from now on
+ if (i == 0) {
+ return null;
+ }
+
+ String[] subRes = new String[i];
+ System.arraycopy(res, 0, subRes, 0 , i);
+
+ return subRes;
+ }
+ }
+
+ return res;
+ }
+
+ public void trace(String val) {
+ System.out.println("DEBUG: " + val);
+ }
+
+ public void error(String val) {
+ System.err.println(val);
+ }
+
+ /* null for eof */
+ public boolean nextTokens() throws Throwable {
+ if (atEof) {
+ return false;
+ }
+
+ for (;;) {
+ curLine = lnr.readLine();
+
+ if (curLine == null) {
+ // EOF so they say
+ atEof = true;
+ return false;
+ }
+
+ curTokens = tokenize(curLine);
+
+ if (curTokens != null) {
+ return true;
+ }
+ }
+ }
+}
Added: trunk/olson/src/org/bedework/timezones/olson/Process.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/Process.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/Process.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,23 @@
+package org.bedework.timezones.olson;
+
+/** Process the current Olson data to produce an internal form suitable for a
+ * timezone servie
+ *
+ * @author Mike Douglass
+ */
+public class Process {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ Parser p = new Parser();
+
+ try {
+ TzData td = p.parseFile(args[0], true);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+}
Added: trunk/olson/src/org/bedework/timezones/olson/RuleSet.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/RuleSet.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/RuleSet.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,5 @@
+package org.bedework.timezones.olson;
+
+public class RuleSet {
+
+}
Added: trunk/olson/src/org/bedework/timezones/olson/TzData.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/TzData.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/TzData.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,13 @@
+package org.bedework.timezones.olson;
+
+public class TzData {
+ public static class TimeData {
+ public final static int timeWall = 0;
+ public final static int timeStandard = 1;
+ public final static int timeUtc = 2;
+
+ public int seconds;
+ public int typeCode;
+ }
+
+}
Added: trunk/olson/src/org/bedework/timezones/olson/Zone.java
===================================================================
--- trunk/olson/src/org/bedework/timezones/olson/Zone.java (rev 0)
+++ trunk/olson/src/org/bedework/timezones/olson/Zone.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,119 @@
+package org.bedework.timezones.olson;
+
+import java.io.Serializable;
+
+import org.bedework.timezones.olson.TzData.TimeData;
+import org.bedework.timezones.olson.Zone.ZoneInfo.Until;
+
+public class Zone implements Serializable {
+ private ParserSource psrc;
+
+ public String name;
+
+ public static class ZoneInfo implements Serializable {
+ public static class Until implements Serializable {
+ int year;
+ int month;
+ }
+
+ public int offsetSeconds;
+
+ public String rulesetName;
+ public RuleSet rules;
+ public Integer seconds;
+
+ public String format;
+
+ /** null for no until part */
+ public Until until;
+ }
+
+ public Zone(ParserSource psrc) {
+ this.psrc = psrc;
+ }
+
+ /** The Zone starts with a line which has the keyword "Zone" at column 0 and
+ * continues over a number of lines until there is no UNTIL field.
+# Zone NAME GMTOFF RULES FORMAT [UNTIL]
+Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02
+ -8:00 US P%sT 1946
+ -8:00 CA P%sT 1967
+ -8:00 US P%sT
+
+ * @return boolean true for parsed OK.
+ */
+ public boolean parse() {
+ name = psrc.getToken(1);
+
+ int tnum = 2;
+ ZoneInfo zi;
+
+ do {
+ zi = new ZoneInfo();
+
+ TimeData secs = psrc.tokenTime(tnum);
+ zi.offsetSeconds = secs.seconds;
+
+ tnum++; // On to rules
+
+ zi.rulesetName = psrc.getToken(tnum);
+ if ("-".equals(zi.rulesetName)) {
+ zi.rulesetName = null;
+ } else {
+ zi.seconds = psrc.number(tnum);
+ if (zi.seconds != null) {
+ zi.rulesetName = null;
+ }
+ }
+
+ tnum++; // On to format
+
+ zi.format = psrc.getToken(tnum);
+
+ tnum++; // On to until part
+
+ if (psrc.getToken(tnum) != null) {
+ // Expecting an Until
+
+ zi.until = getUntil(tnum);
+ }
+ } while (zi.until != null);
+
+ return false;
+ }
+
+ private Until getUntil(int tnum) {
+ if (psrc.getToken(tnum) == null) {
+ return null;
+ }
+
+ Until until = new Until();
+
+ int fldNum = 0;
+ Integer fval;
+
+ while (psrc.getToken(tnum) != null) {
+ switch (fldNum) {
+ case 0:
+ fval = psrc.number(tnum);
+ if (fval == null) {
+ error("Bad year");
+ return until;
+ }
+
+ until.year = fval;
+ break;
+
+ case 1:
+ break;
+
+ }
+ }
+
+ return until;
+ }
+
+ private void error(String msg) {
+ System.err.println(msg + " at " + psrc.getCurLine());
+ }
+}
Added: trunk/resources/log4j.xml
===================================================================
--- trunk/resources/log4j.xml (rev 0)
+++ trunk/resources/log4j.xml 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- Log4j Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml,v 1.5 2005/01/18 02:55:05 rpical Exp $ -->
+
+<!--
+ | For more configuration infromation and examples see the Jakarta Log4j
+ | website: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
+ debug="false">
+
+ <!-- ================================= -->
+ <!-- Preserve messages in a local file -->
+ <!-- ================================= -->
+
+ <!-- A time/date based rolling appender -->
+ <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="File" value="./server.log"/>
+ <param name="Append" value="true"/>
+
+ <!-- Rollover at midnight each day -->
+ <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+ <!-- Rollover at the top of each hour
+ <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
+ -->
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+
+ <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
+ <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+ -->
+ </layout>
+ </appender>
+
+ <!-- A size based file rolling appender
+ <appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
+ <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
+ <param name="File" value="${jboss.server.home.dir}/log/server.log"/>
+ <param name="Append" value="false"/>
+ <param name="MaxFileSize" value="500KB"/>
+ <param name="MaxBackupIndex" value="1"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+ </layout>
+ </appender>
+ -->
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- Set Threshold to INFO/DEBUG -->
+ <!-- ============================== -->
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="Target" value="System.out"/>
+ <param name="Threshold" value="DEBUG"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="JSR77" class="org.apache.log4j.FileAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="Append" value="false"/>
+ <param name="File" value="${tomcat.home}/logs/jsr77.log"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+ <!-- ====================== -->
+ <!-- More Appender examples -->
+ <!-- ====================== -->
+
+ <!-- Buffer events and log them asynchronously
+ <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <appender-ref ref="FILE"/>
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="SMTP"/>
+ </appender>
+ -->
+
+ <!-- EMail events to an administrator
+ <appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="Threshold" value="ERROR"/>
+ <param name="To" value="admin at myhost.domain.com"/>
+ <param name="From" value="nobody at myhost.domain.com"/>
+ <param name="Subject" value="JBoss Sever Errors"/>
+ <param name="SMTPHost" value="localhost"/>
+ <param name="BufferSize" value="10"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/>
+ </layout>
+ </appender>
+ -->
+
+ <!-- Syslog events
+ <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="Facility" value="LOCAL7"/>
+ <param name="FacilityPrinting" value="true"/>
+ <param name="SyslogHost" value="localhost"/>
+ </appender>
+ -->
+
+ <!-- Log events to JMS (requires a topic to be created)
+ <appender name="JMS" class="org.apache.log4j.net.JMSAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="Threshold" value="ERROR"/>
+ <param name="TopicConnectionFactoryBindingName" value="java:/ConnectionFactory"/>
+ <param name="TopicBindingName" value="topic/MyErrorsTopic"/>
+ </appender>
+ -->
+
+ <!-- Log events through SNMP
+ <appender name="TRAP_LOG" class="org.apache.log4j.ext.SNMPTrapAppender">
+ <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/>
+ <param name="ImplementationClassName" value="org.apache.log4j.ext.JoeSNMPTrapSender"/>
+ <param name="ManagementHost" value="127.0.0.1"/>
+ <param name="ManagementHostTrapListenPort" value="162"/>
+ <param name="EnterpriseOID" value="1.3.6.1.4.1.24.0"/>
+ <param name="LocalIPAddress" value="127.0.0.1"/>
+ <param name="LocalTrapSendPort" value="161"/>
+ <param name="GenericTrapType" value="6"/>
+ <param name="SpecificTrapType" value="12345678"/>
+ <param name="CommunityString" value="public"/>
+ <param name="ForwardStackTraceWithTrap" value="true"/>
+ <param name="Threshold" value="DEBUG"/>
+ <param name="ApplicationTrapOID" value="1.3.6.1.4.1.24.12.10.22.64"/>
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d,%p,[%t],[%c],%m%n"/>
+ </layout>
+ </appender>
+ -->
+
+ <appender name="CHAINSAW_CLIENT" class="org.apache.log4j.net.SocketAppender">
+ <param name="RemoteHost" value="localhost"/>
+ <param name="Port" value="4445"/>
+ <param name="LocationInfo" value="true"/>
+ </appender>
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <!-- Limit the org.apache stuff -->
+ <!--
+ <category name="org.apache.commons">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="org.apache.catalina.startup.TldConfig">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="org.apache.jasper">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="org.apache.struts">
+ <priority value="INFO"/>
+ </category>
+ -->
+ <category name="org.apache">
+ <priority value="INFO"/>
+ </category>
+
+ <!--
+ <category name="org.apache.commons.digester">
+ <priority value="DEBUG"/>
+ </category>
+ -->
+
+ <!--
+ <category name="org.apache.commons.beanutils">
+ <priority value="TRACE"/>
+ </category>
+ -->
+
+ <!-- ical4j is noisy -->
+ <category name="net.fortuna.ical4j">
+ <priority value="INFO"/>
+ </category>
+
+ <!-- caching is noisy too -->
+ <category name="net.sf.ehcache">
+ <priority value="INFO"/>
+ </category>
+
+ <!-- hibernate is noisy too -->
+ <category name="org.hibernate">
+ <priority value="INFO"/>
+ </category>
+
+ <!-- Set rpi categories -->
+<!--
+ <category name="edu.rpi">
+ <priority value="DEBUG"/>
+ </category>
+ -->
+
+ <category name="edu.rpi.cmt.access.Acl">
+ <priority value="INFO"/>
+ </category>
+
+ <category name="org.bedework.calcore.AccessUtil">
+ <priority value="INFO"/>
+ </category>
+
+ <!--
+ | An example of enabling the custom TRACE level priority that is used
+ | by the JBoss internals to diagnose low level details. This example
+ | turns on TRACE level msgs for the org.jboss.ejb.plugins package and its
+ | subpackages. This will produce A LOT of logging output.
+ <category name="org.jboss.system">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+ <category name="org.jboss.ejb.plugins">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+ -->
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <priority value ="TRACE" />
+ <appender-ref ref="FILE"/>
+ <appender-ref ref="CONSOLE"/>
+ </root>
+</log4j:configuration>
Added: trunk/resources/tzregistry.xml
===================================================================
--- trunk/resources/tzregistry.xml (rev 0)
+++ trunk/resources/tzregistry.xml 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<timezone-registry>
+ <provider>
+ <prefix>/EXAMPLE</prefix>
+ <url>http://localhost:8080/tzsvr</url>
+ <contact>http://localhost:9090/carddav/orgs/Example</contact>
+ </provider>
+ <!--
+ <provider>
+ <prefix>/MICROSOFT</prefix>
+ <url>http://localhost:9090/mstzs</url>
+ <contact>http://localhost:9090/carddav/orgs/MS</contact>
+ </provider>
+ <provider>
+ <prefix>/APPLE</prefix>
+ <url>http://localhost:9090/appletzs</url>
+ <contact>http://localhost:9090/carddav/orgs/Apple</contact>
+ </provider>
+ -->
+</timezone-registry>
Modified: trunk/tzsvr/src/org/bedework/timezones/server/GetMethod.java
===================================================================
--- trunk/tzsvr/src/org/bedework/timezones/server/GetMethod.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzsvr/src/org/bedework/timezones/server/GetMethod.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -63,13 +63,8 @@
String[] tzids = req.getParameterValues("tzid");
String provider = req.getParameter("provider");
- if (provider != null) {
- // XXX We should see if this is one of our prefixes. If not we should call
- // a server which does support that prefix - probably based on registry values.
- }
+ TzUtil util = new TzUtil(props.getProperty(TzServerUtil.pnameDbName), debug);
- TzUtil util = new TzUtil(debug);
-
doTzids(resp, tzids, format, provider, util);
}
@@ -78,8 +73,10 @@
TzUtil util) throws ServletException {
Collection<TimezoneDef> tzdefs = new ArrayList<TimezoneDef>();
+ boolean fetchAll = (tzids == null) || (tzids.length == 0);
+
try {
- if ((tzids == null) || (tzids.length == 0)) {
+ if (fetchAll) {
tzdefs = util.fetchDefs(null, null);
} else {
tzdefs = new ArrayList<TimezoneDef>();
@@ -119,28 +116,34 @@
}
}
+ // ical can be picky about line endings.
+ private static String newline = "\r\n";
+
+ private static String calHdr = "BEGIN:VCALENDAR" + newline +
+ "PRODID:-//TzService//1.0//EN" + newline +
+ "VERSION:2.0" + newline +
+ "CALSCALE:GREGORIAN" + newline;
+
private void makeVcalendar(HttpServletResponse resp,
Collection<TimezoneDef> tzdefs) throws ServletException {
try {
PrintWriter wtr = resp.getWriter();
- // ical can be picky about line endings.
- String newline = "\r\n";
+ wtr.write(calHdr);
- wtr.write("BEGIN:VCALENDAR");
- wtr.write(newline);
- wtr.write("PRODID:-//TzService//1.0//EN\n");
- wtr.write(newline);
- wtr.write("VERSION:2.0\n");
- wtr.write(newline);
- wtr.write("CALSCALE:GREGORIAN\n");
- wtr.write(newline);
-
for (TimezoneDef def: tzdefs) {
- TimezoneInfo tzinfo = XmlToV.parseXml(def.tzDef);
+ TimezoneInfo tzinfo = TzServerUtil.getCachedVtz(def.getPrefixedId());
+ if (tzinfo == null) {
+ tzinfo = XmlToV.parseXml(def.tzDef);
+
+ if (tzinfo != null) {
+ TzServerUtil.putCachedVtz(tzinfo);
+ }
+ }
+
if (tzinfo != null) {
- wtr.write(tzinfo.tz.toString());
+ wtr.write(tzinfo.getStringTzValue());
}
}
Modified: trunk/tzsvr/src/org/bedework/timezones/server/TzServer.java
===================================================================
--- trunk/tzsvr/src/org/bedework/timezones/server/TzServer.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzsvr/src/org/bedework/timezones/server/TzServer.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -85,16 +85,16 @@
String propVal = props.getProperty(TzServerUtil.pnameDerbySystemHome);
if (propVal == null) {
- propVal =sysp.getProperty("user.home");
+ propVal = sysp.getProperty("user.home");
if (propVal == null) {
error("No home");
throw new ServletException("No derby system home");
}
-
- sysp.put(TzServerUtil.pnameDerbySystemHome, propVal);
}
+ sysp.put(TzServerUtil.pnameDerbySystemHome, propVal);
+
Long propLong = TzServerUtil.longProp(props,
TzServerUtil.pnameRegistryRefetchInterval);
if (propLong == null) {
@@ -113,8 +113,18 @@
propLong *= 1000;
props.put(TzServerUtil.pnameRegistryRetryInterval, propLong);
- propVal = props.getProperty(TzServerUtil.pnameTzsvcRefreshOnInit);
- if ((propVal != null) && "true".equals(propVal)) {
+ if (TzServerUtil.boolProp(props,TzServerUtil.pnameTzsvcRootProvider)) {
+ if (!TzServerUtil.boolProp(props,TzServerUtil.pnameTzsvcRootUseDb)) {
+ /* We need a root url */
+ propVal = props.getProperty(TzServerUtil.pnameTzsvcRootUrl);
+ if (propVal == null) {
+ error("No root url");
+ throw new ServletException("No root provider url");
+ }
+ }
+ }
+
+ if (TzServerUtil.boolProp(props,TzServerUtil.pnameTzsvcRefreshOnInit)) {
TzServerUtil.refresh(props, debug);
}
} catch (ServletException se) {
@@ -137,6 +147,9 @@
if (methodName.equals("OPTIONS")) {
new OptionsMethod(debug).doMethod(req, resp, props);
} else if (methodName.equals("GET")) {
+ if (TzServerUtil.refreshDue(props)) {
+ TzServerUtil.refresh(props, debug);
+ }
new GetMethod(debug).doMethod(req, resp, props);
} else if (methodName.equals("POST")) {
new PostMethod(debug).doMethod(req, resp, props);
@@ -158,18 +171,19 @@
*
* @param req
*/
+ @SuppressWarnings("unchecked")
public void dumpRequest(HttpServletRequest req) {
Logger log = getLogger();
try {
- Enumeration names = req.getHeaderNames();
+ Enumeration<String> names = req.getHeaderNames();
String title = "Request headers";
log.debug(title);
while (names.hasMoreElements()) {
- String key = (String)names.nextElement();
+ String key = names.nextElement();
String val = req.getHeader(key);
log.debug(" " + key + " = \"" + val + "\"");
}
@@ -193,7 +207,7 @@
log.debug(title);
while (names.hasMoreElements()) {
- String key = (String)names.nextElement();
+ String key = names.nextElement();
String val = req.getParameter(key);
log.debug(" " + key + " = \"" + val + "\"");
}
Modified: trunk/tzsvr/src/org/bedework/timezones/server/TzServerUtil.java
===================================================================
--- trunk/tzsvr/src/org/bedework/timezones/server/TzServerUtil.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzsvr/src/org/bedework/timezones/server/TzServerUtil.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -26,6 +26,11 @@
package org.bedework.timezones.server;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+
+import org.bedework.timezones.tzutil.TimezoneInfo;
import org.bedework.timezones.tzutil.TimezoneProvider;
import org.bedework.timezones.tzutil.TzUtil;
@@ -52,6 +57,9 @@
/** We use derby to store data - property defining location of the files */
public static final String pnameDerbySystemHome = "derby.system.home";
+ /** Database name we use */
+ public static final String pnameDbName = "tzsvc.database.name";
+
/** Property defining location of the registry */
public static final String pnameRegistryUrl = "tzsvc.registry.url";
@@ -71,6 +79,23 @@
/** Property defining a preferred provider for this server */
public static final String pnamePreferredProvider = "tzsvc.preferred.provider";
+ /** True if this server is a root server - in this case we serve up the preferred
+ * provider to others. */
+ public static final String pnameTzsvcRootProvider = "tzsvc.root.provider";
+
+ /** If this server is a root server this indicates we are using a db
+ * maintained externally for our own data */
+ public static final String pnameTzsvcRootUseDb = "tzsvc.root.use.db";
+
+ /** If this server is a root server and we are not using an externally maintained
+ * db we use this (possibly private) URL to fetch the xml formatted data */
+ public static final String pnameTzsvcRootUrl = "tzsvc.root.url";
+
+ /** True if this server is a root server only - that is it does not serve up
+ * other provider data.
+ */
+ public static final String pnameTzsvcRootOnly = "tzsvc.root.only";
+
/** Internal use: a collection of provider info */
public static final String pnameProviderMap = "tzsvc.provider.map";
@@ -81,6 +106,10 @@
*/
public static final String pnameTzsvcRefreshOnInit = "tzsvc.refresh.on.init";
+ /** name of vtimezone cache
+ */
+ public static final String pnameVtzCache = "tzsvc.vtimezones.cache.name";
+
/* ======================= Error codes ======================= */
/** Unable to retrieve the registry */
@@ -89,6 +118,10 @@
/** Time we last fetched the registry */
public volatile static long lastRegistryFetch;
+ private static CacheManager manager = new CacheManager();
+
+ private static Cache vtzCache;
+
/** Set up a Properties from the resources
*
* @param servlet
@@ -97,7 +130,7 @@
* @throws ServletException
*/
static Properties getResources(HttpServlet servlet,
- ServletConfig config) throws ServletException {
+ ServletConfig config) throws ServletException {
String resname = config.getInitParameter("application");
Properties props = new Properties();
@@ -119,6 +152,8 @@
}
}
+ cacheInit(props);
+
return props;
}
@@ -168,56 +203,162 @@
* @throws ServletException
*/
static void refresh(Properties props, boolean debug) throws ServletException {
- logIt("Refreshing the server");
+ try {
+ logIt("Refreshing the server");
- /* ============= First get the registry ================= */
+ /* ============= First get the registry ================= */
- TzUtil util = new TzUtil(debug);
+ TzUtil util = new TzUtil(props.getProperty(TzServerUtil.pnameDbName), debug);
- Map<String, TimezoneProvider> tps =
- (Map<String, TimezoneProvider>)props.get(pnameProviderMap);
+ Map<String, TimezoneProvider> tps = getMap(props);
- if (tps == null) {
- /* Not in properties - fetch from server */
- tps = getRegistry(props, util);
+ if (tps == null) {
+ /* Not in properties - fetch from server */
+ tps = getRegistry(props, util);
- if (tps == null) {
- error("Unable to fetch registry.");
- throw new ServletException(errorNoRegistry);
+ if (tps == null) {
+ error("Unable to fetch registry.");
+ throw new ServletException(errorNoRegistry);
+ }
}
- }
- /* ============= For each provider - refresh their data ================= */
+ /* ============= For each provider - refresh their data ================= */
- try {
- for (TimezoneProvider tp: tps.values()) {
+ /* If this is the root provider we behave differently for our own prefix.
+ * We either fetch the data from a supplied url or we are serving out of a
+ * database which is updated externally in which case we do nothing.
+ *
+ * In addition, as a root server we refresh the data from other providers.
+ */
+
+ String ourPrefix = props.getProperty(TzServerUtil.pnamePreferredProvider);
+ boolean rootServer = false;
+ boolean onlyOurs = false;
+ boolean fromDb = false;
+ String rootUrl = null;
+
+ if (boolProp(props, pnameTzsvcRootProvider)) {
+ rootServer = true;
+ onlyOurs = boolProp(props,TzServerUtil.pnameTzsvcRootOnly);
+
+ if (boolProp(props,TzServerUtil.pnameTzsvcRootUseDb)) {
+ fromDb = true;
+ } else {
+ rootUrl = props.getProperty(TzServerUtil.pnameTzsvcRootUrl);
+ }
+ }
+
+ if (rootServer && !fromDb) {
+ /* Refresh from a given url. */
+ TimezoneProvider tp = new TimezoneProvider(ourPrefix,
+ rootUrl, null);
TzUtil.RefreshStatus rs = util.refresh(tp);
- if (rs == TzUtil.RefreshStatus.OK) {
+ if (rs != TzUtil.RefreshStatus.OK) {
+ retryOrReschedule(props, debug);
+ return;
+ }
+ }
+
+ if (onlyOurs) {
+ // No refresh for anybody else
+
+ cacheRefresh();
+ return;
+ }
+
+ for (TimezoneProvider tp: tps.values()) {
+ if (rootServer && ourPrefix.equals(tp.prefix)) {
+ // Skip our entry
continue;
}
- /* This could be network or bad data or a bad url. If we just refetched
- * the registry we'll ignore it for the moment and schedule a refetch
- * just after the registry refetch interval.
- */
+ TzUtil.RefreshStatus rs = util.refresh(tp);
- Long regRefetchInterval = (Long)props.get(pnameRegistryRefetchInterval);
- if ((System.currentTimeMillis() - lastRegistryFetch) > regRefetchInterval) {
- props.remove(pnameProviderMap);
- refresh(props, debug);
- return;
+ if (rs == TzUtil.RefreshStatus.OK) {
+ continue;
}
- /* We refetched not long ago. Reschedule */
+ retryOrReschedule(props, debug);
+ break;
+ }
- // TODO
- }
+ cacheRefresh();
} catch (Throwable t) {
throw new ServletException(t);
}
}
+ /* ====================================================================
+ * Caching
+ * ==================================================================== */
+
+ static void cacheInit(Properties props) throws ServletException {
+ vtzCache = manager.getCache(props.getProperty(pnameVtzCache));
+ }
+
+ static void cacheRefresh() throws ServletException {
+ cacheRefresh(vtzCache);
+ }
+
+ static TimezoneInfo getCachedVtz(String name) throws ServletException {
+ Element el = vtzCache.get(name);
+
+ if (el == null) {
+ return null;
+ }
+
+ return (TimezoneInfo)el.getValue();
+ }
+
+ static void putCachedVtz(TimezoneInfo vtz) throws ServletException {
+ Element el = new Element(vtz.name, vtz);
+
+ vtzCache.put(el);
+ }
+
+ /* ====================================================================
+ * Private methods
+ * ==================================================================== */
+
+ private static void cacheRefresh(Cache cache) throws ServletException {
+ if (cache != null) {
+ cache.flush();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Map<String, TimezoneProvider> getMap(Properties props) {
+ return (Map<String, TimezoneProvider>)props.get(pnameProviderMap);
+ }
+
+ static boolean refreshDue(Properties props) {
+ Long regRefetchInterval = (Long)props.get(pnameRegistryRefetchInterval);
+ if ((System.currentTimeMillis() - lastRegistryFetch) > regRefetchInterval) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void retryOrReschedule(Properties props,
+ boolean debug) throws Throwable {
+ /* This could be network or bad data or a bad url. If we just refetched
+ * the registry we'll ignore it for the moment and schedule a refetch
+ * just after the registry refetch interval.
+ */
+
+ if (refreshDue(props)) {
+ props.remove(pnameProviderMap);
+ refresh(props, debug);
+ return;
+ }
+
+ /* We refetched not long ago. Reschedule */
+
+ // TODO
+ }
+
static Long longProp(Properties props, String name) throws Throwable {
String propVal = props.getProperty(name);
if (propVal == null) {
@@ -227,6 +368,15 @@
return Long.valueOf(propVal);
}
+ static boolean boolProp(Properties props, String name) throws Throwable {
+ String propVal = props.getProperty(name);
+ if (propVal == null) {
+ return false;
+ }
+
+ return Boolean.valueOf(propVal);
+ }
+
/**
* @return Logger
*/
Added: trunk/tzsvr/war/WEB-INF/classes/ehcache.xml
===================================================================
--- trunk/tzsvr/war/WEB-INF/classes/ehcache.xml (rev 0)
+++ trunk/tzsvr/war/WEB-INF/classes/ehcache.xml 2008-07-24 19:43:24 UTC (rev 30)
@@ -0,0 +1,29 @@
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="ehcache.xsd">
+ <diskStore path="java.io.tmpdir"/>
+
+ <!--
+ Sample cache named sampleCache2
+ This cache has a maximum of 1000 elements in memory. There is no overflow to disk, so 1000
+ is also the maximum cache size. Note that when a cache is eternal, timeToLive and
+ timeToIdle are not used and do not need to be specified.
+ -->
+ <defaultCache maxElementsInMemory="10000"
+ eternal="false"
+ timeToIdleSeconds="120"
+ timeToLiveSeconds="120"
+ overflowToDisk="true"
+ diskSpoolBufferSizeMB="30"
+ maxElementsOnDisk="10000000"
+ diskPersistent="false"
+ diskExpiryThreadIntervalSeconds="120"
+ memoryStoreEvictionPolicy="LRU"
+ />
+
+ <cache name="vtz"
+ maxElementsInMemory="1000"
+ eternal="true"
+ overflowToDisk="false"
+ memoryStoreEvictionPolicy="FIFO"
+ />
+</ehcache>
Modified: trunk/tzsvr/war/WEB-INF/classes/servlet.properties
===================================================================
--- trunk/tzsvr/war/WEB-INF/classes/servlet.properties 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzsvr/war/WEB-INF/classes/servlet.properties 2008-07-24 19:43:24 UTC (rev 30)
@@ -10,6 +10,9 @@
# We use derby to store data - property defining location of the files
derby.system.home=$TOMCAT_HOME/../derbyhome
+# Database name we use
+tzsvc.database.name=tzdb
+
# Property defining integer seconds retry interval for registry fetches
# on registry fetch failure
tzsvc.registry.retry.interval=60
@@ -22,10 +25,32 @@
tzsvc.post.id=12345abcde
# Property defining a preferred provider for this server
-tzsvc.preferred.provider=/OLSON
+tzsvc.preferred.provider=/EXAMPLE
+# True if this server is a root server - in this case we serve up the preferred
+# provider to others.
+tzsvc.root.provider=yes
+
+# If this server is a root server this indicates we are using a db
+# maintained externally for our own data
+tzsvc.root.use.db=true
+
+# If this server is a root server and we are not using an externally maintained
+# db we use this (possibly private) URL to fetch the xml formatted data
+tzsvc.root.url=http://localhost:9090/olsontzs
+
+# True if this server is a root server only - that is it does not serve up
+# other provider data.
+tzsvc.root.only=no
+
# If true the server can refresh on init. This must be false for a root server
# fetching from it's own applcation server or deadlock will result.
#
# Such a server needs an explicit POST after startup
tzsvc.refresh.on.init=false
+
+# =========================================================================
+# Caching information - most of this is in ehcache.xml
+# =========================================================================
+
+tzsvc.vtimezones.cache.name=vtz
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/Reader.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/Reader.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/Reader.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -108,11 +108,13 @@
Collection<TimezoneChange> tzChanges = null;
PropertyList pl = tz.getProperties();
+ String name = null;
while (nextStart()) {
if (tzid.equals(rdr.getName())) {
rdr.next();
- pl.add(new TzId(rdr.getText()));
+ name = rdr.getText();
+ pl.add(new TzId(name));
continue;
}
@@ -154,7 +156,7 @@
debugMsg(tz.toString());
}
- tzs.add(new TimezoneInfo(tz, tzChanges));
+ tzs.add(new TimezoneInfo(name, tz, tzChanges));
return true;
}
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneChange.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneChange.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneChange.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -1,5 +1,7 @@
package org.bedework.timezones.tzutil;
+import java.io.Serializable;
+
import net.fortuna.ical4j.model.PeriodList;
import net.fortuna.ical4j.model.property.DtStamp;
@@ -7,7 +9,7 @@
*
* @author Mike Douglass
*/
-public class TimezoneChange implements Comparable<TimezoneChange> {
+public class TimezoneChange implements Comparable<TimezoneChange>, Serializable {
/** Date the change was made - these are ordered
*/
public DtStamp dateStamp;
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneDef.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneDef.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneDef.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -1,12 +1,13 @@
package org.bedework.timezones.tzutil;
+import java.io.Serializable;
import java.util.Collection;
/** Timezone definition saved and extracted from db
*
* @author Mike Douglass
*/
-public class TimezoneDef {
+public class TimezoneDef implements Serializable {
/** The timezone prefix
*/
public String tzPrefix;
@@ -38,4 +39,8 @@
this.tzAliases = tzAliases;
this.tzDef = tzDef;
}
+
+ public String getPrefixedId() {
+ return tzPrefix + "/" + tzId;
+ }
}
\ No newline at end of file
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneInfo.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneInfo.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneInfo.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -2,13 +2,18 @@
import net.fortuna.ical4j.model.component.VTimeZone;
+import java.io.Serializable;
import java.util.Collection;
/** Timezone spec and related changes.
*
* @author Mike Douglass
*/
-public class TimezoneInfo {
+public class TimezoneInfo implements Serializable {
+ /** Prefix id
+ */
+ public String name;
+
/** The timezone spec
*/
public VTimeZone tz;
@@ -17,13 +22,23 @@
*/
public Collection<TimezoneChange> changes;
+ /* Vlaue of tz */
+ private String stringTzValue;
+
/**
* @param tz
* @param changes
*/
- public TimezoneInfo(VTimeZone tz,
+ public TimezoneInfo(String name,
+ VTimeZone tz,
Collection<TimezoneChange> changes) {
+ this.name = name;
this.tz = tz;
this.changes = changes;
+ stringTzValue = tz.toString();
}
+
+ public String getStringTzValue() {
+ return stringTzValue;
+ }
}
\ No newline at end of file
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneProvider.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneProvider.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/TimezoneProvider.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -26,4 +26,18 @@
this.url = url;
this.contact = contact;
}
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("TimezoneProvider{prefix=");
+ sb.append(prefix);
+ sb.append(", url=");
+ sb.append(url);
+ sb.append(", contact=");
+ sb.append(contact);
+ sb.append("}");
+
+ return sb.toString();
+ }
}
\ No newline at end of file
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/TzUtil.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/TzUtil.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/TzUtil.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -40,6 +40,8 @@
public class TzUtil {
private boolean debug;
+ private String dbName;
+
private Connection conn;
private boolean stayOpen;
@@ -60,6 +62,11 @@
this.debug = debug;
}
+ public TzUtil(String dbName, boolean debug) {
+ this.dbName = dbName;
+ this.debug = debug;
+ }
+
/**
* @param registryUrl
* @return collection
@@ -213,6 +220,13 @@
}
return RefreshStatus.OK;
+ } catch (Throwable t) {
+ error("Unable to access " + tp);
+ if (debug) {
+ t.printStackTrace();
+ }
+
+ return RefreshStatus.NOCONNECTION;
} finally {
close();
}
@@ -230,13 +244,17 @@
* @throws Throwable
*/
public void connect(boolean stayOpen) throws Throwable {
+ if (dbName == null) {
+ throw new Exception("No dbName");
+ }
+
if (conn != null) {
throw new Exception("Already open");
}
try {
String driver = "org.apache.derby.jdbc.EmbeddedDriver";
- String url = "jdbc:derby:tzdb;create=true";
+ String url = "jdbc:derby:" + dbName + ";create=true";
try {
Class.forName(driver);
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/VtoXml.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/VtoXml.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/VtoXml.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -71,6 +71,10 @@
private String dirName;
+ private String dbName = "tzdb";
+
+ private String derbySystemHome;
+
private File inDir;
private StringWriter out;
@@ -98,10 +102,16 @@
void open() throws Throwable {
inDir = new File(dirName);
- tzutil = new TzUtil(debug);
+ tzutil = new TzUtil(dbName, debug);
if (clean) {
- tzutil.dropAll();
+ File f = new File(derbySystemHome + "/" + dbName);
+
+ if (f.exists()) {
+ throw new Exception("Delete " + derbySystemHome + "/" + dbName +
+ " and rerun");
+ }
+
tzutil.createDb();
}
@@ -117,6 +127,7 @@
void close(boolean ok) throws Throwable {
if (tzutil == null) {
+ warn("No conversion?");
return;
}
@@ -126,13 +137,14 @@
}
if (initDb) {
- // We were updating a prefix
+ // We were updating a prefix and failed
+ warn("Error in conversion?");
tzutil.close();
}
long ct = tzutil.countDefs();
- info("Created: " + ct);
+ info("Conversion complete, created: " + ct);
}
void stats() throws Throwable {
@@ -372,13 +384,14 @@
return true;
}
- String derbySystemHome = null;
-
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-debug")) {
debug = true;
} else if (args[i].equals("-ndebug")) {
debug = false;
+ } else if (argpar("-db", args, i)) {
+ i++;
+ dbName = args[i];
} else if (argpar("-dir", args, i)) {
i++;
dirName = args[i];
@@ -436,10 +449,10 @@
usage();
return false;
}
-
- p.put("derby.system.home", derbySystemHome);
}
+ p.put("derby.system.home", derbySystemHome);
+
info("derbySystemHome=" + derbySystemHome);
return true;
@@ -457,6 +470,8 @@
System.out.println(" update the db - if not specified we just validate");
System.out.println(" -dir dirname");
System.out.println(" directory containing timezone defs");
+ System.out.println(" -dsh dirname");
+ System.out.println(" derby db home directory");
System.out.println(" -prefix prefix");
System.out.println(" prefix for timezone ids with leading '/'");
System.out.println("If -update is specified clean or init must be specified ");
@@ -491,6 +506,10 @@
getLog().error(msg);
}
+ protected void warn(String msg) {
+ getLog().warn(msg);
+ }
+
protected void trace(String msg) {
getLog().debug(msg);
}
Modified: trunk/tzutil/src/org/bedework/timezones/tzutil/XmlToV.java
===================================================================
--- trunk/tzutil/src/org/bedework/timezones/tzutil/XmlToV.java 2008-07-02 04:02:42 UTC (rev 29)
+++ trunk/tzutil/src/org/bedework/timezones/tzutil/XmlToV.java 2008-07-24 19:43:24 UTC (rev 30)
@@ -57,6 +57,7 @@
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
+import java.io.StringReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
@@ -70,8 +71,12 @@
*
*/
public class XmlToV implements TzDefs {
+ private static XmlToV parser =new XmlToV();
+
private boolean debug = true;
+ private boolean verbose = false;
+
/** Parse a single timezone definition delivered as a String value and
* return the TimeZoneInfo object for the specification.
*
@@ -81,15 +86,15 @@
*/
public static TimezoneInfo parseXml(String xmlData) throws Throwable {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(false);
+ factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(new InputSource(xmlData));
+ Document doc = builder.parse(new InputSource(new StringReader(xmlData)));
Element root = doc.getDocumentElement();
- return new XmlToV().parseXml(root);
+ return parser.parseXml(root);
}
/**
@@ -103,6 +108,7 @@
}
VTimeZone tz = new VTimeZone();
+ String name = null;
Collection<TimezoneChange> tzChanges = null;
PropertyList pl = tz.getProperties();
@@ -110,7 +116,8 @@
Element[] tzNodes = TzUtil.getElementsArray(tzEl);
for (Element el: tzNodes) {
if (TzUtil.nodeMatches(el, tzid)) {
- pl.add(new TzId(TzUtil.getElementContent(el)));
+ name = TzUtil.getElementContent(el);
+ pl.add(new TzId(name));
continue;
}
@@ -151,7 +158,7 @@
debugMsg(tz.toString());
}
- return new TimezoneInfo(tz, tzChanges);
+ return new TimezoneInfo(name, tz, tzChanges);
}
private Collection<TimezoneChange> parseChanges(Element chgsEl) throws Throwable {
@@ -167,7 +174,7 @@
String desc = null;
PeriodList affectedlist = null;
- if (debug) {
+ if (debug && verbose) {
debugMsg("parseChanges: start-change");
}
@@ -258,7 +265,7 @@
Observance ob = null;
- if (debug) {
+ if (debug && verbose) {
debugMsg("parseObservance: start");
}
@@ -387,27 +394,27 @@
for (int i = 0; i < attrCt; i++) {
Node attr = nnm.item(i);
- if (debug) {
+ if (debug && verbose) {
debugMsg("attr: " + attr);
}
- if (TzUtil.nodeMatches(el, date)) {
+ if (TzUtil.nodeMatches(attr, date)) {
// Equivalent to RDATE
dateVal = attr.getNodeValue();
continue;
}
- if (TzUtil.nodeMatches(el, month)) {
+ if (TzUtil.nodeMatches(attr, month)) {
bymonthVal = attr.getNodeValue();
continue;
}
- if (TzUtil.nodeMatches(el, monthday)) {
+ if (TzUtil.nodeMatches(attr, monthday)) {
bymonthdayVal = attr.getNodeValue();
continue;
}
- if (TzUtil.nodeMatches(el, day)) {
+ if (TzUtil.nodeMatches(attr, day)) {
bydayVal = attr.getNodeValue();
continue;
}
More information about the Bedework-commit
mailing list