View Javadoc

1   /*  Copyright 2004 Brian McCallister
2    *
3    *   Licensed under the Apache License, Version 2.0 (the "License");
4    *   you may not use this file except in compliance with the License.
5    *   You may obtain a copy of the License at
6    *
7    *       http://www.apache.org/licenses/LICENSE-2.0
8    *
9    *   Unless required by applicable law or agreed to in writing, software
10   *   distributed under the License is distributed on an "AS IS" BASIS,
11   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   *   See the License for the specific language governing permissions and
13   *   limitations under the License.
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 }