View Javadoc

1   package com.atlassian.bonnie;
2   
3   import org.apache.log4j.Category;
4   import org.apache.lucene.document.DateField;
5   import org.apache.lucene.document.Document;
6   import org.apache.lucene.document.Field;
7   import org.apache.lucene.index.Term;
8   import org.apache.lucene.search.*;
9   
10  import java.util.*;
11  
12  /**
13   * <class-comment/>
14   */
15  public class LuceneUtils
16  {
17      /**
18       * Logger.
19       */
20      protected static Category log = Category.getInstance(LuceneUtils.class);
21  
22      public static String dateToString(Date date)
23      {
24          //TODO: This should probably be changed to be DateTools.stringToDate, but since this will require a full
25          // reindex we'll leave it to be the depracted method for now.
26          return DateField.dateToString(date);
27      }
28  
29      public static Date stringToDate(String s)
30      {
31          if (s != null && s.trim().length() > 0)
32          {
33              //TODO: This should probably be changed to be DateTools.stringToDate, but since this will require a full
34              // reindex we'll leave it to be the depracted method for now.
35              return DateField.stringToDate(s);
36          }
37          return new Date();
38      }
39  
40      public static Query buildSingleFieldSingleValueTermQuery(String field, String query)
41      {
42          return buildSingleFieldMultiValueTermQuery(field, Collections.singletonList(query), true);
43      }
44  
45      /**
46       * Builds a query that checks that the field contains all or some of the values specified.
47       * You can set this behaviour by adjusting the value of the addQuery parameter
48       *
49       * @param field
50       * @param values
51       * @param andQuery - set to true if you require the value of the field to match ALL values
52       * @return
53       */
54      public static Query buildSingleFieldMultiValueTermQuery(String field, Collection values, boolean andQuery)
55      {
56          BooleanQuery query = new BooleanQuery();
57  
58          BooleanClause.Occur occur = andQuery ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
59  
60          for (Iterator iterator = values.iterator(); iterator.hasNext();)
61          {
62              String value = (String) iterator.next();
63              query.add(new TermQuery(new Term(field, value)), occur);
64          }
65  
66          return query;
67      }
68  
69      public static Query buildSingleFieldMultiValuePrefixQuery(String field, Collection values, boolean andQuery)
70      {
71          BooleanQuery query = new BooleanQuery();
72  
73          BooleanClause.Occur occur = andQuery ? BooleanClause.Occur.MUST : BooleanClause.Occur.SHOULD;
74  
75          for (Iterator iterator = values.iterator(); iterator.hasNext();)
76          {
77              String value = (String) iterator.next();
78              query.add(new PrefixQuery(new Term(field, value)), occur);
79          }
80  
81          return query;
82      }
83  
84      /**
85       * Builds a Map representation of a Document.
86       * This allows dot-style notation in Velocity to be retained for both object- and map-backed
87       * representations.
88       * <p/>
89       * Dotted fields are split into maps that will lead to the eventual value.
90       * For example, content.space.name will resolve to map->map->string.
91       * This approach also assumes there is no clash between dotted keys and top-level keys,
92       * i.e. there aren't both content=foo and content.space.name=bar.
93       * </p>
94       *
95       * @param doc
96       * @return
97       */
98      public static Map buildMapFromDocument(Document doc)
99      {
100         Map result = new HashMap();
101         for (Iterator iter = doc.getFields().iterator(); iter.hasNext();)
102         {
103             Field f = (Field) iter.next();
104             String fieldname = f.name();
105             if (fieldname.indexOf('.') > -1)
106             {
107                 String[] split = fieldname.split("\\.");
108                 Map last = result;
109                 for (int i = 0; i < split.length; ++i)
110                 {
111                     String key = split[i];
112                     if (i == split.length - 1)
113                     {
114                         last.put(key, f.stringValue()); // terminal case
115                     }
116                     else
117                     {
118                         Object temp = last.get(key);
119                         if (temp != null && !(temp instanceof Map))
120                         {
121                             break;
122                         }
123 
124                         if (temp == null)
125                         {
126                             temp = new HashMap(5);
127                             last.put(key, temp);
128                         }
129                         last = (Map) temp;
130                     }
131                 }
132             }
133             else
134             {
135                 result.put(fieldname, f.stringValue());      // assume there's only one value/field
136             }
137         }
138         return result;
139     }
140 }