View Javadoc

1   package com.atlassian.bonnie.search.extractor;
2   
3   import com.atlassian.bonnie.Searchable;
4   import com.atlassian.bonnie.LuceneUtils;
5   import com.atlassian.bonnie.LuceneException;
6   import com.atlassian.bonnie.search.Extractor;
7   import com.atlassian.bonnie.search.DocumentBuilder;
8   import com.atlassian.bonnie.search.extractor.XmlClassConfigurations;
9   import com.atlassian.core.util.ObjectUtils;
10  import org.apache.commons.beanutils.PropertyUtils;
11  import org.apache.lucene.document.Document;
12  import org.apache.lucene.document.Field;
13  
14  import java.lang.reflect.Array;
15  import java.lang.reflect.InvocationTargetException;
16  import java.util.Collection;
17  import java.util.Date;
18  import java.util.Iterator;
19  
20  public class XmlConfiguredExtractor implements Extractor
21  {
22      public void addFields(Document document, StringBuffer defaultSearchableText, Searchable searchable)
23      {
24          XmlClassConfigurations.ClassConfiguration classConfig = XmlClassConfigurations.getClassConfiguration(ObjectUtils.getTrueClass(searchable));
25  
26          if (classConfig != null)
27          {
28              Iterator iter = classConfig.getFieldConfigurations().iterator();
29              while (iter.hasNext())
30              {
31                  XmlClassConfigurations.FieldConfiguration fieldConfiguration = (XmlClassConfigurations.FieldConfiguration) iter.next();
32                  String attributeNames[] = fieldConfiguration.getAttributeName().split(",");
33                  for (int i = 0; i < attributeNames.length; ++i)
34                  {
35                      Object o = getContentOfAttribute(searchable, attributeNames[i]);
36                      if (o.getClass().isArray())
37                          indexArrayField(document, fieldConfiguration, o);
38                      else if (o instanceof Collection)
39                          indexCollectionField(document, fieldConfiguration, (Collection) o);
40                      else
41                      if (o instanceof Date && fieldConfiguration.getType().equals(XmlClassConfigurations.FieldConfiguration.TYPE_KEYWORD))
42                          indexDateField(document, fieldConfiguration, (Date) o);
43                      else if (DocumentBuilder.CONTENT_FIELD_NAME.equals(fieldConfiguration.getFieldName()))
44                          defaultSearchableText.append(String.valueOf(o));
45                      else
46                          indexStringField(document, fieldConfiguration, String.valueOf(o));
47                  }
48              }
49          }
50      }
51  
52      private void indexDateField(Document doc, XmlClassConfigurations.FieldConfiguration fieldConfiguration, Date date)
53      {
54          Field field = new Field(fieldConfiguration.getFieldName(), LuceneUtils.dateToString(date), Field.Store.YES, Field.Index.UN_TOKENIZED);
55          doc.add(field);
56      }
57  
58      private void indexArrayField(Document doc, XmlClassConfigurations.FieldConfiguration fieldConfiguration, Object arr)
59      {
60          int length = Array.getLength(arr);
61          for (int i = 0; i < length; i++)
62          {
63              Object o = Array.get(arr, i);
64              indexStringField(doc, fieldConfiguration, String.valueOf(o));
65          }
66      }
67  
68      private void indexCollectionField(Document doc, XmlClassConfigurations.FieldConfiguration fieldConfiguration, Collection collection)
69      {
70          for (Iterator it = collection.iterator(); it.hasNext();)
71          {
72              Object o = it.next();
73              indexStringField(doc, fieldConfiguration, String.valueOf(o));
74          }
75      }
76  
77      private void indexStringField(Document doc, XmlClassConfigurations.FieldConfiguration fieldConfiguration, String strContent)
78      {
79          Field field;
80          if (fieldConfiguration.getType().equals(XmlClassConfigurations.FieldConfiguration.TYPE_TEXT))
81          {
82              field = new Field(fieldConfiguration.getFieldName(), strContent, Field.Store.YES, Field.Index.TOKENIZED);
83          }
84          else if (fieldConfiguration.getType().equals(XmlClassConfigurations.FieldConfiguration.TYPE_KEYWORD))
85          {
86              field = new Field(fieldConfiguration.getFieldName(), strContent, Field.Store.YES, Field.Index.UN_TOKENIZED);
87          }
88          else if (fieldConfiguration.getType().equals(XmlClassConfigurations.FieldConfiguration.TYPE_UNINDEXED))
89          {
90              field = new Field(fieldConfiguration.getFieldName(), strContent, Field.Store.YES, Field.Index.NO);
91          }
92          else if (fieldConfiguration.getType().equals(XmlClassConfigurations.FieldConfiguration.TYPE_UNSTORED))
93          {
94              field = new Field(fieldConfiguration.getFieldName(), strContent, Field.Store.NO, Field.Index.TOKENIZED);
95          }
96          else
97          {
98              throw new LuceneException("Unknown type for a field, fieldName=" + fieldConfiguration.getFieldName());
99          }
100 
101         doc.add(field);
102     }
103 
104     private Object getContentOfAttribute(Object obj, String attributeName)
105     {
106         try
107         {
108             String[] attributes = attributeName.split("\\.");
109             Object o = null;
110             for (int i = 0; i < attributes.length; ++i)
111                 o = PropertyUtils.getProperty(obj, attributeName);
112             return (o == null) ? "" : o;
113         }
114         catch (IllegalAccessException iae)
115         {
116             throw new LuceneException("Couldn't get string content of attribute, as property accessor method for " + attributeName + " cannot be accessed");
117         }
118         catch (NoSuchMethodException e)
119         {
120             throw new LuceneException("Couldn't get string content of attribute, as no such property accessor method for " + attributeName + " exists");
121         }
122         catch (InvocationTargetException e)
123         {
124             throw new LuceneException("Calling property accessor method for attribute " + attributeName + " threw an exception", e);
125         }
126     }
127 }