| /******************************************************************************* |
| * Copyright (c) 2006 Oracle Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.validator.tools; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.GregorianCalendar; |
| import java.util.Locale; |
| import java.util.TimeZone; |
| |
| import javax.xml.namespace.QName; |
| |
| /** |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| * @author Glenn Mi (glenn.me@oracle.com) |
| * |
| * @date Sep 29, 2006 |
| * |
| */ |
| public class ParserTool { |
| |
| private static final Locale INTERNAL_PARSE_LOCALE = Locale.US; |
| |
| private static final Locale INTERNAL_CAL_LOCALE = Locale.US; |
| |
| private static SimpleDateFormat zulu = new SimpleDateFormat( |
| "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$ |
| |
| static { |
| zulu.setTimeZone(TimeZone.getDefault()); |
| } |
| |
| /** |
| * Format date time string into the format: |
| * 2005-04-04T14:59:11.302-08:00 |
| * |
| * @param time |
| * @return the formatted date time string. |
| */ |
| |
| public static String getDateTimeString(long time) { |
| // 2005-04-04T14:59:11.302-08:00 |
| SimpleDateFormat xmlDateFormat = new SimpleDateFormat( |
| "yyyy-MM-dd'T'HH:mm:ss.SSSZ", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$ |
| Calendar cal = Calendar.getInstance(INTERNAL_CAL_LOCALE); |
| cal.setTime(new Date(time)); |
| String javaFmt = xmlDateFormat.format(cal.getTime()); |
| |
| int length = javaFmt.length(); |
| String dt = javaFmt.substring(0, length - 2); |
| |
| StringBuilder retVal = new StringBuilder(dt); |
| retVal.append(":"); //$NON-NLS-1$ |
| retVal.append(javaFmt.substring(length - 2, length)); |
| |
| return retVal.toString(); |
| } |
| |
| public static String getDateString(long time) { |
| Calendar cal = Calendar.getInstance(INTERNAL_CAL_LOCALE); |
| cal.setTime(new Date(time)); |
| SimpleDateFormat xmlDateFormat = new SimpleDateFormat( |
| "yyyy-MM-dd", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$ |
| return xmlDateFormat.format(cal.getTime()); |
| } |
| |
| /** |
| * parse XML duration in the format of P1Y2M3DT10H30M12.3S |
| * |
| * @param src |
| * @return ? |
| * @throws IllegalArgumentException |
| */ |
| |
| public static long parseDuration(String src) |
| throws IllegalArgumentException { |
| int years = 0; |
| int months = 0; |
| int days = 0; |
| int hours = 0; |
| int minutes = 0; |
| double seconds = 0.; |
| |
| int idx = 0; |
| int idx2 = 0; |
| if (src.charAt(idx) != 'P') |
| throw new IllegalArgumentException( |
| "Duration has to start with 'P'."); //$NON-NLS-1$ |
| idx++; |
| |
| String dayPart = null; |
| String timePart = null; |
| |
| idx2 = src.indexOf('T'); |
| if (idx2 > 0) { |
| dayPart = src.substring(idx, idx2); |
| timePart = src.substring(idx2 + 1); |
| } else { |
| dayPart = src.substring(idx); |
| } |
| |
| try { |
| String str; |
| if (dayPart != null && dayPart.length() > 0) { |
| // parse day part |
| idx = 0; |
| |
| idx2 = dayPart.indexOf('Y'); |
| if (idx2 > 0) { |
| str = dayPart.substring(idx, idx2); |
| years = Integer.parseInt(str); |
| idx = idx2 + 1; |
| } |
| |
| idx2 = dayPart.indexOf('M'); |
| if (idx2 > 0) { |
| str = dayPart.substring(idx, idx2); |
| months = Integer.parseInt(str); |
| idx = idx2 + 1; |
| } |
| |
| idx2 = dayPart.indexOf('D'); |
| if (idx2 > 0) { |
| str = dayPart.substring(idx, idx2); |
| days = Integer.parseInt(str); |
| idx = idx2 + 1; |
| } |
| |
| if (dayPart.indexOf('H') >= 0 || dayPart.indexOf('S') >= 0) |
| throw new NumberFormatException(); |
| } |
| |
| if (timePart != null) { |
| // parse time part |
| idx = 0; |
| |
| idx2 = timePart.indexOf('H'); |
| if (idx2 > 0) { |
| str = timePart.substring(idx, idx2); |
| hours = Integer.parseInt(str); |
| idx = idx2 + 1; |
| } |
| |
| idx2 = timePart.indexOf('M'); |
| if (idx2 > 0) { |
| str = timePart.substring(idx, idx2); |
| minutes = Integer.parseInt(str); |
| idx = idx2 + 1; |
| } |
| |
| idx2 = timePart.indexOf('S'); |
| if (idx2 > 0) { |
| str = timePart.substring(idx, idx2); |
| seconds = Double.parseDouble(str); |
| } |
| |
| if (timePart.indexOf('Y') >= 0 || timePart.indexOf('D') >= 0) |
| throw new NumberFormatException(); |
| } |
| } catch (NumberFormatException e) { |
| throw new IllegalArgumentException( |
| "duration should be in the format of 'P1Y2M3DT10H30M12.3S'"); //$NON-NLS-1$ |
| } |
| |
| long duration = (long) (((((((years * 365 + months * 30) + days) * 24 + hours) * 60) + minutes) * 60 + seconds) * 1000); |
| return duration; |
| } |
| |
| /** |
| * Parse date string into a Date. |
| * |
| * @param dateStr |
| * @return the date |
| */ |
| |
| public static Date parseDate(String dateStr) { |
| try { |
| if( dateStr == null || dateStr.length() < 10 ) |
| throw new NumberFormatException("badDateTime"); //$NON-NLS-1$ |
| |
| SimpleDateFormat df = new SimpleDateFormat( |
| "yyyy-MM-dd", INTERNAL_PARSE_LOCALE); //$NON-NLS-1$ |
| return df.parse( dateStr ); |
| |
| } catch (Exception e) { |
| throw new NumberFormatException(e.toString()); |
| } |
| } |
| |
| public static Date parseDateFromLong(String longString) { |
| if (longString != null) { |
| return new Date(Long.parseLong(longString)); |
| } |
| return null; |
| } |
| |
| public static Calendar parseDateTimeFromLong(String longString) { |
| if (longString != null) { |
| Calendar calendar = Calendar.getInstance(INTERNAL_CAL_LOCALE); |
| calendar.setTime(new Date(Long.parseLong(longString))); |
| return calendar; |
| } |
| return null; |
| } |
| |
| public static Calendar parseDateTime(String source) { |
| return parseDateAndTime(source); |
| } |
| |
| /** |
| * The simple deserializer provides most of the stuff. We just need to |
| * override makeValue(). |
| * |
| * @param source |
| * the source string to parse |
| * @return the Calandar instance that the string was parsed into |
| * |
| */ |
| |
| public static Calendar parseDateAndTime(String source) { |
| if (source == null || isEmpty(source)) |
| return null; |
| |
| Calendar calendar = Calendar.getInstance(INTERNAL_CAL_LOCALE); |
| Date date; |
| boolean bc = false; |
| |
| // validate fixed portion of format |
| if (source.charAt(0) == '+') |
| source = source.substring(1); |
| |
| if (source.charAt(0) == '-') { |
| source = source.substring(1); |
| bc = true; |
| } |
| if (source.length() < 19) { |
| throw new NumberFormatException("badDateTime"); //$NON-NLS-1$ |
| } |
| |
| if (source.charAt(4) != '-' || source.charAt(7) != '-' |
| || source.charAt(10) != 'T') { |
| throw new NumberFormatException("badDate"); //$NON-NLS-1$ |
| } |
| |
| if (source.charAt(13) != ':' || source.charAt(16) != ':') { |
| throw new NumberFormatException("badTime"); //$NON-NLS-1$ |
| } |
| |
| // convert what we have validated so far |
| try { |
| synchronized (zulu) { |
| date = zulu.parse((source.substring(0, 19) + ".000Z")); //$NON-NLS-1$ |
| } |
| } catch (Exception e) { |
| throw new NumberFormatException(e.toString()); |
| } |
| |
| int pos = 19; |
| |
| // parse optional milliseconds |
| if (pos < source.length() && source.charAt(pos) == '.') { |
| int milliseconds = 0; |
| int start = ++pos; |
| while (pos < source.length() |
| && Character.isDigit(source.charAt(pos))) |
| pos++; |
| |
| String decimal = source.substring(start, pos); |
| if (decimal.length() == 3) |
| milliseconds = Integer.parseInt(decimal); |
| else if (decimal.length() < 3) |
| milliseconds = Integer.parseInt((decimal + "000") //$NON-NLS-1$ |
| .substring(0, 3)); |
| else { |
| milliseconds = Integer.parseInt(decimal.substring(0, 3)); |
| if (decimal.charAt(3) >= '5') |
| ++milliseconds; |
| } |
| |
| // add milliseconds to the current date |
| date.setTime(date.getTime() + milliseconds); |
| } |
| |
| // parse optional timezone |
| if (pos + 5 < source.length() |
| && (source.charAt(pos) == '+' || (source.charAt(pos) == '-'))) { |
| if (!Character.isDigit(source.charAt(pos + 1)) |
| || !Character.isDigit(source.charAt(pos + 2)) |
| || source.charAt(pos + 3) != ':' |
| || !Character.isDigit(source.charAt(pos + 4)) |
| || !Character.isDigit(source.charAt(pos + 5))) { |
| throw new NumberFormatException("badTimezone"); //$NON-NLS-1$ |
| } |
| |
| // subtract milliseconds from current date to obtain GMT |
| // if (source.charAt(pos)=='+') milliseconds=-milliseconds; |
| // date.setTime(date.getTime()+milliseconds); |
| pos += 6; |
| } |
| |
| if (pos < source.length() && source.charAt(pos) == 'Z') { |
| pos++; |
| // calendar.setTimeZone(TimeZone.getTimeZone("GMT")); |
| } |
| |
| if (pos < source.length()) |
| throw new NumberFormatException("badChars"); |
| |
| calendar.setTime(date); |
| |
| // support dates before the Christian era |
| if (bc) { |
| calendar.set(Calendar.ERA, GregorianCalendar.BC); |
| } |
| |
| return calendar; |
| } |
| |
| public static float parseFloat(String floatStr) { |
| if (!isEmpty(floatStr)) { |
| return Float.parseFloat(floatStr); |
| } |
| return 0f; |
| } |
| |
| public static double parseDouble(String value) { |
| String v = String.valueOf(value); |
| if (!isEmpty(v)) { |
| return Double.parseDouble(v); |
| } |
| return 0d; |
| } |
| |
| public static int parseInt(String value) { |
| try { |
| if (!isEmpty(value)) { |
| value = String.valueOf(adjustResult(value)); |
| return Integer.parseInt(value); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return 0; |
| |
| } |
| |
| public static boolean parseBoolean(String value) { |
| if (!isEmpty(value)) { |
| return Boolean.valueOf( value ); |
| } |
| return false; |
| } |
| |
| public static short parseShort(String value) { |
| if (!isEmpty(value)) { |
| value = String.valueOf(adjustResult(value)); |
| return Short.parseShort(value); |
| } |
| return 0; |
| } |
| |
| public static byte parseByte(String value) { |
| if (!isEmpty(value)) { |
| return Byte.parseByte(value); |
| } |
| return 0; |
| } |
| |
| public static long parseLong(String value) { |
| if (!isEmpty(value)) { |
| return Long.parseLong(value); |
| } |
| return 0l; |
| } |
| |
| public static char parseChar(String value) { |
| if (!isEmpty(value)) { |
| char arr[] = value.toCharArray(); |
| return arr[0]; |
| } |
| return 0; |
| } |
| |
| public static Object convertToObject(double d) { |
| return Double.valueOf( d ); |
| } |
| |
| public static Object convertToObject(int d) { |
| return Integer.valueOf( d ); |
| } |
| |
| public static Object convertToObject(char d) { |
| return Character.valueOf( d ); |
| } |
| |
| public static Object convertToObject(byte d) { |
| return Byte.valueOf( d ); |
| } |
| |
| public static Object convertToObject(short d) { |
| return Short.valueOf( d ); |
| } |
| |
| public static Object convertToObject(long d) { |
| return Long.valueOf( d ); |
| } |
| |
| public static Object convertToObject(float d) { |
| return Float.valueOf( d ); |
| } |
| |
| public static Object convertToObject(Object d) { |
| return d; |
| } |
| |
| public static String convertToXMLString(Object value) { |
| String xmlString = null; |
| if (value != null) { |
| // Conversion process: |
| // Object -> Object |
| // primitve -> String |
| // |
| Class type = value.getClass(); |
| if (type.isPrimitive()) { |
| xmlString = primitiveToXMLString(value, type); |
| } else if (value instanceof QName) { |
| // calender |
| QName qname = (QName) value; |
| if (qname.getPrefix() != null && qname.getPrefix().length() > 0) |
| xmlString = qname.getPrefix() + ":" + qname.getLocalPart(); |
| else |
| xmlString = qname.getLocalPart(); |
| } else if (value instanceof Calendar) { |
| // calender |
| xmlString = calendarToXMLString((Calendar) value); |
| } else if (value instanceof Date) { |
| xmlString = dateToXMLString((Date) value); |
| } |
| // else if (value instanceof DateTimeBase) |
| // { |
| // xmlString = dateTimeToXMLString( (DateTimeBase) value ); |
| // } |
| // else if (value instanceof Duration) |
| // { |
| // xmlString = durationToXMLString( (Duration) value ); |
| // } |
| else { |
| xmlString = String.valueOf(value); |
| } |
| |
| } |
| return xmlString; |
| } |
| |
| // public static String durationToXMLString( Duration value ) |
| // { |
| // return value != null ? value.toString() : ""; |
| // } |
| // |
| // public static String dateTimeToXMLString( DateTimeBase value ) |
| // { |
| // return value != null ? calendarToXMLString( value.toCalendar() ) : ""; |
| // } |
| // |
| public static String dateToXMLString(Date value) { |
| return value != null ? getDateString(value.getTime()) : ""; |
| } |
| |
| public static String calendarToXMLString(Calendar value) { |
| return value != null ? getDateTimeString(value.getTime().getTime()) |
| : ""; |
| } |
| |
| public static String primitiveToXMLString(Object primitiveObject, Class type) { |
| String xmlString = null; |
| if (type == Double.class) { |
| xmlString = ((Double) primitiveObject).toString(); |
| } else if (type == Integer.class) { |
| xmlString = ((Integer) primitiveObject).toString(); |
| } else if (type == Boolean.class) { |
| xmlString = ((Boolean) primitiveObject).toString(); |
| } else if (type == Float.class) { |
| xmlString = ((Float) primitiveObject).toString(); |
| } else if (type == Byte.class) { |
| xmlString = ((Byte) primitiveObject).toString(); |
| } else if (type == Short.class) { |
| xmlString = ((Short) primitiveObject).toString(); |
| } else if (type == Long.class) { |
| xmlString = ((Long) primitiveObject).toString(); |
| } else if (type == Character.class) { |
| xmlString = ((Character) primitiveObject).toString(); |
| } |
| return xmlString; |
| } |
| |
| public static void main(String[] args) throws Exception { |
| // System.out.println(parseDuration(args[0])); |
| |
| Date d = new Date(); |
| String dtStr = getDateTimeString(d.getTime()); |
| System.out.println("dateTime=" + dtStr); |
| Calendar cal = parseDateTime(dtStr); |
| System.out.println("cal is: " + cal); |
| System.out.println("date is: " + cal.getTime()); |
| System.out.println("XML Datetime " |
| + getDateTimeString(cal.getTime().getTime())); |
| System.out |
| .println("XML Date " + getDateString(cal.getTime().getTime())); |
| |
| } |
| |
| private static Object adjustResult(String result) { |
| if (result != null && result.indexOf(".") > 0) { |
| String dS = result; |
| |
| int fracIndex = dS.indexOf("."); |
| String fr = dS.substring(fracIndex + 1, dS.length()); |
| String in = dS.substring(0, fracIndex); |
| // fraction = (n - abs(n)) |
| // if the fraction is 0 then assume that the result is an integer |
| // and construct an integer object and return it. |
| // |
| // TODO: FIXME Once we have schema types then we should do proper |
| // typed return value |
| // System.out.println("___________ fraction : " + fr ); |
| // System.out.println("___________ before decimal : " + in ); |
| Double d1 = new Double(fr); |
| if (d1.doubleValue() == 0) { |
| return new Integer(in); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Returns true if the string is either null or contains just whitespace. |
| */ |
| |
| static boolean isEmpty(String value) { |
| if (value == null || value.length() == 0) { |
| return true; |
| } |
| for (int i = 0, j = value.length(); i < j; i++) { |
| if (!Character.isWhitespace(value.charAt(i))) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |