some fixes and tests
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/385a92bc Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/385a92bc Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/385a92bc Branch: refs/heads/MARMOTTA-655_Memento_Compliance_Issues Commit: 385a92bc7f4f4a11dcdf63864c9cf04b6a6e08cc Parents: 837d5d0 Author: Thomas Kurz <[email protected]> Authored: Wed Oct 19 16:04:26 2016 +0200 Committer: Thomas Kurz <[email protected]> Committed: Wed Oct 19 16:04:26 2016 +0200 ---------------------------------------------------------------------- .../versioning/io/HtmlVersionSerializer.java | 3 +- .../versioning/io/LinkVersionSerializer.java | 4 +- .../versioning/model/MementoVersionSet.java | 9 +- .../services/VersionSerializerServiceImpl.java | 16 +-- .../platform/versioning/utils/MementoUtils.java | 26 ++++- .../webservices/MementoWebService.java | 4 +- .../resources/templates/memento_timemap.ftl | 4 +- .../versioning/MementoWebServiceTest.java | 105 ++++++++++++++++++- 8 files changed, 155 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/HtmlVersionSerializer.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/HtmlVersionSerializer.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/HtmlVersionSerializer.java index edbf006..881ca02 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/HtmlVersionSerializer.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/HtmlVersionSerializer.java @@ -94,7 +94,7 @@ public class HtmlVersionSerializer implements VersionSerializer { //write data to map Map<String, Object> data = new HashMap<String, Object>(); - data.put("original",original.toString()); + data.put("original", MementoUtils.originalURI(original.toString(),configurationService.getBaseUri())); List<Map<String,String>> vs = new ArrayList<Map<String,String>>(); @@ -102,6 +102,7 @@ public class HtmlVersionSerializer implements VersionSerializer { Version v = versions.next(); Map<String,String> m = new HashMap<String,String>(); m.put("date",v.getCommitTime().toString()); + m.put("formatedDate", MementoUtils.MEMENTO_DATE_FORMAT.format(v.getCommitTime())); m.put("uri",MementoUtils.resourceURI(original.toString(), v.getCommitTime(), configurationService.getBaseUri()).toString()); m.put("tstamp", TSTAMP.format(v.getCommitTime())); vs.add(m); http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/LinkVersionSerializer.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/LinkVersionSerializer.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/LinkVersionSerializer.java index 60f2aae..5bac7dd 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/LinkVersionSerializer.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/io/LinkVersionSerializer.java @@ -80,7 +80,7 @@ public class LinkVersionSerializer implements VersionSerializer { //write original resource w.append("<"); - w.append(original.toString()); + w.append(MementoUtils.originalURI(original.toString(), configurationService.getBaseUri()).toString()); w.append(">;rel=\"original\","); w.newLine(); @@ -108,7 +108,7 @@ public class LinkVersionSerializer implements VersionSerializer { //add datetime w.append("\"; datetime=\""); - w.append(v.getCommitTime().toString()); + w.append(MementoUtils.MEMENTO_DATE_FORMAT.format(v.getCommitTime())); w.append("\","); w.newLine(); http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/model/MementoVersionSet.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/model/MementoVersionSet.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/model/MementoVersionSet.java index c1a71c2..a3ce5be 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/model/MementoVersionSet.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/model/MementoVersionSet.java @@ -18,10 +18,13 @@ package org.apache.marmotta.platform.versioning.model; import org.apache.marmotta.kiwi.versioning.model.Version; +import org.apache.marmotta.platform.core.api.config.ConfigurationService; import org.apache.marmotta.platform.versioning.exception.MementoException; import org.apache.marmotta.platform.versioning.utils.MementoUtils; import org.openrdf.model.Resource; +import javax.inject.Inject; +import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -60,7 +63,11 @@ public class MementoVersionSet { links.add(buildLink(prefix,original.toString(),current.getCommitTime(),"memento")); //add link to original - links.add("<"+original.toString()+">;rel=\"original\""); + try { + links.add("<"+MementoUtils.originalURI(original.toString(),baseURI).toString()+">;rel=\"original\""); + } catch (UnsupportedEncodingException e) { + throw new MementoException(e); + } //add next and previous if they exist if( next != null ) links.add(buildLink(prefix,original.toString(),next.getCommitTime(),"next memento")); http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/services/VersionSerializerServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/services/VersionSerializerServiceImpl.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/services/VersionSerializerServiceImpl.java index 579e167..b4b535c 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/services/VersionSerializerServiceImpl.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/services/VersionSerializerServiceImpl.java @@ -42,15 +42,19 @@ public class VersionSerializerServiceImpl implements VersionSerializerService { /** * returns an adequate serializer for a mimetype - * @param type a list of mimetype (from Accept header) + * @param types a list of mimetype (from Accept header) * @return a serializer * @throws IOException if there is no serializer for mimetype */ @Override - public VersionSerializer getSerializer(List<ContentType> type) throws IOException { - for(VersionSerializer serializer : serializers) { - if(MarmottaHttpUtils.bestContentType(serializer.getContentTypes(),type) != null) return serializer; - } - throw new IOException("Cannot find serializer for " + type); + public VersionSerializer getSerializer(List<ContentType> types) throws IOException { + for(ContentType type : types) { + for(VersionSerializer serializer : serializers) { + for(ContentType stype : serializer.getContentTypes()) { + if(stype.matches(type)) return serializer; + } + } + } //TODO there is not fuzzy match e.g. text/* + throw new IOException("Cannot find serializer for " + types); } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/utils/MementoUtils.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/utils/MementoUtils.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/utils/MementoUtils.java index 5742952..6df05a0 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/utils/MementoUtils.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/utils/MementoUtils.java @@ -17,10 +17,16 @@ */ package org.apache.marmotta.platform.versioning.utils; +import org.apache.marmotta.platform.core.api.config.ConfigurationService; + +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URLEncoder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; /** * ... @@ -38,10 +44,28 @@ public class MementoUtils { * is used for date format used in memento resource uris * TODO should be HTTP Date format specified by RFC 1123 and in the GMT timezone like "Mon, 19 Sep 2016 23:47:12 GMT" */ - public static final DateFormat MEMENTO_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); + public static final DateFormat MEMENTO_DATE_FORMAT; + + static { + MEMENTO_DATE_FORMAT = new SimpleDateFormat( + "EEE, dd MMM yyyy HH:mm:ss z", Locale.US); //TODO which locale should be used? + MEMENTO_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); + } public static final DateFormat MEMENTO_DATE_FORMAT_FOR_URIS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); + public static URI originalURI(String resource, String baseURI) throws UnsupportedEncodingException { + + if(resource.startsWith(baseURI)) { + return URI.create(resource); + } else { + return URI.create( + baseURI + + ConfigurationService.RESOURCE_PATH + "?uri=" + + URLEncoder.encode(resource, "UTF-8")); + } + } + /** * builds a memento permalink * @param date the date of the version that should be represented by the permalink http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/webservices/MementoWebService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/webservices/MementoWebService.java b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/webservices/MementoWebService.java index 9174715..ae9b653 100644 --- a/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/webservices/MementoWebService.java +++ b/platform/marmotta-versioning-kiwi/src/main/java/org/apache/marmotta/platform/versioning/webservices/MementoWebService.java @@ -116,7 +116,7 @@ public class MementoWebService { if(date_string == null) { date = new Date(); } else { - DateUtils.parseDate(date_string); + date = DateUtils.parseDate(date_string); } URI resource = conn.getValueFactory().createURI(resource_string); @@ -288,7 +288,7 @@ public class MementoWebService { Set<String> links = new HashSet<String>(); links.add("<" + MementoUtils.timegateURI(resource_string, configurationService.getBaseUri()) + ">;rel=timegate"); - links.add("<" + resource_string + ">;rel=original"); + links.add("<" + MementoUtils.originalURI(resource_string, configurationService.getBaseUri()) + ">;rel=original"); //create response return Response http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/main/resources/templates/memento_timemap.ftl ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/main/resources/templates/memento_timemap.ftl b/platform/marmotta-versioning-kiwi/src/main/resources/templates/memento_timemap.ftl index 4deff79..16843e5 100644 --- a/platform/marmotta-versioning-kiwi/src/main/resources/templates/memento_timemap.ftl +++ b/platform/marmotta-versioning-kiwi/src/main/resources/templates/memento_timemap.ftl @@ -56,7 +56,7 @@ var target = "#timeknots", v = [ <#list versions as version> - {'name':"${MEMENTO_DATE_FORMAT.format(version.date)}", 'date':new Date("${version.tstamp}"), 'uri':"${version.uri}"}, + {'name':"${version.formatedDate}", 'date':new Date("${version.tstamp}"), 'uri':"${version.uri}"}, </#list> {'name':"now", 'date':new Date(),'lineWidth':1, 'uri':"${SERVER_URL}resource?uri=${original?url}"} ]; @@ -88,7 +88,7 @@ </tr> <#list versions as version> <tr> - <td><a target="_blank" href="${version.uri}" class="ldcache">${MEMENTO_DATE_FORMAT.format(version.date)}</a></td> + <td><a target="_blank" href="${version.uri}" class="ldcache">${version.formatedDate}</a></td> </tr> </#list> </table> http://git-wip-us.apache.org/repos/asf/marmotta/blob/385a92bc/platform/marmotta-versioning-kiwi/src/test/java/org/apache/marmotta/platform/versioning/MementoWebServiceTest.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-versioning-kiwi/src/test/java/org/apache/marmotta/platform/versioning/MementoWebServiceTest.java b/platform/marmotta-versioning-kiwi/src/test/java/org/apache/marmotta/platform/versioning/MementoWebServiceTest.java index c78b551..7aa647e 100644 --- a/platform/marmotta-versioning-kiwi/src/test/java/org/apache/marmotta/platform/versioning/MementoWebServiceTest.java +++ b/platform/marmotta-versioning-kiwi/src/test/java/org/apache/marmotta/platform/versioning/MementoWebServiceTest.java @@ -1,6 +1,8 @@ package org.apache.marmotta.platform.versioning; import com.jayway.restassured.RestAssured; +import com.jayway.restassured.response.Response; +import com.jayway.restassured.response.ValidatableResponse; import org.apache.marmotta.platform.core.api.importer.ImportService; import org.apache.marmotta.platform.core.api.triplestore.ContextService; import org.apache.marmotta.platform.core.api.user.UserService; @@ -8,6 +10,9 @@ import org.apache.marmotta.platform.core.exception.io.MarmottaImportException; import org.apache.marmotta.platform.core.test.base.JettyMarmotta; import org.apache.marmotta.platform.versioning.utils.MementoUtils; import org.apache.marmotta.platform.versioning.webservices.MementoWebService; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.core.IsEqual; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -16,9 +21,14 @@ import org.slf4j.LoggerFactory; import java.io.InputStream; import java.net.URISyntaxException; +import java.text.ParseException; import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import static com.jayway.restassured.RestAssured.expect; +import static com.jayway.restassured.RestAssured.*; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertTrue; /** * @author Thomas Kurz ([email protected]) @@ -75,4 +85,97 @@ public class MementoWebServiceTest { get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEGATE + "/http://example.org/resource1"); } + @Test + public void testTimemapWithoutMementoDatetimeHeader() { + expect(). + log().ifError().header("Memento-Datetime", isEmptyOrNullString()). + when().request().redirects().follow(false). + get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEGATE + "/http://example.org/resource1"); + } + + @Test + public void testWithDatetimeHeader() { + expect(). + log().ifError(). + when().request().redirects().follow(false). + header("Accept-Datetime","Mon, 19 Sep 2016 23:47:12 GMT"). + get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEGATE + "/http://example.org/resource1"); + } + + @Test + public void testDateFormatForTimemap() { + when(). + get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEMAP + "/http://example.org/resource1"). + then().body(containsValidMementoDatetimeFormats("datetime=\"([^\"]+)\"")); + } + + @Test + public void testDateFormatForLinkHeaders() { + //timemap + expect(). + log().ifError(). + when().request().redirects().follow(false). + get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEMAP + "/http://example.org/resource1"). + then().header("date",containsValidMementoDatetimeFormats("(.+)")); + + //timegate + String location = given().request().redirects().follow(false). + when(). + get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEGATE + "/http://example.org/resource1"). + then(). + header("date",containsValidMementoDatetimeFormats("(.+)")). + header("link", containsValidMementoDatetimeFormats("datetime=\"([^\"]+)\"")).extract().header("location"); + + //memento resource + when(). + get(location). + then(). + header("date", containsValidMementoDatetimeFormats("(.+)")). + header("memento-datetime",containsValidMementoDatetimeFormats("(.+)")). + header("link", containsValidMementoDatetimeFormats("datetime=\"([^\"]+)\"")).extract().header("location"); + } + + @Test + public void testTimemapSerialization() { + expect() + .log().ifError() + .when() + .request().header("Accept", "text / html, application / xhtml + xml, application/xml;q=0.9,image/webp,*/*;q=0.8") + .get(MementoUtils.MEMENTO_WEBSERVICE + "/" + MementoUtils.MEMENTO_TIMEMAP + "/http://example.org/resource1") + .then() + .contentType(is("text / html")); + } + + //matcher tests if all matching groups are in correct memento datetime serialization + private org.hamcrest.Matcher containsValidMementoDatetimeFormats(final String pattern) { + return new BaseMatcher() { + + private String lastGroup; + + @Override + public boolean matches(final Object item) { + + Pattern p = Pattern.compile(pattern); + + Matcher m = p.matcher((String)item); + + while(m.find()) { + lastGroup = m.group(1); + try { + Date date = MementoUtils.MEMENTO_DATE_FORMAT.parse(lastGroup); + if(!lastGroup.equals(MementoUtils.MEMENTO_DATE_FORMAT.format(date))) return false; + } catch (ParseException ex) { + return false; + } + } + + return true; + } + @Override + public void describeTo(final Description description) { + description.appendText("datetime does not match MementoDatetime: ").appendText(lastGroup); + } + }; + } + }
