You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by jo...@apache.org on 2006/05/20 23:10:48 UTC

svn commit: r408093 - in /webservices/xmlrpc/trunk: client/src/main/java/org/apache/xmlrpc/client/ common/src/main/java/org/apache/xmlrpc/ common/src/main/java/org/apache/xmlrpc/common/ common/src/main/java/org/apache/xmlrpc/parser/ common/src/main/jav...

Author: jochen
Date: Sat May 20 14:10:47 2006
New Revision: 408093

URL: http://svn.apache.org/viewvc?rev=408093&view=rev
Log:
Removed support for java.util.Calendar by default in favour of a new extension type ex:dateTime.

Added:
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/CalendarParser.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/CalendarSerializer.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeDateFormat.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeFormat.java
Modified:
    webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLocalTransport.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfig.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfigImpl.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/common/TypeFactoryImpl.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/DateParser.java
    webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/DateSerializer.java
    webservices/xmlrpc/trunk/src/site/apt/index.apt
    webservices/xmlrpc/trunk/src/site/apt/types.apt
    webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
    webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java

Modified: webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLocalTransport.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLocalTransport.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLocalTransport.java (original)
+++ webservices/xmlrpc/trunk/client/src/main/java/org/apache/xmlrpc/client/XmlRpcLocalTransport.java Sat May 20 14:10:47 2006
@@ -15,6 +15,7 @@
  */
 package org.apache.xmlrpc.client;
 
+import java.util.Date;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -55,6 +56,7 @@
 			return false;
 		} else {
 			return !(pObject instanceof Integer
+                     ||  pObject instanceof Date
 					 ||  pObject instanceof String
 					 ||  pObject instanceof byte[]
 					 ||  pObject instanceof Double);

Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfig.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfig.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfig.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfig.java Sat May 20 14:10:47 2006
@@ -15,6 +15,8 @@
  */
 package org.apache.xmlrpc;
 
+import java.util.TimeZone;
+
 
 /** A common base interface for
  * {@link org.apache.xmlrpc.client.XmlRpcClientConfig}, and
@@ -30,4 +32,9 @@
 	 * @return Whether extensions are enabled or not.
 	 */
 	boolean isEnabledForExtensions();
+
+	/** Returns the timezone, which is used to interpret date/time
+     * values. Defaults to {@link TimeZone#getDefault()}.
+	 */
+    TimeZone getTimeZone();
 }

Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfigImpl.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfigImpl.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfigImpl.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/XmlRpcConfigImpl.java Sat May 20 14:10:47 2006
@@ -15,6 +15,8 @@
  */
 package org.apache.xmlrpc;
 
+import java.util.TimeZone;
+
 import org.apache.xmlrpc.common.XmlRpcHttpConfig;
 
 
@@ -25,6 +27,7 @@
 	private boolean contentLengthOptional;
 	private String basicEncoding;
 	private String encoding;
+    private TimeZone timeZone = TimeZone.getDefault();
 
 	public boolean isEnabledForExtensions() { return enabledForExtensions; }
 
@@ -69,4 +72,15 @@
 	public void setContentLengthOptional(boolean pContentLengthOptional) {
 		contentLengthOptional = pContentLengthOptional;
 	}
+
+    public TimeZone getTimeZone() {
+        return timeZone;
+    }
+
+    /** Returns the timezone, which is used to interpret date/time
+     * values. Defaults to {@link TimeZone#getDefault()}.
+     */
+    public void setTimeZone(TimeZone pTimeZone) {
+        timeZone = pTimeZone;
+    }
 }

Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/common/TypeFactoryImpl.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/common/TypeFactoryImpl.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/common/TypeFactoryImpl.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/common/TypeFactoryImpl.java Sat May 20 14:10:47 2006
@@ -18,15 +18,18 @@
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.TimeZone;
 
 import org.apache.ws.commons.util.NamespaceContextImpl;
 import org.apache.xmlrpc.parser.BigDecimalParser;
 import org.apache.xmlrpc.parser.BigIntegerParser;
 import org.apache.xmlrpc.parser.BooleanParser;
 import org.apache.xmlrpc.parser.ByteArrayParser;
+import org.apache.xmlrpc.parser.CalendarParser;
 import org.apache.xmlrpc.parser.DateParser;
 import org.apache.xmlrpc.parser.DoubleParser;
 import org.apache.xmlrpc.parser.FloatParser;
@@ -45,6 +48,7 @@
 import org.apache.xmlrpc.serializer.BigIntegerSerializer;
 import org.apache.xmlrpc.serializer.BooleanSerializer;
 import org.apache.xmlrpc.serializer.ByteArraySerializer;
+import org.apache.xmlrpc.serializer.CalendarSerializer;
 import org.apache.xmlrpc.serializer.DateSerializer;
 import org.apache.xmlrpc.serializer.DoubleSerializer;
 import org.apache.xmlrpc.serializer.FloatSerializer;
@@ -61,6 +65,7 @@
 import org.apache.xmlrpc.serializer.StringSerializer;
 import org.apache.xmlrpc.serializer.TypeSerializer;
 import org.apache.xmlrpc.serializer.XmlRpcWriter;
+import org.apache.xmlrpc.util.XmlRpcDateTimeDateFormat;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
 
@@ -73,7 +78,6 @@
 	private static final TypeSerializer I4_SERIALIZER = new I4Serializer();
 	private static final TypeSerializer BOOLEAN_SERIALIZER = new BooleanSerializer();
 	private static final TypeSerializer DOUBLE_SERIALIZER = new DoubleSerializer();
-	private static final TypeSerializer DATE_SERIALIZER = new DateSerializer();
 	private static final TypeSerializer BYTE_SERIALIZER = new I1Serializer();
 	private static final TypeSerializer SHORT_SERIALIZER = new I2Serializer();
 	private static final TypeSerializer LONG_SERIALIZER = new I8Serializer();
@@ -82,8 +86,10 @@
     private static final TypeSerializer SERIALIZABLE_SERIALIZER = new SerializableSerializer();
     private static final TypeSerializer BIGDECIMAL_SERIALIZER = new BigDecimalSerializer();
     private static final TypeSerializer BIGINTEGER_SERIALIZER = new BigIntegerSerializer();
+    private static final TypeSerializer CALENDAR_SERIALIZER = new CalendarSerializer();
 
 	private final XmlRpcController controller;
+    private DateSerializer dateSerializer;
 
 	/** Creates a new instance.
 	 * @param pController The controller, which operates the type factory.
@@ -140,9 +146,23 @@
 			}
 		} else if (pObject instanceof Double) {
 			return DOUBLE_SERIALIZER;
-		} else if (pObject instanceof Date) {
-			return DATE_SERIALIZER;
-		} else if (pObject instanceof byte[]) {
+		} else if (pObject instanceof Calendar) {
+            if (pConfig.isEnabledForExtensions()) {
+                return CALENDAR_SERIALIZER;
+            } else {
+                throw new SAXException(new XmlRpcExtensionException("Calendar values aren't supported, if isEnabledForExtensions() == false"));
+            }
+        } else if (pObject instanceof Date) {
+            if (dateSerializer == null) {
+                dateSerializer = new DateSerializer(new XmlRpcDateTimeDateFormat(){
+                    private static final long serialVersionUID = 24345909123324234L;
+                    protected TimeZone getTimeZone() {
+                        return controller.getConfig().getTimeZone();
+                    }
+                });
+            }
+            return dateSerializer;
+    	} else if (pObject instanceof byte[]) {
 			return new ByteArraySerializer();
 		} else if (pObject instanceof Object[]) {
 			return new ObjectArraySerializer(this, pConfig);
@@ -202,7 +222,9 @@
                 return new BigIntegerParser();
 			} else if (SerializableSerializer.SERIALIZABLE_TAG.equals(pLocalName)) {
 				return new SerializableParser();
-			}
+			} else if (CalendarSerializer.CALENDAR_TAG.equals(pLocalName)) {
+			    return new CalendarParser();
+            }
 		} else if ("".equals(pURI)) {
 			if (I4Serializer.INT_TAG.equals(pLocalName)  ||  I4Serializer.I4_TAG.equals(pLocalName)) {
 				return new I4Parser();
@@ -211,7 +233,12 @@
 			} else if (DoubleSerializer.DOUBLE_TAG.equals(pLocalName)) {
 				return new DoubleParser();
 			} else if (DateSerializer.DATE_TAG.equals(pLocalName)) {
-				return new DateParser();
+				return new DateParser(new XmlRpcDateTimeDateFormat(){
+                    private static final long serialVersionUID = 7585237706442299067L;
+                    protected TimeZone getTimeZone() {
+                        return controller.getConfig().getTimeZone();
+                    }
+                });
 			} else if (ObjectArraySerializer.ARRAY_TAG.equals(pLocalName)) {
 				return new ObjectArrayParser(pConfig, pContext, this);
 			} else if (MapSerializer.STRUCT_TAG.equals(pLocalName)) {

Added: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/CalendarParser.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/CalendarParser.java?rev=408093&view=auto
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/CalendarParser.java (added)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/CalendarParser.java Sat May 20 14:10:47 2006
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xmlrpc.parser;
+
+import java.text.ParseException;
+
+import org.apache.ws.commons.util.XsDateTimeFormat;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+
+/** Parser for integer values.
+ */
+public class CalendarParser extends AtomicParser {
+	private static final XsDateTimeFormat format = new XsDateTimeFormat();
+
+    protected void setResult(String pResult) throws SAXException {
+		try {
+			super.setResult(format.parseObject(pResult.trim()));
+		} catch (ParseException e) {
+			throw new SAXParseException("Failed to parse integer value: " + pResult,
+										getDocumentLocator());
+		}
+	}
+}

Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/DateParser.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/DateParser.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/DateParser.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/parser/DateParser.java Sat May 20 14:10:47 2006
@@ -17,7 +17,7 @@
 
 import java.text.ParseException;
 
-import org.apache.ws.commons.util.XmlRpcDateTimeFormat;
+import org.apache.xmlrpc.util.XmlRpcDateTimeDateFormat;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
@@ -25,9 +25,15 @@
 /** Parser for integer values.
  */
 public class DateParser extends AtomicParser {
-	private static final XmlRpcDateTimeFormat f = new XmlRpcDateTimeFormat();
+	private final XmlRpcDateTimeDateFormat f;
 
-	protected void setResult(String pResult) throws SAXException {
+    /** Creates a new instance with the given format.
+     */
+    public DateParser(XmlRpcDateTimeDateFormat pFormat) {
+        f = pFormat;
+    }
+
+    protected void setResult(String pResult) throws SAXException {
 		try {
 			super.setResult(f.parseObject(pResult.trim()));
 		} catch (ParseException e) {

Added: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/CalendarSerializer.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/CalendarSerializer.java?rev=408093&view=auto
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/CalendarSerializer.java (added)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/CalendarSerializer.java Sat May 20 14:10:47 2006
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xmlrpc.serializer;
+
+import org.apache.ws.commons.util.XsDateTimeFormat;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+
+/** A {@link TypeSerializer} for date values.
+ */
+public class CalendarSerializer extends TypeSerializerImpl {
+    private static final XsDateTimeFormat format = new XsDateTimeFormat();
+
+    /** Tag name of a BigDecimal value.
+     */
+    public static final String CALENDAR_TAG = "dateTime";
+
+    private static final String EX_CALENDAR_TAG = "ex:" + CALENDAR_TAG;
+
+    /** Tag name of a date value.
+     */
+    public static final String DATE_TAG = "dateTime.iso8601";
+
+	public void write(ContentHandler pHandler, Object pObject) throws SAXException {
+        write(pHandler, CALENDAR_TAG, EX_CALENDAR_TAG, format.format(pObject));
+	}
+}

Modified: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/DateSerializer.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/DateSerializer.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/DateSerializer.java (original)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/serializer/DateSerializer.java Sat May 20 14:10:47 2006
@@ -15,10 +15,7 @@
  */
 package org.apache.xmlrpc.serializer;
 
-import java.util.Calendar;
-import java.util.Date;
-
-import org.apache.ws.commons.util.XmlRpcDateTimeFormat;
+import org.apache.xmlrpc.util.XmlRpcDateTimeDateFormat;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
@@ -26,21 +23,19 @@
 /** A {@link TypeSerializer} for date values.
  */
 public class DateSerializer extends TypeSerializerImpl {
-	/** Tag name of a date value.
-	 */
-	public static final String DATE_TAG = "dateTime.iso8601";
-	private static final XmlRpcDateTimeFormat format = new XmlRpcDateTimeFormat();
+    /** Tag name of a date value.
+     */
+    public static final String DATE_TAG = "dateTime.iso8601";
+
+    private final XmlRpcDateTimeDateFormat format;
+
+    /** Creates a new instance with the given formatter.
+     */
+    public DateSerializer(XmlRpcDateTimeDateFormat pFormat) {
+        format = pFormat;
+    }
+
 	public void write(ContentHandler pHandler, Object pObject) throws SAXException {
-	    final Calendar cal;
-        if (pObject instanceof Calendar) {
-            cal = (Calendar) pObject;
-        } else if (pObject instanceof Date) {
-            cal = Calendar.getInstance();
-            cal.setTime((Date) pObject);
-        } else {
-            throw new IllegalStateException("Expected Calendar|Date, got "
-                    + pObject.getClass().getName());
-        }
-        write(pHandler, DATE_TAG, format.format(cal));
+        write(pHandler, DATE_TAG, format.format(pObject));
 	}
 }

Added: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeDateFormat.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeDateFormat.java?rev=408093&view=auto
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeDateFormat.java (added)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeDateFormat.java Sat May 20 14:10:47 2006
@@ -0,0 +1,32 @@
+package org.apache.xmlrpc.util;
+
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.Date;
+
+
+
+/** An extension of {@link XmlRpcDateTimeFormat}, which accepts
+ * and/or creates instances of {@link Date}.
+ */
+public abstract class XmlRpcDateTimeDateFormat extends XmlRpcDateTimeFormat {
+    private static final long serialVersionUID = -5107387618606150784L;
+
+    public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) {
+        final Object cal;
+        if (pCalendar != null  &&  pCalendar instanceof Date) {
+            Calendar calendar = Calendar.getInstance(getTimeZone());
+            calendar.setTime((Date) pCalendar);
+            cal = calendar;
+        } else {
+            cal = pCalendar;
+        }
+        return super.format(cal, pBuffer, pPos);
+    }
+
+    public Object parseObject(String pString, ParsePosition pParsePosition) {
+        Calendar cal = (Calendar) super.parseObject(pString, pParsePosition);
+        return cal == null ? null : cal.getTime();
+    }
+}

Added: webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeFormat.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeFormat.java?rev=408093&view=auto
==============================================================================
--- webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeFormat.java (added)
+++ webservices/xmlrpc/trunk/common/src/main/java/org/apache/xmlrpc/util/XmlRpcDateTimeFormat.java Sat May 20 14:10:47 2006
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2003, 2004  The Apache Software Foundation
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xmlrpc.util;
+
+
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+
+/** <p>An instance of {@link java.text.Format}, which may be used
+ * to parse and format <code>dateTime</code> values, as specified
+ * by the XML-RPC specification. The specification doesn't precisely
+ * describe the format, it only gives an example:</p>
+ * <pre>
+ *   19980717T14:08:55
+ * </pre>
+ * This class accepts and creates instances of {@link Calendar}.
+ */
+public abstract class XmlRpcDateTimeFormat extends Format {
+    private static final long serialVersionUID = -8008230377361175138L;
+
+    /** Returns the time zone, which is used to interpret date/time
+     * values.
+     */
+    protected abstract TimeZone getTimeZone();
+
+    private int parseInt(String pString, int pOffset, StringBuffer pDigits, int pMaxDigits) {
+        int length = pString.length();
+        pDigits.setLength(0);
+        while (pMaxDigits-- > 0  &&  pOffset < length) {
+            char c = pString.charAt(pOffset);
+            if (Character.isDigit(c)) {
+                pDigits.append(c);
+                ++pOffset;
+            } else {
+                break;
+            }
+        }
+        return pOffset;
+    }
+
+    public Object parseObject(String pString, ParsePosition pParsePosition) {
+        if (pString == null) {
+            throw new NullPointerException("The String argument must not be null.");
+        }
+        if (pParsePosition == null) {
+            throw new NullPointerException("The ParsePosition argument must not be null.");
+        }
+        int offset = pParsePosition.getIndex();
+        int length = pString.length();
+
+        StringBuffer digits = new StringBuffer();
+        int year, month, mday;
+
+        offset = parseInt(pString, offset, digits, 4);
+        if (digits.length() < 4) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        year = Integer.parseInt(digits.toString());
+	
+        offset = parseInt(pString, offset, digits, 2);
+        if (digits.length() != 2) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        month = Integer.parseInt(digits.toString());
+	
+        offset = parseInt(pString, offset, digits, 2);
+        if (digits.length() != 2) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        mday = Integer.parseInt(digits.toString());
+
+        if (offset < length  &&  pString.charAt(offset) == 'T') {
+            ++offset;
+        } else {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+
+        int hour, minute, second;
+        offset = parseInt(pString, offset, digits, 2);
+        if (digits.length() != 2) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        hour = Integer.parseInt(digits.toString());
+	
+        if (offset < length  &&  pString.charAt(offset) == ':') {
+            ++offset;
+        } else {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+	
+        offset = parseInt(pString, offset, digits, 2);
+        if (digits.length() != 2) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        minute = Integer.parseInt(digits.toString());
+	
+        if (offset < length  &&  pString.charAt(offset) == ':') {
+            ++offset;
+        } else {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+	
+        offset = parseInt(pString, offset, digits, 2);
+        if (digits.length() != 2) {
+            pParsePosition.setErrorIndex(offset);
+            return null;
+        }
+        second = Integer.parseInt(digits.toString());
+	
+        Calendar cal = Calendar.getInstance(getTimeZone());
+        cal.set(year, month-1, mday, hour, minute, second);
+        cal.set(Calendar.MILLISECOND, 0);
+        pParsePosition.setIndex(offset);
+        return cal;
+    }
+
+    private void append(StringBuffer pBuffer, int pNum, int pMinLen) {
+        String s = Integer.toString(pNum);
+        for (int i = s.length();  i < pMinLen;  i++) {
+            pBuffer.append('0');
+        }
+        pBuffer.append(s);
+    }
+
+    public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) {
+        if (pCalendar == null) {
+            throw new NullPointerException("The Calendar argument must not be null.");
+        }
+        if (pBuffer == null) {
+            throw new NullPointerException("The StringBuffer argument must not be null.");
+        }
+        if (pPos == null) {
+            throw new NullPointerException("The FieldPosition argument must not be null.");
+        }
+
+        Calendar cal = (Calendar) pCalendar;
+        int year = cal.get(Calendar.YEAR);
+        append(pBuffer, year, 4);
+        append(pBuffer, cal.get(Calendar.MONTH)+1, 2);
+        append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2);
+        pBuffer.append('T');
+        append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2);
+        pBuffer.append(':');
+        append(pBuffer, cal.get(Calendar.MINUTE), 2);
+        pBuffer.append(':');
+        append(pBuffer, cal.get(Calendar.SECOND), 2);
+        return pBuffer;
+    }
+}

Modified: webservices/xmlrpc/trunk/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/site/apt/index.apt?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/src/site/apt/index.apt (original)
+++ webservices/xmlrpc/trunk/src/site/apt/index.apt Sat May 20 14:10:47 2006
@@ -16,6 +16,9 @@
   * All primitive Java types are supported, including long,
     byte, short, and double.
 
+  * Calendar objects are supported. In particular, timezone
+    settings, and milliseconds may be sent.
+
   * DOM nodes, or JAXB objects, can be transmitted. So are
     objects implementing the java.io.Serializable interface.
 

Modified: webservices/xmlrpc/trunk/src/site/apt/types.apt
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/src/site/apt/types.apt?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/src/site/apt/types.apt (original)
+++ webservices/xmlrpc/trunk/src/site/apt/types.apt Sat May 20 14:10:47 2006
@@ -22,8 +22,8 @@
 |                    |                    | precision, floating point number.   |
 |                    |                    | (64 bit)                            |
 *--------------------+--------------------+-------------------------------------+
-| java.util.Calendar | <dateTime.iso8601> | A pseudo ISO8601 timestamp, like    |
-| java.util.Date     |                    | 19980717T14:08:55. However,         |
+| java.util.Date     | <dateTime.iso8601> | A pseudo ISO8601 timestamp, like    |
+|                    |                    | 19980717T14:08:55. However,         |
 |                    |                    | compared to a true ISO8601 value,   |
 |                    |                    | milliseconds, and time zone         |
 |                    |                    | informations are missing.           |
@@ -70,6 +70,11 @@
 | BigDecimal           | <ex:bigdecimal>    | A BigDecimal                        |
 *----------------------+--------------------+-------------------------------------+
 | BigInteger           | <ex:biginteger>    | A BigInteger                        |
+*----------------------+--------------------+-------------------------------------+
+| java.util.Calendar   | <ex:dateTime>      | Unlike the dateTime.iso8601 type,   |
+|                      |                    | this is a full blown xs:dateTime    |
+|                      |                    | value. In particular, it includes   |
+|                      |                    | milliseconds, and timezone settings.|
 *----------------------+--------------------+-------------------------------------+
 
   In the above table, the prefix <<<ex>>> refers to the namespace URI

Modified: webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java (original)
+++ webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/BaseTest.java Sat May 20 14:10:47 2006
@@ -16,9 +16,11 @@
 package org.apache.xmlrpc.test;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.io.StringReader;
 import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -260,14 +262,44 @@
 			}
 		}
 
-		/** Returns the calendar value in milliseconds.
+		/** Example of a Serializable instance.
+		 */
+        public static class CalendarWrapper implements Serializable {
+            private static final long serialVersionUID = 8153663910532549627L;
+            final Calendar cal;
+            CalendarWrapper(Calendar pCalendar) {
+                cal = pCalendar;
+            }
+        }
+
+        /** Returns the calendar value in milliseconds.
 		 * @param pCal Calendar object
 		 * @return <code>pCal.getTime().getTime()</code>.
 		 */
-		public long serializableParam(Calendar pCal) {
-			return pCal.getTime().getTime();
+		public long serializableParam(CalendarWrapper pCal) {
+			return pCal.cal.getTime().getTime();
 		}
-	}
+
+		/** Returns midnight of the following day.
+		 */
+        public Calendar calendarParam(Calendar pCal) {
+            Calendar cal = (Calendar) pCal.clone();
+            cal.add(Calendar.DAY_OF_MONTH, 1);
+            cal.set(Calendar.HOUR_OF_DAY, 0);
+            cal.set(Calendar.MINUTE, 0);
+            cal.set(Calendar.SECOND, 0);
+            cal.set(Calendar.MILLISECOND, 0);
+            return cal;
+        }
+
+        /** Returns midnight of the following day.
+         */
+        public Date dateParam(Date pDate) {
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(pDate);
+            return calendarParam(cal).getTime();
+        }
+    }
 
 	protected XmlRpcHandlerMapping getHandlerMapping() throws IOException, XmlRpcException {
 		return new PropertyHandlerMapping(getClass().getClassLoader(),
@@ -798,7 +830,7 @@
 	}
 
 	/** Test, whether we can invoke a method, passing an instance of
-	 * {@link java.io.Serializable} as an instance.
+	 * {@link java.io.Serializable} as a parameter.
 	 * @throws Exception The test failed.
 	 */
 	public void testSerializableParam() throws Exception {
@@ -810,14 +842,9 @@
 	private void testSerializableParam(ClientProvider pProvider) throws Exception {
 		final String methodName = "Remote.serializableParam";
 		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-		cal.set(Calendar.YEAR, 2005);
-		cal.set(Calendar.MONTH, 5);
-		cal.set(Calendar.DAY_OF_MONTH, 23);
-		cal.set(Calendar.HOUR_OF_DAY, 8);
-		cal.set(Calendar.MINUTE, 4);
-		cal.set(Calendar.SECOND, 0);
+		cal.set(2005, 5, 23, 8, 4, 0);
 		cal.set(Calendar.MILLISECOND, 5);
-		final Object[] params = new Object[]{cal};
+		final Object[] params = new Object[]{new Remote.CalendarWrapper(cal)};
 		final XmlRpcClient client = pProvider.getClient();
 		Object result = client.execute(getExConfig(pProvider), methodName, params);
 		assertEquals(new Long(cal.getTime().getTime()), result);
@@ -829,4 +856,67 @@
 		}
 		assertTrue(ok);
 	}
+
+	/** Tests, whether we can invoke a method, passing an instance of
+     * {@link Calendar} as a parameter.
+     * @throws Exception The test failed.
+	 */
+	public void testCalendarParam() throws Exception {
+	    for (int i = 0;  i < providers.length;  i++) {
+	        testCalendarParam(providers[i]);
+        }
+    }
+
+	private void testCalendarParam(ClientProvider pProvider) throws Exception {
+	    final String methodName = "Remote.calendarParam";
+        Calendar cal1 = newCalendarParam();
+        Calendar cal2 = newCalendarResult();
+        final Object[] params = new Object[]{cal1};
+        final XmlRpcClient client = pProvider.getClient();
+        Object result = client.execute(getExConfig(pProvider), methodName, params);
+        assertEquals(cal2.getTime(), ((Calendar) result).getTime());
+        boolean ok = false;
+        try {
+            client.execute(getConfig(pProvider), methodName, params);
+        } catch (XmlRpcExtensionException e) {
+            ok = true;
+        }
+        assertTrue(ok);
+    }
+
+    private Calendar newCalendarResult() {
+        Calendar cal2 = Calendar.getInstance(TimeZone.getDefault());
+        cal2.set(2005, 5, 24, 0, 0, 0);
+        cal2.set(Calendar.MILLISECOND, 0);
+        return cal2;
+    }
+
+    private Calendar newCalendarParam() {
+        Calendar cal1 = Calendar.getInstance(TimeZone.getDefault());
+        cal1.set(2005, 5, 23, 8, 4, 0);
+        cal1.set(Calendar.MILLISECOND, 5);
+        return cal1;
+    }
+
+    /** Tests, whether we can invoke a method, passing an instance of
+     * {@link Date} as a parameter.
+     * @throws Exception The test failed.
+     */
+    public void testDateParam() throws Exception {
+        for (int i = 0;  i < providers.length;  i++) {
+            testDateParam(providers[i]);
+        }
+    }
+
+    private void testDateParam(ClientProvider pProvider) throws Exception {
+        final String methodName = "Remote.dateParam";
+        Date date1 = newCalendarParam().getTime();
+        Calendar cal2 = newCalendarResult();
+        final Object[] params = new Object[]{date1};
+        final XmlRpcClient client = pProvider.getClient();
+        Object result = client.execute(getExConfig(pProvider), methodName, params);
+        assertEquals(cal2.getTime(), result);
+        result = client.execute(getConfig(pProvider), methodName, params);
+        assertEquals(cal2.getTime(), result);
+    }
 }

Modified: webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java
URL: http://svn.apache.org/viewvc/webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java?rev=408093&r1=408092&r2=408093&view=diff
==============================================================================
--- webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java (original)
+++ webservices/xmlrpc/trunk/tests/src/test/java/org/apache/xmlrpc/test/SerializerTest.java Sat May 20 14:10:47 2006
@@ -137,7 +137,7 @@
 
 	/** Tests serialization of a calendar instance.
 	 */
-    public void testDateParam() throws Exception {
+    public void testCalendarParam() throws Exception {
         TimeZone tz = TimeZone.getTimeZone("GMT");
         Calendar cal1 = Calendar.getInstance(tz);
         cal1.set(1933, 5, 12, 11, 7, 21);
@@ -145,15 +145,15 @@
         Calendar cal2 = Calendar.getInstance(TimeZone.getDefault());
         cal2.set(1933, 5, 12, 11, 7, 21);
         cal2.set(Calendar.MILLISECOND, 311);
-        XmlRpcStreamRequestConfig config = getConfig();
+        XmlRpcStreamRequestConfig config = getExConfig();
         XmlRpcRequest request = new XmlRpcClientRequestImpl(config, "dateParam", new Object[]{cal1, cal2.getTime()});
         String got = writeRequest(config, request);
         String expect =
             "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>"
-            + "<methodCall>"
+            + "<methodCall xmlns:ex=\"http://ws.apache.org/xmlrpc/namespaces/extensions\">"
             + "<methodName>dateParam</methodName><params>"
-            + "<param><value><dateTime.iso8601>1933-06-12T11:07:21.311</dateTime.iso8601></value></param>"
-            + "<param><value><dateTime.iso8601>1933-06-12T11:07:21.311</dateTime.iso8601></value></param>"
+            + "<param><value><ex:dateTime>1933-06-12T11:07:21.311Z</ex:dateTime></value></param>"
+            + "<param><value><dateTime.iso8601>19330612T11:07:21</dateTime.iso8601></value></param>"
             + "</params></methodCall>";
         assertEquals(expect, got);
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: xmlrpc-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: xmlrpc-dev-help@ws.apache.org