View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.extension;
21  
22  import com.google.common.collect.Iterables;
23  import eu.ehri.extension.base.AbstractAccessibleResource;
24  import eu.ehri.extension.base.AbstractResource;
25  import eu.ehri.extension.base.CreateResource;
26  import eu.ehri.extension.base.DeleteResource;
27  import eu.ehri.extension.base.GetResource;
28  import eu.ehri.extension.base.ListResource;
29  import eu.ehri.extension.base.ParentResource;
30  import eu.ehri.extension.base.UpdateResource;
31  import eu.ehri.project.api.Api;
32  import eu.ehri.project.core.Tx;
33  import eu.ehri.project.definitions.Entities;
34  import eu.ehri.project.exceptions.AccessDenied;
35  import eu.ehri.project.exceptions.DeserializationError;
36  import eu.ehri.project.exceptions.ItemNotFound;
37  import eu.ehri.project.exceptions.PermissionDenied;
38  import eu.ehri.project.exceptions.SerializationError;
39  import eu.ehri.project.exceptions.ValidationError;
40  import eu.ehri.project.exporters.eac.Eac2010Exporter;
41  import eu.ehri.project.exporters.eac.EacExporter;
42  import eu.ehri.project.models.HistoricalAgent;
43  import eu.ehri.project.models.cvoc.AuthoritativeItem;
44  import eu.ehri.project.models.cvoc.AuthoritativeSet;
45  import eu.ehri.project.persistence.Bundle;
46  import org.neo4j.graphdb.GraphDatabaseService;
47  
48  import javax.ws.rs.Consumes;
49  import javax.ws.rs.DELETE;
50  import javax.ws.rs.DefaultValue;
51  import javax.ws.rs.GET;
52  import javax.ws.rs.POST;
53  import javax.ws.rs.PUT;
54  import javax.ws.rs.Path;
55  import javax.ws.rs.PathParam;
56  import javax.ws.rs.Produces;
57  import javax.ws.rs.QueryParam;
58  import javax.ws.rs.core.Context;
59  import javax.ws.rs.core.MediaType;
60  import javax.ws.rs.core.Response;
61  import javax.ws.rs.core.Response.Status;
62  import java.io.IOException;
63  import java.util.List;
64  
65  /**
66   * Provides a web service interface for the AuthoritativeSet items. model.
67   * Authoritative Sets are containers for Historical Agents
68   * (authority files.)
69   */
70  @Path(AbstractResource.RESOURCE_ENDPOINT_PREFIX + "/" + Entities.AUTHORITATIVE_SET)
71  public class AuthoritativeSetResource extends
72          AbstractAccessibleResource<AuthoritativeSet>
73          implements GetResource, ListResource, DeleteResource, CreateResource, UpdateResource, ParentResource {
74  
75      public AuthoritativeSetResource(@Context GraphDatabaseService database) {
76          super(database, AuthoritativeSet.class);
77      }
78  
79      @GET
80      @Produces(MediaType.APPLICATION_JSON)
81      @Path("{id:[^/]+}")
82      @Override
83      public Response get(@PathParam("id") String id) throws ItemNotFound {
84          return getItem(id);
85      }
86  
87      @GET
88      @Produces(MediaType.APPLICATION_JSON)
89      @Override
90      public Response list() {
91          return listItems();
92      }
93  
94      @GET
95      @Produces(MediaType.APPLICATION_JSON)
96      @Path("{id:[^/]+}/list")
97      @Override
98      public Response listChildren(
99              @PathParam("id") String id,
100             @QueryParam(ALL_PARAM) @DefaultValue("false") boolean all) throws ItemNotFound {
101 
102         try (final Tx tx = beginTx()) {
103             AuthoritativeSet set = api().detail(id, cls);
104             Response response = streamingPage(() ->
105                     getQuery().page(set.getAuthoritativeItems(), AuthoritativeItem.class));
106             tx.success();
107             return response;
108         }
109     }
110 
111     @POST
112     @Consumes(MediaType.APPLICATION_JSON)
113     @Produces(MediaType.APPLICATION_JSON)
114     @Override
115     public Response create(Bundle bundle,
116             @QueryParam(ACCESSOR_PARAM) List<String> accessors)
117             throws PermissionDenied, ValidationError, DeserializationError {
118         try (Tx tx = beginTx()) {
119             Response response = createItem(bundle, accessors);
120             tx.success();
121             return response;
122         }
123     }
124 
125     @PUT
126     @Consumes(MediaType.APPLICATION_JSON)
127     @Produces(MediaType.APPLICATION_JSON)
128     @Path("{id:[^/]+}")
129     @Override
130     public Response update(@PathParam("id") String id, Bundle bundle)
131             throws PermissionDenied, ValidationError,
132             DeserializationError, ItemNotFound {
133         try (Tx tx = beginTx()) {
134             Response response = updateItem(id, bundle);
135             tx.success();
136             return response;
137         }
138     }
139 
140     @DELETE
141     @Path("{id:[^/]+}")
142     @Override
143     public void delete(@PathParam("id") String id)
144             throws PermissionDenied, ItemNotFound, ValidationError {
145         try (Tx tx = beginTx()) {
146             deleteItem(id);
147             tx.success();
148         }
149     }
150 
151     @DELETE
152     @Path("{id:[^/]+}/all")
153     public Response deleteAllAuthoritativeSetHistoricalAgents(
154             @PathParam("id") String id)
155             throws ItemNotFound, AccessDenied, PermissionDenied {
156         try (Tx tx = beginTx()) {
157             Api api = api();
158             AuthoritativeSet set = api.detail(id, cls);
159             Iterable<AuthoritativeItem> agents = set.getAuthoritativeItems();
160             Api scopedApi = api.withScope(set);
161             for (AuthoritativeItem agent : agents) {
162                 scopedApi.delete(agent.getId());
163             }
164             tx.success();
165             return Response.status(Status.OK).build();
166         } catch (ValidationError | SerializationError e) {
167             throw new RuntimeException(e);
168         }
169     }
170 
171     @POST
172     @Consumes(MediaType.APPLICATION_JSON)
173     @Produces(MediaType.APPLICATION_JSON)
174     @Path("{id:[^/]+}")
175     @Override
176     public Response createChild(@PathParam("id") String id,
177             Bundle bundle, @QueryParam(ACCESSOR_PARAM) List<String> accessors)
178             throws PermissionDenied, ValidationError,
179             DeserializationError, ItemNotFound {
180         try (Tx tx = beginTx()) {
181             final AuthoritativeSet set = api().detail(id, cls);
182             Response item = createItem(bundle, accessors, agent -> {
183                 set.addItem(agent);
184                 agent.setPermissionScope(set);
185             }, api().withScope(set), HistoricalAgent.class);
186             tx.success();
187             return item;
188         }
189     }
190 
191     /**
192      * Export the given set's historical agents as EAC streamed
193      * in a ZIP file.
194      *
195      * @param id   the set ID
196      * @param lang a three-letter ISO639-2 code
197      * @return a zip containing the set's historical agents as EAC
198      */
199     @GET
200     @Path("{id:[^/]+}/eac")
201     @Produces("application/zip")
202     public Response exportEag(@PathParam("id") String id,
203             final @QueryParam("lang") @DefaultValue("eng") String lang)
204             throws IOException, ItemNotFound {
205         try (final Tx tx = beginTx()) {
206             final AuthoritativeSet set = api().detail(id, cls);
207             final EacExporter eacExporter = new Eac2010Exporter(api());
208             Iterable<HistoricalAgent> agents = Iterables
209                     .transform(set.getAuthoritativeItems(), a -> a.as(HistoricalAgent.class));
210             Response response = exportItemsAsZip(eacExporter, agents, lang);
211             tx.success();
212             return response;
213         }
214     }
215 }