]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
9f0d93018992691a1065a729d8680a6fe1815a4f
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.common.vocabulary;
25
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.Context;
38 import javax.ws.rs.core.MultivaluedMap;
39 import javax.ws.rs.core.Request;
40 import javax.ws.rs.core.Response;
41 import javax.ws.rs.core.UriBuilder;
42 import javax.ws.rs.core.UriInfo;
43
44 import org.collectionspace.services.client.*;
45 import org.collectionspace.services.common.CSWebApplicationException;
46 import org.collectionspace.services.common.ResourceMap;
47 import org.collectionspace.services.common.ServiceMessages;
48 import org.collectionspace.services.common.StoredValuesUriTemplate;
49 import org.collectionspace.services.common.UriInfoWrapper;
50 import org.collectionspace.services.common.UriTemplateFactory;
51 import org.collectionspace.services.common.UriTemplateRegistryKey;
52 import org.collectionspace.services.common.vocabulary.AuthorityResource;
53 import org.collectionspace.services.common.context.JaxRsContext;
54 import org.collectionspace.services.common.context.RemoteServiceContext;
55 import org.collectionspace.services.common.context.ServiceContext;
56 import org.collectionspace.services.common.document.BadRequestException;
57 import org.collectionspace.services.common.document.DocumentException;
58 import org.collectionspace.services.common.document.DocumentFilter;
59 import org.collectionspace.services.common.document.DocumentHandler;
60 import org.collectionspace.services.common.document.DocumentNotFoundException;
61 import org.collectionspace.services.contact.ContactResource;
62 import org.collectionspace.services.contact.ContactsCommon;
63 import org.collectionspace.services.contact.ContactJAXBSchema;
64 import org.collectionspace.services.contact.nuxeo.ContactConstants;
65 import org.collectionspace.services.contact.nuxeo.ContactDocumentModelHandler;
66 import org.collectionspace.services.jaxb.AbstractCommonList;
67 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
68 import org.jboss.resteasy.util.HttpResponseCodes;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71 import org.w3c.dom.Element;
72
73 /**
74  * The Class AuthorityResourceWithContacts.
75  */
76 @Consumes("application/xml")
77 @Produces("application/xml")
78 public abstract class AuthorityResourceWithContacts<AuthCommon, AuthItemHandler> extends //FIXME: REM - Why is this resource in this package instead of somewhere in 'common'?
79         AuthorityResource<AuthCommon, AuthItemHandler> {
80
81     private ContactResource contactResource = new ContactResource(); // Warning: ContactResource is a singleton.
82     final Logger logger = LoggerFactory.getLogger(AuthorityResourceWithContacts.class);
83
84     public AuthorityResourceWithContacts(
85             Class<AuthCommon> authCommonClass, Class<?> resourceClass,
86             String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
87         super(authCommonClass, resourceClass,
88                 authorityCommonSchemaName, authorityItemCommonSchemaName);
89     }
90
91     public abstract String getItemServiceName();
92
93     public String getContactServiceName() {
94         return contactResource.getServiceName();
95     }
96     
97     private DocumentHandler createContactDocumentHandler(
98             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
99             String inItem) throws Exception {
100         UriInfo ui = null;
101         return createContactDocumentHandler(ctx, inAuthority, inItem, ui);
102     }
103
104     private DocumentHandler createContactDocumentHandler(
105             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
106             String inItem, UriInfo ui) throws Exception {
107         ContactDocumentModelHandler docHandler = (ContactDocumentModelHandler) createDocumentHandler(
108                 ctx,
109                 ctx.getCommonPartLabel(getContactServiceName()),
110                 ContactsCommon.class);
111         docHandler.setInAuthority(inAuthority);
112         docHandler.setInItem(inItem);
113         docHandler.getServiceContext().setUriInfo(ui);
114         return docHandler;
115     }
116
117     /*************************************************************************
118      * Contact parts - this is a sub-resource of the AuthorityItem
119      * @param parentspecifier either a CSID or one of the urn forms
120      * @param itemspecifier either a CSID or one of the urn forms
121      * @return contact
122      *************************************************************************/
123     @POST
124     @Path("{parentcsid}/items/{itemcsid}/contacts")
125     public Response createContact(
126             @PathParam("parentcsid") String parentspecifier,
127             @PathParam("itemcsid") String itemspecifier,
128             String xmlPayload,
129             @Context UriInfo ui) {
130         try {
131             PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
132             String parentcsid = lookupParentCSID(parentspecifier, "createContact(authority)", "CREATE_ITEM_CONTACT", null);
133
134             ServiceContext itemCtx = createServiceContext(getItemServiceName());
135             String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "createContact(item)", "CREATE_ITEM_CONTACT");
136
137             // Note that we have to create the service context and document
138             // handler for the Contact service, not the main service.
139             ServiceContext ctx = createServiceContext(getContactServiceName(), input);
140             DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, ui);
141             String csid = getRepositoryClient(ctx).create(ctx, handler);
142
143             UriBuilder path = UriBuilder.fromResource(resourceClass);
144             path.path("" + parentcsid + "/items/" + itemcsid + "/contacts/" + csid);
145             Response response = Response.created(path.build()).build();
146             return response;
147         } catch (Exception e) {
148             throw bigReThrow(e,
149                     "Create Contact failed; one of the requested specifiers for authority:"
150                     + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
151                     itemspecifier);
152         }
153     }
154     
155     public String createContact(ServiceContext existingCtx, String parentCsid, String itemCsid, PoxPayloadIn input,
156             UriInfo ui) throws Exception {
157         ServiceContext ctx = createServiceContext(getContactServiceName(), input);
158         if (existingCtx != null) {
159             Object repoSession = existingCtx.getCurrentRepositorySession();
160             if (repoSession != null) {
161                 ctx.setCurrentRepositorySession(repoSession);
162                 ctx.setProperties(existingCtx.getProperties());
163             }
164         }
165         
166         DocumentHandler handler = createContactDocumentHandler(ctx, parentCsid, itemCsid, ui);
167         String csid = getRepositoryClient(ctx).create(ctx, handler);
168
169         return csid;
170     }
171
172     /**
173      * Gets the contact list.
174      * 
175      * @param parentspecifier either a CSID or one of the urn forms
176      * @param itemspecifier either a CSID or one of the urn forms
177      * @param ui the ui
178      * 
179      * @return the contact list
180      */
181     @GET
182     @Produces({"application/xml"})
183     @Path("{parentcsid}/items/{itemcsid}/contacts/")
184     public AbstractCommonList getContactList(
185             @PathParam("parentcsid") String parentspecifier,
186             @PathParam("itemcsid") String itemspecifier,
187             @Context UriInfo uriInfo) {
188         AbstractCommonList contactObjectList = new AbstractCommonList();
189
190         contactObjectList = getContactList(null, parentspecifier, itemspecifier, uriInfo);
191         
192         return contactObjectList;
193     }
194     
195     public AbstractCommonList getContactList(
196             ServiceContext existingCtx,
197             String parentspecifier,
198             String itemspecifier,
199             UriInfo uriInfo) {
200         AbstractCommonList contactObjectList = new AbstractCommonList();
201
202         try {
203             ServiceContext ctx = createServiceContext(getContactServiceName(), uriInfo);
204             if (existingCtx != null) {
205                 Object repoSession = existingCtx.getCurrentRepositorySession();
206                 if (repoSession != null) {
207                     ctx.setCurrentRepositorySession(repoSession);
208                     ctx.setProperties(existingCtx.getProperties());
209                 }
210             }
211             
212             String parentcsid = lookupParentCSID(parentspecifier, "getContactList(parent)", "GET_CONTACT_LIST", null);
213             ServiceContext itemCtx = createServiceContext(getItemServiceName());
214             String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "getContactList(item)", "GET_CONTACT_LIST");
215
216             DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, uriInfo);
217             DocumentFilter myFilter = handler.getDocumentFilter(); //new DocumentFilter();
218             myFilter.appendWhereClause(ContactJAXBSchema.CONTACTS_COMMON + ":"
219                     + ContactJAXBSchema.IN_AUTHORITY
220                     + "='" + parentcsid + "'"
221                     + IQueryManager.SEARCH_QUALIFIER_AND
222                     + ContactJAXBSchema.CONTACTS_COMMON + ":"
223                     + ContactJAXBSchema.IN_ITEM
224                     + "='" + itemcsid + "'",
225                     IQueryManager.SEARCH_QUALIFIER_AND);  // "AND" this clause to any existing
226             getRepositoryClient(ctx).getFiltered(ctx, handler);
227             contactObjectList = (AbstractCommonList) handler.getCommonPartList();
228         } catch (Exception e) {
229             throw bigReThrow(e,
230                     "Get ContactList failed; one of the requested specifiers for authority:"
231                     + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
232                     itemspecifier);
233         }
234         
235         return contactObjectList;
236     }    
237
238     @GET
239     @Path("{csid}/items/{itemcsid}")
240     public byte[] getAuthorityItem(
241             @Context Request request,
242             @Context UriInfo uriInfo,
243             @Context ResourceMap resourceMap,            
244             @PathParam("csid") String parentIdentifier,
245             @PathParam("itemcsid") String itemIdentifier) {
246         uriInfo = new UriInfoWrapper(uriInfo);
247         PoxPayloadOut result = null;
248         try {
249             RemoteServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = 
250                     (RemoteServiceContext<PoxPayloadIn, PoxPayloadOut>) createServiceContext(getItemServiceName(), resourceMap, uriInfo);
251
252             JaxRsContext jaxRsContext = new JaxRsContext(request, uriInfo); // Needed for getting account permissions part of the resource
253             ctx.setJaxRsContext(jaxRsContext);
254             
255             result = getAuthorityItem(ctx, parentIdentifier, itemIdentifier);
256             
257             //
258             // Include the Contact subresource(s) as part of the payload.  The current UI supports a single contact resource only, so
259             // this code will return only the first contact resource
260             //
261             
262             //FIXME: Need to support paging
263             AbstractCommonList contactObjectList = getContactList(null, parentIdentifier, itemIdentifier, uriInfo);
264             if (contactObjectList.getTotalItems() > 1) {
265                         String errMsg = String.format("Can't get complete list of contacts for authority term '%s' in authority '%s'.", parentIdentifier, itemIdentifier);
266                         logger.warn(errMsg);
267             }
268             
269             if (contactObjectList.getTotalItems() > 1) {
270                         ListItem item = contactObjectList.getListItem().get(0);
271                         String csid = this.getCsid(item);
272                         PoxPayloadOut contactPayloadOut = getContactPayload(parentIdentifier, itemIdentifier, csid);
273                         PayloadOutputPart contactCommonPart = contactPayloadOut.getPart(ContactClient.PART_COMMON_LABEL);
274                         result.addPart(contactCommonPart);
275             }
276             
277         } catch (DocumentNotFoundException dnf) {
278             throw bigReThrow(dnf, ServiceMessages.resourceNotFoundMsg(itemIdentifier));
279         } catch (Exception e) {
280             throw bigReThrow(e, ServiceMessages.GET_FAILED);
281         }
282                 
283         return result.getBytes();
284     }
285     
286     /**
287      * Gets the contact.
288      * 
289      * @param parentspecifier either a CSID or one of the urn forms
290      * @param itemspecifier either a CSID or one of the urn forms
291      * @param csid the csid
292      * 
293      * @return the contact
294      */
295     @GET
296     @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
297     public String getContact(
298             @PathParam("parentcsid") String parentspecifier,
299             @PathParam("itemcsid") String itemspecifier,
300             @PathParam("csid") String csid) {
301         PoxPayloadOut result = null;
302         try {
303             result = getContactPayload(parentspecifier, itemspecifier, csid);
304         } catch (Exception e) {
305             throw bigReThrow(e, "Get failed, the requested Contact CSID:" + csid
306                     + ": or one of the specifiers for authority:" + parentspecifier
307                     + ": and item:" + itemspecifier + ": was not found.",
308                     csid);
309         }
310         if (result == null) {
311             Response response = Response.status(Response.Status.NOT_FOUND).entity("Get failed, the requested Contact CSID:" + csid + ": was not found.").type("text/plain").build();
312             throw new CSWebApplicationException(response);
313         }
314         return result.toXML();
315     }
316     
317     protected PoxPayloadOut getContactPayload(
318             String parentspecifier,
319             String itemspecifier,
320             String csid) throws Exception {
321         PoxPayloadOut result = null;
322
323         String parentcsid = lookupParentCSID(parentspecifier, "getContact(parent)", "GET_ITEM_CONTACT", null);
324
325         ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
326         String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "getContact(item)", "GET_ITEM_CONTACT");
327
328         // Note that we have to create the service context and document handler for the Contact service, not the main service.
329         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getContactServiceName());
330         DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
331         getRepositoryClient(ctx).get(ctx, csid, handler);
332         result = (PoxPayloadOut) ctx.getOutput();
333
334         return result;
335     }
336
337     /**
338      * Update contact.
339      * 
340      * @param parentspecifier either a CSID or one of the urn forms
341      * @param itemspecifier either a CSID or one of the urn forms
342      * @param csid the csid
343      *
344      * @return the multipart output
345      */
346     @PUT
347     @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
348     public String updateContact(
349             @PathParam("parentcsid") String parentspecifier,
350             @PathParam("itemcsid") String itemspecifier,
351             @PathParam("csid") String csid,
352             String xmlPayload) {
353         PoxPayloadOut result = null;
354         try {
355             PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
356             String parentcsid = lookupParentCSID(parentspecifier, "updateContact(authority)", "UPDATE_CONTACT", null);
357
358             ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
359             String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "updateContact(item)", "UPDATE_CONTACT");
360
361             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
362             // Note that we have to create the service context and document handler for the Contact service, not the main service.
363             ctx = createServiceContext(getContactServiceName(), theUpdate);
364             DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
365             getRepositoryClient(ctx).update(ctx, csid, handler);
366             result = (PoxPayloadOut) ctx.getOutput();
367         } catch (Exception e) {
368             throw bigReThrow(e, "Update failed, the requested Contact CSID:" + csid
369                     + ": or one of the specifiers for authority:" + parentspecifier
370                     + ": and item:" + itemspecifier + ": was not found.",
371                     csid);
372         }
373         
374         return result.toXML();
375     }
376     
377     public void updateContact(ServiceContext existingCtx, String parentCsid, String itemCsid, String csid,
378             PayloadInputPart theUpdate) throws Exception {
379         PoxPayloadOut result = null;
380         
381         String payloadTemplate = "<?xml version='1.0' encoding='UTF-8'?><document>%s</document>";
382         String xmlPayload = String.format(payloadTemplate, theUpdate.asXML());
383         PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
384         
385         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getContactServiceName(), input);
386         if (existingCtx != null) {
387             Object repoSession = existingCtx.getCurrentRepositorySession();
388             if (repoSession != null) {
389                 ctx.setCurrentRepositorySession(repoSession);
390                 ctx.setProperties(existingCtx.getProperties());
391             }
392         }
393         
394         DocumentHandler handler = createContactDocumentHandler(ctx, parentCsid, itemCsid);
395         getRepositoryClient(ctx).update(ctx, csid, handler);
396     }    
397
398     /**
399      * Delete contact.
400      * 
401      * @param parentspecifier either a CSID or one of the urn forms
402      * @param itemspecifier either a CSID or one of the urn forms
403      * @param csid the csid
404      * 
405      * @return the response
406      */
407     @DELETE
408     @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
409     public Response deleteContact(
410             @PathParam("parentcsid") String parentspecifier,
411             @PathParam("itemcsid") String itemspecifier,
412             @PathParam("csid") String csid) {
413         try {
414             String parentcsid = lookupParentCSID(parentspecifier, "deleteContact(authority)", "DELETE_CONTACT", null);
415
416             ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
417             String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "deleteContact(item)", "DELETE_CONTACT");
418             //NOTE: itemcsid is not used below.  Leaving the above call in for possible side effects???       CSPACE-3175
419
420             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
421             // Note that we have to create the service context for the Contact service, not the main service.
422             ctx = createServiceContext(getContactServiceName());
423             DocumentHandler handler = createDocumentHandler(ctx);
424             getRepositoryClient(ctx).delete(ctx, csid, handler);
425             return Response.status(HttpResponseCodes.SC_OK).build();
426         } catch (Exception e) {
427             throw bigReThrow(e, "DELETE failed, the requested Contact CSID:" + csid
428                     + ": or one of the specifiers for authority:" + parentspecifier
429                     + ": and item:" + itemspecifier + ": was not found.", csid);
430         }
431     }
432     
433     protected String getContactDocType() {
434         return ContactConstants.NUXEO_DOCTYPE;
435     }
436     
437     /**
438      * Returns a UriRegistry entry: a map of tenant-qualified URI templates
439      * for the current resource, for all tenants
440      * 
441      * @return a map of URI templates for the current resource, for all tenants
442      */
443     @Override
444     public Map<UriTemplateRegistryKey,StoredValuesUriTemplate> getUriRegistryEntries() {
445         Map<UriTemplateRegistryKey,StoredValuesUriTemplate> uriRegistryEntriesMap =
446                 super.getUriRegistryEntries();
447         List<String> tenantIds = getTenantBindingsReader().getTenantIds();
448         for (String tenantId : tenantIds) {
449                 uriRegistryEntriesMap.putAll(getUriRegistryEntries(tenantId, getContactDocType(), UriTemplateFactory.CONTACT));
450         }
451         return uriRegistryEntriesMap;
452     }
453
454 }