/*
* This is eMonocot, a global online biodiversity information resource.
*
* Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford
*
* eMonocot is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* The complete text of the GNU Affero General Public License is in the source repository as the file
* ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>.
*/
package org.emonocot.model.marshall.json;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
import org.easymock.EasyMock;
import org.emonocot.api.GroupService;
import org.emonocot.api.ImageService;
import org.emonocot.api.ReferenceService;
import org.emonocot.api.TaxonService;
import org.emonocot.api.UserService;
import org.emonocot.api.job.JobExecutionInfo;
import org.emonocot.model.Annotation;
import org.emonocot.model.Description;
import org.emonocot.model.Distribution;
import org.emonocot.model.Image;
import org.emonocot.model.MeasurementOrFact;
import org.emonocot.model.Place;
import org.emonocot.model.Reference;
import org.emonocot.model.Taxon;
import org.emonocot.model.auth.Group;
import org.emonocot.model.auth.User;
import org.emonocot.model.constants.AnnotationCode;
import org.emonocot.model.constants.DescriptionType;
import org.emonocot.model.constants.Location;
import org.emonocot.model.constants.RecordType;
import org.emonocot.pager.DefaultPageImpl;
import org.emonocot.pager.Page;
import org.gbif.dwc.terms.IucnTerm;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.DefaultCoordinateSequenceFactory;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
/**
*
* @author ben
*
*/
public class JsonConversionTest {
private static Logger logger = LoggerFactory.getLogger(JsonConversionTest.class);
private ObjectMapper objectMapper;
private ReferenceService referenceService;
private TaxonService taxonService;
private ImageService imageService;
private UserService userService;
private GroupService groupService;
private Place place;
@Before
public void setUp() {
referenceService = EasyMock.createMock(ReferenceService.class);
taxonService = EasyMock.createMock(TaxonService.class);
imageService = EasyMock.createMock(ImageService.class);
userService = EasyMock.createMock(UserService.class);
groupService = EasyMock.createMock(GroupService.class);
CustomObjectMapperFactory objectMapperFactory = new CustomObjectMapperFactory();
objectMapperFactory.setReferenceService(referenceService);
objectMapperFactory.setTaxonService(taxonService);
objectMapperFactory.setImageService(imageService);
objectMapperFactory.setGroupService(groupService);
objectMapperFactory.setUserService(userService);
objectMapper = objectMapperFactory.getObject();
place = new Place();
place.setTitle("testName");
place.setIdentifier("test.jk.triangle");
Coordinate[] coords = {new Coordinate(57,26), new Coordinate(0,0), new Coordinate(25,25), new Coordinate(57,26)};
LinearRing shell = new LinearRing(new DefaultCoordinateSequenceFactory().create(coords), new GeometryFactory());
Polygon shape = new Polygon(shell, null, new GeometryFactory());
place.setShape(shape);
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testReadTaxon() throws Exception {
Reference reference = new Reference();
EasyMock.expect(
referenceService.load(EasyMock
.eq("urn:kew.org:wcs:publication:1"))).andReturn(
reference).anyTimes();
EasyMock.replay(referenceService, imageService);
String content = "{\"identifier\":\"urn:kew.org:wcs:taxon:2295\",\"scientificName\":\"Acorus\",\"images\":[1],\"namePublishedIn\":\"urn:kew.org:wcs:publication:1\", \"descriptions\": [{\"type\":\"habitat\",\"description\":\"Lorem ipsum\", \"references\":[\"urn:kew.org:wcs:publication:1\"]}], \"distribution\":[{\"location\":\"REU\"}]}";
Taxon taxon = (Taxon) objectMapper.readValue(content, Taxon.class);
EasyMock.verify(referenceService, imageService);
assertNotNull("Returned object should not be null", taxon);
assertEquals("The identifier should be \"urn:kew.org:wcs:taxon:2295\"",
"urn:kew.org:wcs:taxon:2295", taxon.getIdentifier());
assertEquals("The name should be \"Acorus\"", "Acorus", taxon.getScientificName());
assertFalse("There should be some content", taxon.getDescriptions()
.isEmpty());
Description habitat = null;
for(Description d : taxon.getDescriptions()) {
if(d.getType().equals(DescriptionType.habitat)) {
habitat = d;
break;
}
}
assertNotNull("There should information on habitat", habitat);
assertEquals("The habitat should be 'Lorem ipsum'",habitat.getDescription(), "Lorem ipsum");
assertEquals("The taxon should be set on the content", habitat.getTaxon(), taxon);
assertTrue("The reference should be set on the content",habitat.getReferences()
.contains(reference));
assertEquals("The protologue should be set", reference,
taxon.getNamePublishedIn());
assertFalse("The taxon should contain a distribution", taxon
.getDistribution().isEmpty());
Distribution reunion = null;
for(Distribution d : taxon.getDistribution()) {
if(d.getLocation().equals(Location.REU)) {
reunion = d;
break;
}
}
assertNotNull("The taxon should occur in Reunion", reunion);
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testWriteTaxon() throws Exception {
Reference reference = new Reference();
reference.setIdentifier("urn:kew.org:wcs:publication:1");
Taxon taxon = new Taxon();
taxon.setIdentifier("urn:kew.org:wcs:taxon:2295");
taxon.setCreated(new DateTime());
taxon.setScientificName("Acorus");
Description description = new Description();
description.setDescription("Lorem ipsum");
description.setType(DescriptionType.habitat);
description.getReferences().add(reference);
description.setTaxon(taxon);
taxon.getDescriptions().add(description);
Distribution distribution = new Distribution();
distribution.setTaxon(taxon);
distribution.setLocation(Location.REU);
taxon.getDistribution().add(distribution);
taxon.getReferences().add(reference);
taxon.setNamePublishedIn(reference);
MeasurementOrFact measurementOrFact = new MeasurementOrFact();
measurementOrFact.setMeasurementType(IucnTerm.threatStatus);
measurementOrFact.setTaxon(taxon);
measurementOrFact.setMeasurementValue("Least Concern");
taxon.getMeasurementsOrFacts().add(measurementOrFact);
for (int i = 0; i < 3; i++) {
Image image = new Image();
image.setIdentifier("urn:identifier:image:" + i);
image.setTaxon(taxon);
image.getTaxa().add(taxon);
taxon.getImages().add(image);
}
try {
logger.debug(objectMapper.writeValueAsString(taxon));
} catch (Exception e) {
fail(e.getMessage());
}
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testWriteImage() throws Exception {
Taxon taxon = new Taxon();
taxon.setIdentifier("urn:kew.org:wcs:taxon:2295");
String content = "{\"identifier\":\"urn:http:upload.wikimedia.org:wikipedia.commons.2.25:Illustration_Acorus_calamus0.jpg\",\"caption\":\"Acorus\",\"taxa\":[\"urn:kew.org:wcs:taxon:2295\"]}";
Image image = new Image();
image.setIdentifier("urn:http:upload.wikimedia.org:wikipedia.commons.2.25:Illustration_Acorus_calamus0.jpg");
image.setTitle("Acorus");
image.getTaxa().add(taxon);
try {
String output = objectMapper.writeValueAsString(image);
logger.debug(output);
} catch (Exception e) {
fail(e.getMessage());
}
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testReadImage() throws Exception {
Taxon taxon = new Taxon();
EasyMock.expect(
taxonService.load(EasyMock.eq("urn:kew.org:wcs:taxon:2295"),
EasyMock.eq("taxon-page"))).andReturn(taxon).times(1);
EasyMock.replay(referenceService, taxonService);
String content = "{\"location\":null,\"id\":null,\"description\":null,\"taxon\":null,\"taxa\":[\"urn:kew.org:wcs:taxon:2295\"],\"title\":\"Acorus\",\"format\":null,\"subject\":null,\"spatial\":null,\"authority\":null,\"license\":null,\"created\":null,\"modified\":null,\"creator\":null,\"identifier\":\"urn:http:upload.wikimedia.org:wikipedia.commons.2.25:Illustration_Acorus_calamus0.jpg\"}";
Image image = (Image) objectMapper.readValue(content, Image.class);
EasyMock.verify(referenceService, taxonService);
assertNotNull("Returned object should not be null", image);
assertEquals(
"The identifier should be \"urn:http:upload.wikimedia.org:wikipedia.commons.2.25:Illustration_Acorus_calamus0.jpg\"",
"urn:http:upload.wikimedia.org:wikipedia.commons.2.25:Illustration_Acorus_calamus0.jpg",
image.getIdentifier());
assertEquals("The caption should be \"Acorus\"", "Acorus",
image.getTitle());
assertTrue("The taxon should be set on the image", image.getTaxa()
.contains(taxon));
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testReadReference() throws Exception {
EasyMock.replay(referenceService, imageService);
String content = "{\"identifier\":\"urn:kew.org:wcs:publication:123\",\"title\":\"Lorem ipsum\"}";
Reference reference = (Reference) objectMapper.readValue(content,
Reference.class);
EasyMock.verify(referenceService, imageService);
assertNotNull("Returned object should not be null", reference);
assertEquals(
"The identifier should be \"urn:kew.org:wcs:publication:123\"",
"urn:kew.org:wcs:publication:123", reference.getIdentifier());
assertEquals("The title should be \"Lorem ipsum\"", "Lorem ipsum",
reference.getTitle());
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testWriteUser() throws Exception {
User user = new User();
user.setUsername("test@example.com");
user.setPassword("123456");
Group group = new Group();
group.setIdentifier("groupname");
user.getGroups().add(group);
try{
objectMapper.writeValueAsString(user);
} catch (Exception e) {
fail();
}
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testReadUser() throws Exception {
Group group = new Group();
EasyMock.expect(groupService.load(EasyMock.eq("TestGroup"))).andReturn(
group);
EasyMock.replay(groupService, userService);
String content = "{\"identifier\":\"test@example.com\",\"password\":\"Lorem ipsum\", \"groups\":[\"TestGroup\"]}";
User user = (User) objectMapper.readValue(content, User.class);
EasyMock.verify(userService, groupService);
assertNotNull("Returned object should not be null", user);
assertEquals("The username should be \"test@example.com\"",
"test@example.com", user.getIdentifier());
assertEquals("The group should be \"TestGroup\"", group, user
.getGroups().iterator().next());
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testWriteJobInstance() throws Exception {
Map<String, JobParameter> jobParameterMap
= new HashMap<String, JobParameter>();
jobParameterMap.put("authority.name", new JobParameter("test"));
JobInstance jobInstance = new JobInstance(1L, new JobParameters(
jobParameterMap), "testJob");
jobInstance.setVersion(1);
try {
objectMapper.writeValueAsString(jobInstance);
} catch (Exception e) {
fail("No exception expected here");
}
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testReadJobInstance() throws Exception {
JobInstance jobInstance = objectMapper.readValue("{\"id\":1,\"jobName\":\"testJob\", \"version\":\"1\",\"parameters\":[{\"name\":\"authority.name\",\"type\":\"STRING\",\"value\":\"test\"}]}", JobInstance.class);
assertEquals(jobInstance.getId(), new Long(1L));
assertEquals(jobInstance.getJobName(), "testJob");
assertEquals(
jobInstance.getJobParameters().getString("authority.name"),
"test");
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testWriteAnnotation() throws Exception {
Annotation annotation = new Annotation();
annotation.setCode(AnnotationCode.Absent);
annotation.setDateTime(new DateTime());
annotation.setIdentifier("1");
annotation.setRecordType(RecordType.Taxon);
annotation.setText("wibble");
annotation.setValue("wibble");
Taxon t = new Taxon();
t.setIdentifier("testIdentifier");
annotation.setAnnotatedObj(t);
try{
objectMapper.writeValueAsString(annotation);
} catch (Exception e) {
fail();
}
}
@Test
public void testWritePage() throws Exception {
List<Annotation> annotations = new ArrayList<Annotation>();
Annotation annotation = new Annotation();
annotation.setCode(AnnotationCode.Absent);
annotation.setDateTime(new DateTime());
annotation.setIdentifier("1");
annotation.setRecordType(RecordType.Taxon);
annotation.setText("wibble");
annotation.setValue("wibble");
Page<Annotation> page = new DefaultPageImpl<Annotation>(100, 0, 10, annotations, null);
try{
logger.debug(objectMapper.writeValueAsString(page));
} catch (Exception e) {
logger.debug("ERROR" + e.getMessage());
fail();
}
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testAnnotation() throws Exception {
Taxon taxon = new Taxon();
EasyMock.expect(taxonService.find(EasyMock.eq("testIdentifier")))
.andReturn(taxon);
EasyMock.replay(taxonService);
Annotation annotation = objectMapper.readValue("{\"value\":\"wibble\",\"id\":null,\"type\":null,\"authority\":null,\"code\":\"Absent\",\"text\":\"wibble\",\"jobId\":null,\"annotatedObj\":\"testIdentifier\",\"recordType\":\"Taxon\",\"dateTime\":\"2013-01-01T09:00:00.000Z\",\"identifier\":\"1\"}", Annotation.class);
EasyMock.verify(taxonService);
assertNotNull(annotation.getAnnotatedObj());
assertEquals(taxon, annotation.getAnnotatedObj());
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Ignore
@Test
public void testWriteJobExecutionInfo() throws Exception {
JobExecutionInfo jobExecutionInfo = new JobExecutionInfo();
jobExecutionInfo.setStartTime(new DateTime(2012,3,29,14,17,0,0));
String actual = objectMapper.writeValueAsString(jobExecutionInfo);
assertEquals("Actual JSON should match expected JSON","{\"jobInstance\":null,\"exitCode\":null,\"duration\":null,\"exitDescription\":null,\"resource\":null,\"id\":null,\"startTime\":\"2012-03-29T14:17:00.000+01:00\",\"status\":null}", actual);
}
/**
*
* @throws Exception
* if there is a problem serializing the object
*/
@Test
public void testJobExecutionException() throws Exception {
JobExecutionException jobExecutionException = objectMapper.readValue("{\"errors\" : { \"spring.integration.http.handler.error\" : \"A Spring Integration handler raised an exception while handling an HTTP request. The exception is of type class org.springframework.integration.MessageHandlingException and it has a message: (org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={query.string=from Source, attempt=9}. If you want to run this job again, change the parameters.)\" } }", JobExecutionException.class);
}
@Test
public void testWriteMultiPolygon() throws Exception {
String serialized = objectMapper.writeValueAsString(place);
logger.debug(serialized);
assertTrue("Expected JSON to contain the identifier", serialized.contains("\"identifier\":\"test.jk.triangle\""));
assertTrue("Expected JSON to contain the name", serialized.contains("\"title\":\"testName\""));
assertTrue("Expected JSON to contain the shape", serialized.contains("\"shape\":\"POLYGON ((57 26, 0 0, 25 25, 57 26))\""));
}
@Test
public void testReadMultiPolygon() throws Exception {
String placeJson = "{\"title\":\"testName\",\"id\":null,\"shape\":\"POLYGON ((57 26, 0 0, 25 25, 57 26))\",\"point\":null,\"fipsCode\":null,\"authority\":null,\"identifier\":\"test.jk.triangle\",\"license\":null,\"created\":null,\"modified\":null}";
Place desrialized = objectMapper.readValue(placeJson, Place.class);
assertEquals("Expected identifier to be " + place.getIdentifier(), place.getIdentifier(), desrialized.getIdentifier());
assertEquals("Expected name to be " + place.getTitle(), place.getTitle(), desrialized.getTitle());
assertEquals("Expected shape to be " + place.getShape().toText(),place.getShape().toText(),desrialized.getShape().toText());
}
@Test
public void testReadJobInstanceList() throws Exception {
String jobInstanceListJson = "[{\"id\":1,\"jobName\":\"testJob\",\"version\":1,\"parameters\":[]}]";
List<JobInstance> jobInstanceList = objectMapper.readValue(jobInstanceListJson, List.class);
logger.debug("JOBINSTANCELIST " + jobInstanceList.size());
}
@Test
public void testWriteSchema() throws Exception {
JsonSchema jsonSchema = objectMapper.generateJsonSchema(Page.class);
}
}