1 package org.collectionspace.services.listener;
3 import java.util.ArrayList;
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7 import org.nuxeo.ecm.core.api.ClientException;
8 import org.nuxeo.ecm.core.api.CoreSession;
9 import org.nuxeo.ecm.core.api.DocumentModel;
10 import org.nuxeo.ecm.core.api.DocumentModelList;
11 import org.nuxeo.ecm.core.api.impl.LifeCycleFilter;
12 import org.nuxeo.ecm.core.event.Event;
13 import org.nuxeo.ecm.core.event.EventContext;
14 import org.nuxeo.ecm.core.event.EventListener;
15 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
17 public class UpdateRelationsOnDelete implements EventListener {
19 // FIXME: Consider adding the following constant to
20 // org.collectionspace.services.common.workflow.jaxb.WorkflowJAXBSchema
21 // and referencing it from there.
22 private static final String WORKFLOWTRANSITION_TO = "to";
23 // FIXME: Consider substituting existing constant WorkflowClient.WORKFLOWSTATE_DELETED
24 private static final String WORKFLOWSTATE_DELETED = "deleted";
25 // FIXME: Consider substituting existing constant WorkflowClient.WORKFLOWSTATE_LOCKED
26 private static final String WORKFLOWSTATE_LOCKED = "locked";
27 // FIXME: Consider substituting existing constant WorkflowClient.WORKFLOWTRANSITION_DELETE
28 private static final String WORKFLOWTRANSITION_DELETE = "delete";
30 // FIXME: We might experiment here with using log4j instead of Apache Commons Logging;
31 // am using the latter to follow Ray's pattern for now
32 final Log logger = LogFactory.getLog(UpdateRelationsOnDelete.class);
35 public void handleEvent(Event event) throws ClientException {
36 logger.info("In handleEvent in UpdateRelationsOnDelete ...");
38 EventContext eventContext = event.getContext();
40 if (isDocumentSoftDeletedEvent(eventContext)) {
42 DocumentEventContext docContext = (DocumentEventContext) eventContext;
43 DocumentModel docModel = docContext.getSourceDocument();
45 // Retrieve a list of relation records, where the soft deleted
46 // document provided in the context of the current event is
47 // either the subject or object of any relation
49 // Build a query string
50 String csid = docModel.getName();
51 StringBuilder queryString = new StringBuilder("");
52 queryString.append("SELECT * FROM Relation WHERE ");
53 // FIXME: Obtain and add tenant ID to the query here
54 // queryString.append("collectionspace_core:tenantId = 1 ");
55 // queryString.append(" AND ");
56 // queryString.append("ecm:currentLifeCycleState <> 'deleted' ");
57 queryString.append("ecm:isProxy = 0 ");
58 queryString.append(" AND ");
59 queryString.append("(");
60 queryString.append("relations_common:subjectCsid = ");
61 queryString.append("'");
62 queryString.append(csid);
63 queryString.append("'");
64 queryString.append(" OR ");
65 queryString.append("relations_common:objectCsid = ");
66 queryString.append("'");
67 queryString.append(csid);
68 queryString.append("'");
69 queryString.append(")");
71 // Create a filter to exclude from the list results any records
72 // that have already been soft deleted or are locked
73 List<String> workflowStatesToFilter = new ArrayList<String>();
74 workflowStatesToFilter.add(WORKFLOWSTATE_DELETED);
75 workflowStatesToFilter.add(WORKFLOWSTATE_LOCKED);
76 LifeCycleFilter workflowStateFilter = new LifeCycleFilter(null, workflowStatesToFilter);
78 // Perform the filtered query
79 CoreSession session = docModel.getCoreSession();
80 DocumentModelList matchingDocuments;
82 matchingDocuments = session.query(queryString.toString(), workflowStateFilter);
83 } catch (ClientException ce) {
84 logger.warn("Error attempting to retrieve relation records where "
85 + "record of type '" + docModel.getType() + "' with CSID " + csid
86 + " is the subject or object of any relation: " + ce.getMessage());
90 // Cycle through the list results, soft deleting each matching relation record
91 logger.trace("Attempting to soft delete " + matchingDocuments.size() + " relation records.");
92 for (DocumentModel doc : matchingDocuments) {
93 doc.followTransition(WORKFLOWTRANSITION_DELETE);
101 * Identifies whether a supplied event concerns a document that has
102 * been transitioned to the 'deleted' workflow state.
104 * @param eventContext an event context
106 * @return true if this event concerns a document that has
107 * been transitioned to the 'deleted' workflow state.
109 private boolean isDocumentSoftDeletedEvent(EventContext eventContext) {
110 boolean isSoftDeletedEvent = false;
111 if (eventContext instanceof DocumentEventContext) {
112 if (eventContext.getProperties().containsKey(WORKFLOWTRANSITION_TO)
113 && eventContext.getProperties().get(WORKFLOWTRANSITION_TO).equals(WORKFLOWSTATE_DELETED)) {
114 isSoftDeletedEvent = true;
117 return isSoftDeletedEvent;