diff --git a/src/main/java/hrider/config/GlobalConfig.java b/src/main/java/hrider/config/GlobalConfig.java index 6705b10..a82c02c 100644 --- a/src/main/java/hrider/config/GlobalConfig.java +++ b/src/main/java/hrider/config/GlobalConfig.java @@ -24,12 +24,14 @@ public class GlobalConfig extends PropertiesConfig { //region Constants private static final String KEY_DATE_FORMAT = "global.dateFormat"; + private static final String KEY_JODATIME_DATE_FORMAT = "global.jodaTimeDateFormat"; private static final String KEY_EXTERNAL_VIEWER_FILE_EXTENSION = "global.externalViewerFileExtension"; private static final String KEY_EXTERNAL_VIEWER_DELIMETER = "global.externalViewerDelimiter"; private static final String KEY_BATCH_READ_SIZE = "global.batch.readSize"; private static final String KEY_BATCH_WRITE_SIZE = "global.batch.writeSize"; private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + private static final String DEFAULT_JODATIME_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS ZZ"; private static final String DEFAULT_EXTERNAL_VIEWER_FILE_EXTENSION = ".csv"; private static final String DEFAULT_EXTERNAL_VIEWER_DELIMETER = ","; private static final String DEFAULT_BATCH_READ_SIZE = "1000"; @@ -68,6 +70,15 @@ public String getDateFormat() { return get(String.class, KEY_DATE_FORMAT, DEFAULT_DATE_FORMAT); } + /** + * Gets the date time format to be used to parse/convert JodaTime DateTime strings. + * + * @return A {@link String} representing date time format. + */ + public String getJodaDateFormat() { + return get(String.class, KEY_JODATIME_DATE_FORMAT, DEFAULT_JODATIME_DATE_FORMAT); + } + /** * Gets an extension to be used for a file to be created for the external viewer. * diff --git a/src/main/java/hrider/data/ObjectType.java b/src/main/java/hrider/data/ObjectType.java index 4e96e3d..18f9f6a 100644 --- a/src/main/java/hrider/data/ObjectType.java +++ b/src/main/java/hrider/data/ObjectType.java @@ -2,6 +2,9 @@ import hrider.config.GlobalConfig; import org.apache.hadoop.hbase.util.Bytes; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import java.text.DateFormat; import java.text.ParseException; @@ -41,6 +44,7 @@ public enum ObjectType { Boolean, Short, DateTime, + JodaDateTime, Xml, Json; @@ -98,6 +102,18 @@ public Object toObject(String value) { catch (ParseException ignored) { return null; } + case JodaDateTime: + String pattern = GlobalConfig.instance().getJodaDateFormat(); + DateTimeFormatter jodaDF = DateTimeFormat.forPattern(pattern); + jodaDF.withOffsetParsed(); + try { + DateTime parsedValue = jodaDF.parseDateTime(value); + return parsedValue; + } catch (UnsupportedOperationException ignored) { + return null; + } catch (IllegalArgumentException ignored) { + return null; + } case Xml: case Json: return value; @@ -136,6 +152,8 @@ public byte[] fromString(String value) { return Bytes.toBytes(java.lang.Short.parseShort(value)); case DateTime: return Bytes.toBytes(value); + case JodaDateTime: + return Bytes.toBytes(java.lang.Long.parseLong(value)); case Xml: case Json: return Bytes.toBytes(value); @@ -180,6 +198,8 @@ public Object fromByteArray(byte[] value) { catch (ParseException ignored) { return null; } + case JodaDateTime: + return new DateTime(Bytes.toLong(value)); case Xml: case Json: return Bytes.toString(value); @@ -224,6 +244,8 @@ public byte[] fromObject(Object value) { else { return Bytes.toBytes((String)value); } + case JodaDateTime: + return Bytes.toBytes(((DateTime)value).getMillis()); case Xml: case Json: return Bytes.toBytes((String)value); diff --git a/src/main/java/hrider/data/TypedObject.java b/src/main/java/hrider/data/TypedObject.java index 7ca01fa..cbbb5ec 100644 --- a/src/main/java/hrider/data/TypedObject.java +++ b/src/main/java/hrider/data/TypedObject.java @@ -1,6 +1,9 @@ package hrider.data; import hrider.config.GlobalConfig; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -162,6 +165,11 @@ public String toString() { DateFormat df = new SimpleDateFormat(GlobalConfig.instance().getDateFormat(), Locale.ENGLISH); return df.format((Date)this.value); } + else if (this.type == ObjectType.JodaDateTime) { + String pattern = GlobalConfig.instance().getJodaDateFormat(); + DateTimeFormatter jodaDF = DateTimeFormat.forPattern(pattern); + return jodaDF.print((DateTime)this.value); + } return this.value.toString(); } return ""; diff --git a/src/main/java/hrider/ui/design/EditorType.java b/src/main/java/hrider/ui/design/EditorType.java index 15a6555..a98b577 100644 --- a/src/main/java/hrider/ui/design/EditorType.java +++ b/src/main/java/hrider/ui/design/EditorType.java @@ -22,6 +22,7 @@ */ public enum EditorType { Date, + JodaDate, Text, Xml, Json diff --git a/src/main/java/hrider/ui/design/JCellEditor.java b/src/main/java/hrider/ui/design/JCellEditor.java index 769bdeb..fbf63ca 100644 --- a/src/main/java/hrider/ui/design/JCellEditor.java +++ b/src/main/java/hrider/ui/design/JCellEditor.java @@ -7,6 +7,9 @@ import hrider.ui.ChangeTracker; import hrider.ui.controls.json.JsonEditor; import hrider.ui.controls.xml.XmlEditor; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import javax.swing.*; import javax.swing.table.TableCellEditor; @@ -47,6 +50,7 @@ public class JCellEditor extends AbstractCellEditor implements TableCellEditor { //region Variables private JTextField textEditor; private DatePicker dateEditor; + private DatePicker jodaDateEditor; private XmlEditor xmlEditor; private JsonEditor jsonEditor; private DataCell cell; @@ -70,6 +74,10 @@ public JCellEditor(ChangeTracker changeTracker, int typeColumn, boolean canEdit) this.dateEditor.setBorder(BorderFactory.createEmptyBorder()); this.dateEditor.setDateFormat(new SimpleDateFormat(GlobalConfig.instance().getDateFormat(), Locale.ENGLISH)); this.dateEditor.setFieldEditable(canEdit); + this.jodaDateEditor = new DatePicker(null); + this.jodaDateEditor.setBorder(BorderFactory.createEmptyBorder()); + this.jodaDateEditor.setDateFormat(new SimpleDateFormat(GlobalConfig.instance().getJodaDateFormat(), Locale.ENGLISH)); + this.jodaDateEditor.setFieldEditable(canEdit); this.xmlEditor = new XmlEditor(); this.xmlEditor.setEditable(canEdit); this.jsonEditor = new JsonEditor(); @@ -111,6 +119,9 @@ public Component getTableCellEditorComponent(JTable table, Object value, boolean if (type == ObjectType.DateTime) { this.editorType = EditorType.Date; } + else if (type == ObjectType.JodaDateTime) { + this.editorType = EditorType.JodaDate; + } else if (type == ObjectType.Xml) { this.editorType = EditorType.Xml; } @@ -141,6 +152,17 @@ public Object getCellEditorValue() { text = df.format(date); } break; + case JodaDate: + // Try parsing it, just to make sure it won't get accidentally set to null + // if there's text but it has a typo. + Date jodaDate = this.jodaDateEditor.getDate(); + if (jodaDate != null) { + String pattern = GlobalConfig.instance().getJodaDateFormat(); + DateTimeFormatter jodaDF = DateTimeFormat.forPattern(pattern); + jodaDF.withOffsetParsed(); + text = jodaDF.print(new DateTime(jodaDate)); + } + break; case Text: text = this.textEditor.getText().trim(); break; @@ -190,6 +212,15 @@ private void initializeEditor(Object value) { catch (PropertyVetoException ignore) { } break; + case JodaDate: + try { + if (this.cell != null) { + this.jodaDateEditor.setDate(((DateTime)this.cell.getTypedValue().getValue()).toDate()); + } + } + catch (PropertyVetoException ignore) { + } + break; case Text: if (value != null) { this.textEditor.setText(value.toString()); @@ -226,6 +257,8 @@ private Component getEditor() { switch (this.editorType) { case Date: return this.dateEditor; + case JodaDate: + return this.jodaDateEditor; case Text: return this.textEditor; case Xml: