001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.cocoon.components.search;
017:
018: import java.io.File;
019: import java.io.IOException;
020: import java.util.Date;
021:
022: import org.apache.avalon.framework.configuration.ConfigurationException;
023: import org.apache.avalon.framework.service.ServiceException;
024: import org.apache.avalon.framework.service.ServiceManager;
025: import org.apache.cocoon.components.search.components.AnalyzerManager;
026: import org.apache.cocoon.components.search.components.Indexer;
027: import org.apache.cocoon.components.search.fieldmodel.DateFieldDefinition;
028: import org.apache.cocoon.components.search.fieldmodel.FieldDefinition;
029: import org.apache.lucene.document.Document;
030: import org.apache.lucene.document.Field;
031: import org.apache.lucene.index.IndexReader;
032: import org.apache.lucene.index.IndexWriter;
033: import org.apache.lucene.store.Directory;
034: import org.apache.lucene.store.FSDirectory;
035:
036: /**
037: * Index Class
038: *
039: * @author Nicolas Maisonneuve
040: */
041: public class Index {
042:
043: /**
044: * default analyzer ID
045: */
046: private String defaultAnalyzer;
047:
048: /**
049: * Index Structure definition
050: */
051: private IndexStructure structure;
052:
053: /**
054: * Index ID
055: */
056: private String id;
057:
058: /**
059: * Lucene Directory of the index
060: */
061: private Directory directory;
062:
063: /**
064: * Number of try to access to the indexer
065: *
066: */
067: private int numtries = 5;
068:
069: /**
070: * is the indexer working (not released)
071: */
072: private boolean indexer_busy;
073:
074: /**
075: * Indexer Role name
076: */
077: private String indexer_role;
078:
079: private ServiceManager manager;
080:
081: /**
082: * Create a lucene document
083: *
084: * @param uid
085: * String the document uid
086: * @return Document a empty document
087: */
088: public Document createDocument(String uid) {
089: Document doc = new Document();
090: try {
091: doc.add(createField(Indexer.DOCUMENT_UID_FIELD, uid));
092: } catch (IndexException ex) {
093: }
094: return doc;
095: }
096:
097: /**
098: * create a lucene field
099: *
100: * @param fieldname
101: * String fieldname (must existed in the index structure)
102: * @param value
103: * String value
104: */
105: public Field createField(String fieldname, String value)
106: throws IndexException {
107: FieldDefinition f = structure.getFieldDef(fieldname);
108: if (f == null) {
109: throw new IndexException("Field with the name: "
110: + fieldname + " doesn't exist");
111: }
112: return f.createLField(value);
113: }
114:
115: /**
116: * create a lucene field for date value
117: *
118: * @param fieldname
119: * String fieldname (must existed in the index structure)
120: * @param value
121: * String value
122: */
123: public Field createField(String fieldname, Date value)
124: throws IndexException {
125: DateFieldDefinition f = (DateFieldDefinition) structure
126: .getFieldDef(fieldname);
127: if (f == null) {
128: throw new IndexException("Field with the name: "
129: + fieldname + " doesn't exist");
130: }
131: return f.createLField(value);
132: }
133:
134: /**
135: * get the indexer of the index
136: *
137: * @throws IndexException
138: * @return Indexer
139: */
140: public synchronized Indexer getIndexer() throws IndexException {
141:
142: long endTime = System.currentTimeMillis() + numtries * 1000;
143: // wait the end of the indexing
144: while (indexer_busy && System.currentTimeMillis() < endTime) {
145: try {
146: wait(1000);
147: } catch (InterruptedException ex) {
148: }
149: }
150:
151: if (indexer_busy) {
152: throw new IndexException(
153: "Timeout to access to the indexer (the indexer is indexing)");
154: }
155: AnalyzerManager analyzerM = null;
156: try {
157:
158: indexer_busy = true;
159: Indexer indexer = (Indexer) this .manager
160: .lookup(indexer_role);
161:
162: // update maybe the analyzer
163: analyzerM = (AnalyzerManager) this .manager
164: .lookup(AnalyzerManager.ROLE);
165:
166: indexer.setAnalyzer(analyzerM
167: .getAnalyzer(getDefaultAnalyzerID()));
168: indexer.setIndex(directory);
169:
170: return indexer;
171: } catch (ServiceException ex1) {
172: throw new IndexException(ex1);
173: } catch (ConfigurationException ex2) {
174: throw new IndexException(ex2);
175: } finally {
176: if (analyzerM != null) {
177: manager.release(analyzerM);
178: }
179: }
180: }
181:
182: /**
183: * Release the indexer
184: *
185: * @param indexer
186: */
187: public synchronized void releaseIndexer(Indexer indexer) {
188: if (indexer != null) {
189: this .manager.release(indexer);
190: indexer_busy = false;
191: }
192: notifyAll();
193: }
194:
195: /**
196: * get the index ID
197: *
198: * @return the index ID
199: */
200: public String getID() {
201: return id;
202: }
203:
204: /**
205: * Set the index ID
206: *
207: * @param id
208: * index ID
209: */
210: public void setID(String id) {
211: this .id = id;
212: }
213:
214: /**
215: * get the default Analyzer
216: *
217: * @return the id of the default analyzer
218: */
219: public String getDefaultAnalyzerID() {
220: return defaultAnalyzer;
221: }
222:
223: /**
224: * set the default Analyzer
225: *
226: * @param defaultAnalyzerID
227: * the id of the default Analyzer
228: */
229: public void setDefaultAnalyzerID(String defaultAnalyzerID) {
230: this .defaultAnalyzer = defaultAnalyzerID;
231: }
232:
233: /**
234: * Return the index Structure
235: *
236: * @return the index Structure
237: */
238: public IndexStructure getStructure() {
239: return structure;
240: }
241:
242: /**
243: * Set the index structure
244: *
245: * @param structure
246: * IndexStructure
247: */
248: public void setStructure(IndexStructure structure) {
249: this .structure = structure;
250: }
251:
252: public void setManager(ServiceManager manager) {
253: this .manager = manager;
254: }
255:
256: /**
257: * get the lucene directory
258: *
259: * @return the lucene directory
260: */
261: public Directory getDirectory() {
262: return directory;
263: }
264:
265: /**
266: * Set the lucene Directory
267: *
268: * @param dir
269: * lucene Directory
270: * @return success or not
271: * @throws IOException
272: */
273: public boolean setDirectory(Directory dir) throws IOException {
274: boolean locked = false;
275: this .directory = dir;
276:
277: // if index is locked
278: if (IndexReader.isLocked(directory)) {
279: IndexReader.unlock(directory);
280: locked = true;
281: }
282:
283: // create index if the index doesn't exist
284: if (!IndexReader.indexExists(directory)) {
285: (new IndexWriter(directory, null, true)).close();
286: }
287:
288: return locked;
289:
290: }
291:
292: /**
293: * Set the index path directory
294: *
295: * @param path
296: * String
297: * @throws IOException
298: */
299: public boolean setDirectory(String path) throws IOException {
300: File fpath = new File(path);
301: Directory dir = FSDirectory
302: .getDirectory(fpath, !fpath.exists());
303: return setDirectory(dir);
304: }
305:
306: /**
307: * @param indexer The indexer to set.
308: */
309: public void setIndexer(String indexer) {
310: this.indexer_role = indexer;
311: }
312: }
|