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 eu.ehri.extension.base.AbstractAccessibleResource;
23 import eu.ehri.extension.base.AbstractResource;
24 import eu.ehri.extension.base.CreateResource;
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.api.Api;
31 import eu.ehri.project.core.Tx;
32 import eu.ehri.project.definitions.Entities;
33 import eu.ehri.project.definitions.EventTypes;
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.cvoc.JenaSkosExporter;
41 import eu.ehri.project.importers.cvoc.SkosRDFVocabulary;
42 import eu.ehri.project.models.base.Actioner;
43 import eu.ehri.project.models.cvoc.Concept;
44 import eu.ehri.project.models.cvoc.Vocabulary;
45 import eu.ehri.project.persistence.ActionManager;
46 import eu.ehri.project.persistence.Bundle;
47 import org.apache.jena.rdf.model.Model;
48 import org.neo4j.graphdb.GraphDatabaseService;
49
50 import javax.ws.rs.Consumes;
51 import javax.ws.rs.DELETE;
52 import javax.ws.rs.DefaultValue;
53 import javax.ws.rs.GET;
54 import javax.ws.rs.POST;
55 import javax.ws.rs.PUT;
56 import javax.ws.rs.Path;
57 import javax.ws.rs.PathParam;
58 import javax.ws.rs.Produces;
59 import javax.ws.rs.QueryParam;
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 java.io.IOException;
65 import java.util.List;
66
67
68
69
70
71 @Path(AbstractResource.RESOURCE_ENDPOINT_PREFIX + "/" + Entities.CVOC_VOCABULARY)
72 public class VocabularyResource extends AbstractAccessibleResource<Vocabulary>
73 implements GetResource, ListResource, DeleteResource, CreateResource, UpdateResource, ParentResource {
74
75 public VocabularyResource(@Context GraphDatabaseService database) {
76 super(database, Vocabulary.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 try (final Tx tx = beginTx()) {
102 Vocabulary vocabulary = api().detail(id, cls);
103 Response response = streamingPage(() -> getQuery()
104 .page(vocabulary.getConcepts(), Concept.class));
105 tx.success();
106 return response;
107 }
108 }
109
110 @POST
111 @Consumes(MediaType.APPLICATION_JSON)
112 @Produces(MediaType.APPLICATION_JSON)
113 @Override
114 public Response create(Bundle bundle,
115 @QueryParam(ACCESSOR_PARAM) List<String> accessors)
116 throws PermissionDenied, ValidationError, DeserializationError {
117 try (final Tx tx = beginTx()) {
118 Response item = createItem(bundle, accessors);
119 tx.success();
120 return item;
121 }
122 }
123
124 @PUT
125 @Consumes(MediaType.APPLICATION_JSON)
126 @Produces(MediaType.APPLICATION_JSON)
127 @Path("{id:[^/]+}")
128 @Override
129 public Response update(@PathParam("id") String id, Bundle bundle)
130 throws PermissionDenied, ValidationError,
131 DeserializationError, ItemNotFound {
132 try (final Tx tx = beginTx()) {
133 Response item = updateItem(id, bundle);
134 tx.success();
135 return item;
136 }
137 }
138
139 @DELETE
140 @Path("{id:[^/]+}")
141 @Override
142 public void delete(@PathParam("id") String id)
143 throws PermissionDenied, ItemNotFound, ValidationError {
144 try (final Tx tx = beginTx()) {
145 deleteItem(id);
146 tx.success();
147 }
148 }
149
150 @DELETE
151 @Path("{id:[^/]+}/all")
152 public void deleteAllVocabularyConcepts(@PathParam("id") String id)
153 throws ItemNotFound, AccessDenied, PermissionDenied {
154 try (final Tx tx = beginTx()) {
155 Actioner user = getCurrentActioner();
156 Api api = api().enableLogging(false);
157 Vocabulary vocabulary = api.detail(id, cls);
158 ActionManager actionManager = api.actionManager().setScope(vocabulary);
159 Iterable<Concept> concepts = vocabulary.getConcepts();
160 if (concepts.iterator().hasNext()) {
161 ActionManager.EventContext context = actionManager
162 .newEventContext(user, EventTypes.deletion, getLogMessage());
163 for (Concept concept : concepts) {
164 context.addSubjects(concept);
165 context.createVersion(concept);
166 }
167 context.commit();
168 for (Concept concept : concepts) {
169 api.delete(concept.getId());
170 }
171 }
172 tx.success();
173 } catch (SerializationError | ValidationError e) {
174 throw new RuntimeException(e);
175 }
176 }
177
178 @POST
179 @Consumes(MediaType.APPLICATION_JSON)
180 @Produces(MediaType.APPLICATION_JSON)
181 @Path("{id:[^/]+}")
182 @Override
183 public Response createChild(@PathParam("id") String id,
184 Bundle bundle, @QueryParam(ACCESSOR_PARAM) List<String> accessors)
185 throws PermissionDenied, ValidationError,
186 DeserializationError, ItemNotFound {
187 try (final Tx tx = beginTx()) {
188 final Vocabulary vocabulary = api().detail(id, cls);
189 Response item = createItem(bundle, accessors,
190 concept -> concept.setVocabulary(vocabulary),
191 api().withScope(vocabulary), Concept.class);
192 tx.success();
193 return item;
194 }
195 }
196
197
198
199
200
201
202
203
204
205 @GET
206 @Path("{id:[^/]+}/export")
207 @Produces({TURTLE_MIMETYPE, RDF_XML_MIMETYPE, N3_MIMETYPE})
208 public Response exportSkos(@PathParam("id") String id,
209 final @QueryParam("format") String format,
210 final @QueryParam("baseUri") String baseUri)
211 throws IOException, ItemNotFound {
212 final String rdfFormat = getRdfFormat(format, "TTL");
213 final String base = baseUri == null ? SkosRDFVocabulary.DEFAULT_BASE_URI : baseUri;
214 final MediaType mediaType = MediaType.valueOf(RDF_MIMETYPE_FORMATS
215 .inverse().get(rdfFormat));
216 try (final Tx tx = beginTx()) {
217 final Vocabulary vocabulary = api().detail(id, cls);
218 final JenaSkosExporter skosImporter = new JenaSkosExporter(graph, vocabulary);
219 final Model model = skosImporter.export(base);
220 tx.success();
221 return Response.ok((StreamingOutput) outputStream ->
222 model.getWriter(rdfFormat).write(model, outputStream, base))
223 .type(mediaType + "; charset=utf-8").build();
224 }
225 }
226 }