From: Richard Millet Date: Fri, 22 Apr 2016 07:18:46 +0000 (-0700) Subject: CSPACE-6937-A: Added support for soft-deleting authority terms that are referenced... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=23e15456dc25a306b8e480560d7489787d00b675;p=tmp%2Fjakarta-migration.git CSPACE-6937-A: Added support for soft-deleting authority terms that are referenced by only soft-deleted records. Hard-delete requests on authority terms with only references from soft-deleted objects will be soft-deleted. --- diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java index a2dbcbb52..d6ee4c05e 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountRoleDocumentHandler.java @@ -123,8 +123,9 @@ public class AccountRoleDocumentHandler * @see org.collectionspace.services.common.document.AbstractDocumentHandlerImpl#handleDelete(org.collectionspace.services.common.document.DocumentWrapper) */ @Override - public void handleDelete(DocumentWrapper> wrapDoc) throws Exception { + public boolean handleDelete(DocumentWrapper> wrapDoc) throws Exception { fillCommonPart(getCommonPart(), wrapDoc, true); + return true; } /* (non-Javadoc) diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java index 96a5759b0..51a12e20a 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java @@ -696,13 +696,15 @@ public abstract class AuthorityResource @PUT @Path("{csid}/items/{itemcsid}" + WorkflowClient.SERVICE_PATH + "/{transition}") public byte[] updateItemWorkflowWithTransition( + @Context UriInfo uriInfo, @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier, @PathParam("transition") String transition) { PoxPayloadOut result = null; - try { - result = updateItemWorkflowWithTransition(NULL_CONTEXT, + try { + ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); + result = updateItemWorkflowWithTransition(ctx, parentIdentifier, itemIdentifier, transition, AuthorityServiceUtils.UPDATE_REV); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.UPDATE_FAILED + WorkflowClient.SERVICE_PAYLOAD_NAME, parentIdentifier); @@ -1262,6 +1264,7 @@ public abstract class AuthorityResource @DELETE @Path("{csid}/items/{itemcsid}") public Response deleteAuthorityItem( + @Context UriInfo uriInfo, @PathParam("csid") String parentIdentifier, @PathParam("itemcsid") String itemIdentifier) { Response result = null; @@ -1273,7 +1276,8 @@ public abstract class AuthorityResource } try { - deleteAuthorityItem(null, parentIdentifier, itemIdentifier); + ServiceContext ctx = createServiceContext(getItemServiceName(), uriInfo); + deleteAuthorityItem(ctx, parentIdentifier, itemIdentifier); result = Response.status(HttpResponseCodes.SC_OK).build(); } catch (Exception e) { throw bigReThrow(e, ServiceMessages.DELETE_FAILED + " itemcsid: " + itemIdentifier + " parentcsid:" + parentIdentifier); @@ -1294,7 +1298,7 @@ public abstract class AuthorityResource String itemIdentifier) throws Exception { Response result = null; - ServiceContext ctx = createServiceContext(getItemServiceName()); + ServiceContext ctx = createServiceContext(getItemServiceName(), existingCtx.getUriInfo()); String parentcsid = lookupParentCSID(ctx, parentIdentifier, "deleteAuthorityItem(parent)", "DELETE_ITEM", null); String itemCsid = lookupItemCSID(ctx, itemIdentifier, parentcsid, "deleteAuthorityItem(item)", "DELETE_ITEM"); //use itemServiceCtx if it is not null diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java index 9d55b196a..c2a89e740 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java @@ -234,6 +234,8 @@ public abstract class AuthorityDocumentModelHandler long result = 0; ArrayList failureList = new ArrayList(); + ctx.setProperty(AuthorityServiceUtils.SHOULD_UPDATE_REV_PROPERTY, false); + for (String refName:refNameList) { AuthorityTermInfo itemInfo = RefNameUtils.parseAuthorityTermInfo(refName); AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(); diff --git a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java index a8879546e..bef1d4517 100644 --- a/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java +++ b/services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java @@ -384,10 +384,18 @@ public abstract class AuthorityItemDocumentModelHandler // DocumentModel docModel = wrapDoc.getWrappedObject(); if (transitionDef.getName().equalsIgnoreCase(WorkflowClient.WORKFLOWTRANSITION_DELETE)) { - if (hasReferencingObjects(this.getServiceContext(), docModel, false) == true) { - throw new DocumentReferenceException(String.format("Cannot delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", - docModel.getName())); - } + long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); + long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); + if (refsToAllObjects > 0) { + if (refsToAllObjects > refsToSoftDeletedObjects) { + // + // If the number of refs to active objects is greater than the number of refs to + // soft deleted objects then we can't delete the item. + // + throw new DocumentReferenceException(String.format("Cannot delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", + docModel.getName())); + } + } } } @@ -561,17 +569,37 @@ public abstract class AuthorityItemDocumentModelHandler * (non-Javadoc) */ @Override - public void handleDelete(DocumentWrapper wrapDoc) throws Exception { + public boolean handleDelete(DocumentWrapper wrapDoc) throws Exception { + boolean result = true; + ServiceContext ctx = getServiceContext(); DocumentModel docModel = wrapDoc.getWrappedObject(); - long refsToObjects = hasReferencingObjects(ctx, docModel, false); + long refsToAllObjects = hasReferencingObjects(ctx, docModel, false); long refsToSoftDeletedObjects = hasReferencingObjects(ctx, docModel, true); - - if (refsToObjects > refsToSoftDeletedObjects) { - throw new DocumentReferenceException(String.format("Cannot delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", - docModel.getName())); + if (refsToAllObjects > 0) { + if (refsToAllObjects > refsToSoftDeletedObjects) { + // + // If the number of refs to active objects is greater than the number of refs to + // soft deleted objects then we can't delete the item. + // + throw new DocumentReferenceException(String.format("Cannot delete authority item '%s' because it still has records in the system that are referencing it. See the service layer log file for details.", + docModel.getName())); + } else { + // + // If all the refs are to soft-deleted objects, we should soft-delete this authority item instead of hard-deleting it and instead of failing. + // + Boolean shouldUpdateRev = (Boolean) ctx.getProperty(AuthorityServiceUtils.SHOULD_UPDATE_REV_PROPERTY); + String parentCsid = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.IN_AUTHORITY); + String itemCsid = docModel.getName(); + AuthorityResource authorityResource = (AuthorityResource) ctx.getResource(getAuthorityServicePath()); + authorityResource.updateItemWorkflowWithTransition(ctx, parentCsid, itemCsid, WorkflowClient.WORKFLOWTRANSITION_DELETE, + shouldUpdateRev != null ? shouldUpdateRev : true); + result = false; // Don't delete since we just soft-deleted it. + } } + + return result; } /** @@ -589,7 +617,13 @@ public abstract class AuthorityItemDocumentModelHandler AuthorityResource authorityResource = (AuthorityResource)ctx.getResource(getAuthorityServicePath()); String itemCsid = docModel.getName(); UriTemplateRegistry uriTemplateRegistry = ServiceMain.getInstance().getUriTemplateRegistry(); - ctx.getUriInfo().getQueryParameters().add(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED, Boolean.toString(onlyRefsToDeletedObjects)); // Add the wf_deleted query param to the resource call + if (ctx.getUriInfo() == null) { + // + // We need a UriInfo object so we can pass "query" params to the AuthorityResource's getReferencingObjects() method + // + ctx.setUriInfo(this.getServiceContext().getUriInfo()); // try to get a UriInfo instance from the handler's context + } + ctx.getUriInfo().getQueryParameters().addFirst(WorkflowClient.WORKFLOW_QUERY_ONLY_DELETED, Boolean.toString(onlyRefsToDeletedObjects)); // Add the wf_deleted query param to the resource call AuthorityRefDocList refObjs = authorityResource.getReferencingObjects(ctx, inAuthorityCsid, itemCsid, uriTemplateRegistry, ctx.getUriInfo()); diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java index 40ebde150..5ed610a13 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleDocumentHandler.java @@ -126,8 +126,9 @@ public class PermissionRoleDocumentHandler * @see org.collectionspace.services.common.document.AbstractDocumentHandlerImpl#handleDelete(org.collectionspace.services.common.document.DocumentWrapper) */ @Override - public void handleDelete(DocumentWrapper> wrapDoc) throws Exception { + public boolean handleDelete(DocumentWrapper> wrapDoc) throws Exception { fillCommonPart(getCommonPart(), wrapDoc, true); + return true; } /* (non-Javadoc) diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java index 61ff77bb8..028dd4cea 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java @@ -248,7 +248,7 @@ public abstract class AbstractDocumentHandlerImpl break; case DELETE: - handleDelete((DocumentWrapper) wrapDoc); + result = handleDelete((DocumentWrapper) wrapDoc); break; case SYNC: @@ -297,8 +297,8 @@ public abstract class AbstractDocumentHandlerImpl * @see org.collectionspace.services.common.document.DocumentHandler#handleDelete(org.collectionspace.services.common.document.DocumentWrapper) */ @Override - public void handleDelete(DocumentWrapper wrapDoc) throws Exception { - // Do nothing. Subclasses can override if they want/need to. + public boolean handleDelete(DocumentWrapper wrapDoc) throws Exception { + return true; } /* (non-Javadoc) diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java index 90ed731e0..5e1db5046 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java +++ b/services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java @@ -160,7 +160,7 @@ public interface DocumentHandler { * @param wrapDoc * @throws Exception */ - public void handleDelete(DocumentWrapper wrapDoc) throws Exception; + public boolean handleDelete(DocumentWrapper wrapDoc) throws Exception; /** * complete is called by the client to provide an opportunity to the handler diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java index 8e89459dc..931446ec9 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java @@ -1618,8 +1618,9 @@ public class RepositoryClientImpl implements RepositoryClient(repoSession.getDocument(docRef)); ((DocumentModelHandler) handler).setRepositorySession(repoSession); - handler.handle(Action.DELETE, wrapDoc); - repoSession.removeDocument(docRef); + if (handler.handle(Action.DELETE, wrapDoc)) { + repoSession.removeDocument(docRef); + } } catch (ClientException ce) { String msg = logException(ce, "Could not find document to delete with CSID=" + id); throw new DocumentNotFoundException(msg, ce); diff --git a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java index 8d30d6c87..a15c7fb47 100644 --- a/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java +++ b/services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java @@ -149,7 +149,9 @@ public class RelationDocumentModelHandler } @Override - public void handleDelete(DocumentWrapper wrapDoc) throws Exception { + public boolean handleDelete(DocumentWrapper wrapDoc) throws Exception { + boolean result = true; + String workflowState = WorkflowClient.WORKFLOWSTATE_LOCKED; // Neither the subject nor the object can be locked if (subjectOrObjectInWorkflowState(wrapDoc, workflowState) == false) { @@ -158,6 +160,8 @@ public class RelationDocumentModelHandler throw new ServiceException(HttpURLConnection.HTTP_FORBIDDEN, "Cannot delete a relationship if either end is in the workflow state: " + workflowState); } + + return result; } private void populateSubjectAndObjectValues(DocumentWrapper wrapDoc) throws Exception {