Skip to content

Commit

Permalink
[Fixes GEOS-8701] - Importer rest interface does not configure time d…
Browse files Browse the repository at this point in the history
…imension when a DateFormatTransform is defined on tasks

 - Add test cases
  • Loading branch information
Alessio Fabiani committed May 6, 2018
1 parent d36f4e3 commit d082d58
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import java.util.logging.Level;

import org.geotools.data.DataStore;
import org.geoserver.catalog.DimensionInfo;
import org.geoserver.catalog.DimensionPresentation;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.impl.DimensionInfoImpl;
import org.geoserver.importer.DatePattern;
import org.geoserver.importer.Dates;
import org.geoserver.importer.ImportTask;
Expand All @@ -28,9 +32,39 @@ public class DateFormatTransform extends AttributeRemapTransform {
private static final long serialVersionUID = 1L;

DatePattern datePattern;

private String enddate;

private String presentation;

/**
* Default Constructor taking two parameters
* - [mandatory] The field used as time dimension
* - [optional] The date-time pattern to be used in case of String fields
*
* @param field
* @param datePattern
* @throws ValidationException
*/
public DateFormatTransform(String field, String datePattern) throws ValidationException {
init(field,datePattern);
this(field, datePattern, null, null);
}

/**
* Default Constructor taking four parameters
* - [mandatory] The field used as time dimension
* - [optional] The date-time pattern to be used in case of String fields
* - [optional] The field used as end date for the time dimension
* - [optional] The time dimension presentation type; one of {LIST; DISCRETE_INTERVAL; CONTINUOUS_INTERVAL}
*
* @param field
* @param datePattern
* @param enddate
* @param presentation
* @throws ValidationException
*/
public DateFormatTransform(String field, String datePattern, String enddate, String presentation) throws ValidationException {
init(field, datePattern, enddate, presentation);
init();
}

Expand All @@ -46,7 +80,35 @@ public void setDatePattern(DatePattern datePattern) {
this.datePattern = datePattern;
}

private void init(String field, String datePattern) throws ValidationException {
/**
* @return the enddate
*/
public String getEnddate() {
return enddate;
}

/**
* @param enddate the enddate to set
*/
public void setEnddate(String enddate) {
this.enddate = enddate;
}

/**
* @return the presentation
*/
public String getPresentation() {
return presentation;
}

/**
* @param presentation the presentation to set
*/
public void setPresentation(String presentation) {
this.presentation = presentation;
}

private void init(String field, String datePattern, String enddate, String presentation) throws ValidationException {
setType(Date.class);
setField(field);
if (datePattern != null) {
Expand All @@ -60,21 +122,49 @@ private void init(String field, String datePattern) throws ValidationException {
throw new ValidationException("Invalid date parsing format",iae);
}
}
this.enddate = enddate;
this.presentation = presentation != null ? presentation : "LIST";
}

@Override
public SimpleFeature apply(ImportTask task, DataStore dataStore, SimpleFeature oldFeature,
SimpleFeature feature) throws Exception {
Object val = oldFeature.getAttribute(field);
if (val != null) {
Date parsed = parseDate(val.toString());
Date parsed = (val instanceof Date ? (Date) val : parseDate(val.toString()));
if (parsed == null) {
task.addMessage(Level.WARNING, "Invalid date '" + val + "' specified for " + feature.getID());
feature = null;
} else {
feature.setAttribute(field, parsed);

if (enddate != null) {
val = oldFeature.getAttribute(field);
if (val != null) {
parsed = (val instanceof Date ? (Date) val : parseDate(val.toString()));
if (parsed != null) {
feature.setAttribute(enddate, parsed);
}
}
}
}
}

//set up the time dimension object
if (task.getLayer() != null) {
ResourceInfo r = task.getLayer().getResource();
if (r != null && r.getMetadata().get(ResourceInfo.TIME) == null) {
DimensionInfo dim = new DimensionInfoImpl();
dim.setEnabled(true);
dim.setAttribute(field);
dim.setEndAttribute(enddate);
dim.setPresentation(DimensionPresentation.valueOf(presentation));
dim.setUnits("ISO8601"); //TODO: is there an enumeration for this?

r.getMetadata().put(ResourceInfo.TIME, dim);
}
}

return feature;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void testDateFormatTransform() throws Exception {
context.setTargetStore(store);

ImportTask task = context.getTasks().get(0);
task.getTransform().add(new DateFormatTransform("timestamp", "yyyy-MM-dd HH:mm:ss.S"));
task.getTransform().add(new DateFormatTransform("timestamp", "yyyy-MM-dd HH:mm:ss.S", null, null));

importer.run(context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class TransformTest {

@Test
public void testDateFormatTransform() throws Exception {
SimpleFeature f = transform(new DateFormatTransform("date", null),
SimpleFeature f = transform(new DateFormatTransform("date", null, null, null),
"date", String.class, "1980-09-10"
);
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,11 @@ public ImportTransform transform(JSONObject json) throws IOException {
ImportTransform transform;
String type = json.getString("type");
if ("DateFormatTransform".equalsIgnoreCase(type)) {
transform = new DateFormatTransform(json.getString("field"), json.optString("format", null));
transform = new DateFormatTransform(
json.getString("field"),
json.optString("format", null),
json.optString("enddate", null),
json.optString("presentation", null));
} else if ("IntegerFieldToDateTransform".equalsIgnoreCase(type)) {
transform = new IntegerFieldToDateTransform(json.getString("field"));
} else if ("CreateIndexTransform".equalsIgnoreCase(type)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,13 @@ public void transform(FlushableJSONBuilder json, ImportTransform transform, int
json.key("format").value(df.getDatePattern().dateFormat().toPattern());
}

if (df.getEnddate() != null) {
json.key("enddate").value(df.getEnddate());
}

if (df.getPresentation() != null) {
json.key("presentation").value(df.getPresentation());
}
} else if (transform instanceof IntegerFieldToDateTransform) {
IntegerFieldToDateTransform df = (IntegerFieldToDateTransform) transform;
json.key("field").value(df.getField());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.geoserver.importer.DatePattern;
import org.geoserver.importer.Dates;
import org.geoserver.importer.transform.DateFormatTransform;
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand All @@ -24,10 +25,10 @@ public class DateFormatTransformTest extends TransformTestSupport {
public DateFormatTransformTest() {
}

@Test
public void testExtents() throws Exception {
// this is mostly a verification of the extents of the builtin date parsing
String NOT_USED = null;
DateFormatTransform transform = new DateFormatTransform("not used", NOT_USED);
DateFormatTransform transform = new DateFormatTransform("not used", null);

GregorianCalendar cal = new GregorianCalendar();
cal.clear();
Expand All @@ -49,9 +50,9 @@ public void testExtents() throws Exception {
assertEquals(GregorianCalendar.AD, cal.get(Calendar.ERA));
}

@Test
public void testTransformSuccess() throws ParseException {
String NOT_USED = null;
DateFormatTransform transform = new DateFormatTransform("not used", NOT_USED);
DateFormatTransform transform = new DateFormatTransform("not used", null);

Date now = new Date();

Expand All @@ -78,6 +79,7 @@ public String apply(DatePattern input) {
}
}

@Test
public void testTransformSuccessCustomFormat() throws ParseException {
String customFormat = "yyyy-MM-dd'X'00";
DateFormatTransform transform = new DateFormatTransform("not used", customFormat);
Expand All @@ -90,8 +92,13 @@ public void testTransformSuccessCustomFormat() throws ParseException {
assertEquals(expected, parsed);
}

@Test
public void testJSON() throws Exception {
doJSONTest(new DateFormatTransform("foo", null));
doJSONTest(new DateFormatTransform("foo", "yyyy-MM-dd"));
doJSONTest(new DateFormatTransform("foo", null, null, "LIST"));
doJSONTest(new DateFormatTransform("foo", null, null, "DISCRETE_INTERVAL"));
doJSONTest(new DateFormatTransform("foo", null, null, "CONTINUOUS_INTERVAL"));
doJSONTest(new DateFormatTransform("foo", null, "enddate", null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.geoserver.catalog.*;
import org.geoserver.catalog.impl.DimensionInfoImpl;
import org.geoserver.importer.ImportContext;
import org.geoserver.importer.ImportTask;
import org.geoserver.importer.ImporterDataTest;
Expand Down Expand Up @@ -49,7 +50,6 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

Expand Down Expand Up @@ -679,4 +679,67 @@ public void testRunPostScriptWithOptions() throws Exception {
File testFile = new File(scripts, "test.abc");
assertTrue(testFile.exists());
}

@Test
public void testRunWithTimeDimention() throws Exception {
Catalog cat = getCatalog();

DataStoreInfo ds = createH2DataStore(cat.getDefaultWorkspace().getName(), "ming");

// the target layer is not there
assertNull(getCatalog().getLayerByName("ming_time"));

// create context with default name
File dir = unpack("shape/ming_time.zip");
ImportContext context = importer.createContext(0l);
importer.changed(context);
importer.update(context, new SpatialFile(new File(dir, "ming_time.shp")));
context.setTargetStore(ds);

assertEquals(1, context.getTasks().size());

context.getTasks().get(0).getData().setCharsetEncoding("UTF-8");

// add a transformation to run post script
String json = "{\n" +
" \"type\": \"DateFormatTransform\",\n" +
" \"field\": \"Year_Date\",\n" +
" \"presentation\": \"DISCRETE_INTERVAL\"" +
"}";

MockHttpServletResponse resp = postAsServletResponse(
RestBaseController.ROOT_PATH + "/imports/0/tasks/0/transforms", json, "application/json");
assertEquals(HttpStatus.CREATED.value(), resp.getStatus());

// run it
context = importer.getContext(0);
ImportTask task = context.getTasks().get(0);
task.setDirect(false);
task.setStore(ds);
importer.changed(task);
assertEquals(ImportTask.State.READY, task.getState());

context.updated();
assertEquals(ImportContext.State.PENDING, context.getState());
importer.run(context);

assertEquals(ImportContext.State.COMPLETE, context.getState());

// check the layer has been created
LayerInfo layer = cat.getLayerByName("ming_time");
assertNotNull(layer);

ResourceInfo resource = layer.getResource();

// verify the TIME dimension has benn defined
MetadataMap md = resource.getMetadata();
assertNotNull(md);
assertTrue(md.containsKey("time"));

DimensionInfo timeDimension = (DimensionInfo) md.get("time");
assertNotNull(timeDimension);

assertEquals(timeDimension.getAttribute(), "Year_Date");
assertEquals(timeDimension.getPresentation(), DimensionPresentation.DISCRETE_INTERVAL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if (dateFormat == null || "".equals(dateFormat.trim())) {
dateFormat = null;
}
item.setModelObject(new DateFormatTransform(field, dateFormat));
item.setModelObject(new DateFormatTransform(field, dateFormat, null, null));
}
else if (Number.class.isAssignableFrom(type)) {
item.setModelObject(new NumberFormatTransform(field, type));
Expand Down

0 comments on commit d082d58

Please sign in to comment.