Date parsing with java.time
This commit is contained in:
parent
b3cb4b792c
commit
63135b5554
|
@ -1,8 +1,13 @@
|
||||||
package org.gcube.data.publishing.ckan2zenodo;
|
package org.gcube.data.publishing.ckan2zenodo;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
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 java.util.List;
|
||||||
|
|
||||||
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.Commons;
|
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.Commons;
|
||||||
|
@ -16,22 +21,30 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Fixer {
|
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 PATH_CONFIGURATION=null;
|
||||||
private static Configuration ALWAYS_LIST_CONFIG=null;
|
private static Configuration ALWAYS_LIST_CONFIG=null;
|
||||||
static {
|
static {
|
||||||
INCOMING_DATE_FORMATS.add(new SimpleDateFormat("YYYY-MM-DD"));
|
INCOMING_FORMATTER=DateTimeFormatter.ofPattern("[yyyy-MM-dd['T'HH:mm:ss[.SSSSSS[z][XXX]]]]");
|
||||||
INCOMING_DATE_FORMATS.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX"));
|
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) {
|
public static final String fixIncoming(String toFix) {
|
||||||
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
|
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
|
||||||
DocumentContext pathCtx=JsonPath.using(PATH_CONFIGURATION).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, "$.modified");
|
||||||
ctx=fixIncomingDate(ctx,pathCtx, "$..publication_date");
|
ctx=fixIncomingDate(ctx,pathCtx, "$..publication_date");
|
||||||
ctx=fixIncomingDate(ctx,pathCtx, "$..embargo_date");
|
ctx=fixIncomingDate(ctx,pathCtx, "$..embargo_date");
|
||||||
|
|
||||||
return ctx.jsonString();
|
return ctx.jsonString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String fixSending(String toFix) {
|
public static String fixSending(String toFix) {
|
||||||
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
|
DocumentContext ctx=JsonPath.using(ALWAYS_LIST_CONFIG).parse(toFix);
|
||||||
DocumentContext pathCtx=JsonPath.using(PATH_CONFIGURATION).parse(toFix);
|
DocumentContext pathCtx=JsonPath.using(PATH_CONFIGURATION).parse(toFix);
|
||||||
|
|
||||||
ctx=fixOutgoingDate(ctx,pathCtx, "$.created");
|
ctx=fixOutgoingDate(ctx,pathCtx, "$.created");
|
||||||
ctx=fixOutgoingDate(ctx,pathCtx, "$.modified");
|
ctx=fixOutgoingDate(ctx,pathCtx, "$.modified");
|
||||||
ctx=fixOutgoingDate(ctx,pathCtx, "$..publication_date");
|
ctx=fixOutgoingDate(ctx,pathCtx, "$..publication_date");
|
||||||
ctx=fixOutgoingDate(ctx,pathCtx, "$..embargo_date");
|
ctx=fixOutgoingDate(ctx,pathCtx, "$..embargo_date");
|
||||||
|
|
||||||
|
|
||||||
return ctx.jsonString();
|
return ctx.jsonString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//*** INCOMINGs
|
//*** INCOMINGs
|
||||||
private static final DocumentContext fixIncomingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
|
private static final DocumentContext fixIncomingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
|
||||||
try {
|
try {
|
||||||
List<String> values=valuesCtx.read(toFixPath);
|
List<String> values=valuesCtx.read(toFixPath);
|
||||||
List<String> paths=pathCtx.read(toFixPath);
|
List<String> paths=pathCtx.read(toFixPath);
|
||||||
|
if(values!=null)
|
||||||
for(int i=0;i<values.size();i++) {
|
for(int i=0;i<values.size();i++) {
|
||||||
String toFix=values.get(i);
|
String toFix=values.get(i);
|
||||||
JsonPath path=JsonPath.compile(paths.get(i));
|
if(toFix!=null) {
|
||||||
valuesCtx.set(path, fixIncomingDateString(toFix));
|
JsonPath path=JsonPath.compile(paths.get(i));
|
||||||
}
|
valuesCtx.set(path, fixIncomingDateString(toFix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}catch(Throwable e) {
|
}catch(Throwable e) {
|
||||||
log.debug("Unable to fix "+toFixPath+". Cause : ",e);
|
log.warn("Unable to fix "+toFixPath+". Cause : ",e);
|
||||||
}
|
}
|
||||||
return valuesCtx;
|
return valuesCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String fixIncomingDateString(String toFix) throws Exception {
|
public static final String fixIncomingDateString(String toFix) throws Exception {
|
||||||
String fixed=null;
|
|
||||||
|
|
||||||
for(SimpleDateFormat format:INCOMING_DATE_FORMATS) {
|
TemporalAccessor accessor=INCOMING_FORMATTER.parse(toFix);
|
||||||
try {
|
ZonedDateTime zTime=null;
|
||||||
Date d=format.parse(toFix);
|
if(accessor.isSupported(ChronoField.HOUR_OF_DAY))
|
||||||
fixed=INTERNAL_DATE_FORMAT.format(d);
|
zTime = LocalDateTime.from(accessor).atZone(ZoneOffset.UTC);
|
||||||
break;
|
else {
|
||||||
}catch(Throwable t) {
|
LocalDate date=LocalDate.from(accessor);
|
||||||
//skip
|
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 zTime.format(INTERNAL_FORMATTER);
|
||||||
return fixed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//*** OUTGOINGs
|
//*** OUTGOINGs
|
||||||
|
|
||||||
private static final DocumentContext fixOutgoingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
|
private static final DocumentContext fixOutgoingDate(DocumentContext valuesCtx,DocumentContext pathCtx,String toFixPath) {
|
||||||
try{
|
try{
|
||||||
List<String> values=valuesCtx.read(toFixPath);
|
List<String> values=valuesCtx.read(toFixPath);
|
||||||
List<String> paths=pathCtx.read(toFixPath);
|
List<String> paths=pathCtx.read(toFixPath);
|
||||||
|
if(values!=null)
|
||||||
for(int i=0;i<values.size();i++) {
|
for(int i=0;i<values.size();i++) {
|
||||||
String toFix=values.get(i);
|
String toFix=values.get(i);
|
||||||
JsonPath path=JsonPath.compile(paths.get(i));
|
if(toFix!=null) {
|
||||||
valuesCtx.set(path, toFix.substring(0,toFix.length()-2)+":"+
|
JsonPath path=JsonPath.compile(paths.get(i));
|
||||||
toFix.substring(toFix.length()-2, toFix.length()));
|
valuesCtx.set(path, toFix.substring(0,toFix.length()-2)+":"+
|
||||||
}
|
toFix.substring(toFix.length()-2, toFix.length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}catch(Throwable t) {
|
}catch(Throwable t) {
|
||||||
log.debug("Unable to fix "+toFixPath+".Cause : ",t);
|
log.warn("Unable to fix "+toFixPath+".Cause : ",t);
|
||||||
}
|
}
|
||||||
return valuesCtx;
|
return valuesCtx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package org.gcube.tests;
|
package org.gcube.tests;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.gcube.data.publishing.ckan2zenodo.Fixer;
|
import org.gcube.data.publishing.ckan2zenodo.Fixer;
|
||||||
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.ZenodoDeposition;
|
import org.gcube.data.publishing.ckan2zenodo.model.zenodo.ZenodoDeposition;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
public class ParsingTests {
|
public class ParsingTests {
|
||||||
|
@ -21,16 +22,73 @@ public class ParsingTests {
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void DateTest() throws IOException {
|
public void DateTest() throws Exception {
|
||||||
ZenodoDeposition z=new ZenodoDeposition();
|
for(String d:new String[] {"2019-11-29T14:54:42.542142","2016-06-15T16:10:03.319363+00:00","2019-11-30"}) {
|
||||||
z.setCreated(new Date(System.currentTimeMillis()));
|
System.out.println(d);
|
||||||
System.out.println("Write : ");
|
System.out.println(Fixer.fixIncomingDateString(d));
|
||||||
System.out.println(Fixer.fixSending(mapper.writeValueAsString(z)));
|
System.out.println("--");
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ZenodoTests {
|
||||||
|
|
||||||
Zenodo z=new Zenodo(credentials);
|
Zenodo z=new Zenodo(credentials);
|
||||||
|
|
||||||
System.out.println(z.readDeposition("422983"));
|
System.out.println(z.readDeposition("426312"));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue