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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.common.vocabulary;
26 import java.util.List;
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.Response;
40 import javax.ws.rs.core.UriBuilder;
41 import javax.ws.rs.core.UriInfo;
43 import org.collectionspace.services.client.*;
44 import org.collectionspace.services.common.CSWebApplicationException;
45 import org.collectionspace.services.common.StoredValuesUriTemplate;
46 import org.collectionspace.services.common.UriTemplateFactory;
47 import org.collectionspace.services.common.UriTemplateRegistryKey;
48 import org.collectionspace.services.common.vocabulary.AuthorityResource;
49 import org.collectionspace.services.common.context.ServiceContext;
50 import org.collectionspace.services.common.document.BadRequestException;
51 import org.collectionspace.services.common.document.DocumentException;
52 import org.collectionspace.services.common.document.DocumentFilter;
53 import org.collectionspace.services.common.document.DocumentHandler;
54 import org.collectionspace.services.common.document.DocumentNotFoundException;
55 import org.collectionspace.services.contact.ContactResource;
56 import org.collectionspace.services.contact.ContactsCommon;
57 import org.collectionspace.services.contact.ContactJAXBSchema;
58 import org.collectionspace.services.contact.nuxeo.ContactConstants;
59 import org.collectionspace.services.contact.nuxeo.ContactDocumentModelHandler;
60 import org.collectionspace.services.jaxb.AbstractCommonList;
61 import org.jboss.resteasy.util.HttpResponseCodes;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 * The Class AuthorityResourceWithContacts.
68 @Consumes("application/xml")
69 @Produces("application/xml")
70 public abstract class AuthorityResourceWithContacts<AuthCommon, AuthItemHandler> extends //FIXME: REM - Why is this resource in this package instead of somewhere in 'common'?
71 AuthorityResource<AuthCommon, AuthItemHandler> {
73 private ContactResource contactResource = new ContactResource(); // Warning: ContactResource is a singleton.
74 final Logger logger = LoggerFactory.getLogger(AuthorityResourceWithContacts.class);
76 public AuthorityResourceWithContacts(
77 Class<AuthCommon> authCommonClass, Class<?> resourceClass,
78 String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
79 super(authCommonClass, resourceClass,
80 authorityCommonSchemaName, authorityItemCommonSchemaName);
83 public abstract String getItemServiceName();
85 public String getContactServiceName() {
86 return contactResource.getServiceName();
89 private DocumentHandler createContactDocumentHandler(
90 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
91 String inItem) throws Exception {
93 return createContactDocumentHandler(ctx, inAuthority, inItem, ui);
96 private DocumentHandler createContactDocumentHandler(
97 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
98 String inItem, UriInfo ui) throws Exception {
99 ContactDocumentModelHandler docHandler = (ContactDocumentModelHandler) createDocumentHandler(
101 ctx.getCommonPartLabel(getContactServiceName()),
102 ContactsCommon.class);
103 docHandler.setInAuthority(inAuthority);
104 docHandler.setInItem(inItem);
105 docHandler.getServiceContext().setUriInfo(ui);
109 /*************************************************************************
110 * Contact parts - this is a sub-resource of the AuthorityItem
111 * @param parentspecifier either a CSID or one of the urn forms
112 * @param itemspecifier either a CSID or one of the urn forms
114 *************************************************************************/
116 @Path("{parentcsid}/items/{itemcsid}/contacts")
117 public Response createContact(
118 @PathParam("parentcsid") String parentspecifier,
119 @PathParam("itemcsid") String itemspecifier,
121 @Context UriInfo ui) {
123 PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
124 String parentcsid = lookupParentCSID(parentspecifier, "createContact(authority)", "CREATE_ITEM_CONTACT", null);
126 ServiceContext itemCtx = createServiceContext(getItemServiceName());
127 String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "createContact(item)", "CREATE_ITEM_CONTACT");
129 // Note that we have to create the service context and document
130 // handler for the Contact service, not the main service.
131 ServiceContext ctx = createServiceContext(getContactServiceName(), input);
132 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, ui);
133 String csid = getRepositoryClient(ctx).create(ctx, handler);
135 UriBuilder path = UriBuilder.fromResource(resourceClass);
136 path.path("" + parentcsid + "/items/" + itemcsid + "/contacts/" + csid);
137 Response response = Response.created(path.build()).build();
139 } catch (Exception e) {
141 "Create Contact failed; one of the requested specifiers for authority:"
142 + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
147 public String createContact(ServiceContext existingCtx, String parentCsid, String itemCsid, PoxPayloadIn input,
148 UriInfo ui) throws Exception {
149 ServiceContext ctx = createServiceContext(getContactServiceName(), input);
150 if (existingCtx != null) {
151 Object repoSession = existingCtx.getCurrentRepositorySession();
152 if (repoSession != null) {
153 ctx.setCurrentRepositorySession(repoSession);
154 ctx.setProperties(existingCtx.getProperties());
158 DocumentHandler handler = createContactDocumentHandler(ctx, parentCsid, itemCsid, ui);
159 String csid = getRepositoryClient(ctx).create(ctx, handler);
165 * Gets the contact list.
167 * @param parentspecifier either a CSID or one of the urn forms
168 * @param itemspecifier either a CSID or one of the urn forms
171 * @return the contact list
174 @Produces({"application/xml"})
175 @Path("{parentcsid}/items/{itemcsid}/contacts/")
176 public AbstractCommonList getContactList(
177 @PathParam("parentcsid") String parentspecifier,
178 @PathParam("itemcsid") String itemspecifier,
179 @Context UriInfo uriInfo) {
180 AbstractCommonList contactObjectList = new AbstractCommonList();
182 contactObjectList = getContactList(null, parentspecifier, itemspecifier, uriInfo);
184 return contactObjectList;
187 public AbstractCommonList getContactList(
188 ServiceContext existingCtx,
189 String parentspecifier,
190 String itemspecifier,
192 AbstractCommonList contactObjectList = new AbstractCommonList();
195 ServiceContext ctx = createServiceContext(getContactServiceName(), uriInfo);
196 if (existingCtx != null) {
197 Object repoSession = existingCtx.getCurrentRepositorySession();
198 if (repoSession != null) {
199 ctx.setCurrentRepositorySession(repoSession);
200 ctx.setProperties(existingCtx.getProperties());
204 String parentcsid = lookupParentCSID(parentspecifier, "getContactList(parent)", "GET_CONTACT_LIST", null);
205 ServiceContext itemCtx = createServiceContext(getItemServiceName());
206 String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "getContactList(item)", "GET_CONTACT_LIST");
208 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, uriInfo);
209 DocumentFilter myFilter = handler.getDocumentFilter(); //new DocumentFilter();
210 myFilter.appendWhereClause(ContactJAXBSchema.CONTACTS_COMMON + ":"
211 + ContactJAXBSchema.IN_AUTHORITY
212 + "='" + parentcsid + "'"
213 + IQueryManager.SEARCH_QUALIFIER_AND
214 + ContactJAXBSchema.CONTACTS_COMMON + ":"
215 + ContactJAXBSchema.IN_ITEM
216 + "='" + itemcsid + "'",
217 IQueryManager.SEARCH_QUALIFIER_AND); // "AND" this clause to any existing
218 getRepositoryClient(ctx).getFiltered(ctx, handler);
219 contactObjectList = (AbstractCommonList) handler.getCommonPartList();
220 } catch (Exception e) {
222 "Get ContactList failed; one of the requested specifiers for authority:"
223 + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
227 return contactObjectList;
233 * @param parentspecifier either a CSID or one of the urn forms
234 * @param itemspecifier either a CSID or one of the urn forms
235 * @param csid the csid
237 * @return the contact
240 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
241 public String getContact(
242 @PathParam("parentcsid") String parentspecifier,
243 @PathParam("itemcsid") String itemspecifier,
244 @PathParam("csid") String csid) {
245 PoxPayloadOut result = null;
247 String parentcsid = lookupParentCSID(parentspecifier, "getContact(parent)", "GET_ITEM_CONTACT", null);
249 ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
250 String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "getContact(item)", "GET_ITEM_CONTACT");
252 // Note that we have to create the service context and document handler for the Contact service, not the main service.
253 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getContactServiceName());
254 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
255 getRepositoryClient(ctx).get(ctx, csid, handler);
256 result = (PoxPayloadOut) ctx.getOutput();
257 } catch (Exception e) {
258 throw bigReThrow(e, "Get failed, the requested Contact CSID:" + csid
259 + ": or one of the specifiers for authority:" + parentspecifier
260 + ": and item:" + itemspecifier + ": was not found.",
263 if (result == null) {
264 Response response = Response.status(Response.Status.NOT_FOUND).entity("Get failed, the requested Contact CSID:" + csid + ": was not found.").type("text/plain").build();
265 throw new CSWebApplicationException(response);
267 return result.toXML();
273 * @param parentspecifier either a CSID or one of the urn forms
274 * @param itemspecifier either a CSID or one of the urn forms
275 * @param csid the csid
277 * @return the multipart output
280 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
281 public String updateContact(
282 @PathParam("parentcsid") String parentspecifier,
283 @PathParam("itemcsid") String itemspecifier,
284 @PathParam("csid") String csid,
286 PoxPayloadOut result = null;
288 PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
289 String parentcsid = lookupParentCSID(parentspecifier, "updateContact(authority)", "UPDATE_CONTACT", null);
291 ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
292 String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "updateContact(item)", "UPDATE_CONTACT");
294 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
295 // Note that we have to create the service context and document handler for the Contact service, not the main service.
296 ctx = createServiceContext(getContactServiceName(), theUpdate);
297 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
298 getRepositoryClient(ctx).update(ctx, csid, handler);
299 result = (PoxPayloadOut) ctx.getOutput();
300 } catch (Exception e) {
301 throw bigReThrow(e, "Update failed, the requested Contact CSID:" + csid
302 + ": or one of the specifiers for authority:" + parentspecifier
303 + ": and item:" + itemspecifier + ": was not found.",
307 return result.toXML();
310 public void updateContact(ServiceContext existingCtx, String parentCsid, String itemCsid, String csid,
311 PayloadInputPart theUpdate) throws Exception {
312 PoxPayloadOut result = null;
314 String payloadTemplate = "<?xml version='1.0' encoding='UTF-8'?><document>%s</document>";
315 String xmlPayload = String.format(payloadTemplate, theUpdate.asXML());
316 PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
318 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getContactServiceName(), input);
319 if (existingCtx != null) {
320 Object repoSession = existingCtx.getCurrentRepositorySession();
321 if (repoSession != null) {
322 ctx.setCurrentRepositorySession(repoSession);
323 ctx.setProperties(existingCtx.getProperties());
327 DocumentHandler handler = createContactDocumentHandler(ctx, parentCsid, itemCsid);
328 getRepositoryClient(ctx).update(ctx, csid, handler);
334 * @param parentspecifier either a CSID or one of the urn forms
335 * @param itemspecifier either a CSID or one of the urn forms
336 * @param csid the csid
338 * @return the response
341 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
342 public Response deleteContact(
343 @PathParam("parentcsid") String parentspecifier,
344 @PathParam("itemcsid") String itemspecifier,
345 @PathParam("csid") String csid) {
347 String parentcsid = lookupParentCSID(parentspecifier, "deleteContact(authority)", "DELETE_CONTACT", null);
349 ServiceContext<PoxPayloadIn, PoxPayloadOut> itemCtx = createServiceContext(getItemServiceName());
350 String itemcsid = lookupItemCSID(itemCtx, itemspecifier, parentcsid, "deleteContact(item)", "DELETE_CONTACT");
351 //NOTE: itemcsid is not used below. Leaving the above call in for possible side effects??? CSPACE-3175
353 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
354 // Note that we have to create the service context for the Contact service, not the main service.
355 ctx = createServiceContext(getContactServiceName());
356 DocumentHandler handler = createDocumentHandler(ctx);
357 getRepositoryClient(ctx).delete(ctx, csid, handler);
358 return Response.status(HttpResponseCodes.SC_OK).build();
359 } catch (Exception e) {
360 throw bigReThrow(e, "DELETE failed, the requested Contact CSID:" + csid
361 + ": or one of the specifiers for authority:" + parentspecifier
362 + ": and item:" + itemspecifier + ": was not found.", csid);
366 protected String getContactDocType() {
367 return ContactConstants.NUXEO_DOCTYPE;
371 * Returns a UriRegistry entry: a map of tenant-qualified URI templates
372 * for the current resource, for all tenants
374 * @return a map of URI templates for the current resource, for all tenants
377 public Map<UriTemplateRegistryKey,StoredValuesUriTemplate> getUriRegistryEntries() {
378 Map<UriTemplateRegistryKey,StoredValuesUriTemplate> uriRegistryEntriesMap =
379 super.getUriRegistryEntries();
380 List<String> tenantIds = getTenantBindingsReader().getTenantIds();
381 for (String tenantId : tenantIds) {
382 uriRegistryEntriesMap.putAll(getUriRegistryEntries(tenantId, getContactDocType(), UriTemplateFactory.CONTACT));
384 return uriRegistryEntriesMap;