Mega Code Archive

 
Categories / Java / XML
 

Parse and format xs

/*  * 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.  */ 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>xs:dateTime</code> values.</p>  */ public class XsDateTimeFormat extends Format {   private static final long serialVersionUID = 3258131340871479609L;   final boolean parseDate;     final boolean parseTime;     XsDateTimeFormat(boolean pParseDate, boolean pParseTime) {         parseDate = pParseDate;         parseTime = pParseTime;     }     /** Creates a new instance.      */     public XsDateTimeFormat() {         this(true, true);     }     private int parseInt(String pString, int pOffset, StringBuffer pDigits) {         int length = pString.length();         pDigits.setLength(0);         while (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();         boolean isMinus = false;         StringBuffer digits = new StringBuffer();         int year, month, mday;         if (parseDate) {             // Sign             if (offset < length) {                 char c = pString.charAt(offset);                 if (c == '+') {                     ++offset;                 } else if (c == '-') {                     ++offset;                     isMinus = true;                 }             }           offset = parseInt(pString, offset, digits);           if (digits.length() < 4) {               pParsePosition.setErrorIndex(offset);               return null;           }           year = Integer.parseInt(digits.toString());              if (offset < length  &&  pString.charAt(offset) == '-') {               ++offset;           } else {               pParsePosition.setErrorIndex(offset);               return null;           }              offset = parseInt(pString, offset, digits);           if (digits.length() != 2) {               pParsePosition.setErrorIndex(offset);               return null;           }           month = Integer.parseInt(digits.toString());              if (offset < length &&  pString.charAt(offset) == '-') {               ++offset;           } else {               pParsePosition.setErrorIndex(offset);               return null;           }              offset = parseInt(pString, offset, digits);           if (digits.length() != 2) {               pParsePosition.setErrorIndex(offset);               return null;           }           mday = Integer.parseInt(digits.toString());           if (parseTime) {               if (offset < length  &&  pString.charAt(offset) == 'T') {                   ++offset;               } else {                   pParsePosition.setErrorIndex(offset);                   return null;               }           }         } else {             year = month = mday = 0;         }         int hour, minute, second, millis;         if (parseTime) {           offset = parseInt(pString, offset, digits);           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);           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);           if (digits.length() != 2) {               pParsePosition.setErrorIndex(offset);               return null;           }           second = Integer.parseInt(digits.toString());              if (offset < length  &&  pString.charAt(offset) == '.') {               ++offset;               offset = parseInt(pString, offset, digits);               if (digits.length() > 0) {                   millis = Integer.parseInt(digits.toString());                     if (millis > 999) {                         pParsePosition.setErrorIndex(offset);                         return null;                     }                     for (int i = digits.length();  i < 3;  i++) {                         millis *= 10;                     }               } else {                   millis = 0;               }           } else {               millis = 0;           }         } else {             hour = minute = second = millis = 0;         }         digits.setLength(0);         digits.append("GMT");         if (offset < length) {             char c = pString.charAt(offset);             if (c == 'Z') {                 // Ignore UTC, it is the default                 ++offset;             } else if (c == '+' || c == '-') {                 digits.append(c);                 ++offset;                 for (int i = 0;  i < 5;  i++) {                     if (offset >= length) {                         pParsePosition.setErrorIndex(offset);                         return null;                     }                     c = pString.charAt(offset);                     if ((i != 2  &&  Character.isDigit(c))  ||                         (i == 2  &&  c == ':')) {                         digits.append(c);                     } else {                         pParsePosition.setErrorIndex(offset);                         return null;                     }                     ++offset;                 }             }         }         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(digits.toString()));         cal.set(isMinus ? -year : year, parseDate ? month-1 : month, mday, hour, minute, second);         cal.set(Calendar.MILLISECOND, millis);         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;         if (parseDate) {           int year = cal.get(Calendar.YEAR);           if (year < 0) {               pBuffer.append('-');               year = -year;           }           append(pBuffer, year, 4);           pBuffer.append('-');           append(pBuffer, cal.get(Calendar.MONTH)+1, 2);           pBuffer.append('-');           append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2);           if (parseTime) {               pBuffer.append('T');           }         }         if (parseTime) {           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);           int millis = cal.get(Calendar.MILLISECOND);           if (millis > 0) {               pBuffer.append('.');               append(pBuffer, millis, 3);           }         }         TimeZone tz = cal.getTimeZone();         // JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis());         int offset = cal.get(Calendar.ZONE_OFFSET);         if (tz.inDaylightTime(cal.getTime())) {           offset += cal.get(Calendar.DST_OFFSET);         }         if (offset == 0) {             pBuffer.append('Z');         } else {             if (offset < 0) {                 pBuffer.append('-');                 offset = -offset;             } else {                 pBuffer.append('+');             }             int minutes = offset / (60*1000);             int hours = minutes / 60;             minutes -= hours * 60;             append(pBuffer, hours, 2);             pBuffer.append(':');             append(pBuffer, minutes, 2);         }         return pBuffer;     } } ///////////////////////////////////////////////// /*  * Copyright 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.ws.commons.util.test; import java.text.Format; import java.text.ParseException; import java.util.Calendar; import java.util.TimeZone; import org.apache.ws.commons.util.XsDateFormat; import org.apache.ws.commons.util.XsDateTimeFormat; import org.apache.ws.commons.util.XsTimeFormat; import junit.framework.TestCase; /** <p>Test case for the various instances of {@link java.text.Format},  * which are being used to parse special types like <code>xs:dateTime</code>.</p>  *  * @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>  */ public class XsDateTimeFormatTest extends TestCase {     /** Creates a new test with the given name.      */     public XsDateTimeFormatTest(String pName) {         super(pName);     }     private Calendar getCalendar(TimeZone pTimeZone) {         Calendar cal = Calendar.getInstance(pTimeZone);         cal.set(2004, 01-1, 14, 03, 12, 07);         cal.set(Calendar.MILLISECOND, 0);         return cal;     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsDateTimeFormat#format(Object, StringBuffer, java.text.FieldPosition)}.      */     public void testFormatDateTime() {         Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         XsDateTimeFormat format = new XsDateTimeFormat();         String got = format.format(cal);         String expect = "2004-01-14T03:12:07Z";         assertEquals(expect, got);         cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         got = format.format(cal);         expect = "2004-01-14T03:12:07-03:00";         assertEquals(expect, got);     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsDateTimeFormat#parseObject(String, java.text.ParsePosition)}.      */     public void testParseDateTime() throws ParseException {         String[] dateTimes = new String[]{       "2004-01-14T03:12:07.000Z",       "2004-01-14T03:12:07",       "2004-01-14T03:12:07-00:00",       "2004-01-14T03:12:07+00:00",     };         XsDateTimeFormat format = new XsDateTimeFormat();         Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));         for (int i = 0;  i < dateTimes.length;  i++) {             Calendar got = (Calendar) format.parseObject(dateTimes[0]);             assertEquals(expect, got);         }         String dateTime = "2004-01-14T03:12:07.000-03:00";         expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         Calendar got = (Calendar) format.parseObject(dateTime);         assertEquals(expect, got);     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsDateFormat#format(Object, StringBuffer, java.text.FieldPosition)}.      */     public void testFormatDate() {         Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         XsDateFormat format = new XsDateFormat();         String got = format.format(cal);         String expect = "2004-01-14Z";         assertEquals(expect, got);         cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         got = format.format(cal);         expect = "2004-01-14-03:00";         assertEquals(expect, got);     }     protected void assertEqualDate(Calendar pExpect, Calendar pGot) {         assertEquals(pExpect.get(Calendar.YEAR), pGot.get(Calendar.YEAR));         assertEquals(pExpect.get(Calendar.MONTH), pGot.get(Calendar.MONTH));         assertEquals(pExpect.get(Calendar.DAY_OF_MONTH), pGot.get(Calendar.DAY_OF_MONTH));         assertEquals(pExpect.getTimeZone(), pGot.getTimeZone());     }     protected void assertEqualTime(Calendar pExpect, Calendar pGot) {         assertEquals(pExpect.get(Calendar.HOUR_OF_DAY), pGot.get(Calendar.HOUR_OF_DAY));         assertEquals(pExpect.get(Calendar.MINUTE), pGot.get(Calendar.MINUTE));         assertEquals(pExpect.get(Calendar.SECOND), pGot.get(Calendar.SECOND));         assertEquals(pExpect.get(Calendar.MILLISECOND), pGot.get(Calendar.MILLISECOND));         assertEquals(pExpect.getTimeZone(), pGot.getTimeZone());     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsDateFormat#parseObject(String, java.text.ParsePosition)}.      */     public void testParseDate() throws ParseException {         String[] dateTimes = new String[]{       "2004-01-14Z",       "2004-01-14",       "2004-01-14+00:00",       "2004-01-14-00:00",         };         XsDateFormat format = new XsDateFormat();         Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));         for (int i = 0;  i < dateTimes.length;  i++) {             Calendar got = (Calendar) format.parseObject(dateTimes[0]);             assertEqualDate(expect, got);         }         String dateTime = "2004-01-14-03:00";         expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         Calendar got = (Calendar) format.parseObject(dateTime);         assertEqualDate(expect, got);     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsTimeFormat#format(Object, StringBuffer, java.text.FieldPosition)}.      */     public void testFormatTime() {         Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         XsTimeFormat format = new XsTimeFormat();         String got = format.format(cal);         String expect = "03:12:07Z";         assertEquals(expect, got);         cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         assertEquals(0, cal.get(Calendar.MILLISECOND));         got = format.format(cal);         expect = "03:12:07-03:00";         assertEquals(expect, got);     }     /** Test for      * {@link org.apache.ws.jaxme.xs.util.XsTimeFormat#parseObject(String, java.text.ParsePosition)}.      */     public void testParseTime() throws ParseException {         String[] dateTimes = new String[]{       "03:12:07.000Z",       "03:12:07",       "03:12:07-00:00",       "03:12:07+00:00",         };         XsTimeFormat format = new XsTimeFormat();         Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));         for (int i = 0;  i < dateTimes.length;  i++) {             Calendar got = (Calendar) format.parseObject(dateTimes[0]);             assertEqualTime(expect, got);         }         String dateTime = "03:12:07.000-03:00";         expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));         Calendar got = (Calendar) format.parseObject(dateTime);         assertEqualTime(expect, got);     }     /** Tests, whether e zero as suffix matters in milliseconds.      */     public void testZeroSuffix() throws Exception {         Format format = new XsDateTimeFormat();         Calendar c1 = (Calendar) format.parseObject("2006-05-03T15:29:17.15Z");         Calendar c2 = (Calendar) format.parseObject("2006-05-03T15:29:17.150Z");         assertEquals(c1, c2);         format = new XsTimeFormat();         c1 = (Calendar) format.parseObject("15:29:17.15Z");         c2 = (Calendar) format.parseObject("15:29:17.150Z");         assertEquals(c1, c2);     } }