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.io.ByteArrayInputStream;
27 import java.io.InputStream;
28 import java.util.List;
30 import javax.management.relation.Relation;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.Encoded;
34 import javax.ws.rs.GET;
35 import javax.ws.rs.POST;
36 import javax.ws.rs.PUT;
37 import javax.ws.rs.Path;
38 import javax.ws.rs.PathParam;
39 import javax.ws.rs.Produces;
40 import javax.ws.rs.QueryParam;
41 import javax.ws.rs.WebApplicationException;
42 import javax.ws.rs.core.Context;
43 import javax.ws.rs.core.MultivaluedMap;
44 import javax.ws.rs.core.Request;
45 import javax.ws.rs.core.Response;
46 import javax.ws.rs.core.UriBuilder;
47 import javax.ws.rs.core.UriInfo;
49 import org.collectionspace.services.client.IQueryManager;
50 import org.collectionspace.services.client.PayloadInputPart;
51 import org.collectionspace.services.client.PayloadOutputPart;
52 import org.collectionspace.services.client.PoxPayloadIn;
53 import org.collectionspace.services.client.PoxPayloadOut;
54 import org.collectionspace.services.client.RelationClient;
55 import org.collectionspace.services.client.workflow.WorkflowClient;
56 import org.collectionspace.services.common.document.JaxbUtils;
57 import org.collectionspace.services.common.relation.IRelationsManager;
58 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
59 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
60 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityDocumentModelHandler;
61 import org.collectionspace.services.common.vocabulary.nuxeo.AuthorityItemDocumentModelHandler;
62 import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocumentModelHandler;
63 import org.collectionspace.services.common.AbstractMultiPartCollectionSpaceResourceImpl;
64 import org.collectionspace.services.common.ClientType;
65 import org.collectionspace.services.common.ServiceMain;
66 import org.collectionspace.services.common.ServiceMessages;
67 import org.collectionspace.services.common.api.RefName;
68 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
69 import org.collectionspace.services.common.authorityref.AuthorityRefList;
70 import org.collectionspace.services.common.context.JaxRsContext;
71 import org.collectionspace.services.common.context.MultipartServiceContext;
72 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
73 import org.collectionspace.services.common.context.RemoteServiceContext;
74 import org.collectionspace.services.common.context.ServiceBindingUtils;
75 import org.collectionspace.services.common.context.ServiceContext;
76 import org.collectionspace.services.common.document.BadRequestException;
77 import org.collectionspace.services.common.document.DocumentException;
78 import org.collectionspace.services.common.document.DocumentFilter;
79 import org.collectionspace.services.common.document.DocumentHandler;
80 import org.collectionspace.services.common.document.DocumentNotFoundException;
81 import org.collectionspace.services.common.document.DocumentWrapper;
82 import org.collectionspace.services.common.repository.RepositoryClient;
83 import org.collectionspace.services.common.security.UnauthorizedException;
84 import org.collectionspace.services.common.query.QueryManager;
85 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
86 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
87 import org.collectionspace.services.relation.RelationResource;
88 import org.collectionspace.services.relation.RelationsCommon;
89 import org.collectionspace.services.relation.RelationsCommonList;
90 import org.collectionspace.services.relation.RelationshipType;
91 import org.jboss.resteasy.util.HttpResponseCodes;
92 import org.nuxeo.ecm.core.api.DocumentModel;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
97 * The Class AuthorityResource.
99 @Consumes("application/xml")
100 @Produces("application/xml")
101 public abstract class AuthorityResource<AuthCommon, AuthCommonList, AuthItemCommonList, AuthItemHandler> extends
102 AbstractMultiPartCollectionSpaceResourceImpl {
104 protected Class<AuthCommon> authCommonClass;
105 protected Class<?> resourceClass;
106 protected String authorityCommonSchemaName;
107 protected String authorityItemCommonSchemaName;
109 final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
111 final static String URN_PREFIX = "urn:cspace:";
112 final static int URN_PREFIX_LEN = URN_PREFIX.length();
113 final static String URN_PREFIX_NAME = "name(";
114 final static int URN_NAME_PREFIX_LEN = URN_PREFIX_LEN + URN_PREFIX_NAME.length();
115 final static String URN_PREFIX_ID = "id(";
116 final static int URN_ID_PREFIX_LEN = URN_PREFIX_LEN + URN_PREFIX_ID.length();
117 final static String FETCH_SHORT_ID = "_fetch_";
119 final Logger logger = LoggerFactory.getLogger(AuthorityResource.class);
121 public enum SpecifierForm { CSID, URN_NAME };
123 public class Specifier {
124 public SpecifierForm form;
126 Specifier(SpecifierForm form, String value) {
132 protected Specifier getSpecifier(String specifierIn, String method, String op) throws WebApplicationException {
133 if (logger.isDebugEnabled()) {
134 logger.debug("getSpecifier called by: "+method+" with specifier: "+specifierIn);
136 if (specifierIn != null) {
137 if(!specifierIn.startsWith(URN_PREFIX)) {
138 // We'll assume it is a CSID and complain if it does not match
139 return new Specifier(SpecifierForm.CSID, specifierIn);
141 if(specifierIn.startsWith(URN_PREFIX_NAME, URN_PREFIX_LEN)) {
142 int closeParen = specifierIn.indexOf(')', URN_NAME_PREFIX_LEN);
144 return new Specifier(SpecifierForm.URN_NAME,
145 specifierIn.substring(URN_NAME_PREFIX_LEN, closeParen));
147 } else if(specifierIn.startsWith(URN_PREFIX_ID, URN_PREFIX_LEN)) {
148 int closeParen = specifierIn.indexOf(')', URN_ID_PREFIX_LEN);
150 return new Specifier(SpecifierForm.CSID,
151 specifierIn.substring(URN_ID_PREFIX_LEN, closeParen));
156 logger.error(method+": bad or missing specifier!");
157 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
158 op+" failed on bad or missing Authority specifier").type(
159 "text/plain").build();
160 throw new WebApplicationException(response);
164 * Instantiates a new Authority resource.
166 public AuthorityResource(Class<AuthCommon> authCommonClass, Class<?> resourceClass,
167 String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
168 this.authCommonClass = authCommonClass;
169 this.resourceClass = resourceClass;
170 this.authorityCommonSchemaName = authorityCommonSchemaName;
171 this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
174 public abstract String getItemServiceName();
177 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
180 protected String getVersionString() {
181 /** The last change revision. */
182 final String lastChangeRevision = "$LastChangedRevision: 2617 $";
183 return lastChangeRevision;
187 * @see org.collectionspace.services.common.CollectionSpaceResource#getCommonPartClass()
190 public Class<AuthCommon> getCommonPartClass() {
191 return authCommonClass;
195 * Creates the item document handler.
198 * @param inAuthority the in vocabulary
200 * @return the document handler
202 * @throws Exception the exception
204 protected DocumentHandler createItemDocumentHandler(
205 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
206 String inAuthority, String parentShortIdentifier)
208 String authorityRefNameBase;
209 AuthorityItemDocumentModelHandler<?,?> docHandler;
211 if(parentShortIdentifier==null) {
212 authorityRefNameBase = null;
214 ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx =
215 createServiceContext(getServiceName());
216 if(parentShortIdentifier.equals(FETCH_SHORT_ID)) {
217 // Get from parent document
218 parentShortIdentifier = getAuthShortIdentifier(parentCtx, inAuthority);
220 authorityRefNameBase = buildAuthorityRefNameBase(parentCtx, parentShortIdentifier);
223 docHandler = (AuthorityItemDocumentModelHandler<?,?>)createDocumentHandler(ctx,
224 ctx.getCommonPartLabel(getItemServiceName()),
226 docHandler.setInAuthority(inAuthority);
227 docHandler.setAuthorityRefNameBase(authorityRefNameBase);
229 return (DocumentHandler)docHandler;
232 public String getAuthShortIdentifier(
233 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String authCSID)
234 throws DocumentNotFoundException, DocumentException {
235 String shortIdentifier = null;
237 DocumentWrapper<DocumentModel> wrapDoc = getRepositoryClient(ctx).getDocFromCsid(ctx, authCSID);
238 AuthorityDocumentModelHandler<?,?> handler =
239 (AuthorityDocumentModelHandler<?,?>)createDocumentHandler(ctx);
240 shortIdentifier = handler.getShortIdentifier(wrapDoc, authorityCommonSchemaName);
241 } catch (DocumentNotFoundException dnfe) {
243 } catch (IllegalArgumentException iae) {
245 } catch (DocumentException de) {
247 } catch (Exception e) {
248 if (logger.isDebugEnabled()) {
249 logger.debug("Caught exception ", e);
251 throw new DocumentException(e);
253 return shortIdentifier;
257 protected String buildAuthorityRefNameBase(
258 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String shortIdentifier) {
259 RefName.Authority authority = RefName.buildAuthority(ctx.getTenantName(),
260 ctx.getServiceName(), shortIdentifier, null);
261 return authority.toString();
267 * Creates the authority.
269 * @return the response
272 public Response createAuthority(String xmlPayload) {
274 PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
275 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);
276 DocumentHandler handler = createDocumentHandler(ctx);
277 String csid = getRepositoryClient(ctx).create(ctx, handler);
278 UriBuilder path = UriBuilder.fromResource(resourceClass);
279 path.path("" + csid);
280 Response response = Response.created(path.build()).build();
282 } catch (Exception e) {
283 throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
287 protected String buildWhereForAuthByName(String name) {
288 return authorityCommonSchemaName+
289 ":"+AuthorityJAXBSchema.SHORT_IDENTIFIER+
293 protected String buildWhereForAuthItemByName(String name, String parentcsid) {
295 authorityItemCommonSchemaName+
296 ":"+AuthorityItemJAXBSchema.SHORT_IDENTIFIER+
298 + authorityItemCommonSchemaName + ":"
299 + AuthorityItemJAXBSchema.IN_AUTHORITY + "="
300 + "'" + parentcsid + "'";
304 * Gets the authority.
306 * @param specifier either a CSID or one of the urn forms
308 * @return the authority
312 public byte[] getAuthority(
314 @PathParam("csid") String specifier) {
315 PoxPayloadOut result = null;
317 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
318 Specifier spec = getSpecifier(specifier, "getAuthority", "GET");
319 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(queryParams);
320 DocumentHandler handler = createDocumentHandler(ctx);
321 if(spec.form == SpecifierForm.CSID) {
322 if (logger.isDebugEnabled()) {
323 logger.debug("getAuthority with csid=" + spec.value);
325 getRepositoryClient(ctx).get(ctx, spec.value, handler);
327 String whereClause = buildWhereForAuthByName(spec.value);
328 DocumentFilter myFilter = new DocumentFilter(whereClause, 0, 1);
329 handler.setDocumentFilter(myFilter);
330 getRepositoryClient(ctx).get(ctx, handler);
332 result = ctx.getOutput();
333 } catch (UnauthorizedException ue) {
334 Response response = Response.status(
335 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
336 throw new WebApplicationException(response);
337 } catch (DocumentNotFoundException dnfe) {
338 if (logger.isDebugEnabled()) {
339 logger.debug("getAuthority", dnfe);
341 Response response = Response.status(Response.Status.NOT_FOUND).entity(
342 "Get failed on Authority specifier=" + specifier).type(
343 "text/plain").build();
344 throw new WebApplicationException(response);
345 } catch (Exception e) {
346 if (logger.isDebugEnabled()) {
347 logger.debug("getAuthority", e);
349 Response response = Response.status(
350 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
351 throw new WebApplicationException(response);
354 if (result == null) {
355 Response response = Response.status(Response.Status.NOT_FOUND).entity(
356 "Get failed, the requested Authority specifier:" + specifier + ": was not found.").type(
357 "text/plain").build();
358 throw new WebApplicationException(response);
361 return result.getBytes();
365 * Finds and populates the authority list.
369 * @return the authority list
372 @Produces("application/xml")
373 public AuthCommonList getAuthorityList(@Context UriInfo ui) {
375 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
376 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(queryParams);
377 DocumentHandler handler = createDocumentHandler(ctx);
378 DocumentFilter myFilter = handler.getDocumentFilter();
379 String nameQ = queryParams.getFirst("refName");
381 myFilter.setWhereClause(authorityCommonSchemaName+":refName='" + nameQ + "'");
383 getRepositoryClient(ctx).getFiltered(ctx, handler);
384 return (AuthCommonList) handler.getCommonPartList();
385 } catch (UnauthorizedException ue) {
386 Response response = Response.status(
387 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
388 throw new WebApplicationException(response);
389 } catch (Exception e) {
390 if (logger.isDebugEnabled()) {
391 logger.debug("Caught exception in getAuthorityList", e);
393 Response response = Response.status(
394 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
395 throw new WebApplicationException(response);
402 * @param specifier the csid or id
404 * @return the multipart output
408 public byte[] updateAuthority(
409 @PathParam("csid") String specifier,
411 PoxPayloadOut result = null;
413 PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
414 Specifier spec = getSpecifier(specifier, "updateAuthority", "UPDATE");
415 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(theUpdate);
416 DocumentHandler handler = createDocumentHandler(ctx);
418 if(spec.form==SpecifierForm.CSID) {
421 String whereClause = buildWhereForAuthByName(spec.value);
422 csid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
424 getRepositoryClient(ctx).update(ctx, csid, handler);
425 result = ctx.getOutput();
426 } catch (Exception e) {
427 throw bigReThrow(e, ServiceMessages.UPDATE_FAILED);
429 return result.getBytes();
435 * @param csid the csid
437 * @return the response
441 public Response deleteAuthority(@PathParam("csid") String csid) {
443 if (logger.isDebugEnabled()) {
444 logger.debug("deleteAuthority with csid=" + csid);
446 if (csid == null || "".equals(csid)) {
447 logger.error("deleteAuthority: missing csid!");
448 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
449 "delete failed on Authority csid=" + csid).type(
450 "text/plain").build();
451 throw new WebApplicationException(response);
454 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
455 getRepositoryClient(ctx).delete(ctx, csid);
456 return Response.status(HttpResponseCodes.SC_OK).build();
457 } catch (UnauthorizedException ue) {
458 Response response = Response.status(
459 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
460 throw new WebApplicationException(response);
461 } catch (DocumentNotFoundException dnfe) {
462 if (logger.isDebugEnabled()) {
463 logger.debug("caught exception in deleteAuthority", dnfe);
465 Response response = Response.status(Response.Status.NOT_FOUND).entity(
466 "Delete failed on Authority csid=" + csid).type(
467 "text/plain").build();
468 throw new WebApplicationException(response);
469 } catch (Exception e) {
470 Response response = Response.status(
471 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
472 throw new WebApplicationException(response);
477 /*************************************************************************
478 * Create an AuthorityItem - this is a sub-resource of Authority
479 * @param specifier either a CSID or one of the urn forms
480 * @return Authority item response
481 *************************************************************************/
483 @Path("{csid}/items")
484 public Response createAuthorityItem(@Context UriInfo ui, @PathParam("csid") String specifier, String xmlPayload) {
487 PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
488 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
489 Specifier spec = getSpecifier(specifier, "createAuthorityItem", "CREATE_ITEM");
491 String parentShortIdentifier;
492 if(spec.form==SpecifierForm.CSID) {
493 parentcsid = spec.value;
494 // Uncomment when app layer is ready to integrate
495 // parentShortIdentifier = FETCH_SHORT_ID;
496 parentShortIdentifier = null;
498 parentShortIdentifier = spec.value;
499 String whereClause = buildWhereForAuthByName(spec.value);
500 ctx = createServiceContext(getServiceName());
501 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
503 ctx = createServiceContext(getItemServiceName(), input);
504 ctx.setUriInfo(ui); //Laramie
505 // Note: must have the parentShortId, to do the create.
506 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid, parentShortIdentifier);
507 String itemcsid = getRepositoryClient(ctx).create(ctx, handler);
508 UriBuilder path = UriBuilder.fromResource(resourceClass);
509 path.path(parentcsid + "/items/" + itemcsid);
510 Response response = Response.created(path.build()).build();
512 //updateRelations(ui, itemcsid, input);
515 } catch (Exception e) {
516 //TODO: if e is 400 type error, then call throwWebAppException(400,...);
517 throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
522 @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH)
523 public byte[] getItemWorkflow(
524 @PathParam("csid") String csid,
525 @PathParam("itemcsid") String itemcsid) {
526 PoxPayloadOut result = null;
529 ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext(getItemServiceName());
530 String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
532 MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME);
533 WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);
534 ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
535 getRepositoryClient(ctx).get(ctx, itemcsid, handler);
536 result = ctx.getOutput();
537 } catch (Exception e) {
538 throw bigReThrow(e, ServiceMessages.READ_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
540 return result.getBytes();
544 @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH)
545 public byte[] updateWorkflow(
546 @PathParam("csid") String csid,
547 @PathParam("itemcsid") String itemcsid,
549 PoxPayloadOut result = null;
551 ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx = createServiceContext(getItemServiceName());
552 String parentWorkspaceName = parentCtx.getRepositoryWorkspaceName();
554 PoxPayloadIn workflowUpdate = new PoxPayloadIn(xmlPayload);
555 MultipartServiceContext ctx = (MultipartServiceContext) createServiceContext(WorkflowClient.SERVICE_NAME, workflowUpdate);
556 WorkflowDocumentModelHandler handler = createWorkflowDocumentHandler(ctx);
557 ctx.setRespositoryWorkspaceName(parentWorkspaceName); //find the document in the parent's workspace
558 getRepositoryClient(ctx).update(ctx, itemcsid, handler);
559 result = ctx.getOutput();
560 } catch (Exception e) {
561 throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, csid);
563 return result.getBytes();
568 * Gets the authority item.
570 * @param parentspecifier either a CSID or one of the urn forms
571 * @param itemspecifier either a CSID or one of the urn forms
573 * @return the authority item
576 @Path("{csid}/items/{itemcsid}")
577 public byte[] getAuthorityItem(
578 @Context Request request,
580 @PathParam("csid") String parentspecifier,
581 @PathParam("itemcsid") String itemspecifier) {
582 PoxPayloadOut result = null;
584 JaxRsContext jaxRsContext = new JaxRsContext(request, ui);
585 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
587 Specifier parentSpec = getSpecifier(parentspecifier, "getAuthorityItem(parent)", "GET_ITEM");
588 Specifier itemSpec = getSpecifier(itemspecifier, "getAuthorityItem(item)", "GET_ITEM");
589 // Note that we have to create the service context for the Items, not the main service
590 RemoteServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
592 if(parentSpec.form==SpecifierForm.CSID) {
593 parentcsid = parentSpec.value;
595 String whereClause = buildWhereForAuthByName(parentSpec.value);
596 ctx = (RemoteServiceContext)createServiceContext(getServiceName(), queryParams);
597 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item?
599 ctx = (RemoteServiceContext)createServiceContext(getItemServiceName(), queryParams);
600 ctx.setJaxRsContext(jaxRsContext);
602 ctx.setUriInfo(ui); //ARG! must pass this or subsequent calls will not have a ui.
604 // We omit the parentShortId, only needed when doing a create...
605 DocumentHandler handler = createItemDocumentHandler(ctx,
607 if(itemSpec.form==SpecifierForm.CSID) {
608 getRepositoryClient(ctx).get(ctx, itemSpec.value, handler);
610 String itemWhereClause =
611 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
612 DocumentFilter myFilter = new DocumentFilter(itemWhereClause, 0, 1);
613 handler.setDocumentFilter(myFilter);
614 getRepositoryClient(ctx).get(ctx, handler);
616 // TODO should we assert that the item is in the passed vocab?
617 result = ctx.getOutput();
618 } catch (Exception e) {
619 throw bigReThrow(e, ServiceMessages.GET_FAILED);
621 if (result == null) {
622 Response response = Response.status(Response.Status.NOT_FOUND).entity(
623 "Get failed, the requested AuthorityItem specifier:" + itemspecifier + ": was not found.").type(
624 "text/plain").build();
625 throw new WebApplicationException(response);
627 return result.getBytes();
632 * Gets the authorityItem list for the specified authority
633 * If partialPerm is specified, keywords will be ignored.
635 * @param specifier either a CSID or one of the urn forms
636 * @param partialTerm if non-null, matches partial terms
637 * @param keywords if non-null, matches terms in the keyword index for items
638 * @param ui passed to include additional parameters, like pagination controls
640 * @return the authorityItem list
643 @Path("{csid}/items")
644 @Produces("application/xml")
645 public AuthItemCommonList getAuthorityItemList(
646 @PathParam("csid") String specifier,
647 @QueryParam(IQueryManager.SEARCH_TYPE_PARTIALTERM) String partialTerm,
648 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords,
649 @Context UriInfo ui) {
651 Specifier spec = getSpecifier(specifier, "getAuthorityItemList", "LIST");
652 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
653 // Note that docType defaults to the ServiceName, so we're fine with that.
654 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
656 if(spec.form==SpecifierForm.CSID) {
657 parentcsid = spec.value;
659 String whereClause = buildWhereForAuthByName(spec.value);
660 ctx = createServiceContext(getServiceName(), queryParams);
661 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
663 ctx = createServiceContext(getItemServiceName(), queryParams);
664 // We omit the parentShortId, only needed when doing a create...
665 DocumentHandler handler = createItemDocumentHandler(ctx,
667 DocumentFilter myFilter = handler.getDocumentFilter();
668 myFilter.appendWhereClause(authorityItemCommonSchemaName + ":" +
669 AuthorityItemJAXBSchema.IN_AUTHORITY + "=" +
670 "'" + parentcsid + "'",
671 IQueryManager.SEARCH_QUALIFIER_AND);
673 // AND vocabularyitems_common:displayName LIKE '%partialTerm%'
674 if (partialTerm != null && !partialTerm.isEmpty()) {
675 String ptClause = QueryManager.createWhereClauseForPartialMatch(
676 authorityItemCommonSchemaName + ":"
677 + AuthorityItemJAXBSchema.DISPLAY_NAME, partialTerm );
678 myFilter.appendWhereClause(ptClause, IQueryManager.SEARCH_QUALIFIER_AND);
679 } else if (keywords != null) {
680 String kwdClause = QueryManager.createWhereClauseFromKeywords(keywords);
681 myFilter.appendWhereClause(kwdClause, IQueryManager.SEARCH_QUALIFIER_AND);
683 if (logger.isDebugEnabled()) {
684 logger.debug("getAuthorityItemList filtered WHERE clause: "
685 + myFilter.getWhereClause());
687 getRepositoryClient(ctx).getFiltered(ctx, handler);
688 return (AuthItemCommonList) handler.getCommonPartList();
689 } catch (Exception e) {
690 throw bigReThrow(e, ServiceMessages.LIST_FAILED);
695 * Gets the entities referencing this Authority item instance. The service type
696 * can be passed as a query param "type", and must match a configured type
697 * for the service bindings. If not set, the type defaults to
698 * ServiceBindingUtils.SERVICE_TYPE_PROCEDURE.
700 * @param parentspecifier either a CSID or one of the urn forms
701 * @param itemspecifier either a CSID or one of the urn forms
704 * @return the info for the referencing objects
707 @Path("{csid}/items/{itemcsid}/refObjs")
708 @Produces("application/xml")
709 public AuthorityRefDocList getReferencingObjects(
710 @PathParam("csid") String parentspecifier,
711 @PathParam("itemcsid") String itemspecifier,
712 @Context UriInfo ui) {
713 AuthorityRefDocList authRefDocList = null;
715 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
716 Specifier parentSpec = getSpecifier(parentspecifier,
717 "getReferencingObjects(parent)", "GET_ITEM_REF_OBJS");
718 Specifier itemSpec = getSpecifier(itemspecifier,
719 "getReferencingObjects(item)", "GET_ITEM_REF_OBJS");
720 // Note that we have to create the service context for the Items, not the main service
721 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
723 if(parentSpec.form==SpecifierForm.CSID) {
724 parentcsid = parentSpec.value;
726 String whereClause = buildWhereForAuthByName(parentSpec.value);
727 ctx = createServiceContext(getServiceName(), queryParams);
728 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause); //FIXME: REM - If the parent is soft-deleted should we still try to find the item?
730 ctx = createServiceContext(getItemServiceName(), queryParams);
732 if(itemSpec.form==SpecifierForm.CSID) {
733 itemcsid = itemSpec.value;
735 String itemWhereClause =
736 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
737 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause); //FIXME: REM - Should we be looking for the 'wf_deleted' query param and filtering on it?
739 // Note that we have to create the service context for the Items, not the main service
740 // We omit the parentShortId, only needed when doing a create...
741 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid, null);
742 RepositoryClient repoClient = getRepositoryClient(ctx);
743 DocumentFilter myFilter = handler.getDocumentFilter();
744 String serviceType = ServiceBindingUtils.SERVICE_TYPE_PROCEDURE;
745 List<String> list = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP);
747 serviceType = list.get(0);
749 DocumentWrapper<DocumentModel> docWrapper = repoClient.getDoc(ctx, itemcsid);
750 DocumentModel docModel = docWrapper.getWrappedObject();
751 String refName = (String)docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
753 authRefDocList = RefNameServiceUtils.getAuthorityRefDocs(ctx,
757 myFilter.getPageSize(), myFilter.getStartPage(), true /*computeTotal*/ );
758 } catch (Exception e) {
759 throw bigReThrow(e, ServiceMessages.GET_FAILED);
761 if (authRefDocList == null) {
762 Response response = Response.status(Response.Status.NOT_FOUND).entity(
763 "Get failed, the requested Item CSID:" + itemspecifier + ": was not found.").type(
764 "text/plain").build();
765 throw new WebApplicationException(response);
767 return authRefDocList;
771 * Gets the authority terms used in the indicated Authority item.
773 * @param parentspecifier either a CSID or one of the urn forms
774 * @param itemspecifier either a CSID or one of the urn forms
775 * @param ui passed to include additional parameters, like pagination controls
777 * @return the authority refs for the Authority item.
780 @Path("{csid}/items/{itemcsid}/authorityrefs")
781 @Produces("application/xml")
782 public AuthorityRefList getAuthorityItemAuthorityRefs(
783 @PathParam("csid") String parentspecifier,
784 @PathParam("itemcsid") String itemspecifier,
785 @Context UriInfo ui) {
786 AuthorityRefList authRefList = null;
788 Specifier parentSpec = getSpecifier(parentspecifier, "getAuthorityItemAuthRefs(parent)", "GET_ITEM_AUTH_REFS");
789 Specifier itemSpec = getSpecifier(itemspecifier, "getAuthorityItemAuthRefs(item)", "GET_ITEM_AUTH_REFS");
790 // Note that we have to create the service context for the Items, not the main service
791 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
792 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
794 if(parentSpec.form==SpecifierForm.CSID) {
795 parentcsid = parentSpec.value;
797 String whereClause = buildWhereForAuthByName(parentSpec.value);
798 ctx = createServiceContext(getServiceName());
799 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
801 ctx = createServiceContext(getItemServiceName(), queryParams);
802 // We omit the parentShortId, only needed when doing a create...
803 RemoteDocumentModelHandlerImpl handler =
804 (RemoteDocumentModelHandlerImpl) createItemDocumentHandler(ctx,
807 if(itemSpec.form==SpecifierForm.CSID) {
808 itemcsid = itemSpec.value;
810 String itemWhereClause =
811 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
812 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
814 DocumentWrapper<DocumentModel> docWrapper =
815 getRepositoryClient(ctx).getDoc(ctx, itemcsid);
816 List<String> authRefFields =
817 ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(
818 ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);
819 authRefList = handler.getAuthorityRefs(docWrapper, authRefFields);
820 } catch (Exception e) {
821 throw bigReThrow(e, ServiceMessages.GET_FAILED + " parentspecifier: "+parentspecifier + " itemspecifier:" +itemspecifier);
826 * Update authorityItem.
828 * @param parentspecifier either a CSID or one of the urn forms
829 * @param itemspecifier either a CSID or one of the urn forms
831 * @return the multipart output
834 @Path("{csid}/items/{itemcsid}")
835 public byte[] updateAuthorityItem(
837 @PathParam("csid") String parentspecifier,
838 @PathParam("itemcsid") String itemspecifier,
840 PoxPayloadOut result = null;
842 PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
843 Specifier parentSpec = getSpecifier(parentspecifier,
844 "updateAuthorityItem(parent)", "UPDATE_ITEM");
845 Specifier itemSpec = getSpecifier(itemspecifier,
846 "updateAuthorityItem(item)", "UPDATE_ITEM");
847 // Note that we have to create the service context for the Items, not the main service
848 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = null;
850 if(parentSpec.form==SpecifierForm.CSID) {
851 parentcsid = parentSpec.value;
853 String whereClause = buildWhereForAuthByName(parentSpec.value);
854 ctx = createServiceContext(getServiceName());
855 parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
857 ctx = createServiceContext(getItemServiceName(), theUpdate);
859 if(itemSpec.form==SpecifierForm.CSID) {
860 itemcsid = itemSpec.value;
862 String itemWhereClause =
863 buildWhereForAuthItemByName(itemSpec.value, parentcsid);
864 itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause);
866 // Note that we have to create the service context for the Items, not the main service
867 // We omit the parentShortId, only needed when doing a create...
868 DocumentHandler handler = createItemDocumentHandler(ctx,
871 getRepositoryClient(ctx).update(ctx, itemcsid, handler);
872 result = ctx.getOutput();
874 //PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
875 //updateRelations(itemcsid, input);
876 } catch (Exception e) {
877 throw bigReThrow(e, ServiceMessages.UPDATE_FAILED);
879 return result.getBytes();
883 * Delete authorityItem.
885 * @param parentcsid the parentcsid
886 * @param itemcsid the itemcsid
888 * @return the response
891 @Path("{csid}/items/{itemcsid}")
892 public Response deleteAuthorityItem(
893 @PathParam("csid") String parentcsid,
894 @PathParam("itemcsid") String itemcsid) {
896 if (logger.isDebugEnabled()) {
897 logger.debug("deleteAuthorityItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid);
900 if (parentcsid == null || "".equals(parentcsid)) {
901 logger.error("deleteVocabularyItem: missing csid!");
902 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
903 "delete failed on AuthorityItem parentcsid=" + parentcsid).type(
904 "text/plain").build();
905 throw new WebApplicationException(response);
907 if (itemcsid == null || "".equals(itemcsid)) {
908 logger.error("deleteVocabularyItem: missing itemcsid!");
909 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
910 "delete failed on AuthorityItem=" + itemcsid).type(
911 "text/plain").build();
912 throw new WebApplicationException(response);
914 }catch (Throwable t){
915 System.out.println("ERROR in setting up DELETE: "+t);
918 // Note that we have to create the service context for the Items, not the main service
919 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName());
920 getRepositoryClient(ctx).delete(ctx, itemcsid);
921 return Response.status(HttpResponseCodes.SC_OK).build();
922 } catch (Exception e) {
923 throw bigReThrow(e, ServiceMessages.DELETE_FAILED + " itemcsid: " + itemcsid+ " parentcsid:" + parentcsid);