001/*- 002 * Copyright 2015, 2016 Diamond Light Source Ltd. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 */ 009 010package org.eclipse.january.dataset; 011 012import java.text.ParseException; 013import java.text.SimpleDateFormat; 014import java.util.Date; 015 016public class DateDatasetImpl extends StringDataset implements DateDataset { 017 // pin UID to base class 018 private static final long serialVersionUID = Dataset.serialVersionUID; 019 020 private static final SimpleDateFormat ISO8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 021 022 static DateDatasetImpl createFromObject(final Object obj) { 023 final DateDatasetImpl result = new DateDatasetImpl(); 024 result.shape = ShapeUtils.getShapeFromObject(obj); 025 result.size = ShapeUtils.calcSize(result.shape); 026 result.odata = result.data = createArray(result.size); 027 028 final int[] pos = new int[result.shape.length]; 029 result.fillData(obj, 0, pos); 030 031 return result; 032 } 033 034 /** 035 * Create a null dataset 036 */ 037 DateDatasetImpl() { 038 super(); 039 } 040 041 DateDatasetImpl(final int... shape) { 042 super(shape); 043 } 044 045 DateDatasetImpl(final Date[] data, int... shape) { 046 super(datesToStrings(data), shape); 047 } 048 049 @Override 050 public int getDType() { 051 return DATE; 052 } 053 054 private static String[] datesToStrings(final Date[] dates) { 055 final String[] dateStrings = new String[dates.length]; 056 for (int i = 0; i < dates.length; i++) { 057 dateStrings[i] = dateToString(dates[i]); 058 } 059 060 return dateStrings; 061 } 062 063 private static String dateToString(final Date date) { 064 if (date != null) { 065 return ISO8601_DATE_FORMAT.format(date); 066 } 067 068 return null; 069 } 070 071 private static String objectToDateString(final Object obj) { 072 if (obj instanceof Date) { 073 return dateToString((Date) obj); 074 } else if (obj instanceof Dataset) { 075 Dataset dataset = (Dataset) obj; 076 if (dataset.getSize() != 1) { 077 logger.error("Given dataset must only have one item"); 078 throw new IllegalArgumentException("Given dataset must have only one item"); 079 } 080 081 return objectToDateString(dataset.getObjectAbs(dataset.getOffset())); 082 } else if (obj instanceof IDataset) { 083 IDataset dataset = (IDataset) obj; 084 if (dataset.getSize() != 1) { 085 logger.error("Given dataset must only have one item"); 086 throw new IllegalArgumentException("Given dataset must have only one item"); 087 } 088 return objectToDateString(dataset.getObject(new int[dataset.getRank()])); 089 } else { 090 logger.error("Argument is of unsupported class"); 091 throw new IllegalArgumentException("Argument is of unsupported class"); 092 } 093 } 094 095 private static Date stringToDate(final String dateAsString) { 096 if (dateAsString != null) { 097 try { 098 return ISO8601_DATE_FORMAT.parse(dateAsString); 099 } catch (ParseException e) { 100 // fall through to return null 101 logger.error("Could not parse datetime: " + dateAsString); 102 } 103 } 104 105 return null; 106 } 107 108 @Override 109 public Date getDate() { 110 final String dateAsString = super.getString(); 111 return stringToDate(dateAsString); 112 } 113 114 @Override 115 public Date getDate(int i) { 116 final String dateAsString = super.getString(i); 117 return stringToDate(dateAsString); 118 } 119 120 @Override 121 public Date getDate(int i, int j) { 122 final String dateAsString = super.getString(i, j); 123 return stringToDate(dateAsString); 124 } 125 126 @Override 127 public Date getDate(int... pos) { 128 final String dateAsString = super.getString(pos); 129 return stringToDate(dateAsString); 130 } 131 132 @Override 133 public Date getDateAbs(int index) { 134 final String dateAsString = super.getStringAbs(index); 135 if (dateAsString != null) { 136 return stringToDate(dateAsString); 137 } 138 139 return null; 140 } 141 142 @Override 143 public void setItemDirect(final int dindex, final int sindex, final Object src) { 144 if (src instanceof String[]) { 145 super.setItemDirect(dindex, sindex, src); 146 } else if (src instanceof Date[]) { 147 String[] datesAsStrings = datesToStrings((Date[]) src); 148 data[dindex] = datesAsStrings[sindex]; 149 } else { 150 logger.error("Argument is of unsupported class"); 151 throw new IllegalArgumentException("Argument is of unsupported class"); 152 } 153 } 154 155 public void setAbs(final int index, final Date date) { 156 data[index] = dateToString(date); 157 setDirty(); 158 } 159 160 /** 161 * @since 2.0 162 */ 163 public void setItem(final Date value) { 164 setAbs(getFirst1DIndex(), value); 165 } 166 167 public void setItem(final Date value, final int i) { 168 setAbs(get1DIndex(i), value); 169 } 170 171 public void setItem(final Date value, final int i, final int j) { 172 setAbs(get1DIndex(i, j), value); 173 } 174 175 public void setItem(final Date value, final int... pos) { 176 setAbs(get1DIndex(pos), value); 177 } 178 179 @Override 180 public void set(final Object obj) { 181 setItem(objectToDateString(obj)); 182 } 183 184 @Override 185 public void set(final Object obj, final int i) { 186 setItem(objectToDateString(obj), i); 187 } 188 189 @Override 190 public void set(final Object obj, final int i, final int j) { 191 setItem(objectToDateString(obj), i, j); 192 } 193 194 @Override 195 public void set(final Object obj, int... pos) { 196 if (pos == null || (pos.length == 0 && shape.length > 0)) { 197 pos = new int[shape.length]; 198 } 199 200 setItem(objectToDateString(obj), pos); 201 } 202 203 @Override 204 public StringDatasetBase sort(Integer axis) { 205 // Note yet supported. 206 // TODO: this method will be inefficient as we store dates formatted as strings 207 throw new UnsupportedOperationException("Cannot sort dataset"); 208 } 209 210}