1 package org.collectionspace.services.listener.botgarden;
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
8 import org.collectionspace.services.batch.nuxeo.UpdateRareFlagBatchJob;
9 import org.collectionspace.services.client.PoxPayloadIn;
10 import org.collectionspace.services.client.PoxPayloadOut;
11 import org.collectionspace.services.client.workflow.WorkflowClient;
12 import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectBotGardenConstants;
13 import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
14 import org.collectionspace.services.common.ResourceMap;
15 import org.collectionspace.services.common.invocable.InvocationResults;
16 import org.collectionspace.services.nuxeo.listener.AbstractCSEventListenerImpl;
17 import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
18 import org.collectionspace.services.taxonomy.nuxeo.TaxonConstants;
19 import org.jboss.resteasy.spi.ResteasyProviderFactory;
20 import org.nuxeo.ecm.core.api.DocumentModel;
21 import org.nuxeo.ecm.core.api.event.CoreEventConstants;
22 import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
23 import org.nuxeo.ecm.core.event.Event;
24 import org.nuxeo.ecm.core.event.EventContext;
25 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
28 * A listener that updates the rare flag on collectionobjects when collectionobjects
29 * are created or modified, and when taxon records are modified.
31 * @see org.collectionspace.services.batch.nuxeo.UpdateRareFlagBatchJob
35 public class UpdateRareFlagListener extends AbstractCSEventListenerImpl {
36 final Log logger = LogFactory.getLog(UpdateRareFlagListener.class);
38 public static final String PREVIOUS_TAXON_PROPERTY_NAME = "UpdateRareFlagListener.previousTaxon";
39 public static final String PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME = "UpdateRareFlagListener.previousHasRareConservationCategory";
41 private static final String[] CONSERVATION_CATEGORY_PATH_ELEMENTS = TaxonBotGardenConstants.CONSERVATION_CATEGORY_FIELD_NAME.split("/");
42 private static final String PLANT_ATTRIBUTES_GROUP_LIST_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[0];
43 private static final String CONSERVATION_CATEGORY_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[2];
45 public void handleEvent(Event event) {
46 EventContext ec = event.getContext();
48 if (ec instanceof DocumentEventContext) {
49 DocumentEventContext context = (DocumentEventContext) ec;
50 DocumentModel doc = context.getSourceDocument();
52 logger.debug("docType=" + doc.getType());
54 if (doc.getType().startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
57 !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
59 if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
60 // Stash the previous primary taxonomic ident, so it can be retrieved in the documentModified handler.
62 DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
63 String previousTaxon = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
64 CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
66 context.setProperty(PREVIOUS_TAXON_PROPERTY_NAME, previousTaxon);
69 boolean updateRequired = false;
71 if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
72 // A collectionobject was modified. As an optimization, check if the primary taxonomic determination
73 // of the collectionobject has changed. We only need to update the rare flag if it has.
75 String previousTaxon = (String) context.getProperty(PREVIOUS_TAXON_PROPERTY_NAME);
76 String currentTaxon = (String) doc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
77 CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
79 if (previousTaxon == null) {
83 if (currentTaxon == null) {
87 if (previousTaxon.equals(currentTaxon)) {
88 logger.debug("update not required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
91 logger.debug("update required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
92 updateRequired = true;
95 else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
96 // A collectionobject was created. Always update the rare flag.
98 updateRequired = true;
101 if (updateRequired) {
102 String collectionObjectCsid = doc.getName();
105 InvocationResults results = createUpdater().updateRareFlag(collectionObjectCsid);
107 logger.debug("updateRareFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
108 } catch (Exception e) {
109 logger.error(e.getMessage(), e);
114 else if (doc.getType().startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
117 !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
119 if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
120 // Stash whether there was previously a non-empty conservation category, so it can be retrieved in the documentModified handler.
122 DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
123 boolean previousHasRareConservationCategory = hasRareConservationCategory(previousDoc);
125 context.setProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME, new Boolean(previousHasRareConservationCategory));
128 boolean updateRequired = false;
130 if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
131 // A taxon record was modified. As an optimization, check if there is now a rare
132 // conservation category when there wasn't before, or vice versa. We only need to update
133 // the rare flags of referencing collectionobjects if there was a change.
135 boolean previousHasRareConservationCategory = (Boolean) context.getProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME);
136 boolean currentHasRareConservationCategory = hasRareConservationCategory(doc);
138 if (previousHasRareConservationCategory == currentHasRareConservationCategory) {
139 logger.debug("update not required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
140 " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
143 logger.debug("update required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
144 " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
145 updateRequired = true;
149 if (updateRequired) {
150 String taxonCsid = doc.getName();
153 InvocationResults results = createUpdater().updateReferencingRareFlags(taxonCsid);
155 logger.debug("updateReferencingRareFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
156 } catch (Exception e) {
157 logger.error(e.getMessage(), e);
165 private boolean hasRareConservationCategory(DocumentModel doc) {
166 List<Map<String, Object>> plantAttributesGroupList = (List<Map<String, Object>>) doc.getProperty(TaxonBotGardenConstants.CONSERVATION_CATEGORY_SCHEMA_NAME,
167 PLANT_ATTRIBUTES_GROUP_LIST_FIELD_NAME);
168 boolean hasRareConservationCategory = false;
170 // UCBG-369: Changing this so that it only checks the primary conservation category.
172 if (plantAttributesGroupList.size() > 0) {
173 Map<String, Object> plantAttributesGroup = plantAttributesGroupList.get(0);
174 String conservationCategory = (String) plantAttributesGroup.get(CONSERVATION_CATEGORY_FIELD_NAME);
176 if (UpdateRareFlagBatchJob.isRare(conservationCategory)) {
177 hasRareConservationCategory = true;
181 // for (Map<String, Object> plantAttributesGroup : plantAttributesGroupList) {
182 // String conservationCategory = (String) plantAttributesGroup.get(CONSERVATION_CATEGORY_FIELD_NAME);
184 // if (UpdateRareFlagBatchJob.isRare(conservationCategory)) {
185 // hasRareConservationCategory = true;
190 return hasRareConservationCategory;
193 private UpdateRareFlagBatchJob createUpdater() {
194 ResourceMap<PoxPayloadIn, PoxPayloadOut> resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
196 UpdateRareFlagBatchJob updater = new UpdateRareFlagBatchJob();
197 updater.setResourceMap(resourceMap);