package nl.knaw.huygens.alexandria.client;
/*
* #%L
* alexandria-java-client
* =======
* Copyright (C) 2015 - 2017 Huygens ING (KNAW)
* =======
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import static org.assertj.core.api.Assertions.assertThat;
import java.net.URI;
import java.util.Map;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.ImmutableMap;
import nl.knaw.huygens.Log;
import nl.knaw.huygens.alexandria.api.model.Annotator;
import nl.knaw.huygens.alexandria.api.model.text.TextImportStatus;
import nl.knaw.huygens.alexandria.api.model.text.TextRangeAnnotation;
import nl.knaw.huygens.alexandria.api.model.text.TextRangeAnnotation.AbsolutePosition;
import nl.knaw.huygens.alexandria.api.model.text.TextRangeAnnotation.Position;
import nl.knaw.huygens.alexandria.api.model.text.TextRangeAnnotationInfo;
import nl.knaw.huygens.alexandria.api.model.text.TextRangeAnnotationList;
public class TextRangeAnnotationTest extends AlexandriaClientTest {
@Before
public void before() {
client.setAuthKey(AUTHKEY);
}
@Test
public void testSetTextRangeAnnotation() {
String xml = singleQuotesToDouble("<text><p xml:id='p-1'>This is a simple paragraph.</p></text>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ed", new Annotator().setCode("ed").setDescription("Eddy Wally"));
assertRequestSucceeded(result);
UUID annotationUUID = UUID.randomUUID();
Position position = new Position()//
.setXmlId("p-1")//
.setOffset(6)//
.setLength(2);
AbsolutePosition absolutePosition = new AbsolutePosition()//
.setXmlId(position.getXmlId().get())//
.setOffset(position.getOffset().get())//
.setLength(position.getLength().get());
TextRangeAnnotation textRangeAnnotation0 = new TextRangeAnnotation()//
.setId(annotationUUID)//
.setName("word")//
.setAnnotator("ed")//
.setPosition(position)//
.setAbsolutePosition(absolutePosition);
RestResult<TextRangeAnnotationInfo> putResult = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation0);
assertRequestSucceeded(putResult);
TextRangeAnnotationInfo info = putResult.get();
assertThat(info.getAnnotates()).isEqualTo("is");
dumpDb();
RestResult<TextRangeAnnotation> getResult = client.getResourceTextRangeAnnotation(resourceUUID, annotationUUID);
assertRequestSucceeded(getResult);
TextRangeAnnotation textRangeAnnotation1 = getResult.get();
textRangeAnnotation0.setAbsolutePosition(null);
assertThat(textRangeAnnotation1).isEqualToComparingFieldByFieldRecursively(textRangeAnnotation0);
}
@Test
public void testSetTextRangeAnnotationWithInvalidXmlId() {
String xml = singleQuotesToDouble("<text><p xml:id='p-1'>This is a simple & short paragraph.</p></text>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ed", new Annotator().setCode("ed").setDescription("Eddy Wally"));
assertRequestSucceeded(result);
UUID uuid = UUID.randomUUID();
Position position = new Position()//
.setXmlId("undefined")//
.setOffset(6)//
.setLength(2);
TextRangeAnnotation textAnnotation = new TextRangeAnnotation()//
.setId(uuid)//
.setName("word")//
.setAnnotator("ed")//
.setPosition(position);
RestResult<TextRangeAnnotationInfo> putResult = client.setResourceTextRangeAnnotation(resourceUUID, textAnnotation);
assertThat(putResult.hasFailed()).isTrue();
assertThat(putResult.getErrorMessage().get()).isEqualTo("The text does not contain an element with the specified xml:id.");
}
@Test
public void testSetTextRangeAnnotationOnElementWithoutText() {
String xml = singleQuotesToDouble("<text><p xml:id='p-9'>Ex Musaeo, & ...</p>\n"//
+ "<p xml:id='p-10'>Tuus ...</p>\n"//
+ "<p xml:id='p-11'>Prenez ...</p>\n"//
+ "<p xml:id='p-12'>Je vous ....</p>\n"//
+ "<p xml:id='p-13'>A <placeName key='se:saumur.fra'>Saumur</placeName>.</p>\n"//
+ "<p xml:id='p-14'><figure><graphic url='beec002jour04ill02.gif'/></figure></p></text>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ed", new Annotator().setCode("ed").setDescription("Eddy Thor"));
assertRequestSucceeded(result);
UUID uuid = UUID.randomUUID();
Position position = new Position()//
.setXmlId("p-14");
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(uuid)//
.setName("hi")//
.setAnnotator("ed")//
.setPosition(position);
RestResult<TextRangeAnnotationInfo> putResult = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult.getFailureCause().ifPresent(Log::info);
assertThat(putResult.hasFailed()).isFalse();
Log.info(putResult.get().toString());
}
@Test
public void testSetNonOverlappingTextRangeAnnotations() {
String xml = singleQuotesToDouble("<text><p xml:id='p-9'>Ex Musaeo,...</p>\n"//
+ "<p xml:id='p-10'>Tuus...</p>\n"//
+ "<p xml:id='p-11'>Prenez ...</p>\n"//
+ "<p xml:id='p-12'>Je vous ....</p>\n"//
+ "<p xml:id='p-13'>A <placeName key='se:saumur.fra'>Saumur</placeName>.</p>\n"//
+ "<p xml:id='p-14'><figure><graphic url='beec002jour04ill02.gif'/></figure></p></text>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ckcc", new Annotator().setCode("ckcc").setDescription("Cees Kacc"));
assertRequestSucceeded(result);
RestResult<TextRangeAnnotationList> restResult = client.getResourceTextRangeAnnotations(resourceUUID);
assertThat(restResult.hasFailed()).isFalse();
TextRangeAnnotationList list = restResult.get();
assertThat(list).hasSize(0);
UUID closer13 = UUID.randomUUID();
Position position = new Position()//
.setXmlId("p-13");
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(closer13)//
.setName("closer")//
.setAnnotator("ckcc")//
.setPosition(position);
RestResult<TextRangeAnnotationInfo> putResult = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult.getFailureCause().ifPresent(Log::info);
assertThat(putResult.hasFailed()).isFalse();
Log.info(putResult.get().toString());
UUID closer9 = UUID.randomUUID();
Position position9 = new Position()//
.setXmlId("p-9");
TextRangeAnnotation textRangeAnnotation9 = new TextRangeAnnotation()//
.setId(closer9)//
.setName("closer")//
.setAnnotator("ckcc")//
.setPosition(position9);
RestResult<TextRangeAnnotationInfo> putResult9 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation9);
putResult9.getFailureCause().ifPresent(Log::info);
assertThat(putResult9.hasFailed()).isFalse();
Log.info(putResult.get().toString());
// now, receive all textrangeannotations for this text.
RestResult<TextRangeAnnotationList> restResult2 = client.getResourceTextRangeAnnotations(resourceUUID);
assertThat(restResult2.hasFailed()).isFalse();
TextRangeAnnotationList list2 = restResult.get();
assertThat(list2).hasSize(0);
}
@Test
public void testSetNonOverlappingAdjacentTextRangeAnnotations() {
String xml = singleQuotesToDouble("<text><p xml:id='p-1'>... Patri M. MersennoR. Descartes S.D...</p></text>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ckcc", new Annotator().setCode("ckcc").setDescription("Co Koccu"));
assertRequestSucceeded(result);
RestResult<TextRangeAnnotationList> restResult = client.getResourceTextRangeAnnotations(resourceUUID);
assertThat(restResult.hasFailed()).isFalse();
TextRangeAnnotationList list = restResult.get();
assertThat(list).hasSize(0);
UUID persName1 = UUID.randomUUID();
Position position1 = new Position()//
.setXmlId("p-1")//
.setOffset(5)//
.setLength(17);
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(persName1)//
.setName("persName")//
.setAnnotator("ckcc")//
.setPosition(position1);
RestResult<TextRangeAnnotationInfo> putResult1 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult1.getFailureCause().ifPresent(Log::info);
assertThat(putResult1.hasFailed()).isFalse();
assertThat(putResult1.get().getAnnotates()).isEqualTo("Patri M. Mersenno");
Log.info(putResult1.get().toString());
UUID persName2 = UUID.randomUUID();
Position position2 = new Position()//
.setXmlId("p-1")//
.setOffset(22)//
.setLength(17);
TextRangeAnnotation textRangeAnnotation2 = new TextRangeAnnotation()//
.setId(persName2)//
.setName("persName")//
.setAnnotator("ckcc")//
.setPosition(position2);
RestResult<TextRangeAnnotationInfo> putResult2 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation2);
putResult2.getFailureCause().ifPresent(Log::info);
assertThat(putResult2.hasFailed()).isFalse();
assertThat(putResult2.get().getAnnotates()).isEqualTo("R. Descartes S.D.");
Log.info(putResult2.get().toString());
// now, receive all textrangeannotations for this text.
RestResult<TextRangeAnnotationList> restResult2 = client.getResourceTextRangeAnnotations(resourceUUID);
assertThat(restResult2.hasFailed()).isFalse();
TextRangeAnnotationList list2 = restResult.get();
assertThat(list2).hasSize(0);
}
@Test
public void testNLA318() {
String xml = singleQuotesToDouble("<p xml:id='p-1'>...epouse mad<sup>le</sup> de <sic>Gendrin</sic> soeur du feu archevesque de Sens...</p>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ckcc", new Annotator().setCode("ckcc").setDescription("Co Koccu"));
assertRequestSucceeded(result);
UUID persName1 = UUID.randomUUID();
Position position1 = new Position()//
.setXmlId("p-1")//
.setOffset(17)//
.setLength(10);
Map<String, String> attributes = ImmutableMap.of("key", "S0328208");
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(persName1)//
.setName("persName")//
.setAnnotator("ckcc")//
.setPosition(position1)//
.setAttributes(attributes);
RestResult<TextRangeAnnotationInfo> putResult1 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult1.getFailureCause().ifPresent(Log::info);
assertThat(putResult1.hasFailed()).isFalse();
assertThat(putResult1.get().getAnnotates()).isEqualTo("de Gendrin");
Log.info(putResult1.get().toString());
String dot = client.getTextAsDot(resourceUUID).get();
Log.info("dot=\n{}", dot);
RestResult<String> textResult = client.getTextAsString(resourceUUID);
assertRequestSucceeded(textResult);
String xml2 = textResult.get();
String expected = "<p xml:id=\"p-1\">...epouse mad<sup>le</sup> <persName key=\"S0328208\" resp=\"#ckcc\">de <sic>Gendrin</sic></persName> soeur du feu archevesque de Sens...</p>";
assertThat(xml2).isEqualTo(expected);
}
@Test
public void testNLA318a() {
String xml = singleQuotesToDouble("<p xml:id='p-1'>A B <y>de</y> <sic>C</sic> D <x>E</x></p>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ckcc", new Annotator().setCode("ckcc").setDescription("Co Koccu"));
assertRequestSucceeded(result);
client.getTextAsDot(resourceUUID).get();
UUID persName1 = UUID.randomUUID();
Position position1 = new Position()//
.setXmlId("p-1")//
.setOffset(3)//
.setLength(6);
Map<String, String> attributes = ImmutableMap.of("key", "VALUE");
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(persName1)//
.setName("persName")//
.setAnnotator("ckcc")//
.setPosition(position1)//
.setAttributes(attributes);
RestResult<TextRangeAnnotationInfo> putResult1 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult1.getFailureCause().ifPresent(Log::info);
assertThat(putResult1.hasFailed()).isFalse();
assertThat(putResult1.get().getAnnotates()).isEqualTo("B de C");
Log.info(putResult1.get().toString());
client.getTextAsDot(resourceUUID).get();
RestResult<String> textResult = client.getTextAsString(resourceUUID);
assertRequestSucceeded(textResult);
String xml2 = textResult.get();
String expected = "<p xml:id=\"p-1\">A <persName key=\"VALUE\" resp=\"#ckcc\">B <y>de</y> <sic>C</sic></persName> D <x>E</x></p>";
assertThat(xml2).isEqualTo(expected);
}
@Test
public void testNLA312() {
String xml = singleQuotesToDouble("<p xml:id='p-1'>Willie Wortel vindt uit.</p>");
UUID resourceUUID = createResourceWithText(xml);
RestResult<Void> result = client.setAnnotator(resourceUUID, "ckcc", new Annotator().setCode("ckcc").setDescription("Co Koccu"));
assertRequestSucceeded(result);
UUID persNameUUID = UUID.randomUUID();
Position position1 = new Position()//
.setXmlId("p-1")//
.setOffset(1)//
.setLength(13);
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(persNameUUID)//
.setName("persName")//
.setAnnotator("ckcc")//
.setPosition(position1);
RestResult<TextRangeAnnotationInfo> putResult1 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult1.getFailureCause().ifPresent(Log::info);
assertThat(putResult1.hasFailed()).isFalse();
assertThat(putResult1.get().getAnnotates()).isEqualTo("Willie Wortel");
Log.info(putResult1.get().toString());
UUID persIdUUID = UUID.randomUUID();
Position position2 = new Position()//
.setTargetAnnotationId(persNameUUID);
Map<String, String> attributes = ImmutableMap.of("id", "W. Wortel (1934-)");
TextRangeAnnotation textRangeAnnotation2 = new TextRangeAnnotation()//
.setId(persIdUUID)//
.setName("persName_id")//
.setAnnotator("ckcc")//
.setPosition(position2)//
.setAttributes(attributes);
RestResult<TextRangeAnnotationInfo> putResult2 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation2);
putResult2.getFailureCause().ifPresent(Log::info);
assertThat(putResult2.hasFailed()).isFalse();
// assertThat(putResult2.get().getAnnotates()).isEqualTo("Willie Wortel");
Log.info(putResult2.get().toString());
RestResult<String> textResult = client.getTextAsString(resourceUUID);
assertRequestSucceeded(textResult);
String xml2 = textResult.get();
String expected = singleQuotesToDouble("<p xml:id='p-1'><persName resp='#ckcc'><persName_id id='W. Wortel (1934-)' resp='#ckcc'>Willie Wortel</persName_id></persName> vindt uit.</p>");
assertThat(xml2).isEqualTo(expected);
}
@Test
public void testNLA307() {
String xml = //
singleQuotesToDouble("<text>\n"//
+ "<p xml:id='p-1'>prologue</p>\n"//
+ "<p xml:id='p-2'>hello</p>\n"//
+ "<p xml:id='p-3'>goodbye</p>\n"//
+ "<p xml:id='p-4'>epilogue</p>\n"//
+ "</text>");
UUID resourceUUID = createResourceWithText(xml);
Log.info("xml 0: {}", xml);
Annotator annotator = new Annotator().setCode("ckcc").setDescription("something");
client.setAnnotator(resourceUUID, "ckcc", annotator);
// set first annotation (bad value, should be "opener"
UUID annotationUUID1 = UUID.randomUUID();
Position position1 = new Position()//
.setXmlId("p-2");
Map<String, String> badProperties = ImmutableMap.of("value", "closer");
TextRangeAnnotation textRangeAnnotation = new TextRangeAnnotation()//
.setId(annotationUUID1)//
.setName("p_type")//
.setAnnotator("ckcc")//
.setPosition(position1)//
.setAttributes(badProperties);
String xmlOut = applyAnnotation(resourceUUID, textRangeAnnotation);
String expectation = //
singleQuotesToDouble("<text>\n"//
+ "<p xml:id='p-1'>prologue</p>\n"//
+ "<p xml:id='p-2'><p_type value='closer' resp='#ckcc'>hello</p_type></p>\n"//
+ "<p xml:id='p-3'>goodbye</p>\n"//
+ "<p xml:id='p-4'>epilogue</p>\n"//
+ "</text>");
assertThat(xmlOut).isEqualTo(expectation);
// correct first annotation
Map<String, String> goodProperties = ImmutableMap.of("value", "opener");
TextRangeAnnotation textRangeAnnotation2 = new TextRangeAnnotation()//
.setId(annotationUUID1)//
.setName("p_type")//
.setAnnotator("ckcc")//
.setPosition(position1)//
.setAttributes(goodProperties);
xmlOut = applyAnnotation(resourceUUID, textRangeAnnotation2);
expectation = //
singleQuotesToDouble("<text>\n"//
+ "<p xml:id='p-1'>prologue</p>\n"//
+ "<p xml:id='p-2'><p_type value='opener' resp='#ckcc'>hello</p_type></p>\n"//
+ "<p xml:id='p-3'>goodbye</p>\n"//
+ "<p xml:id='p-4'>epilogue</p>\n"//
+ "</text>");
assertThat(xmlOut).isEqualTo(expectation);
// set second annotation
UUID annotationUUID2 = UUID.randomUUID();
Position position2 = new Position()//
.setXmlId("p-3");
Map<String, String> properties = ImmutableMap.of("value", "closer");
TextRangeAnnotation textRangeAnnotation3 = new TextRangeAnnotation()//
.setId(annotationUUID2)//
.setName("p_type")//
.setAnnotator("ckcc")//
.setPosition(position2)//
.setAttributes(properties);
xmlOut = applyAnnotation(resourceUUID, textRangeAnnotation3);
expectation = //
singleQuotesToDouble("<text>\n"//
+ "<p xml:id='p-1'>prologue</p>\n"//
+ "<p xml:id='p-2'><p_type value='opener' resp='#ckcc'>hello</p_type></p>\n"//
+ "<p xml:id='p-3'><p_type value='closer' resp='#ckcc'>goodbye</p_type></p>\n"//
+ "<p xml:id='p-4'>epilogue</p>\n"//
+ "</text>");
assertThat(xmlOut).isEqualTo(expectation);
}
private String applyAnnotation(UUID resourceUUID, TextRangeAnnotation textRangeAnnotation) {
RestResult<TextRangeAnnotationInfo> putResult2 = client.setResourceTextRangeAnnotation(resourceUUID, textRangeAnnotation);
putResult2.getFailureCause().ifPresent(Log::info);
assertThat(putResult2.hasFailed()).isFalse();
RestResult<String> textResult = client.getTextAsString(resourceUUID);
assertRequestSucceeded(textResult);
return textResult.get();
}
private UUID createResourceWithText(String xml) {
String resourceRef = "test";
UUID resourceUUID = createResource(resourceRef);
TextImportStatus textGraphImportStatus = setResourceText(resourceUUID, xml);
URI expectedURI = URI.create("http://localhost:2016/resources/" + resourceUUID + "/text/xml");
assertThat(textGraphImportStatus.getTextURI()).isEqualTo(expectedURI);
return resourceUUID;
}
}