View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.impl.document.attribute;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.apache.log4j.MDC;
21  import org.joda.time.DateTime;
22  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
23  import org.kuali.rice.kew.api.KewApiServiceLocator;
24  import org.kuali.rice.kew.api.WorkflowRuntimeException;
25  import org.kuali.rice.kew.api.document.Document;
26  import org.kuali.rice.kew.api.document.DocumentContent;
27  import org.kuali.rice.kew.api.document.DocumentWithContent;
28  import org.kuali.rice.kew.api.document.WorkflowDocumentService;
29  import org.kuali.rice.kew.api.document.attribute.DocumentAttribute;
30  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeDateTime;
31  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeDecimal;
32  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
33  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeInteger;
34  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeString;
35  import org.kuali.rice.kew.docsearch.SearchableAttributeDateTimeValue;
36  import org.kuali.rice.kew.docsearch.SearchableAttributeFloatValue;
37  import org.kuali.rice.kew.docsearch.SearchableAttributeLongValue;
38  import org.kuali.rice.kew.docsearch.SearchableAttributeStringValue;
39  import org.kuali.rice.kew.docsearch.SearchableAttributeValue;
40  import org.kuali.rice.kew.doctype.bo.DocumentType;
41  import org.kuali.rice.kew.framework.document.attribute.SearchableAttribute;
42  import org.kuali.rice.kew.service.KEWServiceLocator;
43  
44  import java.math.BigInteger;
45  import java.sql.Timestamp;
46  import java.util.ArrayList;
47  import java.util.List;
48  
49  /**
50   * Reference implementation of the DocumentAttributeIndexingQueue.
51   *
52   * @author Kuali Rice Team (rice.collab@kuali.org)
53   */
54  public class DocumentAttributeIndexingQueueImpl implements DocumentAttributeIndexingQueue {
55  
56  	private static Logger LOG = Logger.getLogger(DocumentAttributeIndexingQueueImpl.class);
57  
58      @Override
59      public void indexDocument(String documentId) {
60          if (StringUtils.isBlank(documentId)) {
61              throw new RiceIllegalArgumentException("documentId was null or blank");
62          }
63          MDC.put("docId", documentId);
64          try {
65              long t1 = System.currentTimeMillis();
66              LOG.info("Indexing document attributes for document " + documentId);
67              Document document = getWorkflowDocumentService().getDocument(documentId);
68              if (document == null) {
69                  throw new RiceIllegalArgumentException("Failed to locate document with the given id: " + documentId);
70              }
71              DocumentContent documentContent =
72                      KewApiServiceLocator.getWorkflowDocumentService().getDocumentContent(documentId);
73              List<SearchableAttributeValue> attributes = buildSearchableAttributeValues(document, documentContent);
74              KEWServiceLocator.getRouteHeaderService().updateRouteHeaderSearchValues(documentId, attributes);
75              long t2 = System.currentTimeMillis();
76              LOG.info("...finished indexing document " + documentId + " for document search, total time = " + (t2 - t1) +
77                      " ms.");
78          } finally {
79              MDC.remove("docId");
80          }
81      }
82  
83      /**
84       * Determines the {@link DocumentAttribute}s for the given document and returns a List of SearchableAttributeValue
85       * which will be saved.
86       */
87  	private List<SearchableAttributeValue> buildSearchableAttributeValues(Document document, DocumentContent documentContent) {
88  		List<SearchableAttributeValue> searchableAttributeValues = new ArrayList<SearchableAttributeValue>();
89          DocumentType documentTypeBo = KEWServiceLocator.getDocumentTypeService().findByName(document.getDocumentTypeName());
90  		for (DocumentType.ExtensionHolder<SearchableAttribute> searchableAttributeHolder : documentTypeBo.loadSearchableAttributes()) {
91              DocumentWithContent documentWithContent = DocumentWithContent.create(document, documentContent);
92              SearchableAttribute searchableAttribute = searchableAttributeHolder.getExtension();
93              List<DocumentAttribute> documentAttributes = searchableAttribute.extractDocumentAttributes(
94                      searchableAttributeHolder.getExtensionDefinition(), documentWithContent);
95  			if (documentAttributes != null) {
96                  for (DocumentAttribute documentAttribute : documentAttributes) {
97                      if (documentAttribute == null) {
98                          LOG.warn("Encountered a 'null' DocumentAttribute from searchable attribute: " + searchableAttribute);
99                          continue;
100                     }
101                     SearchableAttributeValue searchableAttributeValue = null;
102                     if (documentAttribute instanceof DocumentAttributeString) {
103                         searchableAttributeValue = new SearchableAttributeStringValue();
104                         ((SearchableAttributeStringValue)searchableAttributeValue).setSearchableAttributeValue(((DocumentAttributeString)documentAttribute).getValue());
105                     } else if (documentAttribute instanceof DocumentAttributeDateTime) {
106                         searchableAttributeValue = new SearchableAttributeDateTimeValue();
107                         DateTime dateTimeValue = ((DocumentAttributeDateTime)documentAttribute).getValue();
108                         Timestamp timestamp = (dateTimeValue == null ? null : new Timestamp(dateTimeValue.getMillis()));
109                         ((SearchableAttributeDateTimeValue)searchableAttributeValue).setSearchableAttributeValue(timestamp);
110                     } else if (documentAttribute instanceof DocumentAttributeInteger) {
111                         searchableAttributeValue = new SearchableAttributeLongValue();
112                         BigInteger bigIntegerValue = ((DocumentAttributeInteger)documentAttribute).getValue();
113                         Long longValue = (bigIntegerValue == null ? null : bigIntegerValue.longValue());
114                         ((SearchableAttributeLongValue)searchableAttributeValue).setSearchableAttributeValue(longValue);
115                     } else if (documentAttribute instanceof DocumentAttributeDecimal) {
116                         searchableAttributeValue = new SearchableAttributeFloatValue();
117                         ((SearchableAttributeFloatValue)searchableAttributeValue).setSearchableAttributeValue(((DocumentAttributeDecimal)documentAttribute).getValue());
118                     } else {
119                         throw new WorkflowRuntimeException("Encountered an invalid instance of DocumentAttribute, was: " + documentAttribute.getClass());
120                     }
121                     searchableAttributeValue.setSearchableAttributeKey(documentAttribute.getName());
122                     searchableAttributeValue.setDocumentId(document.getDocumentId());
123                     searchableAttributeValue.setRouteHeader(null); // let the documentId we set represent this reference
124                     searchableAttributeValues.add(searchableAttributeValue);
125                 }
126 			}
127 		}
128 		return searchableAttributeValues;
129 	}
130 
131     protected WorkflowDocumentService getWorkflowDocumentService() {
132         return KewApiServiceLocator.getWorkflowDocumentService();
133     }
134 }