source: VirtualCollectionRegistry/trunk/VirtualCollectionRegistry/src/main/java/eu/clarin/cmdi/virtualcollectionregistry/rest/VirtualCollectionResource.java @ 5514

Last change on this file since 5514 was 5514, checked in by Twan Goosen, 10 years ago

Cleaning up in VirtualCollectionResource?
Refs #604

  • Property svn:eol-style set to native
File size: 9.9 KB
Line 
1package eu.clarin.cmdi.virtualcollectionregistry.rest;
2
3import com.sun.jersey.api.core.InjectParam;
4import eu.clarin.cmdi.virtualcollectionregistry.VirtualCollectionRegistry;
5import eu.clarin.cmdi.virtualcollectionregistry.VirtualCollectionRegistryException;
6import eu.clarin.cmdi.virtualcollectionregistry.VirtualCollectionRegistryUsageException;
7import eu.clarin.cmdi.virtualcollectionregistry.model.VirtualCollection;
8import eu.clarin.cmdi.virtualcollectionregistry.service.VirtualCollectionMarshaller;
9import java.io.IOException;
10import java.io.InputStream;
11import java.net.URI;
12import java.security.Principal;
13import java.util.List;
14import javax.ws.rs.Consumes;
15import javax.ws.rs.DELETE;
16import javax.ws.rs.GET;
17import javax.ws.rs.POST;
18import javax.ws.rs.PUT;
19import javax.ws.rs.Path;
20import javax.ws.rs.PathParam;
21import javax.ws.rs.Produces;
22import javax.ws.rs.core.Context;
23import javax.ws.rs.core.HttpHeaders;
24import javax.ws.rs.core.MediaType;
25import javax.ws.rs.core.Request;
26import javax.ws.rs.core.Response;
27import javax.ws.rs.core.SecurityContext;
28import javax.ws.rs.core.UriBuilder;
29import javax.ws.rs.core.UriInfo;
30import javax.ws.rs.core.Variant;
31
32/**
33 * REST resource representing an individual virtual collection.
34 *
35 * This was designed to act as a managed subresource of
36 * {@link VirtualCollectionsResource}. The user of this class is responsible for
37 * calling {@link #setId(long) } before handing it over or doing anything else
38 * with it.
39 *
40 * @author twagoo
41 */
42public final class VirtualCollectionResource {
43
44    public static class MediaTypes {
45
46        public static final String CMDI = "application/x-cmdi+xml";
47        public static final MediaType CMDI_TYPE = new MediaType("application", "x-cmdi+xml");
48    }
49
50    @InjectParam
51    private VirtualCollectionRegistry registry;
52    @InjectParam
53    private VirtualCollectionMarshaller marshaller;
54    @Context
55    private SecurityContext security;
56    @Context
57    private HttpHeaders headers;
58    @Context
59    private UriInfo uriInfo;
60
61    private Long id;
62
63    /**
64     * Default constructor needed so that it can act as a managed subresource of
65     * {@link VirtualCollectionsResource}, remember to
66     * {@link #setId(long) set the id} after construction!
67     */
68    public VirtualCollectionResource() {
69    }
70
71    /**
72     * Sets the id for this resource; should be called exactly once per
73     * instance; <strong>mandatory call</strong>, not setting will lead to
74     * NullPointerExceptions
75     *
76     * @param id
77     */
78    public synchronized void setId(long id) {
79        if (this.id != null) {
80            throw new IllegalStateException("Id was already set for Virtual Collection resource! Resource is recycled (by Jersey)?");
81        }
82        this.id = id;
83    }
84
85    /**
86     * The virtual collection referenced by the URI will be retrieved
87     *
88     * @param request request object, to be injected by JAX-RS context
89     * @return A response containing a representation of the requested Virtual
90     * Collection. If the virtual collection is not found the appropriate HTTP
91     * status code is issued and an error message is returned.
92     * @throws VirtualCollectionRegistryException
93     */
94    @GET
95    @Produces({VirtualCollectionResource.MediaTypes.CMDI,
96        MediaType.TEXT_XML,
97        MediaType.APPLICATION_XML,
98        MediaType.APPLICATION_JSON})
99    public Response getVirtualCollection(@Context Request request)
100            throws VirtualCollectionRegistryException {
101        final VirtualCollection vc = registry.retrieveVirtualCollection(id);
102        // CMDI's should not be returned for non-public VC's, so check this...
103        if (!vc.isPublic() || (vc.getPersistentIdentifier() == null)) {
104            // exclude CMDI from the options and check if this is ok for request
105            final List<Variant> variants = Variant.mediaTypes(
106                    MediaType.TEXT_XML_TYPE, 
107                    MediaType.APPLICATION_XML_TYPE, 
108                    MediaType.APPLICATION_JSON_TYPE).add().build();
109            final Variant selectVariant = request.selectVariant(variants);
110            if (selectVariant != null) {
111                // alternative option is accepted, return this
112                return Response.ok(vc, selectVariant).build();
113            }
114            // else proceed anyway, will probably fail on writing CMDI body
115        }
116        return Response.ok(vc).build();
117    }
118
119    /**
120     * Redirects the client to the VC's details page in the Wicket frontend
121     *
122     * @return
123     * @throws VirtualCollectionRegistryException
124     */
125    @GET
126    @Produces({MediaType.TEXT_HTML})
127    public Response getVirtualCollectionDetailsRedirect()
128            throws VirtualCollectionRegistryException {
129        final UriBuilder pathBuilder = uriInfo.getBaseUriBuilder().path("../app/details/{arg1}");
130        final URI detailsUri = pathBuilder.build(id);
131        return Response.seeOther(detailsUri).build();
132    }
133
134    /**
135     * The virtual collection identified by the URI will be updated, actually
136     * replaced, with the representation of the virtual collection sent in the
137     * request body.
138     *
139     * @param input Depending on Content-Type header either a valid XML instance
140     * or the JSON representation of a virtual collection conforming to the
141     * above mentioned XML schema. The root element is expected to be
142     * "VirtualCollection"
143     * @return A response containing a {@link RestResponse}
144     * @throws VirtualCollectionRegistryException
145     */
146    @PUT
147    @Consumes({MediaType.TEXT_XML,
148        MediaType.APPLICATION_XML,
149        MediaType.APPLICATION_JSON})
150    @Produces({MediaType.TEXT_XML,
151        MediaType.APPLICATION_XML,
152        MediaType.APPLICATION_JSON})
153    public Response updateVirtualCollection(InputStream input) throws VirtualCollectionRegistryException {
154        Principal principal = security.getUserPrincipal();
155        if (principal == null) {
156            throw new NullPointerException("princial == null");
157        }
158        try {
159            VirtualCollectionMarshaller.Format format = RestUtils.getInputFormat(headers);
160            String encoding = RestUtils.getInputEncoding(headers);
161            VirtualCollection vc
162                    = marshaller.unmarshal(input, format, encoding);
163            registry.updateVirtualCollection(principal, id, vc);
164            RestResponse response = new RestResponse();
165            response.setIsSuccess(true);
166            response.setInfo("updated");
167            response.setId(id);
168            return Response.ok(response).build();
169        } catch (IOException e) {
170            throw new VirtualCollectionRegistryException("update", e);
171
172        }
173    }
174
175    /**
176     * The virtual collection referenced by the URI will be deleted.
177     *
178     * @return A response containing a {@link RestResponse}
179     * @throws VirtualCollectionRegistryException
180     */
181    @DELETE
182    @Produces({MediaType.TEXT_XML,
183        MediaType.APPLICATION_XML,
184        MediaType.APPLICATION_JSON})
185    public Response deleteVirtualCollection()
186            throws VirtualCollectionRegistryException {
187        Principal principal = security.getUserPrincipal();
188        if (principal == null) {
189            throw new NullPointerException("principal == null");
190        }
191        registry.deleteVirtualCollection(principal, id);
192        RestResponse response = new RestResponse();
193        response.setIsSuccess(true);
194        response.setInfo("deleted");
195        response.setId(id);
196        return Response.ok(response).build();
197    }
198
199    /**
200     * The publication state of the virtual collection referenced by the URI
201     *
202     * @return a response containing the {@link State} of the identified Virtual
203     * Collection
204     * @throws VirtualCollectionRegistryException
205     */
206    @GET
207    @Path("/state")
208    @Produces({MediaType.TEXT_XML,
209        MediaType.APPLICATION_XML,
210        MediaType.APPLICATION_JSON})
211    public Response getVirtualCollectionState()
212            throws VirtualCollectionRegistryException {
213        VirtualCollection.State state = registry.getVirtualCollectionState(id);
214        State result = null;
215        switch (state) {
216            case PUBLIC_PENDING:
217            /* FALL-THROUGH */
218            case PUBLIC:
219                result = State.PUBLIC;
220                break;
221            default:
222                result = State.PRIVATE;
223        } // switch
224        return Response.ok(result).build();
225    }
226
227    /**
228     * Updates the publication state of the virtual collection referenced by the
229     * URI
230     *
231     * @param id
232     * @param state
233     * @return a response containg a {@link RestResponse}
234     * @throws VirtualCollectionRegistryException
235     */
236    @POST
237    @Path("/state")
238    @Consumes({MediaType.TEXT_XML,
239        MediaType.APPLICATION_XML,
240        MediaType.APPLICATION_JSON})
241    @Produces({MediaType.TEXT_XML,
242        MediaType.APPLICATION_XML,
243        MediaType.APPLICATION_JSON})
244    public Response setVirtualCollectionState(@PathParam("id") long id,
245            State state)
246            throws VirtualCollectionRegistryException {
247        Principal principal = security.getUserPrincipal();
248        if (principal == null) {
249            throw new NullPointerException("principal == null");
250        }
251        if (state == null) {
252            throw new VirtualCollectionRegistryUsageException("invalid state");
253        }
254        VirtualCollection.State vc_state = null;
255        switch (state) {
256            case PUBLIC:
257                vc_state = VirtualCollection.State.PUBLIC_PENDING;
258                break;
259            case PRIVATE:
260                vc_state = VirtualCollection.State.PRIVATE;
261                break;
262            default:
263                throw new VirtualCollectionRegistryUsageException("invalid state");
264        }
265        registry.setVirtualCollectionState(principal, id, vc_state);
266        RestResponse response = new RestResponse();
267        response.setIsSuccess(true);
268        response.setInfo("updated state to '" + state + "'");
269        response.setId(id);
270        return Response.ok(response).build();
271    }
272}
Note: See TracBrowser for help on using the repository browser.