source: ComponentRegistry/branches/jeaferversion/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java @ 1639

Last change on this file since 1639 was 1639, checked in by jeafer, 12 years ago

Jean-Charles branch ComponentRegistry commit4,
Changes regarding comment on the ComponentRegistry.

Modification of classes Comment, CommentsDao?
Improvement of validation process for comments
Improvement of ComponentRegistryRestService?
Functionnal implementation of class test (RegisterHelper? and RestServiceTest?)

File size: 40.1 KB
Line 
1package clarin.cmdi.componentregistry.rest;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6import java.net.URI;
7import java.security.Principal;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.List;
11
12import javax.servlet.http.HttpServletRequest;
13import javax.ws.rs.Consumes;
14import javax.ws.rs.DELETE;
15import javax.ws.rs.DefaultValue;
16import javax.ws.rs.FormParam;
17import javax.ws.rs.GET;
18import javax.ws.rs.POST;
19import javax.ws.rs.Path;
20import javax.ws.rs.PathParam;
21import javax.ws.rs.Produces;
22import javax.ws.rs.QueryParam;
23import javax.ws.rs.WebApplicationException;
24import javax.ws.rs.core.Context;
25import javax.ws.rs.core.MediaType;
26import javax.ws.rs.core.Response;
27import javax.ws.rs.core.SecurityContext;
28import javax.ws.rs.core.StreamingOutput;
29import javax.ws.rs.core.UriInfo;
30import javax.ws.rs.core.Response.Status;
31
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
35import clarin.cmdi.componentregistry.ComponentRegistry;
36import clarin.cmdi.componentregistry.ComponentRegistryException;
37import clarin.cmdi.componentregistry.ComponentRegistryFactory;
38import clarin.cmdi.componentregistry.DeleteFailedException;
39import clarin.cmdi.componentregistry.UserCredentials;
40import clarin.cmdi.componentregistry.UserUnauthorizedException;
41import clarin.cmdi.componentregistry.components.CMDComponentSpec;
42import clarin.cmdi.componentregistry.model.AbstractDescription;
43import clarin.cmdi.componentregistry.model.Comment;
44import clarin.cmdi.componentregistry.model.ComponentDescription;
45import clarin.cmdi.componentregistry.model.ProfileDescription;
46import clarin.cmdi.componentregistry.model.RegisterResponse;
47
48import com.sun.jersey.multipart.FormDataParam;
49import com.sun.jersey.spi.inject.Inject;
50
51@Path("/registry")
52public class ComponentRegistryRestService {
53
54    @Context
55    private UriInfo uriInfo;
56    @Context
57    private SecurityContext security;
58    @Context
59    private HttpServletRequest request;
60    private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryRestService.class);
61    public static final String DATA_FORM_FIELD = "data";
62    public static final String NAME_FORM_FIELD = "name";
63    public static final String DESCRIPTION_FORM_FIELD = "description";
64    public static final String GROUP_FORM_FIELD = "group";
65    public static final String DOMAIN_FORM_FIELD = "domainName";
66    public static final String USERSPACE_PARAM = "userspace";
67    public static final String METADATA_EDITOR_PARAM = "mdEditor";
68    @Inject(value = "componentRegistryFactory")
69    private ComponentRegistryFactory componentRegistryFactory;
70
71    private ComponentRegistry getRegistry(boolean userspace) {
72        Principal userPrincipal = security.getUserPrincipal();
73        UserCredentials userCredentials = getUserCredentials(userPrincipal);
74        return getRegistry(userspace, userCredentials);
75    }
76
77    private ComponentRegistry getRegistry(boolean userspace, UserCredentials userCredentials) {
78        return componentRegistryFactory.getComponentRegistry(userspace, userCredentials);
79    }
80
81    private Principal checkAndGetUserPrincipal() {
82        Principal principal = security.getUserPrincipal();
83        if (principal == null) {
84            throw new IllegalArgumentException("no user principal found.");
85        }
86        return principal;
87    }
88
89    private UserCredentials getUserCredentials(Principal userPrincipal) {
90        UserCredentials userCredentials = null;
91        if (userPrincipal != null) {
92            userCredentials = new UserCredentials(userPrincipal);
93        }
94        return userCredentials;
95    }
96
97    @GET
98    @Path("/components")
99    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
100    public List<ComponentDescription> getRegisteredComponents(@QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
101        long start = System.currentTimeMillis();
102        List<ComponentDescription> components = getRegistry(userspace).getComponentDescriptions();
103        LOG.info("Releasing " + components.size() + " registered components into the world (" + (System.currentTimeMillis() - start)
104                + " millisecs)");
105        return components;
106    }
107
108    @GET
109    @Path("/profiles")
110    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
111    public List<ProfileDescription> getRegisteredProfiles(@QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace,
112            @QueryParam(METADATA_EDITOR_PARAM) @DefaultValue("false") boolean metadataEditor) throws ComponentRegistryException {
113        long start = System.currentTimeMillis();
114
115        List<ProfileDescription> profiles;
116        if (metadataEditor) {
117            profiles = getRegistry(userspace).getProfileDescriptionsForMetadaEditor();
118        } else {
119            profiles = getRegistry(userspace).getProfileDescriptions();
120        }
121
122        LOG.info("Releasing " + profiles.size() + " registered profiles into the world (" + (System.currentTimeMillis() - start)
123                + " millisecs)");
124        return profiles;
125    }
126
127    @GET
128    @Path("/components/{componentId}")
129    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
130    public CMDComponentSpec getRegisteredComponent(@PathParam("componentId") String componentId,
131            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
132        LOG.info("Component with id: " + componentId + " is requested.");
133        return getRegistry(userspace).getMDComponent(componentId);
134    }
135
136    @GET
137    @Path("/components/{componentId}/{rawType}")
138    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
139    public Response getRegisteredComponentRawType(@PathParam("componentId") final String componentId, @PathParam("rawType") String rawType) {
140        LOG.info("Component with id: " + componentId + " and rawType:" + rawType + " is requested.");
141        StreamingOutput result = null;
142        try {
143            final ComponentRegistry registry = findRegistry(componentId, new ComponentClosure());
144            if (registry == null) {
145                return Response.status(Status.NOT_FOUND).entity("Id: " + componentId + " is not registered, cannot create data.").build();
146            }
147            ComponentDescription desc = registry.getComponentDescription(componentId);
148            checkAndThrowDescription(desc, componentId);
149            String fileName = desc.getName() + "." + rawType;
150            if ("xml".equalsIgnoreCase(rawType)) {
151                result = new StreamingOutput() {
152
153                    @Override
154                    public void write(OutputStream output) throws IOException, WebApplicationException {
155                        try {
156                            registry.getMDComponentAsXml(componentId, output);
157                        } catch (ComponentRegistryException e) {
158                            LOG.info("Could not retrieve component", e);
159                            throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
160                        }
161                    }
162                };
163            } else if ("xsd".equalsIgnoreCase(rawType)) {
164                result = new StreamingOutput() {
165
166                    @Override
167                    public void write(OutputStream output) throws IOException, WebApplicationException {
168                        try {
169                            registry.getMDComponentAsXsd(componentId, output);
170                        } catch (ComponentRegistryException e) {
171                            LOG.info("Could not retrieve component", e);
172                            throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
173                        }
174
175                    }
176                };
177            } else {
178                throw new WebApplicationException(Response.serverError().entity(
179                        "unsupported rawType: " + rawType + " (only xml or xsd are supported)").build());
180            }
181            return createDownloadResponse(result, fileName);
182        } catch (ComponentRegistryException e) {
183            LOG.info("Could not retrieve component", e);
184            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
185        }
186    }
187
188    public ComponentRegistry findRegistry(String id, RegistryClosure<? extends AbstractDescription> clos) throws ComponentRegistryException {
189        AbstractDescription desc = null;
190        ComponentRegistry result = getRegistry(false);
191        desc = clos.getDescription(result, id);
192        if (desc == null) {
193            List<ComponentRegistry> userRegs = componentRegistryFactory.getAllUserRegistries();
194            for (ComponentRegistry reg : userRegs) {
195                desc = clos.getDescription(reg, id);
196                if (desc != null) {
197                    result = reg;
198                    break;
199                }
200            }
201        }
202        return result;
203    }
204
205    @GET
206    @Path("/profiles/{profileId}")
207    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
208    public CMDComponentSpec getRegisteredProfile(@PathParam("profileId") String profileId,
209            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
210        LOG.info("Profile with id: " + profileId + " is requested.");
211        return getRegistry(userspace).getMDProfile(profileId);
212    }
213
214    @GET
215    @Path("/components/usage/{componentId}")
216    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
217    public List<AbstractDescription> getComponentUsage(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("true") boolean userspace) throws ComponentRegistryException {
218        try {
219            final long start = System.currentTimeMillis();
220            ComponentRegistry registry = getRegistry(userspace);
221            List<ComponentDescription> components = registry.getUsageInComponents(componentId);
222            List<ProfileDescription> profiles = registry.getUsageInProfiles(componentId);
223
224            LOG.info("Found " + components.size() + " components and " + profiles.size() + " profiles that use component " + componentId
225                    + " (" + (System.currentTimeMillis() - start) + " millisecs)");
226
227            List<AbstractDescription> usages = new ArrayList<AbstractDescription>(components.size() + profiles.size());
228            usages.addAll(components);
229            usages.addAll(profiles);
230
231            return usages;
232        } catch (ComponentRegistryException e) {
233            LOG.info("Could not retrieve profile usage", e);
234            throw e;
235        }
236    }
237
238    @GET
239    @Path("/profiles/{profileId}/comments")
240    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
241    public List<Comment> getCommentsFromProfile(@PathParam("profileId") String profileId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
242        long start = System.currentTimeMillis();
243        List<Comment> comments = getRegistry(userspace).getCommentsInProfile(profileId);
244        LOG.info("Releasing " + comments.size() + " registered comments in Profile into the world (" + (System.currentTimeMillis() - start)
245                + " millisecs)");
246        return comments;
247    }
248
249    @GET
250    @Path("/components/{componentId}/comments")
251    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
252    public List<Comment> getCommentsFromComponent(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
253        long start = System.currentTimeMillis();
254        List<Comment> comments = getRegistry(userspace).getCommentsInComponent(componentId);
255        LOG.info("Releasing " + comments.size() + " registered comments in Component into the world (" + (System.currentTimeMillis() - start)
256                + " millisecs)");
257        return comments;
258    }
259
260    @GET
261    @Path("/profiles/{profileId}/comments/{commentId}")
262    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
263    public Comment getSpecifiedCommentFromProfile(@PathParam("commentId") String commentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
264        long start = System.currentTimeMillis();
265        LOG.info(" Comments of component with id" + commentId + " are requested.");
266        return getRegistry(userspace).getSpecifiedCommentInProfile(commentId);
267    }
268
269    @GET
270    @Path("/components/{componentId}/comments/{commentId}")
271    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
272    public Comment getSpecifiedCommentFromComponent(@PathParam("commentId") String commentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
273        LOG.info(" Comments of component with id" + commentId + " are requested.");
274        return getRegistry(userspace).getSpecifiedCommentInComponent(commentId);
275    }
276
277    /**
278     *
279     * Purely helper method for my front-end (FLEX) which only does post/get requests. The query param is checked and the "proper" method is
280     * called.
281     * @param profileId
282     * @param method
283     * @return
284     */
285    @POST
286    @Path("/profiles/{profileId}")
287    public Response manipulateRegisteredProfile(@PathParam("profileId") String profileId, @FormParam("method") String method,
288            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
289        if ("delete".equalsIgnoreCase(method)) {
290            return deleteRegisteredProfile(profileId, userspace);
291        } else {
292            return Response.ok().build();
293        }
294    }
295
296    @POST
297    @Path("/profiles/{profileId}/comments/{commentId}")
298    public Response manipulateCommentFromProfile(@PathParam("profileId") String commentId, @FormParam("method") String method,
299            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
300        if ("delete".equalsIgnoreCase(method)) {
301            return deleteCommentFromProfile(commentId, userspace);
302        } else {
303            return Response.ok().build();
304        }
305    }
306
307    @POST
308    @Path("/components/{componentId}/comments/{commentId}")
309    public Response manipulateCommentFromComponent(@PathParam("profileId") String commentId, @FormParam("method") String method,
310            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
311        if ("delete".equalsIgnoreCase(method)) {
312            return deleteCommentFromComponent(commentId, userspace);
313        } else {
314            return Response.ok().build();
315        }
316    }
317
318    @POST
319    @Path("/profiles/{profileId}/publish")
320    @Consumes("multipart/form-data")
321    public Response publishRegisteredProfile(@PathParam("profileId") String profileId, @FormDataParam(DATA_FORM_FIELD) InputStream input,
322            @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
323            @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
324        Principal principal = checkAndGetUserPrincipal();
325        try {
326            ProfileDescription desc = getRegistry(true).getProfileDescription(profileId);
327            if (desc != null) {
328                updateDescription(desc, name, description, domainName, group);
329                return register(input, desc, getUserCredentials(principal), true, new PublishAction(principal));
330            } else {
331                LOG.error("Update of nonexistent id (" + profileId + ") failed.");
332                return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
333            }
334        } catch (ComponentRegistryException e) {
335            LOG.info("Could not retrieve component", e);
336            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
337        }
338    }
339
340    @POST
341    @Path("/profiles/{profileId}/update")
342    @Consumes("multipart/form-data")
343    public Response updateRegisteredProfile(@PathParam("profileId") String profileId,
344            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, @FormDataParam(DATA_FORM_FIELD) InputStream input,
345            @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
346            @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
347        Principal principal = checkAndGetUserPrincipal();
348        UserCredentials userCredentials = getUserCredentials(principal);
349        try {
350            ProfileDescription desc = getRegistry(userspace).getProfileDescription(profileId);
351            if (desc != null) {
352                updateDescription(desc, name, description, domainName, group);
353                return register(input, desc, userCredentials, userspace, new UpdateAction(principal));
354            } else {
355                LOG.error("Update of nonexistent id (" + profileId + ") failed.");
356                return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
357            }
358        } catch (ComponentRegistryException e) {
359            LOG.info("Could not retrieve component", e);
360            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
361        }
362    }
363
364    /**
365     *
366     * Purely helper method for my front-end (FLEX) which van only do post/get requests. The query param is checked and the "proper" method
367     * is called.
368     * @param componentId
369     * @param method
370     * @return
371     */
372    @POST
373    @Path("/components/{componentId}")
374    public Response manipulateRegisteredComponent(@PathParam("componentId") String componentId, @FormParam("method") String method,
375            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
376        if ("delete".equalsIgnoreCase(method)) {
377            return deleteRegisteredComponent(componentId, userspace);
378        } else {
379            return Response.ok().build();
380        }
381    }
382
383    @POST
384    @Path("/components/{componentId}/publish")
385    @Consumes("multipart/form-data")
386    public Response publishRegisteredComponent(@PathParam("componentId") String componentId,
387            @FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
388            @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group,
389            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
390        Principal principal = checkAndGetUserPrincipal();
391        try {
392            ComponentDescription desc = getRegistry(true).getComponentDescription(componentId);
393            if (desc != null) {
394                updateDescription(desc, name, description, domainName, group);
395                return register(input, desc, getUserCredentials(principal), true, new PublishAction(principal));
396            } else {
397                LOG.error("Update of nonexistent id (" + componentId + ") failed.");
398                return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
399            }
400        } catch (ComponentRegistryException e) {
401            LOG.info("Could not retrieve component", e);
402            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
403        }
404    }
405
406    @POST
407    @Path("/components/{componentId}/update")
408    @Consumes("multipart/form-data")
409    public Response updateRegisteredComponent(@PathParam("componentId") String componentId,
410            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, @FormDataParam(DATA_FORM_FIELD) InputStream input,
411            @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
412            @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
413        Principal principal = checkAndGetUserPrincipal();
414        try {
415            ComponentDescription desc = getRegistry(userspace).getComponentDescription(componentId);
416            if (desc != null) {
417                updateDescription(desc, name, description, domainName, group);
418                return register(input, desc, getUserCredentials(principal), userspace, new UpdateAction(principal));
419            } else {
420                LOG.error("Update of nonexistent id (" + componentId + ") failed.");
421                return Response.serverError().entity("Invalid id, cannot update nonexistent component").build();
422            }
423        } catch (ComponentRegistryException e) {
424            LOG.info("Could not retrieve component", e);
425            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
426        }
427    }
428
429    private void updateDescription(AbstractDescription desc, String name, String description, String domainName, String group) {
430        desc.setName(name);
431        desc.setDescription(description);
432        desc.setDomainName(domainName);
433        desc.setGroupName(group);
434        desc.setRegistrationDate(AbstractDescription.createNewDate());
435    }
436
437    @DELETE
438    @Path("/components/{componentId}")
439    public Response deleteRegisteredComponent(@PathParam("componentId") String componentId,
440            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
441        Principal principal = checkAndGetUserPrincipal();
442        ComponentRegistry registry = getRegistry(userspace);
443        LOG.info("Component with id: " + componentId + " set for deletion.");
444        try {
445            registry.deleteMDComponent(componentId, principal, false);
446        } catch (DeleteFailedException e) {
447            LOG.info("Component with id: " + componentId + " deletion failed.", e);
448            return Response.status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
449        } catch (ComponentRegistryException e) {
450            LOG.info("Component with id: " + componentId + " deletion failed.", e);
451            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
452        } catch (IOException e) {
453            LOG.info("Component with id: " + componentId + " deletion failed.", e);
454            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
455        } catch (UserUnauthorizedException e) {
456            LOG.info("Component with id: " + componentId + " deletion failed: " + e.getMessage());
457            return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
458        }
459        LOG.info("Component with id: " + componentId + " deleted.");
460        return Response.ok().build();
461    }
462
463    @DELETE
464    @Path("/profiles/{profileId}")
465    public Response deleteRegisteredProfile(@PathParam("profileId") String profileId,
466            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
467        Principal principal = checkAndGetUserPrincipal();
468        LOG.info("Profile with id: " + profileId + " set for deletion.");
469        try {
470            getRegistry(userspace).deleteMDProfile(profileId, principal);
471        } catch (DeleteFailedException e) {
472            LOG.info("Profile with id: " + profileId + " deletion failed: " + e.getMessage());
473            return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
474        } catch (ComponentRegistryException e) {
475            LOG.info("Could not retrieve component", e);
476            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
477        } catch (IOException e) {
478            LOG.info("Profile with id: " + profileId + " deletion failed.", e);
479            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
480        } catch (UserUnauthorizedException e) {
481            LOG.info("Profile with id: " + profileId + " deletion failed: " + e.getMessage());
482            return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
483        }
484        LOG.info("Profile with id: " + profileId + " deleted.");
485        return Response.ok().build();
486    }
487
488    @DELETE
489    @Path("/profiles/{profileId}/comments/{commentId}")
490    public Response deleteCommentFromProfile(@PathParam("commentId") String commentId,
491            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
492        Principal principal = checkAndGetUserPrincipal();
493        LOG.info("Comment with id: " + commentId + " set for deletion.");
494        try {
495            getRegistry(userspace).deleteComment(commentId, principal);
496        } catch (DeleteFailedException e) {
497            LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
498            return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
499        } catch (ComponentRegistryException e) {
500            LOG.info("Could not retrieve component", e);
501            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
502        } catch (IOException e) {
503            LOG.info("Comment with id: " + commentId + " deletion failed.", e);
504            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
505        } catch (UserUnauthorizedException e) {
506            LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
507            return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
508        }
509        LOG.info("Comment with id: " + commentId + " deleted.");
510        return Response.ok().build();
511    }
512
513    @DELETE
514    @Path("/components/{componentId}/comments/{commentId}")
515    public Response deleteCommentFromComponent(@PathParam("commentId") String commentId,
516            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
517        Principal principal = checkAndGetUserPrincipal();
518        LOG.info("Comment with id: " + commentId + " set for deletion.");
519        try {
520            getRegistry(userspace).deleteComment(commentId, principal);
521        } catch (DeleteFailedException e) {
522            LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
523            return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
524        } catch (ComponentRegistryException e) {
525            LOG.info("Could not retrieve component", e);
526            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
527        } catch (IOException e) {
528            LOG.info("Comment with id: " + commentId + " deletion failed.", e);
529            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
530        } catch (UserUnauthorizedException e) {
531            LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
532            return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
533        }
534        LOG.info("Comment with id: " + commentId + " deleted.");
535        return Response.ok().build();
536    }
537
538    @GET
539    @Path("/profiles/{profileId}/{rawType}")
540    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
541    public Response getRegisteredProfileRawType(@PathParam("profileId") final String profileId, @PathParam("rawType") String rawType) {
542        LOG.info("Profile with id: " + profileId + " and rawType:" + rawType + " is requested.");
543        StreamingOutput result = null;
544        try {
545            final ComponentRegistry registry = findRegistry(profileId, new ProfileClosure());
546            if (registry == null) {
547                return Response.status(Status.NOT_FOUND).entity("Id: " + profileId + " is not registered, cannot create data.").build();
548            }
549            ProfileDescription desc = registry.getProfileDescription(profileId);
550            checkAndThrowDescription(desc, profileId);
551            String fileName = desc.getName() + "." + rawType;
552
553            if ("xml".equalsIgnoreCase(rawType)) {
554                result = new StreamingOutput() {
555
556                    @Override
557                    public void write(OutputStream output) throws IOException, WebApplicationException {
558                        try {
559                            registry.getMDProfileAsXml(profileId, output);
560                        } catch (ComponentRegistryException e) {
561                            LOG.warn("Could not retrieve component", e);
562                            throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
563                        }
564                    }
565                };
566            } else if ("xsd".equalsIgnoreCase(rawType)) {
567                result = new StreamingOutput() {
568
569                    @Override
570                    public void write(OutputStream output) throws IOException, WebApplicationException {
571                        try {
572                            registry.getMDProfileAsXsd(profileId, output);
573                        } catch (ComponentRegistryException e) {
574                            LOG.warn("Could not retrieve component", e);
575                            throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
576                        }
577                    }
578                };
579            } else {
580                throw new WebApplicationException(Response.serverError().entity(
581                        "unsupported rawType: " + rawType + " (only xml or xsd are supported)").build());
582            }
583            return createDownloadResponse(result, fileName);
584        } catch (ComponentRegistryException e) {
585            LOG.info("Could not retrieve component", e);
586            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
587        }
588    }
589
590    private void checkAndThrowDescription(AbstractDescription desc, String id) {
591        if (desc == null) {
592            throw new WebApplicationException(Response.serverError().entity("Incorrect id:" + id + "cannot handle request").build());
593        }
594    }
595
596    private Response createDownloadResponse(StreamingOutput result, String fileName) {
597        //Making response so it triggers browsers native save as dialog.
598        Response response = Response.ok().type("application/x-download").header("Content-Disposition",
599                "attachment; filename=\"" + fileName + "\"").entity(result).build();
600        return response;
601
602    }
603
604    @POST
605    @Path("/profiles")
606    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
607    @Consumes("multipart/form-data")
608    public Response registerProfile(@FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
609            @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName,
610            @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
611        Principal principal = checkAndGetUserPrincipal();
612        UserCredentials userCredentials = getUserCredentials(principal);
613        ProfileDescription desc = createNewProfileDescription();
614        desc.setCreatorName(userCredentials.getDisplayName());
615        desc.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
616        desc.setName(name);
617        desc.setDescription(description);
618        desc.setGroupName(group);
619        desc.setDomainName(domainName);
620        LOG.info("Trying to register Profile: " + desc);
621        return register(input, desc, userCredentials, userspace, new NewAction());
622    }
623
624    @POST
625    @Path("/components")
626    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
627    @Consumes("multipart/form-data")
628    public Response registerComponent(@FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
629            @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group,
630            @FormDataParam(DOMAIN_FORM_FIELD) String domainName, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
631        Principal principal = checkAndGetUserPrincipal();
632        UserCredentials userCredentials = getUserCredentials(principal);
633        ComponentDescription desc = createNewComponentDescription();
634        desc.setCreatorName(userCredentials.getDisplayName());
635        desc.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
636        desc.setName(name);
637        desc.setDescription(description);
638        desc.setGroupName(group);
639        desc.setDomainName(domainName);
640        LOG.info("Trying to register Component: " + desc);
641        return register(input, desc, userCredentials, userspace, new NewAction());
642    }
643
644    @POST
645    @Path("/components/{componentId}/comments")
646    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
647    @Consumes("multipart/form-data")
648    public Response registerCommentInComponent(@FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String comment,
649            @PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
650        Principal principal = checkAndGetUserPrincipal();
651        UserCredentials userCredentials = getUserCredentials(principal);
652        ComponentRegistry registry = getRegistry(userspace, userCredentials);
653        AbstractDescription description = registry.getComponentDescription(componentId);
654        Comment com = createNewComment();
655        com.setComponentDescriptionId("componentId");
656        //com.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
657        //com.setComment(comment);
658        LOG.info("Trying to register Comment: " + com);
659        return registerComment(input, registry, userspace, description, principal, new NewAction());
660    }
661
662    @POST
663    @Path("/profiles/{profileId}/comments")
664    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
665    @Consumes("multipart/form-data")
666    public Response registerCommentInProfile(@FormDataParam(DATA_FORM_FIELD) InputStream input,
667            @PathParam("profileId") String profileId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
668        Principal principal = checkAndGetUserPrincipal();
669        UserCredentials userCredentials = getUserCredentials(principal);
670        ComponentRegistry registry = getRegistry(userspace, userCredentials);
671        AbstractDescription description = registry.getProfileDescription(profileId);
672        //Comment com = createNewComment();
673        //com.setProfileDescriptionId("profileId");
674        //com.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
675        //com.setComment(comment);
676        LOG.info("Trying to register Comment: ");
677        return registerComment(input, registry, userspace, description, principal, new NewAction());
678    }
679
680    @GET
681    @Path("/pingSession")
682    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
683    public Response pingSession() {
684        boolean stillActive = false;
685        Principal userPrincipal = security.getUserPrincipal();
686        LOG.info("ping by user: " + (userPrincipal == null ? "null" : userPrincipal.getName()));
687        if (request != null) {
688            if (userPrincipal != null && !ComponentRegistryFactory.ANONYMOUS_USER.equals(userPrincipal.getName())) {
689                stillActive = !((HttpServletRequest) request).getSession().isNew();
690            }
691        }
692        return Response.ok().entity("<session stillActive=\"" + stillActive + "\"/>").build();
693    }
694
695    private Response register(InputStream input, AbstractDescription desc, UserCredentials userCredentials, boolean userspace,
696            RegisterAction action) {
697        try {
698            ComponentRegistry registry = getRegistry(userspace, userCredentials);
699            DescriptionValidator descriptionValidator = new DescriptionValidator(desc);
700            MDValidator validator = new MDValidator(input, desc, registry, getRegistry(true), componentRegistryFactory.getPublicRegistry());
701            RegisterResponse response = new RegisterResponse();
702            response.setIsInUserSpace(userspace);
703            validate(response, descriptionValidator, validator);
704            if (response.getErrors().isEmpty()) {
705                CMDComponentSpec spec = validator.getCMDComponentSpec();
706                int returnCode = action.execute(desc, spec, response, registry);
707                if (returnCode == 0) {
708                    response.setRegistered(true);
709                    response.setDescription(desc);
710                } else {
711                    response.setRegistered(false);
712                    response.addError("Unable to register at this moment. Internal server error.");
713                }
714            } else {
715                LOG.info("Registration failed with validation errors:" + Arrays.toString(response.getErrors().toArray()));
716                response.setRegistered(false);
717            }
718            response.setIsProfile(desc.isProfile());
719            return Response.ok(response).build();
720        } finally {
721            try {
722                input.close();//either we read the input or there was an exception, we need to close it.
723            } catch (IOException e) {
724                LOG.error("Error when closing inputstream: ", e);
725            }
726        }
727    }
728
729    private Response registerComment(InputStream input, ComponentRegistry registry, boolean userspace,
730            AbstractDescription description, Principal principal,
731            RegisterAction action) {
732        try {
733            CommentValidator validator = new CommentValidator(input, registry, getRegistry(true), description);
734            RegisterResponse response = new RegisterResponse();
735            response.setIsInUserSpace(userspace);
736            validate(response, validator);
737            if (response.getErrors().isEmpty()) {
738                Comment com = validator.getCommentSpec();
739               int returnCode = action.executeComment(com, response, registry, principal.getName());
740              // registry.registerComment(com, principal.getName());
741                if (returnCode == 0) {
742                    response.setRegistered(true);
743                    response.setComment(com);
744                } else {
745                    response.setRegistered(false);
746                    response.addError("Unable to register at this moment. Internal server error.");
747                }
748            } else {
749                LOG.info("Registration failed with validation errors:" + Arrays.toString(response.getErrors().toArray()));
750                response.setRegistered(false);
751            }
752            return Response.ok(response).build();
753        } finally {
754            try {
755                input.close();//either we read the input or there was an exception, we need to close it.
756            } catch (IOException e) {
757                LOG.error("Error when closing inputstream: ", e);
758            }
759        }
760    }
761
762    private ComponentDescription createNewComponentDescription() {
763        ComponentDescription desc = ComponentDescription.createNewDescription();
764        desc.setHref(createXlink(desc.getId()));
765        return desc;
766    }
767
768    private ProfileDescription createNewProfileDescription() {
769        ProfileDescription desc = ProfileDescription.createNewDescription();
770        desc.setHref(createXlink(desc.getId()));
771        return desc;
772    }
773
774    private Comment createNewComment() {
775        Comment com = Comment.createANewComment();
776        return com;
777    }
778
779    private String createXlink(String id) {
780        URI uri = uriInfo.getRequestUriBuilder().path(id).build();
781        return uri.toString();
782    }
783
784    private void validate(RegisterResponse response, Validator... validators) {
785        for (Validator validator : validators) {
786            if (!validator.validate()) {
787                for (String error : validator.getErrorMessages()) {
788                    response.addError(error);
789                }
790            }
791        }
792    }
793
794    /**
795     * @param componentRegistryFactory the componentRegistryFactory to set
796     */
797    public void setComponentRegistryFactory(ComponentRegistryFactory componentRegistryFactory) {
798        this.componentRegistryFactory = componentRegistryFactory;
799    }
800}
Note: See TracBrowser for help on using the repository browser.