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 private static String[] datesToStrings(final Date[] dates) { 050 final String[] dateStrings = new String[dates.length]; 051 for (int i = 0; i < dates.length; i++) { 052 dateStrings[i] = dateToString(dates[i]); 053 } 054 055 return dateStrings; 056 } 057 058 private static String dateToString(final Date date) { 059 if (date != null) { 060 return ISO8601_DATE_FORMAT.format(date); 061 } 062 063 return null; 064 } 065 066 private static String objectToDateString(final Object obj) { 067 if (obj instanceof Date) { 068 return dateToString((Date) obj); 069 } else if (obj instanceof Dataset) { 070 Dataset dataset = (Dataset) obj; 071 if (dataset.getSize() != 1) { 072 logger.error("Given dataset must only have one item"); 073 throw new IllegalArgumentException("Given dataset must have only one item"); 074 } 075 076 return objectToDateString(dataset.getObjectAbs(0)); 077 } else if (obj instanceof IDataset) { 078 IDataset dataset = (IDataset) obj; 079 if (dataset.getSize() != 1) { 080 logger.error("Given dataset must only have one item"); 081 throw new IllegalArgumentException("Given dataset must have only one item"); 082 } 083 return objectToDateString(dataset.getObject(new int[dataset.getRank()])); 084 } else { 085 logger.error("Argument is of unsupported class"); 086 throw new IllegalArgumentException("Argument is of unsupported class"); 087 } 088 } 089 090 private static Date stringToDate(final String dateAsString) { 091 if (dateAsString != null) { 092 try { 093 return ISO8601_DATE_FORMAT.parse(dateAsString); 094 } catch (ParseException e) { 095 // fall through to return null 096 logger.error("Could not parse datetime: " + dateAsString); 097 } 098 } 099 100 return null; 101 } 102 103 @Override 104 public Date getDate() { 105 final String dateAsString = super.getString(); 106 return stringToDate(dateAsString); 107 } 108 109 @Override 110 public Date getDate(int i) { 111 final String dateAsString = super.getString(i); 112 return stringToDate(dateAsString); 113 } 114 115 @Override 116 public Date getDate(int i, int j) { 117 final String dateAsString = super.getString(i, j); 118 return stringToDate(dateAsString); 119 } 120 121 @Override 122 public Date getDate(int... pos) { 123 final String dateAsString = super.getString(pos); 124 return stringToDate(dateAsString); 125 } 126 127 @Override 128 public Date getDateAbs(int index) { 129 final String dateAsString = super.getStringAbs(index); 130 if (dateAsString != null) { 131 return stringToDate(dateAsString); 132 } 133 134 return null; 135 } 136 137 @Override 138 public void setItemDirect(final int dindex, final int sindex, final Object src) { 139 if (src instanceof String[]) { 140 super.setItemDirect(dindex, sindex, src); 141 } else if (src instanceof Date[]) { 142 String[] datesAsStrings = datesToStrings((Date[]) src); 143 data[dindex] = datesAsStrings[sindex]; 144 } else { 145 logger.error("Argument is of unsupported class"); 146 throw new IllegalArgumentException("Argument is of unsupported class"); 147 } 148 } 149 150 public void setAbs(final int index, final Date date) { 151 data[index] = dateToString(date); 152 setDirty(); 153 } 154 155 /** 156 * @since 2.0 157 */ 158 public void setItem(final Date value) { 159 setAbs(getFirst1DIndex(), value); 160 } 161 162 public void setItem(final Date value, final int i) { 163 setAbs(get1DIndex(i), value); 164 } 165 166 public void setItem(final Date value, final int i, final int j) { 167 setAbs(get1DIndex(i, j), value); 168 } 169 170 public void setItem(final Date value, final int... pos) { 171 setAbs(get1DIndex(pos), value); 172 } 173 174 @Override 175 public void set(final Object obj) { 176 setItem(objectToDateString(obj)); 177 } 178 179 @Override 180 public void set(final Object obj, final int i) { 181 setItem(objectToDateString(obj), i); 182 } 183 184 @Override 185 public void set(final Object obj, final int i, final int j) { 186 setItem(objectToDateString(obj), i, j); 187 } 188 189 @Override 190 public void set(final Object obj, int... pos) { 191 if (pos == null || (pos.length == 0 && shape.length > 0)) { 192 pos = new int[shape.length]; 193 } 194 195 setItem(objectToDateString(obj), pos); 196 } 197 198 @Override 199 public StringDatasetBase sort(Integer axis) { 200 // Note yet supported. 201 // TODO: this method will be inefficient as we store dates formatted as strings 202 throw new UnsupportedOperationException("Cannot sort dataset"); 203 } 204 205}