Hi,

It seems that the schema type for java.util.Date has changed from xs:dateTime 
to xs:date in Axis2 1.5. This is preventing me from upgrading, since the 
application depends on having both the date and time available for many 
operations.

The attached patch adds a configuration option to change the schema type back 
to xs:dateTime. When the service parameter JavaDateSchemaType is set to 
xs:dateTime, the format used by SimpleTypeMapper is yyyy-MM-dd'T'HH:mm:ss.SSSZ, 
otherwise it is yyyy-MM-dd like before. Note that the format is different from 
Axis2 1.4.1 because of the TimeZone parameter that was added in 1.5. Setting 
the TimeZone to GMT restores the old behavior completely.

This patch only modifies the formatting in SimpleTypeMapper. Java2WSDL still 
treats Date as xs:date. This doesn't matter for me, since the schema is easy to 
fix using a custom SchemaGenerator or by running the wsdl through sed. Still, 
it doesn't seem hard to add the corresponding support to Java2WSDL.

This fixes issues AXIS2-4329 and AXIS2-4370.

Regards,

Pétur Runólfsson
Betware

The content of this e-mail, together with any of its attachments, is for the 
exclusive and confidential use of the named addressee(s) and it may contain 
legally privileged and confidential information and/or copyrighted material. 
Any other distribution, use or reproduction without the sender's prior consent 
is unauthorized and strictly prohibited. If you have by coincidence, mistake or 
without specific authorization received this e-mail in error, please notify the 
sender by e-mail immediately, uphold strict confidentiality and neither read, 
copy, transfer, disseminate, disclose nor otherwise make use of its content in 
any way and delete the material from your computer.

The content of the e-mail and its attachments is the liability of the 
individual sender, if it does not relate to the affairs of Betware.
Betware does not assume any civil or criminal liability should the e-mail or 
it´s attachments be virus infected.
Index: test/org/apache/axis2/databinding/typemapping/SimpleTypeMapperTest.java
===================================================================
--- test/org/apache/axis2/databinding/typemapping/SimpleTypeMapperTest.java	(revision 0)
+++ test/org/apache/axis2/databinding/typemapping/SimpleTypeMapperTest.java	(revision 0)
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.databinding.typemapping;
+
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+
+import junit.framework.TestCase;
+
+import javax.activation.DataHandler;
+
+import java.awt.datatransfer.Transferable;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class SimpleTypeMapperTest extends TestCase {
+
+    private MessageContext msgContext;
+    private AxisService axisService;
+    private TimeZone prevTimeZone;
+    
+    @Override
+    protected void setUp() throws Exception {
+        prevTimeZone = TimeZone.getDefault();
+        
+        axisService = new AxisService();
+        msgContext = new MessageContext();
+        msgContext.setAxisService(axisService);
+        MessageContext.setCurrentMessageContext(msgContext);
+    }
+    
+    @Override
+    protected void tearDown() throws Exception {
+        MessageContext.setCurrentMessageContext(null);
+        
+        TimeZone.setDefault(prevTimeZone);
+    }
+
+    public void testDataHandlerTypes() {
+        assertTrue(SimpleTypeMapper.isDataHandler(DataHandler.class));
+        assertTrue(SimpleTypeMapper.isDataHandler(Transferable.class));
+    }
+
+    public void testNonDataHandlerTypes() {
+        assertFalse(SimpleTypeMapper.isDataHandler(Object.class));
+    }
+
+    public void testGetStringValueFromDate() {
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeZone() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("Europe/Helsinki"));
+
+        Date date = getDate();
+
+        axisService.addParameter("TimeZone", "Pacific/Honolulu");
+        
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-09", result);
+    }
+
+    public void testGetStringValueFromDateWithTime() throws Exception {
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T09:16:37.000", result.substring(0, 23));
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneHonolulu() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("Europe/Helsinki"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "Pacific/Honolulu");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-09T20:16:37.000-10:00", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneMadrid() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("Europe/Helsinki"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "Europe/Madrid");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T08:16:37.000+02:00", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneCaracas() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "America/Caracas");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T04:46:37.000-04:30", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneKathmandu() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "Asia/Kathmandu");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T15:01:37.000+05:45", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneLocalNewYork() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T09:16:37.000-04:00", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneGMT() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("Australia/Darwin"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "GMT");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-09T23:46:37.000Z", result);
+    }
+
+    public void testGetStringValueFromDateWithTimeAndTimeZoneUTC() throws Exception {
+        TimeZone.setDefault(TimeZone.getTimeZone("America/Phoenix"));
+
+        axisService.addParameter("JavaDateSchemaType", "xs:dateTime");
+        axisService.addParameter("TimeZone", "UTC");
+        
+        Date date = getDate();
+
+        String result = SimpleTypeMapper.getStringValue(date);
+        assertEquals("2009-06-10T16:16:37.000Z", result);
+    }
+    
+    private Date getDate() {
+        Calendar cal = Calendar.getInstance();
+        cal.clear();
+        cal.set(2009, Calendar.JUNE, 10, 9, 16, 37);
+        return cal.getTime();
+    }
+}

Index: src/org/apache/axis2/databinding/typemapping/SimpleTypeMapper.java
===================================================================
--- src/org/apache/axis2/databinding/typemapping/SimpleTypeMapper.java	(revision 783685)
+++ src/org/apache/axis2/databinding/typemapping/SimpleTypeMapper.java	(working copy)
@@ -291,16 +291,7 @@
             zulu.setTimeZone(TimeZone.getTimeZone("GMT"));
             return zulu.format(((Calendar)obj).getTime());
         } else if (obj instanceof Date) {
-            SimpleDateFormat zulu = new SimpleDateFormat("yyyy-MM-dd");
-
-            MessageContext messageContext = MessageContext.getCurrentMessageContext();
-            AxisService axisServce = messageContext.getAxisService();
-            // if the user has given a pirticualr timezone we use it.
-            if (axisServce.getParameter("TimeZone") != null){
-               zulu.setTimeZone(TimeZone.getTimeZone((String)axisServce.getParameter("TimeZone").getValue()));
-            }
-
-            return zulu.format(obj);
+            return formatDate(obj);
         }
         return obj.toString();
     }
@@ -313,4 +304,51 @@
         return ConverterUtil.convertToDateTime(source).getTime();
     }
 
+    /**
+     * Formats a date. The formatting depends on two service parameters. If the
+     * <code>JavaDateSchemaType</code> parameter is set to xs:dateTime, the date
+     * is formatted as xs:dateTime, otherwise it is formatted as xs:date. If the
+     * <code>TimeZone</code> parameter is set, the date is formatted in the
+     * specified time zone, otherwise the default time zone is used.
+     * 
+     * @param obj
+     * @return a string representing the date
+     */
+    private static String formatDate(Object obj) {
+        MessageContext messageContext = MessageContext.getCurrentMessageContext();
+        AxisService axisService = messageContext.getAxisService();
+
+        TimeZone zone;
+        // if the user has given a particular timezone we use it.
+        String zoneParam = (String) axisService.getParameterValue("TimeZone");
+        if (zoneParam != null) {
+            zone = TimeZone.getTimeZone(zoneParam);
+        } else {
+            zone = TimeZone.getDefault();
+        }
+        
+        SimpleDateFormat zulu;
+        boolean hasZoneOffset = false;
+
+        // If the user wants to treat Date as xs:dateTime, add hours, minutes,
+        // seconds, milliseconds and time zone
+        if ("xs:dateTime".equals(axisService.getParameterValue("JavaDateSchemaType"))) {
+            if ("GMT".equals(zone.getID()) || "UTC".equals(zone.getID())) {
+                zulu = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+            } else {
+                zulu = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+                hasZoneOffset = true;
+            }
+        } else {
+            zulu = new SimpleDateFormat("yyyy-MM-dd");
+        }
+        zulu.setTimeZone(zone);
+
+        String result = zulu.format(obj);
+        if (hasZoneOffset) {
+            // SimpleDateFormat formats timezone like +0300, but xs:dateTime wants +03:00 
+            result = result.substring(0, result.length() - 2) + ":" + result.substring(result.length() - 2);
+        }
+        return result;
+    }
 }

Reply via email to