View Javadoc

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