package nl.knaw.huygens.alexandria.endpoint; /* * #%L * alexandria-main * ======= * 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 java.util.stream.Collectors.toList; import java.util.List; import java.util.Map; import java.util.UUID; import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.ws.rs.BadRequestException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.google.common.collect.ImmutableMap; import io.swagger.annotations.ApiOperation; import nl.knaw.huygens.alexandria.api.JsonTypeNames; import nl.knaw.huygens.alexandria.api.model.AlexandriaState; import nl.knaw.huygens.alexandria.endpoint.annotation.AnnotationEntity; import nl.knaw.huygens.alexandria.endpoint.annotation.AnnotationPrototype; import nl.knaw.huygens.alexandria.model.AbstractAnnotatable; import nl.knaw.huygens.alexandria.model.AlexandriaAnnotation; import nl.knaw.huygens.alexandria.model.AlexandriaResource; import nl.knaw.huygens.alexandria.service.AlexandriaService; import nl.knaw.huygens.alexandria.textlocator.AlexandriaTextLocator; import nl.knaw.huygens.alexandria.textlocator.TextLocatorFactory; import nl.knaw.huygens.alexandria.textlocator.TextLocatorParseException; public abstract class AnnotatableObjectAnnotationsEndpoint extends JSONEndpoint { protected final AlexandriaService service; protected final LocationBuilder locationBuilder; protected final AnnotationCreationRequestBuilder requestBuilder; protected final UUID uuid; protected AnnotatableObjectAnnotationsEndpoint(AlexandriaService service, // AnnotationCreationRequestBuilder requestBuilder, // LocationBuilder locationBuilder, // final UUIDParam uuidParam) { // Log.trace("resourceService=[{}], uuidParam=[{}]", service, uuidParam); this.service = service; this.requestBuilder = requestBuilder; this.uuid = uuidParam.getValue(); this.locationBuilder = locationBuilder; // throw exception if annotatableObject doesn't exist or is tentative @SuppressWarnings("unused") AbstractAnnotatable annotatableObject = getAnnotatableObject(); } protected abstract AbstractAnnotatable getAnnotatableObject(); protected abstract AnnotationCreationRequestBuilder getAnnotationCreationRequestBuilder(); @GET @ApiOperation(value = "get the (non-deleted, non-deprecated) annotations", response = AnnotationEntity.class) public Response get() { final List<AnnotationEntity> annotationEntities = getAnnotatableObject().getAnnotations().stream()// .filter(AlexandriaAnnotation::isActive)// .sorted()// .map((AlexandriaAnnotation a) -> AnnotationEntity.of(a).withLocationBuilder(locationBuilder))// .collect(toList()); return ok(jsonWrap(annotationEntities)); } private Map<String, List<Map<String, AnnotationEntity>>> jsonWrap(final List<AnnotationEntity> annotationEntities) { return ImmutableMap.of(// JsonTypeNames.ANNOTATIONLIST, annotationEntities.stream()// .map(this::toAnnotationMap)// .collect(toList())// ); } private Map<String, AnnotationEntity> toAnnotationMap(AnnotationEntity e) { return ImmutableMap.of(JsonTypeNames.ANNOTATION, e); } @POST @Consumes(MediaType.APPLICATION_JSON) @ApiOperation("add annotation") public Response addAnnotation(@NotNull @Valid AnnotationPrototype prototype) { validateLocator(prototype); prototype.setState(AlexandriaState.TENTATIVE); AnnotationCreationRequest request = getAnnotationCreationRequestBuilder().build(prototype); AlexandriaAnnotation annotation = request.execute(service); return created(locationBuilder.locationOf(annotation)); } private void validateLocator(AnnotationPrototype prototype) { if (prototype.getLocator().isPresent()) { if (!(getAnnotatableObject() instanceof AlexandriaResource)) { throw new BadRequestException("locators are only allowed on resource annotations"); } AlexandriaResource resource = (AlexandriaResource) getAnnotatableObject(); if (!resource.hasText()) { throw new BadRequestException("The resource has no attached text to use the locator on."); } String locatorString = prototype.getLocator().get(); try { TextLocatorFactory textLocatorFactory = new TextLocatorFactory(service); AlexandriaTextLocator locator = textLocatorFactory.fromString(locatorString); textLocatorFactory.validate(locator, resource); } catch (TextLocatorParseException e) { throw new BadRequestException(e.getMessage()); } } } }