1 package org.collectionspace.services.listener.botgarden;
6 import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory;
9 import org.collectionspace.services.batch.BatchResource;
10 import org.collectionspace.services.batch.nuxeo.UpdateRareFlagBatchJob;
11 import org.collectionspace.services.client.BatchClient;
12 import org.collectionspace.services.client.PoxPayloadIn;
13 import org.collectionspace.services.client.PoxPayloadOut;
14 import org.collectionspace.services.client.workflow.WorkflowClient;
15 import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectBotGardenConstants;
16 import org.collectionspace.services.collectionobject.nuxeo.CollectionObjectConstants;
17 import org.collectionspace.services.common.ResourceMap;
18 import org.collectionspace.services.common.context.ServiceContext;
19 import org.collectionspace.services.common.invocable.InvocationResults;
20 import org.collectionspace.services.nuxeo.client.java.CoreSessionWrapper;
21 import org.collectionspace.services.nuxeo.listener.AbstractCSEventSyncListenerImpl;
22 import org.collectionspace.services.taxonomy.nuxeo.TaxonBotGardenConstants;
23 import org.collectionspace.services.taxonomy.nuxeo.TaxonConstants;
24 import org.collectionspace.services.taxonomy.nuxeo.TaxonomyAuthorityConstants;
26 import org.jboss.resteasy.spi.ResteasyProviderFactory;
28 import org.nuxeo.ecm.core.api.DocumentModel;
29 import org.nuxeo.ecm.core.api.event.CoreEventConstants;
30 import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
31 import org.nuxeo.ecm.core.event.Event;
32 import org.nuxeo.ecm.core.event.EventContext;
33 import org.nuxeo.ecm.core.event.impl.DocumentEventContext;
36 * A listener that updates the rare flag on collectionobjects when collectionobjects
37 * are created or modified, and when taxon records are modified.
39 * @see org.collectionspace.services.batch.nuxeo.UpdateRareFlagBatchJob
43 public class UpdateRareFlagListener extends AbstractCSEventSyncListenerImpl {
44 static final Log logger = LogFactory.getLog(UpdateRareFlagListener.class);
46 public static final String PREVIOUS_TAXON_PROPERTY_NAME = "UpdateRareFlagListener.previousTaxon";
47 public static final String PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME = "UpdateRareFlagListener.previousHasRareConservationCategory";
49 private static final String[] CONSERVATION_CATEGORY_PATH_ELEMENTS = TaxonBotGardenConstants.CONSERVATION_CATEGORY_FIELD_NAME.split("/");
50 private static final String PLANT_ATTRIBUTES_GROUP_LIST_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[0];
51 private static final String CONSERVATION_CATEGORY_FIELD_NAME = CONSERVATION_CATEGORY_PATH_ELEMENTS[2];
54 public boolean shouldHandleEvent(Event event) {
55 return event.getContext() instanceof DocumentEventContext;
59 public void handleCSEvent(Event event) {
60 EventContext ec = event.getContext();
61 DocumentEventContext context = (DocumentEventContext) ec;
62 DocumentModel doc = context.getSourceDocument();
63 String docType = doc.getType();
65 logger.debug("docType=" + docType);
67 if (docType.startsWith(CollectionObjectConstants.NUXEO_DOCTYPE) &&
70 !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
72 if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
73 // Stash the previous primary taxonomic ident, so it can be retrieved in the documentModified handler.
75 DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
76 String previousTaxon = (String) previousDoc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
77 CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
79 context.setProperty(PREVIOUS_TAXON_PROPERTY_NAME, previousTaxon);
82 boolean updateRequired = false;
84 if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
85 // A collectionobject was modified. As an optimization, check if the primary taxonomic determination
86 // of the collectionobject has changed. We only need to update the rare flag if it has.
88 String previousTaxon = (String) context.getProperty(PREVIOUS_TAXON_PROPERTY_NAME);
89 String currentTaxon = (String) doc.getProperty(CollectionObjectBotGardenConstants.TAXON_SCHEMA_NAME,
90 CollectionObjectBotGardenConstants.PRIMARY_TAXON_FIELD_NAME);
92 if (previousTaxon == null) {
96 if (currentTaxon == null) {
100 if (previousTaxon.equals(currentTaxon)) {
101 logger.debug("update not required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
104 logger.debug("update required: previousTaxon=" + previousTaxon + " currentTaxon=" + currentTaxon);
105 updateRequired = true;
108 else if (event.getName().equals(DocumentEventTypes.DOCUMENT_CREATED)) {
109 // A collectionobject was created. Always update the rare flag.
111 updateRequired = true;
114 if (updateRequired) {
115 String collectionObjectCsid = doc.getName();
118 InvocationResults results = createUpdater(context).updateRareFlag(collectionObjectCsid);
120 logger.debug("updateRareFlag complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
121 } catch (Exception e) {
122 logger.error(e.getMessage(), e);
127 else if (docType.startsWith(TaxonConstants.NUXEO_DOCTYPE) &&
128 !docType.startsWith(TaxonomyAuthorityConstants.NUXEO_DOCTYPE) &&
131 !doc.getCurrentLifeCycleState().equals(WorkflowClient.WORKFLOWSTATE_DELETED)) {
133 if (event.getName().equals(DocumentEventTypes.BEFORE_DOC_UPDATE)) {
134 // Stash whether there was previously a non-empty conservation category, so it can be retrieved in the documentModified handler.
136 DocumentModel previousDoc = (DocumentModel) context.getProperty(CoreEventConstants.PREVIOUS_DOCUMENT_MODEL);
137 boolean previousHasRareConservationCategory = hasRareConservationCategory(previousDoc);
139 context.setProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME, new Boolean(previousHasRareConservationCategory));
142 boolean updateRequired = false;
144 if (event.getName().equals(DocumentEventTypes.DOCUMENT_UPDATED)) {
145 // A taxon record was modified. As an optimization, check if there is now a rare
146 // conservation category when there wasn't before, or vice versa. We only need to update
147 // the rare flags of referencing collectionobjects if there was a change.
149 boolean previousHasRareConservationCategory = (Boolean) context.getProperty(PREVIOUS_HAS_RARE_CONSERVATION_CATEGORY_PROPERTY_NAME);
150 boolean currentHasRareConservationCategory = hasRareConservationCategory(doc);
152 if (previousHasRareConservationCategory == currentHasRareConservationCategory) {
153 logger.debug("update not required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
154 " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
157 logger.debug("update required: previousHasRareConservationCategory=" + previousHasRareConservationCategory +
158 " currentHasRareConservationCategory=" + currentHasRareConservationCategory);
159 updateRequired = true;
163 if (updateRequired) {
164 String taxonCsid = doc.getName();
165 String vocabularyCsid = (String) doc.getProperty(TaxonConstants.IN_AUTHORITY_SCHEMA_NAME, TaxonConstants.IN_AUTHORITY_FIELD_NAME);
168 InvocationResults results = createUpdater(context).updateReferencingRareFlags(taxonCsid, vocabularyCsid);
170 logger.debug("updateReferencingRareFlags complete: numAffected=" + results.getNumAffected() + " userNote=" + results.getUserNote());
171 } catch (Exception e) {
172 logger.error(e.getMessage(), e);
179 private boolean hasRareConservationCategory(DocumentModel doc) {
180 List<Map<String, Object>> plantAttributesGroupList = (List<Map<String, Object>>) doc.getProperty(TaxonBotGardenConstants.CONSERVATION_CATEGORY_SCHEMA_NAME,
181 PLANT_ATTRIBUTES_GROUP_LIST_FIELD_NAME);
182 boolean hasRareConservationCategory = false;
184 // UCBG-369: Changing this so that it only checks the primary conservation category.
186 if (plantAttributesGroupList.size() > 0) {
187 Map<String, Object> plantAttributesGroup = plantAttributesGroupList.get(0);
188 String conservationCategory = (String) plantAttributesGroup.get(CONSERVATION_CATEGORY_FIELD_NAME);
190 if (UpdateRareFlagBatchJob.isRare(conservationCategory)) {
191 hasRareConservationCategory = true;
195 // for (Map<String, Object> plantAttributesGroup : plantAttributesGroupList) {
196 // String conservationCategory = (String) plantAttributesGroup.get(CONSERVATION_CATEGORY_FIELD_NAME);
198 // if (UpdateRareFlagBatchJob.isRare(conservationCategory)) {
199 // hasRareConservationCategory = true;
204 return hasRareConservationCategory;
207 private UpdateRareFlagBatchJob createUpdater(DocumentEventContext context) throws Exception {
208 ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
209 BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
210 ServiceContext<PoxPayloadIn, PoxPayloadOut> serviceContext = batchResource.createServiceContext(batchResource.getServiceName());
212 serviceContext.setCurrentRepositorySession(new CoreSessionWrapper(context.getCoreSession()));
214 UpdateRareFlagBatchJob updater = new UpdateRareFlagBatchJob();
215 updater.setServiceContext(serviceContext);
216 updater.setResourceMap(resourceMap);
222 public Log getLogger() {