001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.lucene.util;
018:
019: import java.io.File;
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.List;
023:
024: import org.apache.lucene.analysis.Analyzer;
025: import org.apache.lucene.document.Document;
026: import org.apache.lucene.document.Field;
027: import org.apache.lucene.index.IndexReader;
028: import org.apache.lucene.index.IndexWriter;
029: import org.apache.lucene.index.Term;
030: import org.apache.lucene.index.TermDocs;
031: import org.apache.lucene.index.TermEnum;
032: import org.apache.lucene.search.Hits;
033: import org.apache.lucene.search.Query;
034: import org.apache.lucene.search.TermQuery;
035: import org.apache.lucene.store.Lock;
036: import org.compass.core.Property;
037: import org.compass.core.Resource;
038: import org.compass.core.engine.SearchEngineException;
039: import org.compass.core.engine.SearchEngineFactory;
040: import org.compass.core.lucene.LuceneProperty;
041: import org.compass.core.lucene.LuceneResource;
042: import org.compass.core.lucene.LuceneResourceFactory;
043: import org.compass.core.lucene.engine.LuceneSearchEngine;
044: import org.compass.core.lucene.engine.LuceneSearchEngineFactory;
045: import org.compass.core.lucene.engine.all.AllAnalyzer;
046: import org.compass.core.mapping.AllMapping;
047: import org.compass.core.mapping.BoostPropertyMapping;
048: import org.compass.core.mapping.ResourceMapping;
049: import org.compass.core.spi.InternalResource;
050: import org.compass.core.spi.ResourceKey;
051:
052: /**
053: * @author kimchy
054: */
055: public abstract class LuceneUtils {
056:
057: public static Query buildResourceLoadQuery(ResourceKey resourceKey) {
058: return new TermQuery(new Term(resourceKey.getUIDPath(),
059: resourceKey.buildUID()));
060: }
061:
062: public static Resource[] hitsToResourceArray(
063: final TermDocs termDocs, IndexReader indexReader,
064: LuceneSearchEngine searchEngine) throws IOException {
065: ArrayList<Resource> list = new ArrayList<Resource>();
066: while (termDocs.next()) {
067: list.add(new LuceneResource(indexReader.document(termDocs
068: .doc()), termDocs.doc(), searchEngine
069: .getSearchEngineFactory()));
070: }
071: return list.toArray(new Resource[list.size()]);
072: }
073:
074: public static Resource[] hitsToResourceArray(final Hits hits,
075: LuceneSearchEngine searchEngine)
076: throws SearchEngineException {
077: int length = hits.length();
078: Resource[] result = new Resource[length];
079: for (int i = 0; i < length; i++) {
080: try {
081: result[i] = new LuceneResource(hits.doc(i), hits.id(i),
082: searchEngine.getSearchEngineFactory());
083: } catch (IOException e) {
084: throw new SearchEngineException(
085: "Failed to fetch document from hits.", e);
086: }
087: }
088: return result;
089: }
090:
091: public static void applyBoostIfNeeded(InternalResource resource,
092: SearchEngineFactory searchEngineFactory) {
093: BoostPropertyMapping boostPropertyMapping = resource
094: .resourceKey().getResourceMapping()
095: .getBoostPropertyMapping();
096: if (boostPropertyMapping == null) {
097: return;
098: }
099: float boostValue = boostPropertyMapping.getDefaultBoost();
100: String boostPropertyName = boostPropertyMapping
101: .getBoostResourcePropertyName();
102: String sBoostValue = resource.getValue(boostPropertyName);
103: if (!searchEngineFactory.getResourceFactory().isNullValue(
104: sBoostValue)) {
105: boostValue = Float.parseFloat(sBoostValue);
106: }
107: resource.setBoost(boostValue);
108: }
109:
110: public static void createResource(IndexWriter indexWriter,
111: Resource resource, Analyzer analyzer)
112: throws SearchEngineException {
113: Document document = ((LuceneResource) resource).getDocument();
114: try {
115: indexWriter.addDocument(document, analyzer);
116: } catch (IOException e) {
117: throw new SearchEngineException(
118: "Failed to create resource " + resource, e);
119: }
120: }
121:
122: public static void addExtendedProeprty(Resource resource,
123: ResourceMapping resourceMapping,
124: LuceneSearchEngineFactory searchEngineFactory) {
125: String extendedAliasProperty = searchEngineFactory
126: .getExtendedAliasProperty();
127: resource.removeProperties(extendedAliasProperty);
128: for (int i = 0; i < resourceMapping.getExtendedAliases().length; i++) {
129: LuceneProperty extendedAliasProp = (LuceneProperty) searchEngineFactory
130: .getResourceFactory().createProperty(
131: extendedAliasProperty,
132: resourceMapping.getExtendedAliases()[i],
133: Property.Store.NO,
134: Property.Index.UN_TOKENIZED);
135: extendedAliasProp.getField().setOmitNorms(true);
136: resource.addProperty(extendedAliasProp);
137: }
138:
139: }
140:
141: public static Analyzer addAllProperty(InternalResource resource,
142: Analyzer analyzer, ResourceMapping resourceMapping,
143: LuceneSearchEngine searchEngine)
144: throws SearchEngineException {
145: AllAnalyzer allAnalyzer = new AllAnalyzer(analyzer, resource,
146: searchEngine);
147: AllMapping allMapping = resourceMapping.getAllMapping();
148: Property property = ((LuceneResourceFactory) searchEngine
149: .getSearchEngineFactory().getResourceFactory())
150: .createProperty(allMapping.getProperty(), allAnalyzer
151: .createAllTokenStream(), allMapping
152: .getTermVector());
153: property.setOmitNorms(allMapping.isOmitNorms());
154: resource.addProperty(property);
155: return allAnalyzer;
156: }
157:
158: public static List<String> findPropertyValues(
159: IndexReader indexReader, String propertyName)
160: throws SearchEngineException {
161: ArrayList<String> list = new ArrayList<String>();
162: try {
163: TermEnum te = indexReader.terms(new Term(propertyName, ""));
164: while (propertyName.equals(te.term().field())) {
165: String value = te.term().text();
166: list.add(value);
167: if (!te.next()) {
168: break;
169: }
170: }
171: } catch (IOException e) {
172: throw new SearchEngineException(
173: "Failed to read property values for property ["
174: + propertyName + "]");
175: }
176: return list;
177: }
178:
179: public static Field.Index getFieldIndex(Property.Index index)
180: throws SearchEngineException {
181: if (index == Property.Index.TOKENIZED) {
182: return Field.Index.TOKENIZED;
183: }
184:
185: if (index == Property.Index.UN_TOKENIZED) {
186: return Field.Index.UN_TOKENIZED;
187: }
188:
189: if (index == Property.Index.NO) {
190: return Field.Index.NO;
191: }
192:
193: throw new SearchEngineException(
194: "No index type is defined for [" + index + "]");
195: }
196:
197: public static Field.Store getFieldStore(Property.Store store)
198: throws SearchEngineException {
199: if (store == Property.Store.YES) {
200: return Field.Store.YES;
201: }
202:
203: if (store == Property.Store.NO) {
204: return Field.Store.NO;
205: }
206:
207: if (store == Property.Store.COMPRESS) {
208: return Field.Store.COMPRESS;
209: }
210:
211: throw new SearchEngineException(
212: "No store type is defined for [" + store + "]");
213: }
214:
215: public static Field.TermVector getFieldTermVector(
216: Property.TermVector termVector)
217: throws SearchEngineException {
218: if (termVector == Property.TermVector.NO) {
219: return Field.TermVector.NO;
220: }
221:
222: if (termVector == Property.TermVector.YES) {
223: return Field.TermVector.YES;
224: }
225:
226: if (termVector == Property.TermVector.WITH_OFFSETS) {
227: return Field.TermVector.WITH_OFFSETS;
228: }
229:
230: if (termVector == Property.TermVector.WITH_POSITIONS) {
231: return Field.TermVector.WITH_POSITIONS;
232: }
233:
234: if (termVector == Property.TermVector.WITH_POSITIONS_OFFSETS) {
235: return Field.TermVector.WITH_POSITIONS_OFFSETS;
236: }
237:
238: throw new SearchEngineException(
239: "No term vector type is defined for [" + termVector
240: + "]");
241: }
242:
243: public static boolean deleteDir(File dir) {
244: boolean globalSuccess = true;
245: if (dir.isDirectory()) {
246: String[] children = dir.list();
247: if (children != null) {
248: for (String aChildren : children) {
249: boolean success = deleteDir(new File(dir, aChildren));
250: if (!success) {
251: globalSuccess = false;
252: }
253: }
254: }
255: }
256: // The directory is now empty so delete it
257: if (!dir.delete()) {
258: globalSuccess = false;
259: }
260: return globalSuccess;
261: }
262:
263: public static void clearLocks(Lock[] locks) {
264: if (locks == null) {
265: return;
266: }
267: for (Lock lock : locks) {
268: if (lock != null) {
269: try {
270: lock.release();
271: } catch (IOException e) {
272: // ignore
273: }
274: }
275: }
276: }
277: }
|