1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.skife.lucene.graph;
16
17 import org.apache.commons.grafolia.graph.Graph;
18 import org.apache.commons.grafolia.graph.ReferenceTraversalWalkerFactory;
19 import org.apache.commons.grafolia.graph.WalkerFactory;
20 import org.apache.lucene.analysis.Analyzer;
21 import org.apache.lucene.analysis.standard.StandardAnalyzer;
22 import org.apache.lucene.document.Field;
23 import org.apache.lucene.index.IndexWriter;
24
25 import java.io.File;
26 import java.io.IOException;
27
28 /***
29 * Facility which provides for creating indexes on graphs of
30 * persistent objects
31 */
32 public class GraphIndexer
33 {
34 private WalkerFactory walkers;
35 private final MetadataFactory metadata;
36 private final ObjectIndexFilter filter;
37 private final Analyzer analyzer;
38 private final NameMapper nameMapper;
39 private final ValueMapper valueMapper;
40
41 /***
42 * No metadata, {@link StandardLibraryFilter} applied to objects traversed,
43 * visits all object and collection references, uses the base name of the class
44 * ({@link SimpleNameMapper}, lower cased, for root names, uses {@link SimpleValueMapper}
45 * for values, and uses the Lucene <code>StandardAnalyzer</code> to build the index
46 */
47 public GraphIndexer()
48 {
49 this(new MetadataFactory()
50 {
51 public Field[] build(Object entity)
52 {
53 return new Field[0];
54 }
55 });
56 }
57
58 /***
59 * Provides the same behavior as the {@link GraphIndexer#GraphIndexer()} constructor
60 * except provides for metadata
61 */
62 public GraphIndexer(final MetadataFactory metadata)
63 {
64 this(new ReferenceTraversalWalkerFactory(),
65 metadata,
66 new StandardAnalyzer(),
67 new StandardLibraryFilter(),
68 new SimpleNameMapper(),
69 new SimpleValueMapper());
70 }
71
72 /***
73 * Provides the same behavior as the {@link GraphIndexer#GraphIndexer()} constructor
74 * except provides for metadata and filtering which objects are indexed
75 */
76 public GraphIndexer(final MetadataFactory metadata,
77 final ObjectIndexFilter filter)
78 {
79 this(new ReferenceTraversalWalkerFactory(),
80 metadata,
81 new StandardAnalyzer(),
82 filter,
83 new SimpleNameMapper(),
84 new SimpleValueMapper());
85 }
86
87 /***
88 * Fully specify the behavior of the GraphIndexer
89 *
90 * @param walkerFactory A Grafolia <code>WalkerFactory</code> which controls
91 * the traversal of the object graph
92 * @param metadata Specify metadata on a per-instance basis
93 * @param analyzer Use a a non-standard Lucene indexer
94 * @param filter Filter which instances are indexed
95 * @param nameMapper Specify names for roots of search chains
96 * @param valueMapper Specify how the values for fields in the filter are generated
97 */
98 public GraphIndexer(final WalkerFactory walkerFactory,
99 final MetadataFactory metadata,
100 final Analyzer analyzer,
101 final ObjectIndexFilter filter,
102 final NameMapper nameMapper,
103 final ValueMapper valueMapper)
104 {
105 this.walkers = walkerFactory;
106 this.metadata = metadata;
107 this.filter = filter;
108 this.analyzer = analyzer;
109 this.nameMapper = nameMapper;
110 this.valueMapper = valueMapper;
111 }
112
113 /***
114 * Creates a relation-aware index for everything referenced under <code>root</code>
115 * <p>
116 * Will create a temporary file to store the index
117 *
118 * @param root root of graph to be indexed, can be a collection
119 * @return file where index is created
120 */
121 public File index(final Object root) throws IOException
122 {
123 final File index = File.createTempFile("index", String.valueOf(root.hashCode()));
124 index.delete();
125 index.mkdir();
126 final IndexWriter writer = new IndexWriter(index, analyzer, true);
127
128 final Graph graph = new Graph(walkers, root);
129 final IndexBuilder builder = new IndexBuilder(graph, metadata, filter, writer, nameMapper, valueMapper);
130 builder.run();
131
132 writer.optimize();
133 writer.close();
134
135 return index;
136 }
137
138 /***
139 * Creates a relation-aware index for everything referenced under <code>root</code>
140 *
141 * @param index Add to an already created index. Must have been previously created
142 * @param root root of graph to be indexed, can be a collection
143 */
144 public File index(final File index, final Object root) throws IOException
145 {
146 index.delete();
147 index.mkdir();
148 final IndexWriter writer = new IndexWriter(index, analyzer, false);
149
150 final Graph graph = new Graph(walkers, root);
151 final IndexBuilder builder = new IndexBuilder(graph,
152 metadata,
153 filter,
154 writer,
155 nameMapper,
156 valueMapper);
157 builder.run();
158
159 writer.optimize();
160 writer.close();
161
162 return index;
163 }
164 }