Date parsing with java.time

This commit is contained in:
Fabio Sinibaldi 2019-11-29 17:57:49 +01:00
parent b3cb4b792c
commit 63135b5554
4 changed files with 164 additions and 66 deletions

View File

@ -1,8 +1,13 @@
package org.gcube.data.publishing.ckan2zenodo;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.List;
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.Commons;
@ -16,22 +21,30 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Fixer {
private static final ArrayList<SimpleDateFormat> INCOMING_DATE_FORMATS=new ArrayList<SimpleDateFormat>();
private static final SimpleDateFormat INTERNAL_DATE_FORMAT=new SimpleDateFormat(Commons.ISO_DATE_PATTERN);
private static DateTimeFormatter INCOMING_FORMATTER=null;
private static DateTimeFormatter INTERNAL_FORMATTER=null;
private static Configuration PATH_CONFIGURATION=null;
private static Configuration ALWAYS_LIST_CONFIG=null;
static {
INCOMING_DATE_FORMATS.add(new SimpleDateFormat("YYYY-MM-DD"));
INCOMING_DATE_FORMATS.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX"));
INCOMING_FORMATTER=DateTimeFormatter.ofPattern("[yyyy-MM-dd['T'HH:mm:ss[.SSSSSS[z][XXX]]]]");
INTERNAL_FORMATTER=DateTimeFormatter.ofPattern(Commons.ISO_DATE_PATTERN);
PATH_CONFIGURATION = Configuration.builder().options(Option.AS_PATH_LIST,Option.SUPPRESS_EXCEPTIONS).build();
ALWAYS_LIST_CONFIG= Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS).build();
PATH_CONFIGURATION = Configuration.builder().options(Option.AS_PATH_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build();
ALWAYS_LIST_CONFIG= Configuration.builder().options(Option.ALWAYS_RETURN_LIST,Option.SUPPRESS_EXCEPTIONS,Option.DEFAULT_PATH_LEAF_TO_NULL).build();
}
public static final String fixIncoming(String toFix) {
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
DocumentContext pathCtx=JsonPath.using(PATH_CONFIGURATION).parse(toFix);
@ -40,76 +53,78 @@ public class Fixer {
ctx=fixIncomingDate(ctx,pathCtx, "$.modified");
ctx=fixIncomingDate(ctx,pathCtx, "$..publication_date");
ctx=fixIncomingDate(ctx,pathCtx, "$..embargo_date");
return ctx.jsonString();
}
public static String fixSending(String toFix) {
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
DocumentContext pathCtx=JsonPath.using(PATH_CONFIGURATION).parse(toFix);
ctx=fixOutgoingDate(ctx,pathCtx, "$.created");
ctx=fixOutgoingDate(ctx,pathCtx, "$.modified");
ctx=fixOutgoingDate(ctx,pathCtx, "$..publication_date");
ctx=fixOutgoingDate(ctx,pathCtx, "$..embargo_date");
return ctx.jsonString();
}
//*** INCOMINGs
private static final DocumentContext fixIncomingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
try {
List<String> values=valuesCtx.read(toFixPath);
List<String> paths=pathCtx.read(toFixPath);
for(int i=0;i<values.size();i++) {
String toFix=values.get(i);
JsonPath path=JsonPath.compile(paths.get(i));
valuesCtx.set(path, fixIncomingDateString(toFix));
}
if(values!=null)
for(int i=0;i<values.size();i++) {
String toFix=values.get(i);
if(toFix!=null) {
JsonPath path=JsonPath.compile(paths.get(i));
valuesCtx.set(path, fixIncomingDateString(toFix));
}
}
}catch(Throwable e) {
log.debug("Unable to fix "+toFixPath+". Cause : ",e);
log.warn("Unable to fix "+toFixPath+". Cause : ",e);
}
return valuesCtx;
}
private static final String fixIncomingDateString(String toFix) throws Exception {
String fixed=null;
public static final String fixIncomingDateString(String toFix) throws Exception {
for(SimpleDateFormat format:INCOMING_DATE_FORMATS) {
try {
Date d=format.parse(toFix);
fixed=INTERNAL_DATE_FORMAT.format(d);
break;
}catch(Throwable t) {
//skip
}
TemporalAccessor accessor=INCOMING_FORMATTER.parse(toFix);
ZonedDateTime zTime=null;
if(accessor.isSupported(ChronoField.HOUR_OF_DAY))
zTime = LocalDateTime.from(accessor).atZone(ZoneOffset.UTC);
else {
LocalDate date=LocalDate.from(accessor);
zTime=LocalDateTime.of(date, LocalTime.of(0, 0, 0, 0)).atZone(ZoneOffset.UTC);
}
if(fixed==null) throw new Exception("No format suitable for incoming date "+toFix);
return fixed;
return zTime.format(INTERNAL_FORMATTER);
}
//*** OUTGOINGs
private static final DocumentContext fixOutgoingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
try{
List<String> values=valuesCtx.read(toFixPath);
List<String> paths=pathCtx.read(toFixPath);
for(int i=0;i<values.size();i++) {
String toFix=values.get(i);
JsonPath path=JsonPath.compile(paths.get(i));
valuesCtx.set(path, toFix.substring(0,toFix.length()-2)+":"+
toFix.substring(toFix.length()-2, toFix.length()));
}
if(values!=null)
for(int i=0;i<values.size();i++) {
String toFix=values.get(i);
if(toFix!=null) {
JsonPath path=JsonPath.compile(paths.get(i));
valuesCtx.set(path, toFix.substring(0,toFix.length()-2)+":"+
toFix.substring(toFix.length()-2, toFix.length()));
}
}
}catch(Throwable t) {
log.debug("Unable to fix "+toFixPath+".Cause : ",t);
log.warn("Unable to fix "+toFixPath+".Cause : ",t);
}
return valuesCtx;
return valuesCtx;
}
}

View File

@ -1,14 +1,15 @@
package org.gcube.tests;
import java.io.IOException;
import java.util.Date;
import org.gcube.data.publishing.ckan2zenodo.Fixer;
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.ZenodoDeposition;
import org.junit.BeforeClass;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ParsingTests {
@ -21,16 +22,73 @@ public class ParsingTests {
@Test
public void DateTest() throws IOException {
ZenodoDeposition z=new ZenodoDeposition();
z.setCreated(new Date(System.currentTimeMillis()));
System.out.println("Write : ");
System.out.println(Fixer.fixSending(mapper.writeValueAsString(z)));
String s="{\"conceptrecid\":\"422982\",\"created\":\"2019-11-26T15:43:49.879+00:00\",\"files\":[],\"id\":422983,\"links\":{\"bucket\":\"https://sandbox.zenodo.org/api/files/a6b09898-1807-4f03-a7ac-ed06b2d3ba2b\",\"discard\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/actions/discard\",\"edit\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/actions/edit\",\"files\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/files\",\"html\":\"https://sandbox.zenodo.org/deposit/422983\",\"latest_draft\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983\",\"latest_draft_html\":\"https://sandbox.zenodo.org/deposit/422983\",\"newversion\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/actions/newversion\",\"publish\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/actions/publish\",\"registerconceptdoi\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983/actions/registerconceptdoi\",\"self\":\"https://sandbox.zenodo.org/api/deposit/depositions/422983\"},\"metadata\":{\"prereserve_doi\":{\"doi\":\"10.5072/zenodo.422983\",\"recid\":422983}},\"modified\":\"2019-11-26T15:43:49.876858+00:00\",\"owner\":31041,\"record_id\":422983,\"state\":\"unsubmitted\",\"submitted\":false,\"title\":\"\"}";
System.out.println("READ : ");
System.out.println(mapper.readValue(Fixer.fixIncoming(s), ZenodoDeposition.class));
public void DateTest() throws Exception {
for(String d:new String[] {"2019-11-29T14:54:42.542142","2016-06-15T16:10:03.319363+00:00","2019-11-30"}) {
System.out.println(d);
System.out.println(Fixer.fixIncomingDateString(d));
System.out.println("--");
}
}
@Test
public void fullCircleFromIncoming() throws JsonParseException, JsonMappingException, IOException {
String s="{\n" +
" \"conceptrecid\": \"426311\",\n" +
" \"created\": \"2019-11-29T14:54:42.542142\",\n" +
" \"doi\": \"\",\n" +
" \"doi_url\": \"https://doi.org/\",\n" +
" \"id\": 426312,\n" +
" \"links\":\n" +
" {\n" +
" \"discard\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312/actions/discard\",\n" +
" \"edit\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312/actions/edit\",\n" +
" \"files\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312/files\",\n" +
" \"html\": \"https://sandbox.zenodo.org/deposit/426312\",\n" +
" \"latest_draft\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312\",\n" +
" \"latest_draft_html\": \"https://sandbox.zenodo.org/deposit/426312\",\n" +
" \"publish\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312/actions/publish\",\n" +
" \"self\": \"https://sandbox.zenodo.org/api/deposit/depositions/426312\"\n" +
" },\n" +
" \"metadata\":\n" +
" {\n" +
" \"access_right\": \"open\",\n" +
" \"creators\": [\n" +
" {\n" +
" \"name\": \"simpleMan\"\n" +
" }],\n" +
" \"description\": \"Simple description\",\n" +
" \"doi\": \"\",\n" +
" \"license\": \"CC0-1.0\",\n" +
" \"prereserve_doi\":\n" +
" {\n" +
" \"doi\": \"10.5072/zenodo.426312\",\n" +
" \"recid\": 426312\n" +
" },\n" +
" \"publication_date\": \"2018-12-30\",\n" +
" \"title\": \"Test\",\n" +
" \"upload_type\": \"dataset\"\n" +
" },\n" +
" \"modified\": \"2019-11-29T14:54:43.203022\",\n" +
" \"owner\": 31041,\n" +
" \"record_id\": 426312,\n" +
" \"state\": \"unsubmitted\",\n" +
" \"submitted\": false,\n" +
" \"title\": \"Test\"\n" +
"}";
System.out.println("Sample String : ");
System.out.println(s);
System.out.println("READ (toString): ");
ZenodoDeposition dep=mapper.readValue(Fixer.fixIncoming(s), ZenodoDeposition.class);
System.out.println(dep);
System.out.println("READ (JSON): ");
String json=mapper.writeValueAsString(dep);
System.out.println(json);
System.out.println("FIXED JSON ");
String fixed=Fixer.fixSending(json);
System.out.println(fixed);
}
}

View File

@ -41,7 +41,7 @@ public class ZenodoTests {
Zenodo z=new Zenodo(credentials);
System.out.println(z.readDeposition("422983"));
System.out.println(z.readDeposition("426312"));
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} | %-5p | [%thread] %logger{5}:%L - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logFile.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} | %-5p | [%thread] %logger{5}:%L - %msg%n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>