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