package org.apache.lucene.index;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.lang.reflect.Field;
import org.apache.blur.index.ExitableReader;
import org.apache.blur.lucene.index.FencedDirectory;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockObtainFailedException;
public class BlurIndexWriter extends org.apache.lucene.index.IndexWriter {
public static class LockOwnerException extends IOException {
private static final long serialVersionUID = -8211546713487754992L;
public LockOwnerException(String msg) {
super(msg);
}
}
private final Lock internalLock;
private final boolean _makeReaderExitable;
public BlurIndexWriter(Directory d, IndexWriterConfig conf) throws CorruptIndexException, LockObtainFailedException,
IOException {
this(d, conf, false);
}
public BlurIndexWriter(Directory d, IndexWriterConfig conf, boolean makeReaderExitable) throws CorruptIndexException,
LockObtainFailedException, IOException {
super(fence(d), conf);
try {
internalLock = findInternalLock();
} catch (Exception e) {
throw new RuntimeException("Could not get the write lock instance.", e);
}
_makeReaderExitable = makeReaderExitable;
deleteUnusedFiles();
}
private static Directory fence(Directory directory) {
if (directory instanceof FencedDirectory) {
return directory;
} else {
return new FencedDirectory(directory);
}
}
public Lock getInternalLock() {
return internalLock;
}
@Override
public synchronized void deleteUnusedFiles() throws IOException {
deleter.refresh();
super.deleteUnusedFiles();
}
@Override
DirectoryReader getReader() throws IOException {
return wrap(super.getReader());
}
@Override
DirectoryReader getReader(boolean applyAllDeletes) throws IOException {
return wrap(super.getReader(applyAllDeletes));
}
private DirectoryReader wrap(DirectoryReader reader) {
if (_makeReaderExitable) {
reader = new ExitableReader(reader);
}
return reader;
}
private Lock findInternalLock() throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field field = org.apache.lucene.index.IndexWriter.class.getDeclaredField("writeLock");
field.setAccessible(true);
return (Lock) field.get(this);
}
@Override
protected void doAfterFlush() throws IOException {
super.doAfterFlush();
if (!internalLock.isLocked()) {
throw new LockOwnerException("Lock [" + internalLock + "] no longer has write lock.");
}
}
@Override
protected void doBeforeFlush() throws IOException {
super.doBeforeFlush();
if (!internalLock.isLocked()) {
throw new LockOwnerException("Lock [" + internalLock + "] no longer has write lock.");
}
}
/**
* This seems a little iffy, but basically only the writer instance itself can
* equal itself.
*/
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
return true;
} else if (obj == null) {
return false;
} else if (obj == this) {
return true;
}
return false;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return "IndexWriter with directory [" + getDirectory() + "]";
}
}