View Javadoc

1   package com.atlassian.bonnie.search;
2   
3   import com.atlassian.bonnie.AnyTypeObjectDao;
4   import com.atlassian.bonnie.Searchable;
5   import com.atlassian.core.util.ObjectUtils;
6   import org.apache.commons.beanutils.PropertyUtils;
7   import org.apache.log4j.Category;
8   import org.apache.lucene.document.Document;
9   import org.apache.lucene.document.Field;
10  
11  import java.util.Iterator;
12  import java.util.List;
13  
14  public abstract class BaseDocumentBuilder implements DocumentBuilder
15  {
16      private static final Category log = Category.getInstance(BaseDocumentBuilder.class);
17  
18      private AnyTypeObjectDao anyTypeObjectDao;
19  
20      public Document getDocument(Searchable searchable)
21      {
22          Document document = getInitialDocument(searchable);
23          StringBuffer contentBody = new StringBuffer();
24  
25          for (Iterator it = getExtractors().iterator(); it.hasNext();)
26          {
27              Extractor extractor = (Extractor) it.next();
28              try
29              {
30                  extractor.addFields(document, contentBody, searchable);
31              }
32              catch (RuntimeException e)
33              {
34                  log.error("Error extracting search fields from " + searchable + " using " + extractor  + ": " + e.getMessage(), e);
35              }
36          }
37  
38          if (contentBody.length() > 0)
39              document.add(new Field(CONTENT_FIELD_NAME, contentBody.toString(), Field.Store.YES, Field.Index.TOKENIZED));
40  
41          return document;
42      }
43  
44      /**
45       * Get the initial document that will be passed through the chain of extractors
46       *
47       * @param searchable the object the document is being created for
48       * @return a new Document pre-filled with the absolute minimum necessary data for it to
49       *         be added.
50       */
51      protected Document getInitialDocument(Searchable searchable)
52      {
53          Document document = new Document();
54  
55          String handleAttributeStringValue = getHandleAttributeStringValue(searchable);
56          Field handleField = new Field(HANDLE_FIELD_NAME, handleAttributeStringValue, Field.Store.YES, Field.Index.UN_TOKENIZED);
57          document.add(handleField);
58  
59          Field classNameField = new Field(CLASSNAME_FIELD_NAME, ObjectUtils.getTrueClass(searchable).getName(), Field.Store.NO, Field.Index.UN_TOKENIZED);
60          document.add(classNameField);
61  
62          try
63          {
64              Object type = PropertyUtils.getProperty(searchable, "type");
65              if (type != null)
66              {
67                  document.add(new Field("type", type.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
68              }
69          }
70          catch (Exception e)
71          {
72              log.warn("Error getting metadata: Reason '" + e.getMessage() + "'");
73          }
74  
75          try
76          {
77              Object urlPath = PropertyUtils.getProperty(searchable, "urlPath");
78              if (urlPath != null)
79              {
80                  document.add(new Field("urlPath", urlPath.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED));
81              }
82          }
83          catch (Exception e)
84          {
85              log.warn("Error getting metadata: Reason '" + e.getMessage() + "'");
86          }
87          return document;
88      }
89  
90  
91      /**
92       * Get the extractors that will be applied to each incoming Searchable to build the
93       * contents of the Lucene document. For example, you may wish to retrieve them from
94       * the plugin subsystem.
95       *
96       * @return the extractors to be applied to all searchable objects
97       */
98      protected abstract List getExtractors();
99  
100     public String getHandleAttributeStringValue(Object obj)
101     {
102         return anyTypeObjectDao.getHandle(obj).toString();
103     }
104 
105     public void setAnyTypeObjectDao(AnyTypeObjectDao anyTypeObjectDao)
106     {
107         this.anyTypeObjectDao = anyTypeObjectDao;
108     }
109 }