| /* |
| * Copyright 2009-2011 by The Regents of the University of California |
| * 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 from |
| * |
| * 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 edu.uci.ics.asterix.dataflow.data.nontagged.serde; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| |
| import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider; |
| import edu.uci.ics.asterix.om.base.AInterval; |
| import edu.uci.ics.asterix.om.base.AMutableInterval; |
| import edu.uci.ics.asterix.om.base.temporal.ADateParserFactory; |
| import edu.uci.ics.asterix.om.base.temporal.ATimeParserFactory; |
| import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem; |
| import edu.uci.ics.asterix.om.types.ATypeTag; |
| import edu.uci.ics.asterix.om.types.BuiltinType; |
| import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException; |
| import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer; |
| import edu.uci.ics.hyracks.api.exceptions.HyracksDataException; |
| |
| public class AIntervalSerializerDeserializer implements ISerializerDeserializer<AInterval> { |
| |
| private static final long serialVersionUID = 1L; |
| |
| public static final AIntervalSerializerDeserializer INSTANCE = new AIntervalSerializerDeserializer(); |
| @SuppressWarnings("unchecked") |
| private static final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE |
| .getSerializerDeserializer(BuiltinType.AINTERVAL); |
| private static final AMutableInterval aInterval = new AMutableInterval(0L, 0L, (byte) 0); |
| private static final String errorMessage = "This can not be an instance of interval"; |
| |
| private AIntervalSerializerDeserializer() { |
| } |
| |
| @Override |
| public AInterval deserialize(DataInput in) throws HyracksDataException { |
| try { |
| return new AInterval(in.readLong(), in.readLong(), in.readByte()); |
| } catch (IOException e) { |
| throw new HyracksDataException(e); |
| } |
| |
| } |
| |
| @Override |
| public void serialize(AInterval instance, DataOutput out) throws HyracksDataException { |
| try { |
| out.writeLong(instance.getIntervalStart()); |
| out.writeLong(instance.getIntervalEnd()); |
| out.writeByte(instance.getIntervalType()); |
| } catch (IOException e) { |
| throw new HyracksDataException(e); |
| } |
| } |
| |
| public static long getIntervalStart(byte[] data, int offset) { |
| return AInt64SerializerDeserializer.getLong(data, offset); |
| } |
| |
| public static long getIntervalEnd(byte[] data, int offset) { |
| return AInt64SerializerDeserializer.getLong(data, offset + 8); |
| } |
| |
| public static byte getIntervalTimeType(byte[] data, int offset) { |
| return data[offset + 8 * 2]; |
| } |
| |
| /** |
| * create an interval value from two given datetime instance. |
| * |
| * @param interval |
| * @param out |
| * @throws HyracksDataException |
| */ |
| public static void parseDatetime(String interval, DataOutput out) throws HyracksDataException { |
| |
| long chrononTimeInMsStart = 0; |
| long chrononTimeInMsEnd = 0; |
| try { |
| |
| // the starting point for parsing (so for the accessor) |
| int startOffset = 0; |
| int endOffset, timeSeperatorOffsetInDatetimeString; |
| |
| // Get the index for the comma |
| int commaIndex = interval.indexOf(','); |
| if (commaIndex < 1) { |
| throw new AlgebricksException("comma is missing for a string of interval"); |
| } |
| |
| endOffset = commaIndex - 1; |
| |
| timeSeperatorOffsetInDatetimeString = interval.indexOf('T'); |
| |
| if (timeSeperatorOffsetInDatetimeString < 0) { |
| throw new AlgebricksException(errorMessage + ": missing T for a datetime value."); |
| } |
| |
| chrononTimeInMsStart = parseDatePart(interval, startOffset, timeSeperatorOffsetInDatetimeString - 1); |
| |
| chrononTimeInMsStart += parseTimePart(interval, timeSeperatorOffsetInDatetimeString + 1, endOffset); |
| |
| // Interval End |
| startOffset = commaIndex + 1; |
| endOffset = interval.length() - 1; |
| |
| timeSeperatorOffsetInDatetimeString = interval.indexOf('T', startOffset); |
| |
| if (timeSeperatorOffsetInDatetimeString < 0) { |
| throw new AlgebricksException(errorMessage + ": missing T for a datetime value."); |
| } |
| |
| chrononTimeInMsEnd = parseDatePart(interval, startOffset, timeSeperatorOffsetInDatetimeString - 1); |
| |
| chrononTimeInMsEnd += parseTimePart(interval, timeSeperatorOffsetInDatetimeString + 1, endOffset); |
| } catch (Exception e) { |
| throw new HyracksDataException(e); |
| } |
| |
| aInterval.setValue(chrononTimeInMsStart, chrononTimeInMsEnd, ATypeTag.DATETIME.serialize()); |
| |
| intervalSerde.serialize(aInterval, out); |
| } |
| |
| public static void parseTime(String interval, DataOutput out) throws HyracksDataException { |
| |
| long chrononTimeInMsStart = 0; |
| long chrononTimeInMsEnd = 0; |
| try { |
| |
| int startOffset = 0; |
| int endOffset; |
| |
| // Get the index for the comma |
| int commaIndex = interval.indexOf(','); |
| if (commaIndex < 0) { |
| throw new AlgebricksException("comma is missing for a string of interval"); |
| } |
| |
| endOffset = commaIndex - 1; |
| |
| // Interval Start |
| chrononTimeInMsStart = parseTimePart(interval, startOffset, endOffset); |
| |
| if (chrononTimeInMsStart < 0) { |
| chrononTimeInMsStart += GregorianCalendarSystem.CHRONON_OF_DAY; |
| } |
| |
| // Interval End |
| startOffset = commaIndex + 1; |
| endOffset = interval.length() - 1; |
| |
| chrononTimeInMsEnd = parseTimePart(interval, startOffset, endOffset); |
| |
| if (chrononTimeInMsEnd < 0) { |
| chrononTimeInMsEnd += GregorianCalendarSystem.CHRONON_OF_DAY; |
| } |
| |
| } catch (Exception e) { |
| throw new HyracksDataException(e); |
| } |
| |
| aInterval.setValue(chrononTimeInMsStart, chrononTimeInMsEnd, ATypeTag.TIME.serialize()); |
| intervalSerde.serialize(aInterval, out); |
| } |
| |
| public static void parseDate(String interval, DataOutput out) throws HyracksDataException { |
| |
| long chrononTimeInMsStart = 0; |
| long chrononTimeInMsEnd = 0; |
| try { |
| |
| // the starting point for parsing (so for the accessor) |
| int startOffset = 0; |
| int endOffset; |
| |
| // Get the index for the comma |
| int commaIndex = interval.indexOf(','); |
| if (commaIndex < 1) { |
| throw new AlgebricksException("comma is missing for a string of interval"); |
| } |
| |
| endOffset = commaIndex - 1; |
| |
| chrononTimeInMsStart = parseDatePart(interval, startOffset, endOffset); |
| |
| // Interval End |
| startOffset = commaIndex + 1; |
| endOffset = interval.length() - 1; |
| |
| chrononTimeInMsEnd = parseDatePart(interval, startOffset, endOffset); |
| |
| } catch (Exception e) { |
| throw new HyracksDataException(e); |
| } |
| |
| aInterval.setValue((chrononTimeInMsStart / GregorianCalendarSystem.CHRONON_OF_DAY), |
| (chrononTimeInMsEnd / GregorianCalendarSystem.CHRONON_OF_DAY), ATypeTag.DATE.serialize()); |
| |
| intervalSerde.serialize(aInterval, out); |
| } |
| |
| private static long parseDatePart(String interval, int startOffset, int endOffset) throws AlgebricksException, |
| HyracksDataException { |
| |
| while (interval.charAt(endOffset) == '"' || interval.charAt(endOffset) == ' ') { |
| endOffset--; |
| } |
| |
| while (interval.charAt(startOffset) == '"' || interval.charAt(startOffset) == ' ') { |
| startOffset++; |
| } |
| |
| return ADateParserFactory.parseDatePart(interval, startOffset, endOffset - startOffset + 1); |
| } |
| |
| private static int parseTimePart(String interval, int startOffset, int endOffset) throws AlgebricksException, |
| HyracksDataException { |
| |
| while (interval.charAt(endOffset) == '"' || interval.charAt(endOffset) == ' ') { |
| endOffset--; |
| } |
| |
| while (interval.charAt(startOffset) == '"' || interval.charAt(startOffset) == ' ') { |
| startOffset++; |
| } |
| |
| return ATimeParserFactory.parseTimePart(interval, startOffset, endOffset - startOffset + 1); |
| } |
| |
| } |