rubys 01/07/08 08:19:26 Modified: java/samples/interop DeploymentDescriptor.xml java/src/org/apache/soap/encoding/soapenc DateSerializer.java Log: Serialize dates without losing precision (the JDK format is contains milliseconds). Deserialize dates with any number of digits of fractional seconds, and with or without a time zone offset. Revision Changes Path 1.7 +2 -7 xml-soap/java/samples/interop/DeploymentDescriptor.xml Index: DeploymentDescriptor.xml =================================================================== RCS file: /home/cvs/xml-soap/java/samples/interop/DeploymentDescriptor.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- DeploymentDescriptor.xml 2001/07/07 13:41:55 1.6 +++ DeploymentDescriptor.xml 2001/07/08 15:19:25 1.7 @@ -41,17 +41,12 @@ java2XMLClassName="samples.interop.DataSerializer" xml2JavaClassName="samples.interop.DataSerializer"/> -<!-- <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:x="" qname="x:inputBase64" - javaType="java.lang.Byte[]" - java2XMLClassName="org.apache.soap.encoding.soapenc.Base64Deserializer"/> - xml2JavaClassName="org.apache.soap.encoding.soapenc.Base64Deserializer"/> ---> + xml2JavaClassName="org.apache.soap.encoding.soapenc.Base64Serializer"/> + <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:x="" qname="x:inputDate" - javaType="java.util.Date" - java2XMLClassName="org.apache.soap.encoding.soapenc.DateSerializer" xml2JavaClassName="org.apache.soap.encoding.soapenc.DateSerializer"/> <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:x="" qname="x:inputDecimal" 1.3 +70 -11 xml-soap/java/src/org/apache/soap/encoding/soapenc/DateSerializer.java Index: DateSerializer.java =================================================================== RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/DateSerializer.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DateSerializer.java 2001/05/25 19:15:49 1.2 +++ DateSerializer.java 2001/07/08 15:19:26 1.3 @@ -75,25 +75,19 @@ * @author Phil Mork * @author Glen Daniels ([EMAIL PROTECTED]) * @author Matthew J. Duftler ([EMAIL PROTECTED]) +* @author Sam Ruby ([EMAIL PROTECTED]) * @see Serializer * @see Deserializer */ public class DateSerializer implements Serializer, Deserializer { SimpleDateFormat sdf; - SimpleDateFormat sdf_ms; public DateSerializer() { - /* - Some folks seem to give with milliseconds, some without. - Let's handle both until we figure out the right thing to do. - */ - sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - sdf_ms = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z'"); - - //For now just use the default locale timezone - //sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + // 0123456789 0 123456789 + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); } public void marshall(String inScopeEncStyle, Class javaType, Object src, @@ -146,7 +140,72 @@ { try { - date=sdf_ms.parse(value); + // validate fixed portion of format + if (value.length() < 19) + throw new ParseException("",0); + + if (value.charAt(4) != '-' || value.charAt(7) != '-' || + value.charAt(10) != 'T') + throw new ParseException("",0); + + if (value.charAt(13) != ':' || value.charAt(16) != ':') + throw new ParseException("",0); + + // convert what we have validated so far + try { + date=sdf.parse(value.substring(0,19)+".000Z"); + } catch (Exception e) { + throw new ParseException("",0); + } + + int pos = 19; + + // parse optional milliseconds + if (pos < value.length() && value.charAt(pos)=='.') { + int milliseconds = 0; + int start = ++pos; + while (pos<value.length() && Character.isDigit(value.charAt(pos))) + pos++; + + String decimal=value.substring(start,pos); + if (decimal.length()==3) { + milliseconds=Integer.parseInt(decimal); + } else if (decimal.length() < 3) { + milliseconds=Integer.parseInt((decimal+"000").substring(0,3)); + } else { + milliseconds=Integer.parseInt(decimal.substring(0,3)); + if (decimal.charAt(3)>='5') ++milliseconds; + } + + // add milliseconds to the current result + date.setTime(date.getTime()+milliseconds); + } + + // parse optional timezone + if (pos+5 < value.length() && + (value.charAt(pos)=='+' || (value.charAt(pos)=='-'))) + { + if (!Character.isDigit(value.charAt(pos+1)) || + !Character.isDigit(value.charAt(pos+2)) || + value.charAt(pos+3) != ':' || + !Character.isDigit(value.charAt(pos+4)) || + !Character.isDigit(value.charAt(pos+5))) + throw new ParseException("",0); + + int hours = (value.charAt(pos+1)-'0')*10+value.charAt(pos+2)-'0'; + int mins = (value.charAt(pos+4)-'0')*10+value.charAt(pos+5)-'0'; + int milliseconds = (hours*60+mins)*60*1000; + + // subtract milliseconds from the current date to obtain GMT + if (value.charAt(pos)=='+') milliseconds=-milliseconds; + date.setTime(date.getTime()+milliseconds); + pos+=6; + } + + if (pos < value.length() && value.charAt(pos)=='Z') pos++; + + if (pos < value.length()) + throw new ParseException("",0); } catch (ParseException pe2) {