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.contact;
26 import java.util.HashMap;
28 import javax.ws.rs.Consumes;
29 import javax.ws.rs.DELETE;
30 import javax.ws.rs.GET;
31 import javax.ws.rs.POST;
32 import javax.ws.rs.PUT;
33 import javax.ws.rs.Path;
34 import javax.ws.rs.PathParam;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.WebApplicationException;
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.IQueryManager;
44 import org.collectionspace.services.client.PoxPayloadIn;
45 import org.collectionspace.services.client.PoxPayloadOut;
46 import org.collectionspace.services.common.StoredValuesUriTemplate;
47 import org.collectionspace.services.common.UriTemplateFactory;
48 import org.collectionspace.services.common.vocabulary.AuthorityResource;
49 import org.collectionspace.services.common.context.ServiceContext;
50 import org.collectionspace.services.common.document.DocumentFilter;
51 import org.collectionspace.services.common.document.DocumentHandler;
52 import org.collectionspace.services.contact.ContactResource;
53 import org.collectionspace.services.contact.ContactsCommon;
54 import org.collectionspace.services.contact.ContactJAXBSchema;
55 import org.collectionspace.services.contact.nuxeo.ContactDocumentModelHandler;
56 import org.collectionspace.services.jaxb.AbstractCommonList;
57 import org.jboss.resteasy.util.HttpResponseCodes;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
62 * The Class AuthorityResourceWithContacts.
64 @Consumes("application/xml")
65 @Produces("application/xml")
66 public abstract class AuthorityResourceWithContacts<AuthCommon, AuthItemHandler> extends //FIXME: REM - Why is this resource in this package instead of somewhere in 'common'?
67 AuthorityResource<AuthCommon, AuthItemHandler> {
69 private ContactResource contactResource = new ContactResource(); // Warning: ContactResource is a singleton.
70 final Logger logger = LoggerFactory.getLogger(AuthorityResourceWithContacts.class);
72 public AuthorityResourceWithContacts(
73 Class<AuthCommon> authCommonClass, Class<?> resourceClass,
74 String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
75 super(authCommonClass, resourceClass,
76 authorityCommonSchemaName, authorityItemCommonSchemaName);
79 public abstract String getItemServiceName();
81 public String getContactServiceName() {
82 return contactResource.getServiceName();
85 private DocumentHandler createContactDocumentHandler(
86 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
87 String inItem) throws Exception {
89 return createContactDocumentHandler(ctx, inAuthority, inItem, ui);
92 private DocumentHandler createContactDocumentHandler(
93 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String inAuthority,
94 String inItem, UriInfo ui) throws Exception {
95 ContactDocumentModelHandler docHandler = (ContactDocumentModelHandler) createDocumentHandler(
97 ctx.getCommonPartLabel(getContactServiceName()),
98 ContactsCommon.class);
99 docHandler.setInAuthority(inAuthority);
100 docHandler.setInItem(inItem);
101 docHandler.getServiceContext().setUriInfo(ui);
105 /*************************************************************************
106 * Contact parts - this is a sub-resource of the AuthorityItem
107 * @param parentspecifier either a CSID or one of the urn forms
108 * @param itemspecifier either a CSID or one of the urn forms
110 *************************************************************************/
112 @Path("{parentcsid}/items/{itemcsid}/contacts")
113 public Response createContact(
114 @PathParam("parentcsid") String parentspecifier,
115 @PathParam("itemcsid") String itemspecifier,
117 @Context UriInfo ui) {
119 PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
120 String parentcsid = lookupParentCSID(parentspecifier, "createContact(authority)", "CREATE_ITEM_CONTACT", null);
122 ServiceContext itemCtx = createServiceContext(getItemServiceName());
123 String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "createContact(item)", "CREATE_ITEM_CONTACT", itemCtx);
125 // Note that we have to create the service context and document
126 // handler for the Contact service, not the main service.
127 ServiceContext ctx = createServiceContext(getContactServiceName(), input);
128 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, ui);
129 String csid = getRepositoryClient(ctx).create(ctx, handler);
130 UriBuilder path = UriBuilder.fromResource(resourceClass);
131 path.path("" + parentcsid + "/items/" + itemcsid + "/contacts/" + csid);
132 Response response = Response.created(path.build()).build();
134 } catch (Exception e) {
136 "Create Contact failed; one of the requested specifiers for authority:"
137 + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
143 * Gets the contact list.
145 * @param parentspecifier either a CSID or one of the urn forms
146 * @param itemspecifier either a CSID or one of the urn forms
149 * @return the contact list
152 @Produces({"application/xml"})
153 @Path("{parentcsid}/items/{itemcsid}/contacts/")
154 public AbstractCommonList getContactList(
155 @PathParam("parentcsid") String parentspecifier,
156 @PathParam("itemcsid") String itemspecifier,
157 @Context UriInfo ui) {
158 AbstractCommonList contactObjectList = new AbstractCommonList();
160 String parentcsid = lookupParentCSID(parentspecifier, "getContactList(parent)", "GET_CONTACT_LIST", null);
162 ServiceContext itemCtx = createServiceContext(getItemServiceName());
163 String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "getContactList(item)", "GET_CONTACT_LIST", itemCtx);
165 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
166 ServiceContext ctx = createServiceContext(getContactServiceName(), queryParams);
167 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid, ui);
168 DocumentFilter myFilter = handler.getDocumentFilter(); //new DocumentFilter();
169 myFilter.appendWhereClause(ContactJAXBSchema.CONTACTS_COMMON + ":"
170 + ContactJAXBSchema.IN_AUTHORITY
171 + "='" + parentcsid + "'"
172 + IQueryManager.SEARCH_QUALIFIER_AND
173 + ContactJAXBSchema.CONTACTS_COMMON + ":"
174 + ContactJAXBSchema.IN_ITEM
175 + "='" + itemcsid + "'",
176 IQueryManager.SEARCH_QUALIFIER_AND); // "AND" this clause to any existing
177 getRepositoryClient(ctx).getFiltered(ctx, handler);
178 contactObjectList = (AbstractCommonList) handler.getCommonPartList();
179 } catch (Exception e) {
181 "Get ContactList failed; one of the requested specifiers for authority:"
182 + parentspecifier + ": and item:" + itemspecifier + ": was not found.",
185 return contactObjectList;
191 * @param parentspecifier either a CSID or one of the urn forms
192 * @param itemspecifier either a CSID or one of the urn forms
193 * @param csid the csid
195 * @return the contact
198 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
199 public String getContact(
200 @PathParam("parentcsid") String parentspecifier,
201 @PathParam("itemcsid") String itemspecifier,
202 @PathParam("csid") String csid) {
203 PoxPayloadOut result = null;
205 String parentcsid = lookupParentCSID(parentspecifier, "getContact(parent)", "GET_ITEM_CONTACT", null);
207 ServiceContext itemCtx = createServiceContext(getItemServiceName());
208 String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "getContact(item)", "GET_ITEM_CONTACT", itemCtx);
210 // Note that we have to create the service context and document handler for the Contact service, not the main service.
211 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getContactServiceName());
212 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
213 getRepositoryClient(ctx).get(ctx, csid, handler);
214 result = ctx.getOutput();
215 } catch (Exception e) {
216 throw bigReThrow(e, "Get failed, the requested Contact CSID:" + csid
217 + ": or one of the specifiers for authority:" + parentspecifier
218 + ": and item:" + itemspecifier + ": was not found.",
221 if (result == null) {
222 Response response = Response.status(Response.Status.NOT_FOUND).entity("Get failed, the requested Contact CSID:" + csid + ": was not found.").type("text/plain").build();
223 throw new WebApplicationException(response);
225 return result.toXML();
231 * @param parentspecifier either a CSID or one of the urn forms
232 * @param itemspecifier either a CSID or one of the urn forms
233 * @param csid the csid
235 * @return the multipart output
238 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
239 public String updateContact(
240 @PathParam("parentcsid") String parentspecifier,
241 @PathParam("itemcsid") String itemspecifier,
242 @PathParam("csid") String csid,
244 PoxPayloadOut result = null;
246 PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
247 String parentcsid = lookupParentCSID(parentspecifier, "updateContact(authority)", "UPDATE_CONTACT", null);
249 ServiceContext itemCtx = createServiceContext(getItemServiceName());
250 String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "updateContact(item)", "UPDATE_CONTACT", itemCtx);
252 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
253 // Note that we have to create the service context and document handler for the Contact service, not the main service.
254 ctx = createServiceContext(getContactServiceName(), theUpdate);
255 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
256 getRepositoryClient(ctx).update(ctx, csid, handler);
257 result = ctx.getOutput();
258 } catch (Exception e) {
259 throw bigReThrow(e, "Update failed, the requested Contact CSID:" + csid
260 + ": or one of the specifiers for authority:" + parentspecifier
261 + ": and item:" + itemspecifier + ": was not found.",
264 return result.toXML();
270 * @param parentspecifier either a CSID or one of the urn forms
271 * @param itemspecifier either a CSID or one of the urn forms
272 * @param csid the csid
274 * @return the response
277 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
278 public Response deleteContact(
279 @PathParam("parentcsid") String parentspecifier,
280 @PathParam("itemcsid") String itemspecifier,
281 @PathParam("csid") String csid) {
283 String parentcsid = lookupParentCSID(parentspecifier, "deleteContact(authority)", "DELETE_CONTACT", null);
285 ServiceContext itemCtx = createServiceContext(getItemServiceName());
286 String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "deleteContact(item)", "DELETE_CONTACT", itemCtx);
287 //NOTE: itemcsid is not used below. Leaving the above call in for possible side effects??? CSPACE-3175
289 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
290 // Note that we have to create the service context for the Contact service, not the main service.
291 ctx = createServiceContext(getContactServiceName());
292 DocumentHandler handler = createDocumentHandler(ctx);
293 getRepositoryClient(ctx).delete(ctx, csid, handler);
294 return Response.status(HttpResponseCodes.SC_OK).build();
295 } catch (Exception e) {
296 throw bigReThrow(e, "DELETE failed, the requested Contact CSID:" + csid
297 + ": or one of the specifiers for authority:" + parentspecifier
298 + ": and item:" + itemspecifier + ": was not found.", csid);
302 public String getContactDocType() {
303 // FIXME: Proof of concept placeholder
304 return getServiceName();
308 public Map<String,StoredValuesUriTemplate> getUriTemplateMap() {
309 // Get resource and item URI templates from superclass
310 Map<String,StoredValuesUriTemplate> uriTemplateMap = super.getUriTemplateMap();
311 // Add item URI template
312 String contactDocType = getContactDocType();
313 StoredValuesUriTemplate itemUriTemplate = getItemUriTemplate();
314 if (contactDocType == null) {
315 return uriTemplateMap; // return map as obtained from superclass
317 if (itemUriTemplate == null) {
318 return uriTemplateMap; // return map as obtained from superclass
320 uriTemplateMap.put(contactDocType, itemUriTemplate);
321 cacheUriTemplateMap(uriTemplateMap);
322 return uriTemplateMap;
325 private StoredValuesUriTemplate getItemUriTemplate() {
326 Map<String,String> storedValuesMap = new HashMap<String,String>();
327 storedValuesMap.put(UriTemplateFactory.SERVICENAME_VAR, getServiceName());
328 StoredValuesUriTemplate template =
329 UriTemplateFactory.getURITemplate(UriTemplateFactory.ITEM,