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.List;
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.QueryParam;
37 import javax.ws.rs.WebApplicationException;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.MultivaluedMap;
40 import javax.ws.rs.core.Response;
41 import javax.ws.rs.core.UriBuilder;
42 import javax.ws.rs.core.UriInfo;
44 import org.collectionspace.services.common.vocabulary.AuthorityResource;
45 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
46 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
47 import org.collectionspace.services.common.vocabulary.AuthorityResource.Specifier;
48 import org.collectionspace.services.common.vocabulary.AuthorityResource.SpecifierForm;
49 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
50 import org.collectionspace.services.common.AbstractMultiPartCollectionSpaceResourceImpl;
51 import org.collectionspace.services.common.ClientType;
52 import org.collectionspace.services.common.ServiceMain;
53 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
54 import org.collectionspace.services.common.authorityref.AuthorityRefList;
55 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
56 import org.collectionspace.services.common.context.ServiceBindingUtils;
57 import org.collectionspace.services.common.context.ServiceContext;
58 import org.collectionspace.services.common.document.BadRequestException;
59 import org.collectionspace.services.common.document.DocumentFilter;
60 import org.collectionspace.services.common.document.DocumentHandler;
61 import org.collectionspace.services.common.document.DocumentNotFoundException;
62 import org.collectionspace.services.common.document.DocumentWrapper;
63 import org.collectionspace.services.contact.ContactResource;
64 import org.collectionspace.services.contact.ContactsCommon;
65 import org.collectionspace.services.contact.ContactsCommonList;
66 import org.collectionspace.services.contact.ContactJAXBSchema;
67 import org.collectionspace.services.contact.nuxeo.ContactDocumentModelHandler;
68 import org.collectionspace.services.common.repository.RepositoryClient;
69 import org.collectionspace.services.common.security.UnauthorizedException;
70 import org.collectionspace.services.common.query.IQueryManager;
71 import org.collectionspace.services.common.query.QueryManager;
72 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
73 import org.jboss.remoting.samples.chat.exceptions.InvalidArgumentException;
74 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
75 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
76 import org.jboss.resteasy.util.HttpResponseCodes;
77 import org.nuxeo.ecm.core.api.DocumentModel;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
82 * The Class AuthorityResourceWithContacts.
84 @Path("/vocabularies")
85 @Consumes("multipart/mixed")
86 @Produces("multipart/mixed")
87 public abstract class AuthorityResourceWithContacts<AuthCommon, AuthCommonList, AuthItemCommonList, AuthItemHandler> extends
88 AuthorityResource<AuthCommon, AuthCommonList, AuthItemCommonList, AuthItemHandler> {
90 /** The contact resource. */
91 private ContactResource contactResource = new ContactResource();
93 final Logger logger = LoggerFactory.getLogger(AuthorityResourceWithContacts.class);
96 * Instantiates a new Authority resource.
98 public AuthorityResourceWithContacts(
99 Class<AuthCommon> authCommonClass, Class<?> resourceClass,
100 String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
101 super(authCommonClass, resourceClass,
102 authorityCommonSchemaName, authorityItemCommonSchemaName);
105 public abstract String getItemServiceName();
108 * Gets the contact service name.
110 * @return the contact service name
112 public String getContactServiceName() {
113 return contactResource.getServiceName();
117 * Creates the contact document handler.
120 * @param inAuthority the in authority
121 * @param inItem the in item
123 * @return the document handler
125 * @throws Exception the exception
127 private DocumentHandler createContactDocumentHandler(
128 ServiceContext<MultipartInput, MultipartOutput> ctx, String inAuthority,
129 String inItem) throws Exception {
131 ContactDocumentModelHandler docHandler = (ContactDocumentModelHandler)createDocumentHandler(
133 ctx.getCommonPartLabel(getContactServiceName()),
134 ContactsCommon.class);
135 docHandler.setInAuthority(inAuthority);
136 docHandler.setInItem(inItem);
141 /*************************************************************************
142 * Contact parts - this is a sub-resource of the AuthorityItem
143 * @param parentspecifier either a CSID or one of the urn forms
144 * @param itemspecifier either a CSID or one of the urn forms
147 *************************************************************************/
149 @Path("{parentcsid}/items/{itemcsid}/contacts")
150 public Response createContact(
151 @PathParam("parentcsid") String parentspecifier,
152 @PathParam("itemcsid") String itemspecifier,
153 MultipartInput input) {
155 Specifier parentSpec = getSpecifier(parentspecifier,
156 "createContact(authority)", "CREATE_ITEM_CONTACT");
157 Specifier itemSpec = getSpecifier(itemspecifier,
158 "createContact(item)", "CREATE_ITEM_CONTACT");
159 // Note that we have to create the service context for the Items, not the main service
160 ServiceContext<MultipartInput, MultipartOutput> ctx = null;
162 if(parentSpec.form==SpecifierForm.CSID) {
163 parentcsid = parentSpec.value;
165 String whereClause = buildWhereForAuthByName(parentSpec.value);
166 ctx = createServiceContext(getServiceName());
167 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
170 if(itemSpec.form==SpecifierForm.CSID) {
171 itemcsid = itemSpec.value;
173 String itemWhereClause =
174 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
175 ctx = createServiceContext(getItemServiceName());
176 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
178 // Note that we have to create the service context and document
179 // handler for the Contact service, not the main service.
180 ctx = createServiceContext(getContactServiceName(), input);
181 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
182 String csid = getRepositoryClient(ctx).create(ctx, handler);
183 UriBuilder path = UriBuilder.fromResource(resourceClass);
184 path.path("" + parentcsid + "/items/" + itemcsid + "/contacts/" + csid);
185 Response response = Response.created(path.build()).build();
187 } catch (BadRequestException bre) {
188 Response response = Response.status(
189 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
190 throw new WebApplicationException(response);
191 } catch (UnauthorizedException ue) {
192 Response response = Response.status(
193 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
194 throw new WebApplicationException(response);
195 } catch (DocumentNotFoundException dnfe) {
196 if (logger.isDebugEnabled()) {
197 logger.debug("createContact", dnfe);
199 Response response = Response.status(Response.Status.NOT_FOUND)
200 .entity("Create Contact failed; one of the requested specifiers for authority:"
201 +parentspecifier+": and item:"+itemspecifier+": was not found.")
202 .type("text/plain").build();
203 throw new WebApplicationException(response);
204 } catch (Exception e) {
205 if (logger.isDebugEnabled()) {
206 logger.debug("Caught exception in createContact", e);
208 Response response = Response.status(
209 Response.Status.INTERNAL_SERVER_ERROR)
210 .entity("Attempt to create Contact failed.")
211 .type("text/plain").build();
212 throw new WebApplicationException(response);
218 * Gets the contact list.
220 * @param parentspecifier either a CSID or one of the urn forms
221 * @param itemspecifier either a CSID or one of the urn forms
224 * @return the contact list
227 @Produces({"application/xml"})
228 @Path("{parentcsid}/items/{itemcsid}/contacts/")
229 public ContactsCommonList getContactList(
230 @PathParam("parentcsid") String parentspecifier,
231 @PathParam("itemcsid") String itemspecifier,
232 @Context UriInfo ui) {
233 ContactsCommonList contactObjectList = new ContactsCommonList();
235 Specifier parentSpec = getSpecifier(parentspecifier,
236 "getContactList(parent)", "GET_CONTACT_LIST");
237 Specifier itemSpec = getSpecifier(itemspecifier,
238 "getContactList(item)", "GET_CONTACT_LIST");
239 // Note that we have to create the service context for the Items, not the main service
240 ServiceContext<MultipartInput, MultipartOutput> ctx = null;
242 if(parentSpec.form==SpecifierForm.CSID) {
243 parentcsid = parentSpec.value;
245 String whereClause = buildWhereForAuthByName(parentSpec.value);
246 ctx = createServiceContext(getServiceName());
247 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
250 if(itemSpec.form==SpecifierForm.CSID) {
251 itemcsid = itemSpec.value;
253 String itemWhereClause =
254 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
255 ctx = createServiceContext(getItemServiceName());
256 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
258 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
259 ctx = createServiceContext(getContactServiceName(), queryParams);
260 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
261 DocumentFilter myFilter = handler.getDocumentFilter(); //new DocumentFilter();
262 myFilter.setWhereClause(ContactJAXBSchema.CONTACTS_COMMON + ":" +
263 ContactJAXBSchema.IN_AUTHORITY +
264 "='" + parentcsid + "'" +
265 IQueryManager.SEARCH_QUALIFIER_AND +
266 ContactJAXBSchema.CONTACTS_COMMON + ":" +
267 ContactJAXBSchema.IN_ITEM +
268 "='" + itemcsid + "'" );
269 getRepositoryClient(ctx).getFiltered(ctx, handler);
270 contactObjectList = (ContactsCommonList) handler.getCommonPartList();
271 } catch (UnauthorizedException ue) {
272 Response response = Response.status(
273 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
274 throw new WebApplicationException(response);
275 } catch (DocumentNotFoundException dnfe) {
276 if (logger.isDebugEnabled()) {
277 logger.debug("getContactList", dnfe);
279 Response response = Response.status(Response.Status.NOT_FOUND)
280 .entity("Get ContactList failed; one of the requested specifiers for authority:"
281 +parentspecifier+": and item:"+itemspecifier+": was not found.")
282 .type("text/plain").build();
283 throw new WebApplicationException(response);
284 } catch (Exception e) {
285 if (logger.isDebugEnabled()) {
286 logger.debug("Caught exception in getContactsList", e);
288 Response response = Response.status(
289 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
290 throw new WebApplicationException(response);
292 return contactObjectList;
298 * @param parentspecifier either a CSID or one of the urn forms
299 * @param itemspecifier either a CSID or one of the urn forms
300 * @param csid the csid
302 * @return the contact
305 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
306 public MultipartOutput getContact(
307 @PathParam("parentcsid") String parentspecifier,
308 @PathParam("itemcsid") String itemspecifier,
309 @PathParam("csid") String csid) {
310 MultipartOutput result = null;
312 Specifier parentSpec = getSpecifier(parentspecifier,
313 "getContact(parent)", "GET_ITEM_CONTACT");
314 Specifier itemSpec = getSpecifier(itemspecifier,
315 "getContact(item)", "GET_ITEM_CONTACT");
316 // Note that we have to create the service context for the Items, not the main service
317 ServiceContext<MultipartInput, MultipartOutput> ctx = null;
319 if(parentSpec.form==SpecifierForm.CSID) {
320 parentcsid = parentSpec.value;
322 String whereClause = buildWhereForAuthByName(parentSpec.value);
323 ctx = createServiceContext(getServiceName());
324 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
327 if(itemSpec.form==SpecifierForm.CSID) {
328 itemcsid = itemSpec.value;
330 String itemWhereClause =
331 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
332 ctx = createServiceContext(getItemServiceName());
333 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
335 // Note that we have to create the service context and document
336 // handler for the Contact service, not the main service.
337 ctx = createServiceContext(getContactServiceName());
338 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
339 getRepositoryClient(ctx).get(ctx, csid, handler);
340 result = (MultipartOutput) ctx.getOutput();
341 } catch (UnauthorizedException ue) {
342 Response response = Response.status(
343 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
344 throw new WebApplicationException(response);
345 } catch (DocumentNotFoundException dnfe) {
346 if (logger.isDebugEnabled()) {
347 logger.debug("getContact", dnfe);
349 Response response = Response.status(Response.Status.NOT_FOUND)
350 .entity("Get failed, the requested Contact CSID:" + csid +
351 ": or one of the specifiers for authority:"+parentspecifier+
352 ": and item:"+itemspecifier+": was not found.")
353 .type("text/plain").build();
354 throw new WebApplicationException(response);
355 } catch (Exception e) {
356 if (logger.isDebugEnabled()) {
357 logger.debug("getContact", e);
359 Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
360 .entity("Get contact failed")
361 .type("text/plain").build();
362 throw new WebApplicationException(response);
364 if (result == null) {
365 Response response = Response.status(Response.Status.NOT_FOUND)
366 .entity("Get failed, the requested Contact CSID:" + csid + ": was not found.")
367 .type("text/plain").build();
368 throw new WebApplicationException(response);
377 * @param parentspecifier either a CSID or one of the urn forms
378 * @param itemspecifier either a CSID or one of the urn forms
379 * @param csid the csid
380 * @param theUpdate the the update
382 * @return the multipart output
385 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
386 public MultipartOutput updateContact(
387 @PathParam("parentcsid") String parentspecifier,
388 @PathParam("itemcsid") String itemspecifier,
389 @PathParam("csid") String csid,
390 MultipartInput theUpdate) {
391 MultipartOutput result = null;
393 Specifier parentSpec = getSpecifier(parentspecifier,
394 "updateContact(authority)", "UPDATE_CONTACT");
395 Specifier itemSpec = getSpecifier(itemspecifier,
396 "updateContact(item)", "UPDATE_CONTACT");
397 // Note that we have to create the service context for the Items, not the main service
398 ServiceContext<MultipartInput, MultipartOutput> ctx = null;
400 if(parentSpec.form==SpecifierForm.CSID) {
401 parentcsid = parentSpec.value;
403 String whereClause = buildWhereForAuthByName(parentSpec.value);
404 ctx = createServiceContext(getServiceName());
405 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
408 if(itemSpec.form==SpecifierForm.CSID) {
409 itemcsid = itemSpec.value;
411 String itemWhereClause =
412 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
413 ctx = createServiceContext(getItemServiceName());
414 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
416 // Note that we have to create the service context and document
417 // handler for the Contact service, not the main service.
418 ctx = createServiceContext(getContactServiceName(), theUpdate);
419 DocumentHandler handler = createContactDocumentHandler(ctx, parentcsid, itemcsid);
420 getRepositoryClient(ctx).update(ctx, csid, handler);
421 result = (MultipartOutput) ctx.getOutput();
422 } catch (BadRequestException bre) {
423 Response response = Response.status(
424 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
425 throw new WebApplicationException(response);
426 } catch (UnauthorizedException ue) {
427 Response response = Response.status(
428 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
429 throw new WebApplicationException(response);
430 } catch (DocumentNotFoundException dnfe) {
431 if (logger.isDebugEnabled()) {
432 logger.debug("caught exception in updateContact", dnfe);
434 Response response = Response.status(Response.Status.NOT_FOUND)
435 .entity("Update failed, the requested Contact CSID:" + csid +
436 ": or one of the specifiers for authority:"+parentspecifier+
437 ": and item:"+itemspecifier+": was not found.")
438 .type("text/plain").build();
439 throw new WebApplicationException(response);
440 } catch (Exception e) {
441 Response response = Response.status(
442 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
443 throw new WebApplicationException(response);
451 * @param parentspecifier either a CSID or one of the urn forms
452 * @param itemspecifier either a CSID or one of the urn forms
453 * @param csid the csid
455 * @return the response
458 @Path("{parentcsid}/items/{itemcsid}/contacts/{csid}")
459 public Response deleteContact(
460 @PathParam("parentcsid") String parentspecifier,
461 @PathParam("itemcsid") String itemspecifier,
462 @PathParam("csid") String csid) {
464 Specifier parentSpec = getSpecifier(parentspecifier,
465 "deleteContact(authority)", "DELETE_CONTACT");
466 Specifier itemSpec = getSpecifier(itemspecifier,
467 "deleteContact(item)", "DELETE_CONTACT");
468 // Note that we have to create the service context for the Items, not the main service
469 ServiceContext<MultipartInput, MultipartOutput> ctx = null;
471 if(parentSpec.form==SpecifierForm.CSID) {
472 parentcsid = parentSpec.value;
474 String whereClause = buildWhereForAuthByName(parentSpec.value);
475 ctx = createServiceContext(getServiceName());
476 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
479 if(itemSpec.form==SpecifierForm.CSID) {
480 itemcsid = itemSpec.value;
482 String itemWhereClause =
483 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
484 ctx = createServiceContext(getItemServiceName());
485 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
487 // Note that we have to create the service context for the
488 // Contact service, not the main service.
489 ctx = createServiceContext(getContactServiceName());
490 getRepositoryClient(ctx).delete(ctx, csid);
491 return Response.status(HttpResponseCodes.SC_OK).build();
492 } catch (UnauthorizedException ue) {
493 Response response = Response.status(
494 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
495 throw new WebApplicationException(response);
496 } catch (DocumentNotFoundException dnfe) {
497 if (logger.isDebugEnabled()) {
498 logger.debug("Caught exception in deleteContact", dnfe);
500 Response response = Response.status(Response.Status.NOT_FOUND)
501 .entity("Delete failed, the requested Contact CSID:" + csid +
502 ": or one of the specifiers for authority:"+parentspecifier+
503 ": and item:"+itemspecifier+": was not found.")
504 .type("text/plain").build();
505 throw new WebApplicationException(response);
506 } catch (Exception e) {
507 Response response = Response.status(
508 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
509 throw new WebApplicationException(response);