]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
dbf63645ed64d04e2f1c2f9cb71ac9851ddd9e7f
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.listener;
2
3 import java.util.ArrayList;
4 import java.util.IllegalFormatException;
5 import java.util.List;
6
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.collectionspace.services.client.workflow.WorkflowClient;
10 import org.collectionspace.services.common.document.DocumentException;
11 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
12 import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
13 import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
14 import org.nuxeo.ecm.core.api.DocumentModel;
15 import org.nuxeo.ecm.core.api.DocumentModelList;
16 import org.nuxeo.ecm.core.api.impl.LifeCycleFilter;
17 import org.nuxeo.ecm.core.event.Event;
18 import org.nuxeo.ecm.core.event.EventContext;
19 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
20
21 public class UpdateRelationsOnDelete extends AbstractCSEventListenerImpl {
22
23     // FIXME: We might experiment here with using log4j instead of Apache Commons Logging;
24     // am using the latter to follow Ray's pattern for now
25     final Log logger = LogFactory.getLog(UpdateRelationsOnDelete.class);
26     
27     // FIXME: Get these constant values from external sources rather than redeclaring here
28     final static String RELATION_DOCTYPE = "Relation";
29     final static String RELATIONS_COMMON_SUBJECT_CSID_FIELD = "relations_common:subjectCsid";
30     final static String RELATIONS_COMMON_OBJECT_CSID_FIELD = "relations_common:objectCsid";
31
32     @Override
33     public void handleEvent(Event event) {
34         logger.trace("In handleEvent in UpdateRelationsOnDelete ...");
35         
36         EventContext eventContext = event.getContext();
37
38         if (isRegistered(event) && isDocumentSoftDeletedEvent(eventContext)) {
39             
40             logger.trace("A soft deletion event was received by UpdateRelationsOnDelete ...");
41             
42             DocumentEventContext docContext = (DocumentEventContext) eventContext;
43             DocumentModel docModel = docContext.getSourceDocument();
44             
45             // Exclude soft deletion events involving Relation records themselves
46             // from handling by this event handler.
47             if (docModel != null && docModel.getType().startsWith(RELATION_DOCTYPE)) {
48                 return;
49             }
50   
51             // Retrieve a list of relation records, where the soft deleted
52             // document provided in the context of the current event is
53             // either the subject or object of any relation
54             
55             // Build a query string
56             String csid = docModel.getName();
57             
58             String queryString;
59             try {
60                 queryString =
61                     String.format("SELECT * FROM Relation WHERE ecm:isProxy = 0 AND (%1$s='%3$s' OR %2$s='%3$s')",
62                     RELATIONS_COMMON_SUBJECT_CSID_FIELD, RELATIONS_COMMON_OBJECT_CSID_FIELD, csid);
63                 logger.trace("Query string=" + queryString);
64             } catch (IllegalFormatException ife) {
65                 logger.warn("Construction of formatted query string failed: ", ife);
66                 logger.warn("Actions in this event listener will NOT be performed, as a result of a previous Exception.");
67                 return;
68             }
69             
70             // Create a filter to exclude from the list results any records
71             // that have already been soft deleted or are locked
72             List<String> workflowStatesToFilter = new ArrayList<String>();
73             workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_DELETED);
74             workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED);
75             workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED);
76             workflowStatesToFilter.add(WorkflowClient.WORKFLOWSTATE_REPLICATED_DELETED);
77             
78             LifeCycleFilter workflowStateFilter = new LifeCycleFilter(null, workflowStatesToFilter);
79             
80             // Perform the filtered query
81             CoreSessionInterface session = new CoreSessionWrapper(docModel.getCoreSession());
82             DocumentModelList matchingDocuments;
83             try {
84                 matchingDocuments = session.query(queryString.toString(), workflowStateFilter);
85             } catch (DocumentException ce) {
86                 logger.error("Error attempting to retrieve relation records where "
87                         + "record of type '" + docModel.getType() + "' with CSID " + csid
88                         + " is the subject or object of any relation: " + ce.getMessage());
89                 return;
90             }
91
92             // Cycle through the list results, soft deleting each matching relation record
93             logger.info("Attempting to soft delete " + matchingDocuments.size() + " relation records pertaining to a soft deleted record.");
94             for (DocumentModel doc : matchingDocuments) {
95                 doc.followTransition(WorkflowClient.WORKFLOWTRANSITION_DELETE);
96             }
97
98         }
99
100     }
101     
102     // FIXME: Generic methods like the following might be split off
103     // into an event utilities class. - ADR 2012-12-05
104
105     /**
106      * Identifies whether a supplied event concerns a document that has
107      * been transitioned to the 'deleted' workflow state.
108      * 
109      * @param eventContext an event context
110      * 
111      * @return true if this event concerns a document that has
112      * been transitioned to the 'deleted' workflow state.
113      */
114     private boolean isDocumentSoftDeletedEvent(EventContext eventContext) {
115         boolean isSoftDeletedEvent = false;
116         
117         if (eventContext instanceof DocumentEventContext) {
118             if (eventContext.getProperties().containsKey(WorkflowClient.WORKFLOWTRANSITION_TO)
119                     &&
120                 (eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_DELETED)
121                                 ||
122                 eventContext.getProperties().get(WorkflowClient.WORKFLOWTRANSITION_TO).equals(WorkflowClient.WORKFLOWSTATE_LOCKED_DELETED))) {
123                 isSoftDeletedEvent = true;
124             }
125         }
126         
127         return isSoftDeletedEvent;
128     }
129 }