source: ComponentRegistry/trunk/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java @ 5556

Last change on this file since 5556 was 5556, checked in by olhsha@mpi.nl, 10 years ago

Unit test for getting profiles and components from groups. A little bug is fixed

File size: 84.8 KB
Line 
1package clarin.cmdi.componentregistry.rest;
2
3import clarin.cmdi.componentregistry.AllowedAttributetypesXML;
4import clarin.cmdi.componentregistry.AuthenticationFailException;
5import clarin.cmdi.componentregistry.ComponentRegistry;
6import clarin.cmdi.componentregistry.ComponentRegistryException;
7import clarin.cmdi.componentregistry.ComponentRegistryFactory;
8import clarin.cmdi.componentregistry.DeleteFailedException;
9import clarin.cmdi.componentregistry.ItemNotFoundException;
10import clarin.cmdi.componentregistry.MDMarshaller;
11import clarin.cmdi.componentregistry.RegistrySpace;
12import clarin.cmdi.componentregistry.UserCredentials;
13import clarin.cmdi.componentregistry.UserUnauthorizedException;
14import clarin.cmdi.componentregistry.components.CMDComponentSpec;
15import clarin.cmdi.componentregistry.components.CMDComponentType;
16import clarin.cmdi.componentregistry.impl.ComponentUtils;
17import clarin.cmdi.componentregistry.impl.database.GroupService;
18import clarin.cmdi.componentregistry.impl.database.ValidationException;
19import clarin.cmdi.componentregistry.model.BaseDescription;
20import clarin.cmdi.componentregistry.model.Comment;
21import clarin.cmdi.componentregistry.model.CommentResponse;
22import clarin.cmdi.componentregistry.model.ComponentDescription;
23import clarin.cmdi.componentregistry.model.Group;
24import clarin.cmdi.componentregistry.model.ProfileDescription;
25import clarin.cmdi.componentregistry.model.RegisterResponse;
26import clarin.cmdi.componentregistry.rss.Rss;
27import clarin.cmdi.componentregistry.rss.RssCreatorComments;
28import clarin.cmdi.componentregistry.rss.RssCreatorDescriptions;
29import com.google.common.collect.Lists;
30
31import com.sun.jersey.api.core.InjectParam;
32import com.sun.jersey.multipart.FormDataParam;
33
34import java.io.IOException;
35import java.io.InputStream;
36import java.io.OutputStream;
37import java.net.URI;
38import java.security.Principal;
39import java.text.ParseException;
40import java.util.ArrayList;
41import java.util.Arrays;
42import java.util.Collections;
43import java.util.Date;
44import java.util.List;
45
46import javax.servlet.ServletContext;
47import javax.servlet.http.HttpServletRequest;
48import javax.servlet.http.HttpServletResponse;
49import javax.ws.rs.Consumes;
50import javax.ws.rs.DELETE;
51import javax.ws.rs.DefaultValue;
52import javax.ws.rs.FormParam;
53import javax.ws.rs.GET;
54import javax.ws.rs.POST;
55import javax.ws.rs.Path;
56import javax.ws.rs.PathParam;
57import javax.ws.rs.Produces;
58import javax.ws.rs.QueryParam;
59import javax.ws.rs.WebApplicationException;
60import javax.ws.rs.core.Context;
61import javax.ws.rs.core.GenericEntity;
62import javax.ws.rs.core.MediaType;
63import javax.ws.rs.core.Response;
64import javax.ws.rs.core.Response.Status;
65import javax.ws.rs.core.SecurityContext;
66import javax.ws.rs.core.StreamingOutput;
67import javax.ws.rs.core.UriInfo;
68import javax.xml.bind.JAXBException;
69import javax.xml.bind.annotation.XmlElement;
70import javax.xml.bind.annotation.XmlRootElement;
71
72import org.slf4j.Logger;
73import org.slf4j.LoggerFactory;
74import org.springframework.beans.factory.annotation.Autowired;
75import org.springframework.stereotype.Service;
76import org.springframework.transaction.annotation.Transactional;
77
78/**
79 * Handles CRUD operations on
80 * {@link ComponentDescription}, {@link ProfileDescription} and {@link Comment}s
81 *
82 * @author twago@mpi.nl
83 * @author olsha@mpi.nl
84 * @author george.georgovassilis@mpi.nl
85 *
86 */
87@Path("/registry")
88@Service
89@Transactional(rollbackFor = {Exception.class, ValidationException.class})
90public class ComponentRegistryRestService implements
91        IComponentRegistryRestService {
92
93    private final static Logger LOG = LoggerFactory
94            .getLogger(IComponentRegistryRestService.class);
95    @Context
96    private UriInfo uriInfo;
97    @Context
98    private SecurityContext security;
99    @Context
100    private HttpServletRequest request;
101    @Context
102    private HttpServletResponse response;
103    @Context
104    private ServletContext servletContext;
105    @InjectParam(value = "componentRegistryFactory")
106    private ComponentRegistryFactory componentRegistryFactory;
107    @InjectParam(value = "mdMarshaller")
108    private MDMarshaller marshaller;
109    @Autowired
110    private GroupService groupService;
111
112    private ComponentRegistry getBaseRegistry() throws AuthenticationFailException {
113        Principal userPrincipal = this.checkAndGetUserPrincipal();
114        UserCredentials userCredentials = this.getUserCredentials(userPrincipal);
115        return componentRegistryFactory.getBaseRegistry(userCredentials);
116    }
117
118    private ComponentRegistry getRegistry(RegistrySpace space, Number groupId) {
119        Principal userPrincipal = security.getUserPrincipal();
120        UserCredentials userCredentials = this.getUserCredentials(userPrincipal);
121        try {
122            return componentRegistryFactory.getComponentRegistry(space, null, userCredentials, groupId);
123        } catch (UserUnauthorizedException uuEx) {
124            LOG.warn("Unauthorized access to {} registry by user {}", space,
125                    userCredentials);
126            LOG.debug("Details for unauthorized access", uuEx);
127            throw new WebApplicationException(uuEx, Status.FORBIDDEN);
128        }
129    }
130
131    /**
132     *
133     * @return Principal of current request
134     * @throws IllegalArgumentException If no user principal found
135     */
136    private Principal checkAndGetUserPrincipal()
137            throws AuthenticationFailException {
138        Principal principal = security.getUserPrincipal();
139        if (principal == null) {
140            throw new AuthenticationFailException("No user principal found.");
141        }
142        return principal;
143    }
144
145    private UserCredentials getUserCredentials(Principal userPrincipal) {
146        UserCredentials userCredentials = null;
147        if (userPrincipal != null) {
148            userCredentials = new UserCredentials(userPrincipal);
149        }
150        return userCredentials;
151    }
152
153    private ComponentRegistry initialiseRegistry(String space, String groupId) throws AuthenticationFailException {
154        //checking credentials
155        RegistrySpace regSpace = RegistrySpace.valueOf(space.toUpperCase());
156        UserCredentials user = this.getUserCredentials(this.checkAndGetUserPrincipal());
157        // initializing the registry
158        Number groupIdNumber = null;
159        if (groupId != null && !groupId.isEmpty()) {
160            groupIdNumber = Integer.parseInt(groupId);
161        }
162
163        return this.getRegistry(regSpace, groupIdNumber);
164    }
165
166    private boolean checkRegistrySpaceString(String registrySpace) {
167        return (registrySpace.equalsIgnoreCase("group") || registrySpace.equalsIgnoreCase("private") || registrySpace.equalsIgnoreCase("published"));
168    }
169
170    @Override
171    @GET
172    @Path("/components")
173    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
174        MediaType.APPLICATION_JSON})
175    public List<ComponentDescription> getRegisteredComponents(
176            @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace,
177            @QueryParam(GROUPID_PARAM) String groupId)
178            throws ComponentRegistryException, IOException {
179        long start = System.currentTimeMillis();
180
181        if (!checkRegistrySpaceString(registrySpace)) {
182            response.sendError(Status.NOT_FOUND.getStatusCode(), "illegal registry space");
183            return new ArrayList<ComponentDescription>();
184        }
185
186        try {
187            ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId);
188            List<ComponentDescription> result = cr.getComponentDescriptions();
189            LOG.debug(
190                    "Releasing {} registered components into the world ({} millisecs)",
191                    result.size(), (System.currentTimeMillis() - start));
192
193            return result;
194        } catch (AuthenticationFailException e) {
195            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
196            return new ArrayList<ComponentDescription>();
197
198        } catch (UserUnauthorizedException e) {
199            response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString());
200            return new ArrayList<ComponentDescription>();
201
202       
203       
204        } catch (ItemNotFoundException e) {
205            response.sendError(Status.NOT_FOUND.getStatusCode(), e.toString());
206            return new ArrayList<ComponentDescription>();
207        }
208
209    }
210
211    @Override
212    @GET
213    @Path("/profiles")
214    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
215        MediaType.APPLICATION_JSON})
216    public List<ProfileDescription> getRegisteredProfiles(
217            @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace,
218            @QueryParam(METADATA_EDITOR_PARAM) @DefaultValue("false") boolean metadataEditor,
219            @QueryParam(GROUPID_PARAM) String groupId)
220            throws ComponentRegistryException, IOException {
221
222        long start = System.currentTimeMillis();
223
224        if (!checkRegistrySpaceString(registrySpace)) {
225            response.sendError(Status.NOT_FOUND.getStatusCode(), "illegal registry space");
226            return new ArrayList<ProfileDescription>();
227        }
228        try {
229            ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId);
230            List<ProfileDescription> result = (metadataEditor) ? cr.getProfileDescriptionsForMetadaEditor() : cr.getProfileDescriptions();
231            LOG.debug(
232                    "Releasing {} registered components into the world ({} millisecs)",
233                    result.size(), (System.currentTimeMillis() - start));
234
235            return result;
236        } catch (AuthenticationFailException e) {
237            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
238            return new ArrayList<ProfileDescription>();
239
240        } catch (UserUnauthorizedException e) {
241            response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString());
242            return new ArrayList<ProfileDescription>();
243       
244       
245        } catch (ItemNotFoundException e) {
246            response.sendError(Status.NOT_FOUND.getStatusCode(), e.toString());
247            return new ArrayList<ProfileDescription>();
248        }
249    }
250
251    @Override
252    @GET
253    @Path("/components/{componentId}")
254    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
255        MediaType.APPLICATION_JSON})
256    public Response getRegisteredComponent(
257            @PathParam("componentId") String componentId) throws IOException {
258        LOG.debug("Component with id: {} is requested.", componentId);
259        try {
260            CMDComponentSpec mdComponent = this.getBaseRegistry().getMDComponentAccessControlled(componentId);
261            return Response.ok(mdComponent).build();
262        } catch (ItemNotFoundException e) {
263            return Response.status(Status.NOT_FOUND).build();
264        } catch (ComponentRegistryException e1) {
265            return Response.serverError().status(Status.CONFLICT).build();
266        } catch (AuthenticationFailException e) {
267            return Response.serverError().status(Status.UNAUTHORIZED).build();
268        } catch (UserUnauthorizedException e) {
269            return Response.serverError().status(Status.FORBIDDEN).build();
270        }
271    }
272
273    @Override
274    @GET
275    @Path("/profiles/{profileId}")
276    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
277        MediaType.APPLICATION_JSON})
278    public Response getRegisteredProfile(
279            @PathParam("profileId") String profileId) throws IOException {
280        LOG.debug("Profile with id {} is requested.", profileId);
281        try {
282            CMDComponentSpec mdProfile = this.getBaseRegistry().getMDProfileAccessControled(profileId);
283            return Response.ok(mdProfile).build();
284        } catch (ItemNotFoundException e) {
285            return Response.status(Status.NOT_FOUND).build();
286        } catch (ComponentRegistryException e1) {
287            return Response.serverError().status(Status.CONFLICT).build();
288        } catch (UserUnauthorizedException e) {
289            return Response.serverError().status(Status.FORBIDDEN).build();
290        } catch (AuthenticationFailException e) {
291            return Response.serverError().status(Status.UNAUTHORIZED).build();
292        }
293    }
294
295    @Override
296    @GET
297    @Path("/components/{componentId}/{rawType}")
298    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
299    public Response getRegisteredComponentRawType(
300            @PathParam("componentId") final String componentId, @PathParam("rawType") String rawType) throws ComponentRegistryException {
301
302        LOG.debug("Component with id: {} and rawType: {} is requested.", componentId, rawType);
303        try {
304            final ComponentRegistry registry = this.getBaseRegistry();
305            try {
306                ComponentDescription desc = registry.getComponentDescriptionAccessControlled(componentId);
307                StreamingOutput result = null;
308                String fileName = desc.getName() + "." + rawType;
309                if ("xml".equalsIgnoreCase(rawType)) {
310                    result = new StreamingOutput() {
311                        @Override
312                        public void write(OutputStream output) throws IOException,
313                                WebApplicationException {
314                            try {
315                                try {
316                                    try {
317                                        registry.getMDComponentAsXml(componentId, output);
318                                    } catch (ItemNotFoundException e1) {
319                                        LOG.warn("Could not retrieve component {}",
320                                                componentId);
321                                        LOG.debug("Details", e1);
322                                        throw new WebApplicationException(e1, Response
323                                                .serverError()
324                                                .status(Status.INTERNAL_SERVER_ERROR)
325                                                .build());
326                                    }
327                                } catch (ComponentRegistryException e) {
328                                    LOG.warn("Could not retrieve component {}",
329                                            componentId);
330                                    LOG.debug("Details", e);
331                                    throw new WebApplicationException(e, Response
332                                            .serverError()
333                                            .status(Status.INTERNAL_SERVER_ERROR)
334                                            .build());
335                                }
336
337                            } catch (UserUnauthorizedException e2) {
338                                LOG.error(e2.toString());
339                            }
340                        }
341                    };
342                    return createDownloadResponse(result, fileName);
343                } else if ("xsd".equalsIgnoreCase(rawType)) {
344                    result = new StreamingOutput() {
345                        @Override
346                        public void write(OutputStream output) throws IOException,
347                                WebApplicationException {
348                            try {
349                                try {
350                                    try {
351                                        registry.getMDComponentAsXsd(componentId, output);
352                                    } catch (ItemNotFoundException e1) {
353                                        LOG.warn("Could not retrieve component {}",
354                                                componentId);
355                                        LOG.debug("Details", e1);
356                                        throw new WebApplicationException(e1, Response
357                                                .serverError()
358                                                .status(Status.INTERNAL_SERVER_ERROR)
359                                                .build());
360                                    }
361                                } catch (ComponentRegistryException e) {
362                                    LOG.warn("Could not retrieve component {}",
363                                            componentId);
364                                    LOG.debug("Details", e);
365                                    throw new WebApplicationException(e, Response
366                                            .serverError()
367                                            .status(Status.INTERNAL_SERVER_ERROR)
368                                            .build());
369                                }
370                            } catch (UserUnauthorizedException e2) {
371                                LOG.error(e2.toString());
372                            }
373
374                        }
375                    };
376                    return createDownloadResponse(result, fileName);
377                } else {
378                    return Response.status(Status.NOT_FOUND).entity("Usupported raw type " + rawType).build();
379                }
380
381
382            } catch (UserUnauthorizedException e2) {
383                return Response.status(Status.FORBIDDEN).build();
384            }
385        } catch (ItemNotFoundException e3) {
386            return Response.status(Status.NOT_FOUND).build();
387        } catch (AuthenticationFailException e) {
388            return Response.serverError().status(Status.UNAUTHORIZED).build();
389        }
390    }
391
392    @Override
393    @GET
394    @Path("/components/usage/{componentId}")
395    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
396        MediaType.APPLICATION_JSON})
397    public List<BaseDescription> getComponentUsage(
398            @PathParam("componentId") String componentId) throws ComponentRegistryException, IOException {
399
400        final long start = System.currentTimeMillis();
401        try {
402            ComponentRegistry registry = this.getBaseRegistry();
403            List<ComponentDescription> components = registry.getUsageInComponents(componentId);
404            List<ProfileDescription> profiles = registry.getUsageInProfiles(componentId);
405
406            LOG.debug(
407                    "Found {} components and {} profiles that use component {} ({} millisecs)",
408                    components.size(), profiles.size(), componentId,
409                    (System.currentTimeMillis() - start));
410
411            List<BaseDescription> usages = new ArrayList<BaseDescription>(components.size() + profiles.size());
412            usages.addAll(components);
413            usages.addAll(profiles);
414
415            return usages;
416        } catch (ComponentRegistryException e) {
417            LOG.warn("Could not retrieve profile usage {}", componentId);
418            LOG.debug("Details", e);
419            return new ArrayList<BaseDescription>();
420        } catch (AuthenticationFailException e1) {
421            response.sendError(Status.UNAUTHORIZED.getStatusCode());
422            return new ArrayList<BaseDescription>();
423        }
424    }
425
426    @Override
427    @GET
428    @Path("/profiles/{profileId}/comments")
429    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
430        MediaType.APPLICATION_JSON})
431    public List<Comment> getCommentsFromProfile(
432            @PathParam("profileId") String profileId)
433            throws IOException {
434        long start = System.currentTimeMillis();
435        try {
436            List<Comment> comments = this.getBaseRegistry().getCommentsInProfile(profileId);
437            LOG.debug(
438                    "Releasing {} registered comments in profile into the world ({} millisecs)",
439                    comments.size(), (System.currentTimeMillis() - start));
440            return comments;
441        } catch (ComponentRegistryException e) {
442            response.sendError(Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage());
443            return new ArrayList<Comment>();
444        } catch (ItemNotFoundException e) {
445            response.sendError(Status.NOT_FOUND.getStatusCode(), e.getMessage());
446            return new ArrayList<Comment>();
447        } catch (UserUnauthorizedException e) {
448            response.sendError(Status.FORBIDDEN.getStatusCode(), e.getMessage());
449            return new ArrayList<Comment>();
450        } catch (AuthenticationFailException e1) {
451            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e1.getMessage());
452            return new ArrayList<Comment>();
453        }
454    }
455
456    @Override
457    @GET
458    @Path("/components/{componentId}/comments")
459    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
460        MediaType.APPLICATION_JSON})
461    public List<Comment> getCommentsFromComponent(
462            @PathParam("componentId") String componentId)
463            throws IOException {
464        long start = System.currentTimeMillis();
465        try {
466            List<Comment> comments = this.getBaseRegistry().getCommentsInComponent(componentId);
467            LOG.debug(
468                    "Releasing {} registered comments in Component into the world ({} millisecs)",
469                    comments.size(), (System.currentTimeMillis() - start));
470            return comments;
471        } catch (ComponentRegistryException e) {
472            response.sendError(Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage());
473            return new ArrayList<Comment>();
474        } catch (ItemNotFoundException e) {
475            response.sendError(Status.NOT_FOUND.getStatusCode(), e.getMessage());
476            return new ArrayList<Comment>();
477        } catch (UserUnauthorizedException e1) {
478            response.sendError(Status.FORBIDDEN.getStatusCode(), e1.getMessage());
479            return new ArrayList<Comment>();
480        } catch (AuthenticationFailException e1) {
481            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e1.getMessage());
482            return new ArrayList<Comment>();
483        }
484    }
485
486    @Override
487    @GET
488    @Path("/profiles/{profileId}/comments/{commentId}")
489    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
490        MediaType.APPLICATION_JSON})
491    public Comment getSpecifiedCommentFromProfile(
492            @PathParam("profileId") String profileId,
493            @PathParam("commentId") String commentId)
494            throws IOException {
495
496        LOG.debug("Comments of profile with id {} are requested.", commentId);
497        try {
498
499            return this.getBaseRegistry().getSpecifiedCommentInProfile(profileId, commentId);
500        } catch (ComponentRegistryException e) {
501            response.sendError(Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage());
502            return new Comment();
503        } catch (ItemNotFoundException e) {
504            response.sendError(Status.NOT_FOUND.getStatusCode(), e.getMessage());
505            return new Comment();
506        } catch (UserUnauthorizedException e1) {
507            response.sendError(Status.FORBIDDEN.getStatusCode(), e1.getMessage());
508            return new Comment();
509        } catch (AuthenticationFailException e1) {
510            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e1.getMessage());
511            return new Comment();
512        }
513    }
514
515    @Override
516    @GET
517    @Path("/components/{componentId}/comments/{commentId}")
518    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
519        MediaType.APPLICATION_JSON})
520    public Comment getSpecifiedCommentFromComponent(
521            @PathParam("componentId") String componentId,
522            @PathParam("commentId") String commentId)
523            throws IOException {
524        LOG.debug("Comments of component with id {} are requested.", commentId);
525        try {
526
527            return this.getBaseRegistry().getSpecifiedCommentInComponent(componentId, commentId);
528        } catch (ComponentRegistryException e) {
529            response.sendError(Status.INTERNAL_SERVER_ERROR.getStatusCode(), e.getMessage());
530            return new Comment();
531        } catch (ItemNotFoundException e) {
532            response.sendError(Status.NOT_FOUND.getStatusCode(), e.getMessage());
533            return new Comment();
534        } catch (UserUnauthorizedException e1) {
535            response.sendError(Status.FORBIDDEN.getStatusCode(), e1.getMessage());
536            return new Comment();
537        } catch (AuthenticationFailException e1) {
538            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e1.getMessage());
539            return new Comment();
540        }
541    }
542
543    /**
544     *
545     * Purely helper method for my front-end (FLEX) which only does post/get
546     * requests. The query param is checked and the "proper" method is called.
547     *
548     * @param profileId
549     * @param method
550     * @return
551     */
552    // TODO: test via POSTMAN
553    @Override
554    @POST
555    @Path("/profiles/{profileId}")
556    public Response manipulateRegisteredProfile(
557            @PathParam("profileId") String profileId,
558            @FormParam("method") String method) {
559        if ("delete".equalsIgnoreCase(method)) {
560            return this.deleteRegisteredProfile(profileId);
561        } else {
562            return Response.ok().build();
563        }
564    }
565
566    @Override
567    @POST
568    @Path("/profiles/{profileId}/comments/{commentId}")
569    public Response manipulateCommentFromProfile(
570            @PathParam("profileId") String profileId,
571            @PathParam("commentId") String commentId,
572            @FormParam("method") String method) {
573        if ("delete".equalsIgnoreCase(method)) {
574            return this.deleteCommentFromProfile(profileId, commentId);
575        } else {
576            return Response.ok().build();
577        }
578    }
579
580    @Override
581    @POST
582    @Path("/components/{componentId}/comments/{commentId}")
583    public Response manipulateCommentFromComponent(
584            @PathParam("componentId") String componentId,
585            @PathParam("commentId") String commentId,
586            @FormParam("method") String method) {
587        if ("delete".equalsIgnoreCase(method)) {
588            return this.deleteCommentFromComponent(componentId, commentId);
589        } else {
590            return Response.ok().build();
591        }
592    }
593
594    // TODO: test via POSTMAN
595    @Override
596    @POST
597    @Path("/profiles/{profileId}/publish")
598    @Consumes("multipart/form-data")
599    public Response publishRegisteredProfile(
600            @PathParam("profileId") String profileId,
601            @FormDataParam(DATA_FORM_FIELD) InputStream input,
602            @FormDataParam(NAME_FORM_FIELD) String name,
603            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
604            @FormDataParam(GROUP_FORM_FIELD) String group,
605            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
606
607        try {
608            Principal principal = checkAndGetUserPrincipal();
609            ComponentRegistry registry = this.getBaseRegistry();
610            ProfileDescription desc = registry.getProfileDescriptionAccessControlled(profileId);
611            if (desc != null) {
612                if (desc.isPublic()) {
613                    return Response.status(Status.CONFLICT).entity("Cannot publish already published profile.")
614                            .build();
615                }
616                desc.setPublic(true);
617                this.updateDescription(desc, name, description, domainName, group);
618                return this.register(input, desc, new PublishAction(principal), registry);
619            } else {
620                LOG.error("Update of nonexistent profile {} failed.", profileId);
621                return Response
622                        .serverError()
623                        .entity("Invalid id, cannot update nonexistent profile")
624                        .build();
625            }
626
627        } catch (AuthenticationFailException e) {
628            return Response.serverError().status(Status.UNAUTHORIZED)
629                    .build();
630        } catch (ItemNotFoundException e1) {
631            return Response.status(Status.NOT_FOUND).entity(e1.getMessage()).build();
632        } catch (ComponentRegistryException e) {
633            LOG.warn("Could not retrieve profile {}", profileId);
634            LOG.debug("Details", e);
635            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
636                    .build();
637        } catch (UserUnauthorizedException ex) {
638            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
639                    .build();
640        }
641    }
642
643    @Override
644    @POST
645    @Path("/profiles/{profileId}/update")
646    @Consumes("multipart/form-data")
647    public Response updateRegisteredProfile(
648            @PathParam("profileId") String profileId,
649            @FormDataParam(DATA_FORM_FIELD) InputStream input,
650            @FormDataParam(NAME_FORM_FIELD) String name,
651            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
652            @FormDataParam(GROUP_FORM_FIELD) String group,
653            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
654        try {
655            ComponentRegistry br = this.getBaseRegistry();
656            ProfileDescription desc = br.getProfileDescriptionAccessControlled(profileId);
657            if (desc != null) {
658                if (desc.isPublic()) {
659                    return Response.status(Status.CONFLICT).entity("Cannot update already published profile.")
660                            .build();
661
662                }
663                Number groupId;
664                RegistrySpace space;
665                List<Number> groupIds = br.getItemGroups(profileId);
666                if (groupIds == null || groupIds.isEmpty()) {
667                    groupId = null;
668                    space = RegistrySpace.PRIVATE;
669                } else {
670                    groupId = groupIds.get(0);
671                    space = RegistrySpace.GROUP;
672                }
673
674                updateDescription(desc, name, description, domainName, group);
675                ComponentRegistry cr = this.getRegistry(space, groupId);
676                return register(input, desc, new UpdateAction(), cr);
677            } else {
678                LOG.error("Update of nonexistent id (" + profileId
679                        + ") failed.");
680                return Response
681                        .serverError()
682                        .entity("Invalid id, cannot update nonexistent profile")
683                        .build();
684            }
685        } catch (ComponentRegistryException e) {
686            LOG.warn("Could not retrieve profile {}", profileId);
687            LOG.debug("Details", e);
688            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
689                    .build();
690
691        } catch (UserUnauthorizedException ex) {
692            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
693                    .build();
694
695        } catch (ItemNotFoundException ex2) {
696            return Response.status(Status.NOT_FOUND).entity(ex2.getMessage())
697                    .build();
698        } catch (AuthenticationFailException e1) {
699            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
700                    .build();
701        }
702
703    }
704
705    /**
706     *
707     * Purely helper method for my front-end (FLEX) which van only do post/get
708     * requests. The query param is checked and the "proper" method is called.
709     *
710     * @param componentId
711     * @param method
712     * @return
713     */
714    // twan: why do we need it?
715    // TODO: test via POSTMAN
716    @Override
717    @POST
718    @Path("/components/{componentId}")
719    public Response manipulateRegisteredComponent(
720            @PathParam("componentId") String componentId,
721            @FormParam("method") String method) {
722        if ("delete".equalsIgnoreCase(method)) {
723            return this.deleteRegisteredComponent(componentId);
724        } else {
725            return Response.ok("Nothing to do, not 'delete' method").build();
726        }
727    }
728
729    // TODO: test via POSTMAN
730    @Override
731    @POST
732    @Path("/components/{componentId}/publish")
733    @Consumes("multipart/form-data")
734    public Response publishRegisteredComponent(
735            @PathParam("componentId") String componentId,
736            @FormDataParam(DATA_FORM_FIELD) InputStream input,
737            @FormDataParam(NAME_FORM_FIELD) String name,
738            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
739            @FormDataParam(GROUP_FORM_FIELD) String group,
740            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
741
742        try {
743            Principal principal = checkAndGetUserPrincipal();
744            ComponentRegistry registry = this.getBaseRegistry();
745            ComponentDescription desc = registry.getComponentDescriptionAccessControlled(componentId);
746            if (desc != null) {
747                if (desc.isPublic()) {
748                    return Response.status(Status.CONFLICT).entity("Cannot publish already published omponent.")
749                            .build();
750                }
751                desc.setPublic(true);
752                this.updateDescription(desc, name, description, domainName, group);
753                return this.register(input, desc, new PublishAction(principal), registry);
754            } else {
755                LOG.error("Update of nonexistent id (" + componentId
756                        + ") failed.");
757                return Response
758                        .serverError()
759                        .entity("Invalid id, cannot update nonexistent profile")
760                        .build();
761            }
762        } catch (AuthenticationFailException e) {
763            LOG.warn("Could not retrieve component {}", componentId);
764            LOG.debug("Details", e);
765            return Response.serverError().status(Status.UNAUTHORIZED)
766                    .build();
767        } catch (ComponentRegistryException e) {
768            LOG.warn("Could not retrieve component {}", componentId);
769            LOG.debug("Details", e);
770            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
771                    .build();
772        } catch (ItemNotFoundException e) {
773            LOG.warn("Could not retrieve component {}", componentId);
774            LOG.debug("Details", e);
775            return Response.serverError().status(Status.NOT_FOUND)
776                    .build();
777        } catch (UserUnauthorizedException ex) {
778            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
779                    .build();
780        }
781    }
782
783    @Override
784    @POST
785    @Path("/components/{componentId}/update")
786    @Consumes("multipart/form-data")
787    public Response updateRegisteredComponent(
788            @PathParam("componentId") String componentId,
789            @FormDataParam(DATA_FORM_FIELD) InputStream input,
790            @FormDataParam(NAME_FORM_FIELD) String name,
791            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
792            @FormDataParam(GROUP_FORM_FIELD) String group,
793            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
794        try {
795            ComponentRegistry br = this.getBaseRegistry();
796            ComponentDescription desc = br.getComponentDescriptionAccessControlled(componentId);
797            if (desc != null) {
798                if (desc.isPublic()) {
799                    return Response.status(Status.CONFLICT).entity("Cannot update already published component.")
800                            .build();
801                }
802                Number groupId;
803                RegistrySpace space;
804                List<Number> groupIds = br.getItemGroups(componentId);
805                if (groupIds == null || groupIds.isEmpty()) {
806                    groupId = null;
807                    space = RegistrySpace.PRIVATE;
808                } else {
809                    groupId = groupIds.get(0);
810                    space = RegistrySpace.GROUP;
811                }
812
813                this.updateDescription(desc, name, description, domainName, group);
814                ComponentRegistry cr = this.getRegistry(space, groupId);
815                return this.register(input, desc, new UpdateAction(), cr);
816            } else {
817                LOG.error("Update of nonexistent id (" + componentId
818                        + ") failed.");
819                return Response
820                        .serverError()
821                        .entity("Invalid id, cannot update nonexistent component")
822                        .build();
823            }
824        } catch (ComponentRegistryException e) {
825            LOG.warn("Could not retrieve component {}", componentId);
826            LOG.debug("Details", e);
827            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
828                    .build();
829        } catch (UserUnauthorizedException ex) {
830            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
831                    .build();
832        } catch (ItemNotFoundException ex2) {
833            return Response.status(Status.FORBIDDEN).entity(ex2.getMessage())
834                    .build();
835        } catch (AuthenticationFailException e1) {
836            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
837                    .build();
838        }
839
840    }
841
842    private void updateDescription(BaseDescription desc, String name,
843            String description, String domainName, String group) {
844        desc.setName(name);
845        desc.setDescription(description);
846        desc.setDomainName(domainName);
847        desc.setGroupName(group);
848        desc.setRegistrationDate(new Date());
849    }
850
851    @Override
852    @DELETE
853    @Path("/components/{componentId}")
854    public Response deleteRegisteredComponent(
855            @PathParam("componentId") String componentId) {
856        try {
857            ComponentRegistry registry = this.getBaseRegistry();
858            LOG.debug("Component with id {} set for deletion.", componentId);
859            registry.deleteMDComponent(componentId, false);
860        } catch (DeleteFailedException e) {
861            LOG.info("Component with id {} deletion failed. Reason: {}",
862                    componentId, e.getMessage());
863            LOG.debug("Deletion failure details:", e);
864            return Response.status(Status.FORBIDDEN)
865                    .entity("" + e.getMessage()).build();
866        } catch (ComponentRegistryException e) {
867            LOG.warn("Component with id " + componentId + " deletion failed.",
868                    e);
869            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
870                    .build();
871        } catch (ItemNotFoundException e) {
872            LOG.warn("Component with id " + componentId + " is not found.");
873            return Response.serverError().status(Status.NOT_FOUND)
874                    .build();
875        } catch (IOException e) {
876            LOG.error("Component with id " + componentId + " deletion failed.",
877                    e);
878            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
879                    .build();
880        } catch (UserUnauthorizedException e) {
881            LOG.info("Component with id {} deletion failed: {}", componentId,
882                    e.getMessage());
883            LOG.debug("Deletion failure details:", e);
884            return Response.serverError().status(Status.FORBIDDEN)
885                    .entity("" + e.getMessage()).build();
886        } catch (AuthenticationFailException e1) {
887            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
888                    .build();
889        }
890
891        LOG.info("Component with id: {} deleted.", componentId);
892        return Response.ok("Component with id" + componentId + " deleted.").build();
893    }
894
895    @Override
896    @DELETE
897    @Path("/profiles/{profileId}")
898    public Response deleteRegisteredProfile(
899            @PathParam("profileId") String profileId) {
900        try {
901            LOG.debug("Profile with id: {} set for deletion.", profileId);
902            this.getBaseRegistry().deleteMDProfile(profileId);
903        } catch (DeleteFailedException e) {
904            LOG.info("Profile with id: {} deletion failed: {}", profileId,
905                    e.getMessage());
906            LOG.debug("Deletion failure details:", e);
907            return Response.serverError().status(Status.FORBIDDEN)
908                    .entity("" + e.getMessage()).build();
909        } catch (ComponentRegistryException e) {
910            LOG.warn("Could not retrieve component", e);
911            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
912                    .build();
913        } catch (ItemNotFoundException e) {
914            LOG.warn("Profile with id " + profileId + " is not found.");
915            return Response.serverError().status(Status.NOT_FOUND)
916                    .build();
917        } catch (IOException e) {
918            LOG.error("Profile with id: " + profileId + " deletion failed.", e);
919            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
920                    .build();
921        } catch (UserUnauthorizedException e) {
922            LOG.info("Profile with id: {} deletion failed: {}", profileId,
923                    e.getMessage());
924            LOG.debug("Deletion failure details:", e);
925            return Response.serverError().status(Status.FORBIDDEN)
926                    .entity("" + e.getMessage()).build();
927        } catch (AuthenticationFailException e1) {
928            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
929                    .build();
930        }
931
932        LOG.info("Profile with id: {} deleted.", profileId);
933        return Response.ok().build();
934    }
935
936    @Override
937    @DELETE
938    @Path("/profiles/{profileId}/comments/{commentId}")
939    public Response deleteCommentFromProfile(
940            @PathParam("profileId") String profileId,
941            @PathParam("commentId") String commentId) {
942        try {
943            final ComponentRegistry registry = this.getBaseRegistry();
944            try {
945                final Comment comment = registry.getSpecifiedCommentInProfile(profileId, commentId);
946                if (comment != null
947                        && profileId.equals(comment.getComponentId())) {
948                    LOG.debug("Comment with id: {} set for deletion.", commentId);
949                    registry.deleteComment(commentId);
950                } else {
951                    throw new ComponentRegistryException(
952                            "Comment not found for specified profile");
953                }
954            } catch (ItemNotFoundException e1) {
955                LOG.info("Comment with id: {} deletion failed: {}", commentId,
956                        e1.getMessage());
957                LOG.debug("Deletion failure details:", e1);
958                return Response.serverError().status(Status.NOT_FOUND)
959                        .entity("" + e1.getMessage()).build();
960            }
961
962        } catch (DeleteFailedException e) {
963            LOG.info("Comment with id: {} deletion failed: {}", commentId,
964                    e.getMessage());
965            LOG.debug("Deletion failure details:", e);
966            return Response.serverError().status(Status.FORBIDDEN)
967                    .entity("" + e.getMessage()).build();
968        } catch (ComponentRegistryException e) {
969            LOG.info("Could not find comment " + commentId + " for " + profileId);
970            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
971                    .build();
972        } catch (IOException e) {
973            LOG.error("Comment with id: " + commentId + " deletion failed.", e);
974            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
975                    .build();
976        } catch (UserUnauthorizedException e) {
977            LOG.info("Comment with id: {} deletion failed: {}", commentId,
978                    e.getMessage());
979            LOG.debug("Deletion failure details:", e);
980            return Response.serverError().status(Status.FORBIDDEN)
981                    .entity("" + e.getMessage()).build();
982        } catch (AuthenticationFailException e1) {
983            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
984                    .build();
985        }
986
987        LOG.info("Comment with id: {} deleted.", commentId);
988        return Response.ok("Comment with id " + commentId + " deleted.").build();
989    }
990
991    @Override
992    @DELETE
993    @Path("/components/{componentId}/comments/{commentId}")
994    public Response deleteCommentFromComponent(
995            @PathParam("componentId") String componentId,
996            @PathParam("commentId") String commentId) {
997        try {
998            final ComponentRegistry registry = this.getBaseRegistry();
999            final Comment comment = registry.getSpecifiedCommentInComponent(componentId, commentId);
1000            if (comment != null
1001                    && componentId.equals(comment.getComponentId())) {
1002                LOG.debug("Comment with id: {} set for deletion.", commentId);
1003                registry.deleteComment(commentId);
1004            } else {
1005                throw new ComponentRegistryException(
1006                        "Comment not found for specified component");
1007            }
1008        } catch (ItemNotFoundException e) {
1009            LOG.info("Comment with id: {} deletion failed: {}", commentId,
1010                    e.getMessage());
1011            LOG.debug("Deletion failure details:", e);
1012            return Response.serverError().status(Status.NOT_FOUND)
1013                    .entity("" + e.getMessage()).build();
1014        } catch (DeleteFailedException e) {
1015            LOG.info("Comment with id: {} deletion failed: {}", commentId,
1016                    e.getMessage());
1017            LOG.debug("Deletion failure details:", e);
1018            return Response.serverError().status(Status.FORBIDDEN)
1019                    .entity("" + e.getMessage()).build();
1020        } catch (ComponentRegistryException e) {
1021            LOG.info("Could not retrieve component " + componentId + " for the component " + componentId);
1022            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
1023                    .build();
1024        } catch (IOException e) {
1025            LOG.error("Comment with id: " + commentId + " deletion failed.", e);
1026            return Response.serverError().status(Status.INTERNAL_SERVER_ERROR)
1027                    .build();
1028        } catch (UserUnauthorizedException e) {
1029            LOG.info("Comment with id: {} deletion failed: {}", commentId,
1030                    e.getMessage());
1031            LOG.debug("Deletion failure details:", e);
1032            return Response.serverError().status(Status.FORBIDDEN)
1033                    .entity("" + e.getMessage()).build();
1034        } catch (AuthenticationFailException e1) {
1035            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
1036                    .build();
1037        }
1038
1039        LOG.info("Comment with id: {} deleted.", commentId);
1040        return Response.ok("Comment with id " + commentId + " deleted.").build();
1041    }
1042
1043    @Override
1044    @GET
1045    @Path("/profiles/{profileId}/{rawType}")
1046    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
1047    public Response getRegisteredProfileRawType(
1048            @PathParam("profileId") final String profileId,
1049            @PathParam("rawType") String rawType) throws ComponentRegistryException, IllegalArgumentException {
1050
1051
1052        LOG.debug("Profile with id {} and rawType {} is requested.", profileId,
1053                rawType);
1054        try {
1055            final ComponentRegistry registry = this.getBaseRegistry();
1056
1057            ProfileDescription desc = registry.getProfileDescriptionAccessControlled(profileId);
1058            if (desc == null) {
1059                return Response.status(Status.NOT_FOUND).build();
1060            }
1061
1062            StreamingOutput result = null;
1063            String fileName = desc.getName() + "." + rawType;
1064            if ("xml".equalsIgnoreCase(rawType)) {
1065                result = new StreamingOutput() {
1066                    @Override
1067                    public void write(OutputStream output) throws IOException,
1068                            WebApplicationException {
1069                        try {
1070                            registry.getMDProfileAsXml(profileId, output);
1071                        } catch (Exception e) {
1072                            LOG.warn("Could not retrieve component {}",
1073                                    profileId);
1074                            LOG.debug("Details", e);
1075                            throw new WebApplicationException(e, Response
1076                                    .serverError()
1077                                    .status(Status.INTERNAL_SERVER_ERROR)
1078                                    .build());
1079                        }
1080                    }
1081                };
1082            } else if ("xsd".equalsIgnoreCase(rawType)) {
1083                result = new StreamingOutput() {
1084                    @Override
1085                    public void write(OutputStream output) throws IOException,
1086                            WebApplicationException {
1087                        try {
1088                            registry.getMDProfileAsXsd(profileId, output);
1089                        } catch (Exception e) {
1090                            LOG.warn("Could not retrieve component {}",
1091                                    profileId);
1092                            LOG.debug("Details", e);
1093                            throw new WebApplicationException(e, Response
1094                                    .serverError()
1095                                    .status(Status.INTERNAL_SERVER_ERROR)
1096                                    .build());
1097                        }
1098                    }
1099                };
1100            } else {
1101                return Response.status(Status.NOT_FOUND).entity("Unsupported raw type " + rawType).build();
1102            }
1103            return createDownloadResponse(result, fileName);
1104        } catch (UserUnauthorizedException ex) {
1105            return Response.status(Status.FORBIDDEN).build();
1106        } catch (ItemNotFoundException e) {
1107            return Response.serverError().status(Status.NOT_FOUND)
1108                    .entity("" + e.getMessage()).build();
1109        } catch (AuthenticationFailException e1) {
1110            return Response.status(Status.UNAUTHORIZED).entity(e1.getMessage())
1111                    .build();
1112        }
1113
1114    }
1115
1116    private Response createDownloadResponse(StreamingOutput result,
1117            String fileName) {
1118        // Making response so it triggers browsers native save as dialog.
1119        Response response = Response
1120                .ok()
1121                .type("application/x-download")
1122                .header("Content-Disposition",
1123                "attachment; filename=\"" + fileName + "\"")
1124                .entity(result).build();
1125        return response;
1126
1127    }
1128
1129    @Override
1130    @POST
1131    @Path("/profiles")
1132    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1133        MediaType.APPLICATION_JSON})
1134    @Consumes("multipart/form-data")
1135    public Response registerProfile(
1136            @FormDataParam(DATA_FORM_FIELD) InputStream input,
1137            @FormDataParam(NAME_FORM_FIELD) String name,
1138            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
1139            @FormDataParam(GROUP_FORM_FIELD) String group,
1140            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
1141        try {
1142            Principal principal = checkAndGetUserPrincipal();
1143            UserCredentials userCredentials = getUserCredentials(principal);
1144            ProfileDescription desc = this.createNewProfileDescription();
1145            desc.setCreatorName(userCredentials.getDisplayName());
1146            desc.setUserId(userCredentials.getPrincipalName()); // Hash used to
1147            // be created
1148            // here, now Id
1149            // is
1150            // constructed
1151            // by impl
1152            desc.setName(name);
1153            desc.setDescription(description);
1154            desc.setGroupName(group);
1155            desc.setDomainName(domainName);
1156            desc.setPublic(false);
1157            LOG.debug("Trying to register Profile: {}", desc);
1158            ComponentRegistry cr = this.getRegistry(RegistrySpace.PRIVATE, null);
1159            return this.register(input, desc, new NewAction(), cr);
1160        } catch (AuthenticationFailException e) {
1161            LOG.debug("Details", e);
1162            return Response.serverError().status(Status.UNAUTHORIZED)
1163                    .build();
1164        } catch (UserUnauthorizedException ex) {
1165            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
1166                    .build();
1167        }
1168    }
1169
1170    @Override
1171    @POST
1172    @Path("/components")
1173    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1174        MediaType.APPLICATION_JSON})
1175    @Consumes("multipart/form-data")
1176    public Response registerComponent(
1177            @FormDataParam(DATA_FORM_FIELD) InputStream input,
1178            @FormDataParam(NAME_FORM_FIELD) String name,
1179            @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
1180            @FormDataParam(GROUP_FORM_FIELD) String group,
1181            @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
1182        try {
1183            Principal principal = checkAndGetUserPrincipal();
1184            UserCredentials userCredentials = getUserCredentials(principal);
1185            ComponentDescription desc = createNewComponentDescription();
1186            desc.setCreatorName(userCredentials.getDisplayName());
1187            desc.setUserId(userCredentials.getPrincipalName()); // Hash used to
1188            // be created
1189            // here, now Id
1190            // is
1191            // constructed
1192            // by impl
1193            desc.setName(name);
1194            desc.setDescription(description);
1195            desc.setGroupName(group);
1196            desc.setDomainName(domainName);
1197            desc.setPublic(false);
1198            LOG.debug("Trying to register Component: {}", desc);
1199            ComponentRegistry cr = this.getRegistry(RegistrySpace.PRIVATE, null);
1200            return this.register(input, desc, new NewAction(), cr);
1201        } catch (AuthenticationFailException e) {
1202            LOG.debug("Details", e);
1203            return Response.serverError().status(Status.UNAUTHORIZED)
1204                    .build();
1205        } catch (UserUnauthorizedException ex) {
1206            return Response.status(Status.FORBIDDEN).entity(ex.getMessage())
1207                    .build();
1208        }
1209    }
1210
1211    @Override
1212    @POST
1213    @Path("/components/{componentId}/comments")
1214    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1215        MediaType.APPLICATION_JSON})
1216    @Consumes("multipart/form-data")
1217    public Response registerCommentInComponent(
1218            @FormDataParam(DATA_FORM_FIELD) InputStream input,
1219            @PathParam("componentId") String componentId) throws ComponentRegistryException {
1220        try {
1221            ComponentRegistry registry = this.getBaseRegistry();
1222            ComponentDescription description = registry.getComponentDescriptionAccessControlled(componentId);
1223
1224            LOG.debug("Trying to register comment to {}", componentId);
1225
1226            return this.registerComment(input, description, registry);
1227        } catch (AuthenticationFailException e) {
1228            LOG.debug("Details", e);
1229            return Response.serverError().status(Status.UNAUTHORIZED)
1230                    .build();
1231        } catch (UserUnauthorizedException ex) {
1232            return Response.status(Status.FORBIDDEN)
1233                    .build();
1234        } catch (ItemNotFoundException e) {
1235            return Response.serverError().status(Status.NOT_FOUND)
1236                    .entity("" + e.getMessage()).build();
1237        }
1238    }
1239
1240    // TODO test with the POSTMAN
1241    @Override
1242    @POST
1243    @Path("/profiles/{profileId}/comments")
1244    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1245        MediaType.APPLICATION_JSON})
1246    @Consumes("multipart/form-data")
1247    public Response registerCommentInProfile(
1248            @FormDataParam(DATA_FORM_FIELD) InputStream input,
1249            @PathParam("profileId") String profileId)
1250            throws ComponentRegistryException {
1251        try {
1252            ComponentRegistry registry = this.getBaseRegistry();
1253            ProfileDescription description = registry
1254                    .getProfileDescriptionAccessControlled(profileId);
1255
1256            LOG.debug("Trying to register comment to {}", profileId);
1257
1258            return this.registerComment(input, description, registry);
1259        } catch (AuthenticationFailException e) {
1260            LOG.debug("Details", e);
1261            return Response.serverError().status(Status.UNAUTHORIZED)
1262                    .build();
1263        } catch (UserUnauthorizedException ex) {
1264            return Response.status(Status.FORBIDDEN)
1265                    .build();
1266        } catch (ItemNotFoundException e1) {
1267            return Response.serverError().status(Status.NOT_FOUND)
1268                    .entity("" + e1.getMessage()).build();
1269        }
1270    }
1271
1272    @Override
1273    @GET
1274    @Path("/pingSession")
1275    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1276        MediaType.APPLICATION_JSON})
1277    public Response pingSession() {
1278        boolean stillActive = false;
1279        Principal userPrincipal = security.getUserPrincipal();
1280        if (LOG.isInfoEnabled()) {
1281            LOG.debug("ping by <{}>",
1282                    (userPrincipal == null ? "unauthorized user"
1283                    : userPrincipal.getName()));
1284        }
1285        if (request != null) {
1286            if (userPrincipal != null
1287                    && !ComponentRegistryFactory.ANONYMOUS_USER
1288                    .equals(userPrincipal.getName())) {
1289                stillActive = !((HttpServletRequest) request).getSession()
1290                        .isNew();
1291            }
1292        }
1293        return Response
1294                .ok()
1295                .entity(String.format("<session stillActive=\"%s\"/>",
1296                stillActive)).build();
1297    }
1298
1299    private Response register(InputStream input, BaseDescription desc, RegisterAction action, ComponentRegistry registry) throws UserUnauthorizedException {
1300        try {
1301
1302
1303            DescriptionValidator descriptionValidator = new DescriptionValidator(
1304                    desc);
1305            MDValidator validator = new MDValidator(input, desc, registry, marshaller);
1306            RegisterResponse response = new RegisterResponse();
1307            //obsolete. Make it setstatus
1308            response.setIsInUserSpace(!desc.isPublic());
1309            this.validate(response, descriptionValidator, validator);
1310            if (response.getErrors().isEmpty()) {
1311
1312                CMDComponentSpec spec = validator.getCMDComponentSpec();
1313
1314                // removing filename from spec before it gets extended.
1315                // recursion over all the components
1316                setFileNamesFromListToNull(Collections.singletonList(spec.getCMDComponent()));
1317
1318                try {
1319                    checkForRecursion(validator, registry, desc);
1320
1321                    // Add profile
1322                    int returnCode = action.execute(desc, spec, response,
1323                            registry);
1324                    if (returnCode == 0) {
1325                        response.setRegistered(true);
1326                        response.setDescription(desc);
1327                    } else {
1328                        response.setRegistered(false);
1329                        response.addError("Unable to register at this moment. Internal server error.");
1330                    }
1331                } catch (ComponentRegistryException ex) {
1332                    // Recursion detected
1333                    response.setRegistered(false);
1334                    response.addError("Error while expanding specification. "
1335                            + ex.getMessage());
1336                } catch (ItemNotFoundException ex) {
1337                    // Recursion detected
1338                    response.setRegistered(false);
1339                    response.addError("Error while expanding specification. "
1340                            + ex.getMessage());
1341                }
1342            } else {
1343                LOG.warn("Registration failed with validation errors: {}",
1344                        Arrays.toString(response.getErrors().toArray()));
1345                response.setRegistered(false);
1346            }
1347            LOG.info("Registered new {} {}", desc.isProfile() ? "profile"
1348                    : "component", desc);
1349            response.setIsProfile(desc.isProfile());
1350            return Response.ok(response).build();
1351        } finally {
1352            try {
1353                input.close();// either we read the input or there was an
1354                // exception, we need to close it.
1355            } catch (IOException e) {
1356                LOG.error("Error when closing inputstream: ", e);
1357            }
1358        }
1359    }
1360
1361    /**
1362     *
1363     * @param validator
1364     * @param registry
1365     * @param desc
1366     * @throws ComponentRegistryException if recursion is detected or something
1367     * goes wrong while trying to detect recursion
1368     */
1369    private void checkForRecursion(MDValidator validator,
1370            ComponentRegistry registry, BaseDescription desc)
1371            throws ComponentRegistryException {
1372        try {
1373            // Expand to check for recursion. Operate on copy so that original
1374            // does not get expanded.
1375            final CMDComponentSpec specCopy = validator
1376                    .getCopyOfCMDComponentSpec();
1377            // In case of recursion, the following will throw a
1378            // ComponentRegistryException
1379            registry.getExpander().expandNestedComponent(
1380                    Lists.newArrayList(specCopy.getCMDComponent()), desc.getId());
1381        } catch (JAXBException ex) {
1382            throw new ComponentRegistryException(
1383                    "Unmarshalling failed while preparing recursion detection",
1384                    ex);
1385        }
1386    }
1387
1388    private Response registerComment(InputStream input, BaseDescription description, ComponentRegistry registry) throws UserUnauthorizedException, AuthenticationFailException {
1389        try {
1390            CommentValidator validator = new CommentValidator(input, description, marshaller);
1391            CommentResponse responseLocal = new CommentResponse();
1392
1393            responseLocal.setIsInUserSpace(!description.isPublic());
1394            this.validateComment(responseLocal, validator);
1395            if (responseLocal.getErrors().isEmpty()) {
1396                Comment com = validator.getCommentSpec();
1397                // int returnCode = action.executeComment(com, response,
1398                // registry, principal.getName());
1399
1400                // If user name is left empty, fill it using the user's display
1401                // name
1402
1403                Principal principal = this.checkAndGetUserPrincipal();
1404                UserCredentials userCredentials = this.getUserCredentials(principal);
1405                if (null == com.getUserName() || "".equals(com.getUserName())) {
1406                    if (userCredentials != null) {
1407                        com.setUserName(userCredentials.getDisplayName());
1408                    } else {
1409                        com.setUserName(principal.getName());
1410                    }
1411                }
1412                try {
1413                    int returnCode = registry.registerComment(com,
1414                            principal.getName());
1415                    if (returnCode == 0) {
1416                        responseLocal.setRegistered(true);
1417                        responseLocal.setComment(com);
1418                    } else {
1419                        responseLocal.setRegistered(false);
1420                        responseLocal.addError("Unable to post at this moment. Internal server error.");
1421                    }
1422                    if (com.getComponentId() != null) {
1423                        LOG.info("Posted new comment on component {}",
1424                                com.getComponentId());
1425                    } else {
1426                        LOG.info("Posted new comment on profile {}",
1427                                com.getComponentId());
1428                    }
1429                } catch (ItemNotFoundException e) {
1430                    return Response.serverError().status(Status.NOT_FOUND)
1431                            .entity("" + e.getMessage()).build();
1432                }
1433            } else {
1434                LOG.warn(
1435                        "Posting of comment failed with validation errors: {}",
1436                        Arrays.toString(responseLocal.getErrors().toArray()));
1437                responseLocal.setRegistered(false);
1438            }
1439            return Response.ok(responseLocal).build();
1440        } catch (ComponentRegistryException ex) {
1441            LOG.error("Error while inserting comment: ", ex);
1442            return Response.serverError().entity(ex.getMessage()).build();
1443        } finally {
1444            try {
1445                input.close();// either we read the input or there was an
1446                // exception, we need to close it.
1447            } catch (IOException e) {
1448                LOG.error("Error when closing inputstream: ", e);
1449                return Response.serverError().build();
1450            }
1451        }
1452    }
1453
1454    private ComponentDescription createNewComponentDescription() {
1455        ComponentDescription desc = ComponentDescription.createNewDescription();
1456        desc.setHref(createXlink(desc.getId()));
1457        return desc;
1458    }
1459
1460    private ProfileDescription createNewProfileDescription() {
1461        ProfileDescription desc = ProfileDescription.createNewDescription();
1462        desc.setHref(createXlink(desc.getId()));
1463        return desc;
1464    }
1465
1466    private String createXlink(String id) {
1467        URI uri = uriInfo.getRequestUriBuilder().path(id).build();
1468        return uri.toString();
1469    }
1470
1471    /**
1472     *
1473     * @return The application's base URI as configured in the
1474     * {@link #APPLICATION_BASE_URL_PARAM} context parameter. If correctly
1475     * configured, it should look something like
1476     * "http://catalog.clarin.eu/ds/ComponentRegistry". <em>Be aware that this
1477     * can also be null if configured incorrectly!</em>
1478     *
1479     * @see #APPLICATION_BASE_URL_PARAM
1480     */
1481    private String getApplicationBaseURI() {
1482        return servletContext.getInitParameter(APPLICATION_BASE_URL_PARAM);
1483    }
1484
1485    private void validate(RegisterResponse response, Validator... validators) throws UserUnauthorizedException {
1486        for (Validator validator : validators) {
1487            if (!validator.validate()) {
1488                for (String error : validator.getErrorMessages()) {
1489                    response.addError(error);
1490                }
1491            }
1492        }
1493    }
1494
1495    private void validateComment(CommentResponse response,
1496            Validator... validators) throws UserUnauthorizedException {
1497        for (Validator validator : validators) {
1498            if (!validator.validate()) {
1499                for (String error : validator.getErrorMessages()) {
1500                    response.addError(error);
1501                }
1502            }
1503        }
1504    }
1505
1506    /**
1507     * @param componentRegistryFactory the componentRegistryFactory to set
1508     */
1509    @Override
1510    public void setComponentRegistryFactory(
1511            ComponentRegistryFactory componentRegistryFactory) {
1512        this.componentRegistryFactory = componentRegistryFactory;
1513    }
1514
1515    /**
1516     *
1517     * @param listofcomponents a list of components whose file-names and whose
1518     * childrens' filenames are to be set to null
1519     */
1520    @Override
1521    public void setFileNamesFromListToNull(
1522            List<CMDComponentType> listofcomponents) {
1523
1524        for (CMDComponentType currentcomponent : listofcomponents) {
1525            setFileNamesToNullCurrent(currentcomponent);
1526        }
1527
1528    }
1529
1530    /**
1531     *
1532     * @param currentcomponent a component whose file-name and whose children
1533     * filenames are to be set to null
1534     */
1535    protected void setFileNamesToNullCurrent(CMDComponentType currentcomponent) {
1536        currentcomponent.setFilename(null);
1537        setFileNamesFromListToNull(currentcomponent.getCMDComponent());
1538    }
1539
1540    /**
1541     *
1542     * @param isPublished if "true" then profiles and components from the user's
1543     * workspace, otherwise -- public
1544     * @param limit the number of items to be displayed
1545     * @return rss for the components in the database to which we are currently
1546     * connected
1547     * @throws ComponentRegistryException
1548     * @throws ParseException
1549     */
1550    @Override
1551    @GET
1552    @Path("/components/rss")
1553    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1554        MediaType.APPLICATION_JSON})
1555    public Rss getRssComponent(@QueryParam(GROUPID_PARAM) String groupId,
1556            @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace,
1557            @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit)
1558            throws ComponentRegistryException, ParseException, IOException {
1559        List<ComponentDescription> components = null;
1560        try {
1561            ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId);
1562            components = cr.getComponentDescriptions();
1563        } catch (AuthenticationFailException e) {
1564            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
1565            return new Rss();
1566        } catch (UserUnauthorizedException e) {
1567            response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString());
1568            return new Rss();
1569        }
1570        catch (ItemNotFoundException e) {
1571            response.sendError(Status.NOT_FOUND.getStatusCode(), e.toString());
1572            return new Rss();
1573        }
1574        // obsolete, add group Id
1575        final RssCreatorDescriptions instance = new RssCreatorDescriptions(!registrySpace.equalsIgnoreCase("published"), getApplicationBaseURI(), "components",
1576                Integer.parseInt(limit), components,
1577                ComponentUtils.COMPARE_ON_DATE);
1578        final Rss rss = instance.getRss();
1579        LOG.debug("Releasing RSS of {} most recently registered components",
1580                limit);
1581        return rss;
1582    }
1583
1584    /**
1585     *
1586     * @param isPublished if "true" then profiles and components from the user's
1587     * workspace, otherwise -- public
1588     * @param limit the number of items to be displayed
1589     * @return rss for the profiles in the database to which we are currently
1590     * connected
1591     * @throws ComponentRegistryException
1592     * @throws ParseException
1593     */
1594    @Override
1595    @GET
1596    @Path("/profiles/rss")
1597    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1598        MediaType.APPLICATION_JSON})
1599    public Rss getRssProfile(@QueryParam(GROUPID_PARAM) String groupId,
1600            @QueryParam(REGISTRY_SPACE_PARAM) @DefaultValue("published") String registrySpace,
1601            @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit)
1602            throws ComponentRegistryException, ParseException, IOException {
1603        List<ProfileDescription> profiles = null;
1604        try {
1605            ComponentRegistry cr = this.initialiseRegistry(registrySpace, groupId);
1606            profiles = cr.getProfileDescriptions();
1607        } catch (AuthenticationFailException e) {
1608            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
1609            return new Rss();
1610        } catch (UserUnauthorizedException e) {
1611            response.sendError(Status.FORBIDDEN.getStatusCode(), e.toString());
1612            return new Rss();
1613       
1614        } catch (ItemNotFoundException e) {
1615            response.sendError(Status.NOT_FOUND.getStatusCode(), e.toString());
1616            return new Rss();
1617        }
1618        final RssCreatorDescriptions instance = new RssCreatorDescriptions(
1619                !registrySpace.equalsIgnoreCase("published"), getApplicationBaseURI(), "profiles",
1620                Integer.parseInt(limit), profiles,
1621                ComponentUtils.COMPARE_ON_DATE);
1622        final Rss rss = instance.getRss();
1623        LOG.debug("Releasing RSS of {} most recently registered profiles",
1624                limit);
1625        return rss;
1626    }
1627
1628    /**
1629     *
1630     * @param profileId the Id of a profile whose comments are to be rss-ed
1631     * @param isPublished if "true" then profiles and components from the user's
1632     * workspace, otherwise -- public
1633     * @param limit the number of items to be displayed
1634     * @return rss of the comments for a chosen profile
1635     * @throws ComponentRegistryException
1636     * @throws IOException
1637     * @throws JAXBException
1638     * @throws ParseException
1639     */
1640    @Override
1641    @GET
1642    @Path("/profiles/{profileId}/comments/rss")
1643    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1644        MediaType.APPLICATION_JSON})
1645    public Rss getRssOfCommentsFromProfile(
1646            @PathParam("profileId") String profileId,
1647            @QueryParam(NUMBER_OF_RSSITEMS) @DefaultValue("20") String limit)
1648            throws ComponentRegistryException, IOException, JAXBException,
1649            ParseException {
1650        try {
1651
1652            ComponentRegistry cr = this.getBaseRegistry();
1653
1654            final List<Comment> comments = cr.getCommentsInProfile(profileId);
1655            final ProfileDescription pd = cr.getProfileDescriptionAccessControlled(profileId);
1656            final String profileName = pd.getName();
1657            boolean profileIsPrivate = !pd.isPublic();
1658            // obsolete, status must be involved, not boolean profileIsPrivate
1659            final RssCreatorComments instance = new RssCreatorComments(profileIsPrivate,
1660                    getApplicationBaseURI(), Integer.parseInt(limit), profileId,
1661                    profileName, "profile", comments, Comment.COMPARE_ON_DATE);
1662            final Rss rss = instance.getRss();
1663            LOG.debug("Releasing RSS of {} most recent post on profile {}", limit,
1664                    profileId);
1665            return rss;
1666        } catch (UserUnauthorizedException ex) {
1667            response.sendError(Status.FORBIDDEN.getStatusCode());
1668            return new Rss();
1669        } catch (ItemNotFoundException e) {
1670            response.sendError(Status.NOT_FOUND.getStatusCode());
1671            return new Rss();
1672        } catch (AuthenticationFailException e) {
1673            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
1674            return new Rss();
1675        }
1676    }
1677
1678    /**
1679     *
1680     * @param componentId the Id of a component whose comments are to be rss-ed
1681     * @param isPublished if "true" then profiles and components from the user's
1682     * workspace, otherwise -- public
1683     * @param limit the number of items to be displayed
1684     * @return rss of the comments for a chosen component
1685     * @throws ComponentRegistryException
1686     * @throws IOException
1687     * @throws JAXBException
1688     * @throws ParseException
1689     */
1690    @Override
1691    @GET
1692    @Path("/components/{componentId}/comments/rss")
1693    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1694        MediaType.APPLICATION_JSON})
1695    public Rss getRssOfCommentsFromComponent(
1696            @PathParam("componentId") String componentId,
1697            @QueryParam(NUMBER_OF_RSSITEMS)
1698            @DefaultValue("20") String limit)
1699            throws ComponentRegistryException, IOException, JAXBException,
1700            ParseException {
1701        try {
1702            ComponentRegistry cr = this.getBaseRegistry();
1703            final List<Comment> comments = cr.getCommentsInComponent(componentId);
1704            final ComponentDescription cd = cr.getComponentDescriptionAccessControlled(componentId);
1705            final String componentName = cd.getName();
1706            final boolean isPrivate = !cd.isPublic();
1707            //oboslete. status must be involved, not boolean isPrivate
1708            final RssCreatorComments instance = new RssCreatorComments(isPrivate,
1709                    getApplicationBaseURI(), Integer.parseInt(limit), componentId,
1710                    componentName, "component", comments, Comment.COMPARE_ON_DATE);
1711            final Rss rss = instance.getRss();
1712            LOG.debug("Releasing RSS of {} most recent post on component {}",
1713                    limit, componentId);
1714            return rss;
1715        } catch (UserUnauthorizedException e) {
1716            response.sendError(Status.FORBIDDEN.getStatusCode());
1717            return new Rss();
1718        } catch (ItemNotFoundException e) {
1719            response.sendError(Status.NOT_FOUND.getStatusCode());
1720            return new Rss();
1721        } catch (AuthenticationFailException e1) {
1722            response.sendError(Status.UNAUTHORIZED.getStatusCode());
1723            return new Rss();
1724        }
1725
1726    }
1727
1728    @Override
1729    @GET
1730    @Path("/AllowedTypes")
1731    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1732        MediaType.APPLICATION_JSON})
1733    public AllowedAttributetypesXML getAllowedAttributeTypes()
1734            throws ComponentRegistryException, IOException, JAXBException,
1735            ParseException {
1736        return (new AllowedAttributetypesXML());
1737    }
1738
1739    @Override
1740    @GET
1741    @Path("/groups/usermembership")
1742    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1743        MediaType.APPLICATION_JSON})
1744    public List<Group> getGroupsTheCurrentUserIsAMemberOf() {
1745        Principal principal = security.getUserPrincipal();
1746        if (principal == null) {
1747            return new ArrayList<Group>();
1748        }
1749        List<Group> groups = groupService.getGroupsOfWhichUserIsAMember(principal.getName());
1750        return groups;
1751    }
1752
1753    @Override
1754    @GET
1755    @Path("/items/{itemId}/groups")
1756    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1757        MediaType.APPLICATION_JSON})
1758    public List<Group> getGroupsTheItemIsAMemberOf(@PathParam("itemId") String itemId) {
1759        return groupService.getGroupsTheItemIsAMemberOf(itemId);
1760    }
1761
1762    @Override
1763    @POST
1764    @Path("/items/{itemId}/transferownership")
1765    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1766        MediaType.APPLICATION_JSON})
1767    public Response transferItemOwnershipToGroup(@PathParam("itemId") String itemId,
1768            @QueryParam("groupId") long groupId) throws IOException {
1769        Principal principal = security.getUserPrincipal();
1770        try {
1771            groupService.transferItemOwnershipFromUserToGroupId(principal.getName(), groupId, itemId);
1772            return Response.ok("Ownership transferred").build();
1773        } catch (UserUnauthorizedException e) {
1774            return Response.status(Status.FORBIDDEN).build();
1775        }
1776    }
1777
1778    @Override
1779    @GET
1780    @Path("/items/{itemId}")
1781    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1782        MediaType.APPLICATION_JSON})
1783    public BaseDescription getBaseDescription(@PathParam("itemId") String itemId) throws ComponentRegistryException, IOException {
1784        LOG.debug("Item with id: {} is requested.", itemId);
1785        try {
1786            ComponentRegistry cr = this.getBaseRegistry();
1787            BaseDescription description;
1788            if (itemId.startsWith(ComponentDescription.COMPONENT_PREFIX)) {
1789                description = cr.getComponentDescriptionAccessControlled(itemId);
1790                return description;
1791            };
1792            if (itemId.startsWith(ProfileDescription.PROFILE_PREFIX)) {
1793                description = cr.getProfileDescriptionAccessControlled(itemId);
1794                return description;
1795            };
1796            response.sendError(Status.BAD_REQUEST.getStatusCode());
1797            return new BaseDescription();
1798
1799
1800        } catch (UserUnauthorizedException ex2) {
1801            response.sendError(Status.FORBIDDEN.getStatusCode(), ex2.getMessage());
1802            return new BaseDescription();
1803        } catch (ItemNotFoundException e) {
1804            response.sendError(Status.NOT_FOUND.getStatusCode(), e.getMessage());
1805            return new BaseDescription();
1806        } catch (AuthenticationFailException e) {
1807            response.sendError(Status.UNAUTHORIZED.getStatusCode(), e.toString());
1808            return new BaseDescription();
1809        }
1810    }
1811
1812    // Group Service (added by Olha)
1813    @Override
1814    @POST
1815    @Path("/groups/create")
1816    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1817        MediaType.APPLICATION_JSON})
1818    public Response createNewGroup(@QueryParam("groupName") String groupName) throws IOException {
1819
1820        try {
1821            Principal principal = this.checkAndGetUserPrincipal();
1822            Number id = groupService.createNewGroup(groupName, principal.getName());
1823            return Response.ok("Group with the name " + groupName + " is created and given an id " + id).build();
1824        } catch (AuthenticationFailException e) {
1825            return Response.status(Status.UNAUTHORIZED).build();
1826        }
1827    }
1828
1829    @Override
1830    @GET
1831    @Path("/groups/principal")
1832    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1833        MediaType.APPLICATION_JSON})
1834    public List<Group> getGroupsOwnedByUser(@QueryParam("principalName") String pricipalName) throws IOException {
1835
1836        try {
1837            Principal principal = this.checkAndGetUserPrincipal();
1838            return groupService.getGroupsOwnedByUser(principal.getName());
1839        } catch (AuthenticationFailException e) {
1840            response.sendError(Status.UNAUTHORIZED.getStatusCode());
1841            return new ArrayList<Group>();
1842        }
1843    }
1844
1845    @Override
1846    @GET
1847    @Path("/groups/names")
1848    public Response listGroupNames() throws IOException {
1849
1850        try {
1851            Principal principal = this.checkAndGetUserPrincipal();
1852            List<String> result = groupService.listGroupNames();
1853            //final GenericEntity<List<String>> entity  = new GenericEntity<List<String>>(result){};
1854            //return Response.status(Status.OK).entity(entity).build();
1855            StringsWrapper ids = new StringsWrapper();
1856            ids.setStrings(result);
1857            return Response.status(Status.OK).entity(ids).build();
1858        } catch (AuthenticationFailException e) {
1859            return Response.status(Status.UNAUTHORIZED).build();
1860        }
1861    }
1862
1863    @Override
1864    @GET
1865    @Path("/groups/ownership")
1866    public Response isOwner(@QueryParam("groupName") String groupName) throws IOException {
1867
1868        try {
1869            Principal principal = this.checkAndGetUserPrincipal();
1870            Boolean isOwner = groupService.isUserOwnerOfGroup(groupName, principal.getName());
1871            return Response.ok(isOwner.toString()).build();
1872        } catch (AuthenticationFailException e) {
1873            return Response.serverError().status(Status.UNAUTHORIZED).build();
1874        }
1875    }
1876
1877    @Override
1878    @POST
1879    @Path("/groups/makemember")
1880    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1881        MediaType.APPLICATION_JSON})
1882    public Response makeGroupMember(@QueryParam("groupName") String groupName, @QueryParam("principalName") String principalName) throws IOException {
1883        try {
1884            ComponentRegistry registry = this.getBaseRegistry();
1885            Number id = registry.makeGroupMember(principalName, groupName);
1886            return Response.ok(id.toString()).build();
1887        } catch (UserUnauthorizedException e) {
1888            return Response.status(Status.FORBIDDEN).entity(e.getMessage()).build();
1889        } catch (ItemNotFoundException e) {
1890            return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
1891       
1892        } catch (AuthenticationFailException e) {
1893            return Response.status(Status.UNAUTHORIZED).build();
1894        }
1895    }
1896   
1897//    @Override
1898//    @DELETE
1899//    @Path("/groups/removemember")
1900//    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML,
1901//        MediaType.APPLICATION_JSON})
1902//    public Response removeGroupMember(@QueryParam("groupName") String groupName, @QueryParam("principalName") String principalName) throws IOException {
1903//        try {
1904//            ComponentRegistry registry = this.getBaseRegistry();
1905//            Number id = registry.removeGroupMember(principalName, groupName);
1906//            return Response.ok(id.toString()).build();
1907//        } catch (UserUnauthorizedException e) {
1908//            return Response.status(Status.FORBIDDEN).entity(e.getMessage()).build();
1909//        } catch (ItemNotFoundException e) {
1910//            return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
1911//       
1912//        } catch (AuthenticationFailException e) {
1913//            return Response.status(Status.UNAUTHORIZED).build();
1914//        }
1915//    }
1916
1917    @Override
1918    @GET
1919    @Path("/groups/profiles")
1920    public Response listProfiles(@QueryParam("groupId") String groupId) throws IOException {
1921
1922        try {
1923            Principal principal = this.checkAndGetUserPrincipal();
1924            List<String> result = groupService.getProfileIdsInGroup(Long.parseLong(groupId));
1925            StringsWrapper ids = new StringsWrapper();
1926            ids.setStrings(result);
1927            return Response.status(Status.OK).entity(ids).build();
1928        } catch (AuthenticationFailException e) {
1929            return Response.status(Status.UNAUTHORIZED).build();
1930        }
1931    }
1932
1933    @Override
1934    @GET
1935    @Path("/groups/components")
1936    public Response listComponents(@QueryParam("groupId") String groupId) throws IOException {
1937
1938        try {
1939            Principal principal = this.checkAndGetUserPrincipal();
1940            List<String> result = groupService.getComponentIdsInGroup(Long.parseLong(groupId));
1941            StringsWrapper ids = new StringsWrapper();
1942            ids.setStrings(result);
1943            return Response.status(Status.OK).entity(ids).build();
1944        } catch (AuthenticationFailException e) {
1945            response.sendError(Status.UNAUTHORIZED.getStatusCode());
1946            return Response.status(Status.UNAUTHORIZED).build();
1947        }
1948    }
1949
1950    @Override
1951    @GET
1952    @Path("/groups/nameById")
1953    public Response getGroupNameById(@QueryParam("groupId") String groupId) throws IOException {
1954
1955        try {
1956            Principal principal = this.checkAndGetUserPrincipal();
1957            String name = groupService.getGroupNameById(Long.parseLong(groupId));
1958            return Response.ok(name).build();
1959        } catch (AuthenticationFailException e) {
1960            return Response.status(Status.UNAUTHORIZED).build();
1961        } catch (ItemNotFoundException e) {
1962            return Response.status(Status.NOT_FOUND).build();
1963        }
1964    }
1965
1966    @Override
1967    @GET
1968    @Path("/groups/idByName")
1969    public Response getGroupIdByName(@QueryParam("groupName") String groupName) throws IOException {
1970
1971        try {
1972            Principal principal = this.checkAndGetUserPrincipal();
1973            Number id = groupService.getGroupIdByName(groupName);
1974            return Response.ok(id.toString()).build();
1975        } catch (AuthenticationFailException e) {
1976            return Response.status(Status.UNAUTHORIZED).build();
1977        } catch (ItemNotFoundException e) {
1978            return Response.status(Status.NOT_FOUND).build();
1979        }
1980    }
1981
1982    @XmlRootElement(name = "Identifiers")
1983    public static class StringsWrapper {
1984
1985        @XmlElement(name = "item")
1986        List<String> strings = new ArrayList<String>();
1987
1988        StringsWrapper() {
1989        }
1990
1991        public void setStrings(List<String> strings) {
1992            this.strings = strings;
1993        }
1994       
1995       
1996    }
1997}
Note: See TracBrowser for help on using the repository browser.