1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package eu.ehri.extension;
21
22 import com.google.common.collect.Lists;
23 import eu.ehri.extension.base.AbstractAccessibleResource;
24 import eu.ehri.extension.base.AbstractResource;
25 import eu.ehri.extension.base.DeleteResource;
26 import eu.ehri.extension.base.GetResource;
27 import eu.ehri.extension.base.ListResource;
28 import eu.ehri.extension.base.ParentResource;
29 import eu.ehri.extension.base.UpdateResource;
30 import eu.ehri.project.core.Tx;
31 import eu.ehri.project.definitions.Entities;
32 import eu.ehri.project.exceptions.DeserializationError;
33 import eu.ehri.project.exceptions.ItemNotFound;
34 import eu.ehri.project.exceptions.PermissionDenied;
35 import eu.ehri.project.exceptions.ValidationError;
36 import eu.ehri.project.exporters.ead.Ead2002Exporter;
37 import eu.ehri.project.exporters.ead.EadExporter;
38 import eu.ehri.project.exporters.eag.Eag2012Exporter;
39 import eu.ehri.project.importers.ImportCallback;
40 import eu.ehri.project.importers.ImportLog;
41 import eu.ehri.project.importers.json.BatchOperations;
42 import eu.ehri.project.models.DocumentaryUnit;
43 import eu.ehri.project.models.Repository;
44 import eu.ehri.project.models.base.Accessible;
45 import eu.ehri.project.models.base.Actioner;
46 import eu.ehri.project.persistence.Bundle;
47 import org.neo4j.graphdb.GraphDatabaseService;
48
49 import javax.ws.rs.Consumes;
50 import javax.ws.rs.DELETE;
51 import javax.ws.rs.DefaultValue;
52 import javax.ws.rs.GET;
53 import javax.ws.rs.POST;
54 import javax.ws.rs.PUT;
55 import javax.ws.rs.Path;
56 import javax.ws.rs.PathParam;
57 import javax.ws.rs.Produces;
58 import javax.ws.rs.QueryParam;
59 import javax.ws.rs.WebApplicationException;
60 import javax.ws.rs.core.Context;
61 import javax.ws.rs.core.MediaType;
62 import javax.ws.rs.core.Response;
63 import javax.ws.rs.core.StreamingOutput;
64 import javax.xml.transform.TransformerException;
65 import java.io.IOException;
66 import java.io.InputStream;
67 import java.util.List;
68
69
70
71
72 @Path(AbstractResource.RESOURCE_ENDPOINT_PREFIX + "/" + Entities.REPOSITORY)
73 public class RepositoryResource extends AbstractAccessibleResource<Repository>
74 implements ParentResource, GetResource, ListResource, UpdateResource, DeleteResource {
75
76 public RepositoryResource(@Context GraphDatabaseService database) {
77 super(database, Repository.class);
78 }
79
80 @GET
81 @Produces(MediaType.APPLICATION_JSON)
82 @Path("{id:[^/]+}")
83 @Override
84 public Response get(@PathParam("id") String id) throws ItemNotFound {
85 return getItem(id);
86 }
87
88 @GET
89 @Produces(MediaType.APPLICATION_JSON)
90 @Override
91 public Response list() {
92 return listItems();
93 }
94
95 @GET
96 @Produces(MediaType.APPLICATION_JSON)
97 @Path("{id:[^/]+}/list")
98 @Override
99 public Response listChildren(
100 @PathParam("id") String id,
101 @QueryParam(ALL_PARAM) @DefaultValue("false") boolean all) throws ItemNotFound {
102 try (final Tx tx = beginTx()) {
103 Repository repository = api().detail(id, cls);
104 Response response = streamingPage(() -> {
105 Iterable<DocumentaryUnit> units = all
106 ? repository.getAllDocumentaryUnits()
107 : repository.getTopLevelDocumentaryUnits();
108 return getQuery().page(units, DocumentaryUnit.class);
109 });
110 tx.success();
111 return response;
112 }
113 }
114
115 @PUT
116 @Consumes(MediaType.APPLICATION_JSON)
117 @Produces(MediaType.APPLICATION_JSON)
118 @Path("{id:[^/]+}")
119 @Override
120 public Response update(@PathParam("id") String id, Bundle bundle)
121 throws PermissionDenied, ValidationError,
122 DeserializationError, ItemNotFound {
123 try (final Tx tx = beginTx()) {
124 Response response = updateItem(id, bundle);
125 tx.success();
126 return response;
127 }
128 }
129
130 @DELETE
131 @Path("{id:[^/]+}")
132 @Override
133 public void delete(@PathParam("id") String id)
134 throws PermissionDenied, ItemNotFound, ValidationError {
135 try (final Tx tx = beginTx()) {
136 deleteItem(id);
137 tx.success();
138 }
139 }
140
141
142
143
144
145
146
147
148 @POST
149 @Consumes(MediaType.APPLICATION_JSON)
150 @Produces(MediaType.APPLICATION_JSON)
151 @Path("{id:[^/]+}")
152 @Override
153 public Response createChild(@PathParam("id") String id,
154 Bundle bundle, @QueryParam(ACCESSOR_PARAM) List<String> accessors)
155 throws PermissionDenied, ValidationError,
156 DeserializationError, ItemNotFound {
157 try (final Tx tx = beginTx()) {
158 final Repository repository = api().detail(id, cls);
159 Response response = createItem(bundle, accessors,
160 repository::addTopLevelDocumentaryUnit,
161 api().withScope(repository), DocumentaryUnit.class);
162 tx.success();
163 return response;
164 }
165 }
166
167
168
169
170
171
172
173
174 @POST
175 @Consumes(MediaType.APPLICATION_JSON)
176 @Produces(MediaType.APPLICATION_JSON)
177 @Path("{id:[^/]+}/list")
178 public ImportLog addChildren(
179 @PathParam("id") String id,
180 InputStream data) throws ItemNotFound, DeserializationError, ValidationError {
181 try (final Tx tx = beginTx()) {
182 Actioner user = getCurrentActioner();
183 Repository repository = api().detail(id, cls);
184 ImportCallback cb = mutation -> {
185 Accessible accessible = mutation.getNode();
186 if (!Entities.DOCUMENTARY_UNIT.equals(accessible.getType())) {
187 throw new RuntimeException("Bundle is not a documentary unit: " + accessible.getId());
188 }
189 accessible.setPermissionScope(repository);
190 repository.addTopLevelDocumentaryUnit(accessible.as(DocumentaryUnit.class));
191 };
192 ImportLog log = new BatchOperations(graph, repository, true,
193 false, Lists.newArrayList(cb)).batchImport(data, user, getLogMessage());
194 logger.debug("Committing batch ingest transaction...");
195 tx.success();
196 return log;
197 }
198 }
199
200
201
202
203
204
205
206
207 @GET
208 @Path("{id:[^/]+}/eag")
209 @Produces(MediaType.TEXT_XML)
210 public Response exportEag(@PathParam("id") String id,
211 final @QueryParam("lang") @DefaultValue("eng") String lang)
212 throws IOException, ItemNotFound {
213 try (final Tx tx = beginTx()) {
214 Repository repository = api().detail(id, cls);
215 tx.success();
216 return Response.ok((StreamingOutput) outputStream -> {
217 try (final Tx tx2 = beginTx()) {
218 new Eag2012Exporter(api()).export(repository, outputStream, lang);
219 tx2.success();
220 } catch (TransformerException e) {
221 throw new WebApplicationException(e);
222 }
223 }).type(MediaType.TEXT_XML + "; charset=utf-8").build();
224 }
225 }
226
227
228
229
230
231
232
233
234
235 @GET
236 @Path("{id:[^/]+}/ead")
237 @Produces("application/zip")
238 public Response exportEad(@PathParam("id") String id,
239 final @QueryParam("lang") @DefaultValue("eng") String lang)
240 throws IOException, ItemNotFound {
241 try (final Tx tx = beginTx()) {
242 final Repository repo = api().detail(id, cls);
243 final EadExporter eadExporter = new Ead2002Exporter(api());
244 Response response = exportItemsAsZip(eadExporter, repo.getTopLevelDocumentaryUnits(), lang);
245 tx.success();
246 return response;
247 }
248 }
249 }