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.engine.transaction;
018:
019: import java.io.IOException;
020: import java.util.ArrayList;
021:
022: import org.apache.lucene.analysis.Analyzer;
023: import org.apache.lucene.search.Filter;
024: import org.apache.lucene.search.Hits;
025: import org.apache.lucene.search.Query;
026: import org.apache.lucene.search.Sort;
027: import org.compass.core.engine.SearchEngineException;
028: import org.compass.core.engine.SearchEngineHits;
029: import org.compass.core.engine.SearchEngineInternalSearch;
030: import org.compass.core.engine.SearchEngineQuery;
031: import org.compass.core.lucene.engine.LuceneDelegatedClose;
032: import org.compass.core.lucene.engine.LuceneSearchEngine;
033: import org.compass.core.lucene.engine.LuceneSearchEngineHits;
034: import org.compass.core.lucene.engine.LuceneSearchEngineInternalSearch;
035: import org.compass.core.lucene.engine.LuceneSearchEngineQuery;
036: import org.compass.core.lucene.engine.analyzer.LuceneAnalyzerManager;
037: import org.compass.core.lucene.engine.manager.LuceneSearchEngineIndexManager;
038: import org.compass.core.mapping.CompassMapping;
039: import org.compass.core.mapping.ResourceMapping;
040: import org.compass.core.spi.InternalResource;
041: import org.compass.core.spi.ResourceKey;
042:
043: /**
044: * A base class for all Lucene based transactions. Provides helper methods for
045: * Lucene index transaction management, and default state management for the
046: * transcational operations.
047: *
048: * @author kimchy
049: */
050: public abstract class AbstractTransaction implements
051: LuceneSearchEngineTransaction {
052:
053: protected LuceneSearchEngine searchEngine;
054:
055: protected LuceneSearchEngineIndexManager indexManager;
056:
057: protected CompassMapping mapping;
058:
059: protected LuceneAnalyzerManager analyzerManager;
060:
061: private ArrayList<LuceneDelegatedClose> delegateClose = new ArrayList<LuceneDelegatedClose>();
062:
063: protected boolean dirty;
064:
065: public void configure(LuceneSearchEngine searchEngine) {
066: this .searchEngine = searchEngine;
067: this .indexManager = searchEngine.getSearchEngineFactory()
068: .getLuceneIndexManager();
069: this .mapping = searchEngine.getSearchEngineFactory()
070: .getMapping();
071: this .analyzerManager = searchEngine.getSearchEngineFactory()
072: .getAnalyzerManager();
073: }
074:
075: public void begin() throws SearchEngineException {
076: closeDelegateClosed();
077: doBegin();
078: }
079:
080: protected abstract void doBegin() throws SearchEngineException;
081:
082: public void rollback() throws SearchEngineException {
083: closeDelegateClosed();
084: doRollback();
085: }
086:
087: protected abstract void doRollback() throws SearchEngineException;
088:
089: public void prepare() throws SearchEngineException {
090: doPrepare();
091: }
092:
093: protected abstract void doPrepare() throws SearchEngineException;
094:
095: public void commit(boolean onePhase) throws SearchEngineException {
096: closeDelegateClosed();
097: doCommit(onePhase);
098: }
099:
100: protected abstract void doCommit(boolean onePhase)
101: throws SearchEngineException;
102:
103: public SearchEngineHits find(SearchEngineQuery query)
104: throws SearchEngineException {
105: LuceneSearchEngineHits hits = doFind((LuceneSearchEngineQuery) query);
106: delegateClose.add(hits);
107: return hits;
108: }
109:
110: protected abstract LuceneSearchEngineHits doFind(
111: LuceneSearchEngineQuery query) throws SearchEngineException;
112:
113: public SearchEngineInternalSearch internalSearch(
114: String[] subIndexes, String[] aliases)
115: throws SearchEngineException {
116: LuceneSearchEngineInternalSearch internalSearch = doInternalSearch(
117: subIndexes, aliases);
118: delegateClose.add(internalSearch);
119: return internalSearch;
120: }
121:
122: protected abstract LuceneSearchEngineInternalSearch doInternalSearch(
123: String[] subIndexes, String[] aliases)
124: throws SearchEngineException;
125:
126: public void create(final InternalResource resource,
127: Analyzer analyzer) throws SearchEngineException {
128: dirty = true;
129: doCreate(resource, analyzer);
130: }
131:
132: protected abstract void doCreate(final InternalResource resource,
133: Analyzer analyzer) throws SearchEngineException;
134:
135: public void delete(final ResourceKey resourceKey)
136: throws SearchEngineException {
137: dirty = true;
138: doDelete(resourceKey);
139: }
140:
141: protected abstract void doDelete(final ResourceKey resourceKey)
142: throws SearchEngineException;
143:
144: public void update(InternalResource resource, Analyzer analyzer)
145: throws SearchEngineException {
146: dirty = true;
147: doUpdate(resource, analyzer);
148: }
149:
150: protected void doUpdate(InternalResource resource, Analyzer analyzer)
151: throws SearchEngineException {
152: doDelete(resource.resourceKey());
153: doCreate(resource, analyzer);
154: }
155:
156: public boolean isDirty() {
157: return dirty;
158: }
159:
160: protected void closeDelegateClosed() throws SearchEngineException {
161: for (LuceneDelegatedClose delegatedClose : delegateClose) {
162: try {
163: delegatedClose.close();
164: } catch (Exception e) {
165: // swallow the exception
166: }
167: }
168: delegateClose.clear();
169: }
170:
171: protected ResourceMapping getResourceMapping(String alias) {
172: return mapping.getRootMappingByAlias(alias);
173: }
174:
175: protected Hits findByQuery(
176: LuceneSearchEngineInternalSearch internalSearch,
177: LuceneSearchEngineQuery searchEngineQuery, Filter filter)
178: throws SearchEngineException {
179: Query query = searchEngineQuery.getQuery();
180: if (searchEngineQuery.isRewrite()) {
181: try {
182: query = query.rewrite(internalSearch.getReader());
183: } catch (IOException e) {
184: throw new SearchEngineException(
185: "Failed to rewrite query [" + query.toString()
186: + "]", e);
187: }
188: }
189: Sort sort = searchEngineQuery.getSort();
190: Hits hits;
191: try {
192: if (filter == null) {
193: hits = internalSearch.getSearcher().search(query, sort);
194: } else {
195: hits = internalSearch.getSearcher().search(query,
196: filter, sort);
197: }
198: } catch (IOException e) {
199: throw new SearchEngineException(
200: "Failed to search with query [" + query + "]", e);
201: }
202: return hits;
203: }
204: }
|