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; + } }