View Javadoc

1   /*
2    * MMBase Lucene module
3    *
4    * The contents of this file are subject to the Mozilla Public License
5    * Version 1.0 (the "License"); you may not use this file except in
6    * compliance with the License. You may obtain a copy of the License at
7    * http://www.mozilla.org/MPL/
8    *
9    * Software distributed under the License is distributed on an "AS IS"
10   * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11   * License for the specific language governing rights and limitations
12   * under the License.
13   */
14  package net.sf.mmapps.modules.lucenesearch;
15  
16  import java.util.ArrayList;
17  import java.util.Collection;
18  import java.util.HashSet;
19  import java.util.Iterator;
20  import java.util.Set;
21  
22  import net.sf.mmapps.modules.cloudprovider.CloudProvider;
23  import net.sf.mmapps.modules.cloudprovider.CloudProviderFactory;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.lucene.analysis.Analyzer;
28  import org.apache.lucene.analysis.standard.StandardAnalyzer;
29  import org.apache.lucene.index.Term;
30  import org.mmbase.bridge.Cloud;
31  import org.mmbase.bridge.CloudContext;
32  import org.mmbase.bridge.ContextProvider;
33  import org.mmbase.module.Module;
34  import org.mmbase.module.core.MMBase;
35  import org.mmbase.module.core.MMBaseObserver;
36  
37  /***
38   * This object represents the root of the Lucene index, it holds all the tables defined for indexing
39   * 
40   * @author Wouter Heijke
41   * @version $Revision: 1.3 $
42   */
43  public class SearchIndex extends IndexHelper implements MMBaseObserver {
44      private static Log log = LogFactory.getLog(SearchIndex.class);
45      private static CloudProvider cloudProvider = CloudProviderFactory.getCloudProvider();
46      /***
47       * Name of this index (just the name)
48       */
49      private String name;
50  
51      /***
52       * Available tables in this index
53       */
54      private ArrayList tableList = new ArrayList();
55  
56      /***
57       * System temp dir
58       */
59      private String indexPath = System.getProperty("java.io.tmpdir", "tmp") + System.getProperty("file.separator");
60  
61      /***
62       * Lucene Analyzer
63       */
64      private Analyzer analyzer = new StandardAnalyzer();
65  
66      /*** The mmbase instance */
67      private MMBase mmbase = null;
68  
69      /***
70       * 
71       */
72      public SearchIndex() {
73          super();
74          mmbase = (MMBase) Module.getModule("mmbaseroot", true);
75  
76      }
77  
78      /***
79       * Collects all tables
80       * 
81       * @param cloud MMBase cloud to use for indexing
82       */
83      protected void collectAll(Cloud cloud) {
84          create(getIndex(), analyzer);
85          // process all tables stored in this object
86          for (int t = 0; t < tableList.size(); t++) {
87              SourceTable tab = (SourceTable) tableList.get(t);
88              tab.collectAll(cloud, this);
89          }
90          log.info(size() + " indexed documents in " + name);
91          close();
92      }
93  
94      /***
95       * @return All fields defined in this index
96       */
97      public Collection getAllFields() {
98          Set result = new HashSet();
99          for (Iterator it = tableList.iterator(); it.hasNext();) {
100             SourceTable tab = (SourceTable) it.next();
101             result.addAll(tab.getAllFields());
102         }
103         return result;
104     }
105 
106     /***
107      * @return All fulltext fields defined in this index
108      */
109     public Collection getFulltextFields() {
110         Collection result = getAllFields();
111         for (Iterator it = result.iterator(); it.hasNext();) {
112             DataField df = (DataField) it.next();
113             if (!df.isFulltext()) {
114                 it.remove();
115             }
116         }
117         return result;
118     }
119 
120     /***
121      * Setter for the name of the Index
122      * 
123      * @param indexName
124      */
125     public void setName(String indexName) {
126         this.name = indexName;
127     }
128 
129     /***
130      * Getter for the name of the Index
131      * 
132      * @return The name of this Index
133      */
134     public String getName() {
135         return this.name;
136     }
137 
138     /***
139      * Getter for the full name of the Index
140      * 
141      * @return String containing path to the Lucene index
142      */
143     public String getIndex() {
144         return getPath() + getName();
145     }
146 
147     /***
148      * Add a Table object to this object
149      * 
150      * @param table SourceTable object
151      */
152     public void addTable(SourceTable table) {
153         tableList.add(table);
154         // add mmbase node change observer
155         mmbase.addLocalObserver(table.getName(), this);
156 
157         log.info("TABLE: " + table.getName());
158     }
159 
160     /***
161      * Find a table by name in the list of tables attatched to this index
162      * 
163      * @param name Name of the builder/table wer're looking for
164      * @return SourceTable object or null of nothign was found.
165      */
166     public SourceTable getTableByName(String name) {
167         for (int t = 0; t < tableList.size(); t++) {
168             SourceTable tab = (SourceTable) tableList.get(t);
169             if (tab.getName().equalsIgnoreCase(name)) {
170                 return tab;
171             }
172         }
173         return null;
174     }
175 
176     /***
177      * Sets the Analyzer Class
178      * 
179      * @param className the full qualified name of the analyzer class
180      * @throws InstantiationException when the analyzer class can not be instanciated
181      * @throws IllegalAccessException when the analyzer class may not be instanciated
182      * @throws ClassNotFoundException when the analyzer class is not available
183      */
184     public void setAnalyzerClass(String className) throws InstantiationException, IllegalAccessException,
185             ClassNotFoundException {
186         analyzer = (Analyzer) Class.forName(className).newInstance();
187     }
188 
189     /***
190      * Getter for the Analyzer in use in the Index
191      * 
192      * @return an instance of the analyzer
193      */
194     public Analyzer getAnalyzer() {
195         return analyzer;
196     }
197 
198     /***
199      * Getter for the path used to get to the Index
200      * 
201      * @return Returns the path.
202      */
203     public String getPath() {
204         return indexPath;
205     }
206 
207     /***
208      * Set the path to the Index
209      * 
210      * @param path The path to set.
211      */
212     public void setPath(String path) {
213         this.indexPath = path;
214     }
215 
216     /*
217      * (non-Javadoc)
218      * 
219      * @see org.mmbase.module.core.MMBaseObserver#nodeRemoteChanged(java.lang.String, java.lang.String,
220      * java.lang.String, java.lang.String)
221      */
222     public boolean nodeRemoteChanged(String machine, String number, String builder, String ctype) {
223         return false;
224     }
225 
226     /*
227      * (non-Javadoc)
228      * 
229      * @see org.mmbase.module.core.MMBaseObserver#nodeLocalChanged(java.lang.String, java.lang.String, java.lang.String,
230      * java.lang.String)
231      */
232     public boolean nodeLocalChanged(String machine, String number, String builder, String ctype) {
233         // delete the index entry in any case
234         if (ctype.equals("c") || ctype.equals("r") || ctype.equals("d")) { // delete
235             log.debug("delete");
236             Term term = new Term(Constants.NODE_FIELD, number);
237             delete(term);
238         }
239         // and create a new one
240         if (ctype.equals("c") || ctype.equals("r")) {
241             Cloud c = cloudProvider.getCloud();
242             
243             log.debug("change and/or relation (" + ctype + ")");
244             SourceTable table = getTableByName(builder);
245             open();
246             table.collectOne(c.getNode(number), this);
247             close();
248         } else {
249             log.debug("unknown action{" + ctype + " }");
250         }
251         return true;
252     }
253 }