package com.mysema.luja.impl;
import java.io.IOException;
import java.util.Locale;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mysema.luja.LuceneSession;
import com.mysema.luja.LuceneWriter;
import com.mysema.luja.SessionClosedException;
import com.mysema.luja.SessionReadOnlyException;
import com.mysema.luja.serializer.AnnotationSerializer;
import com.mysema.query.QueryException;
import com.mysema.query.lucene.LuceneQuery;
import com.mysema.query.lucene.LuceneSerializer;
public class LuceneSessionImpl implements LuceneSession {
private static final Logger logger = LoggerFactory.getLogger(LuceneSessionHolder.class);
private final boolean readOnly;
private boolean closed = false;
private final LuceneSessionFactoryImpl sessionFactory;
@Nullable
private LuceneSearcher searcher;
@Nullable
private FileLockingWriter writer;
private final LuceneSerializer serializer;
public LuceneSessionImpl(LuceneSessionFactoryImpl sessionFactory, boolean readOnly, Locale sortLocale) {
this.sessionFactory = sessionFactory;
this.readOnly = readOnly;
this.serializer = new AnnotationSerializer(sortLocale);
}
@Override
public LuceneQuery createQuery() {
checkClosed();
return new LuceneQuery(serializer, getSearcher().getIndexSearcer());
}
@Override
public LuceneWriter beginAppend() {
checkClosed();
return getWriter(false);
}
@Override
public LuceneWriter beginReset() {
checkClosed();
return getWriter(true);
}
@Override
public boolean isClosed() {
return closed;
}
@Override
public void close() {
if (closed) {
return;
}
QueryException searcherException = null;
if (searcher != null) {
try {
sessionFactory.release(searcher);
} catch (QueryException e) {
logger.error("Searcher release failed", e);
searcherException = e;
}
}
if (writer != null) {
sessionFactory.release(writer);
}
if (searcherException != null) {
throw searcherException;
}
closed = true;
}
@Override
public void rollback() {
checkClosed();
//TODO How to get all the exceptions out, not only the first one
try {
if (writer != null) {
if (logger.isDebugEnabled()) {
logger.debug("Rollbacking session");
}
writer.getIndexWriter().rollback();
}
} catch (IOException e) {
logger.error("Session rollback failed " + e);
throw new QueryException(e);
} finally {
close();
}
}
@Override
public void commit() {
checkClosed();
if (writer != null) {
writer.commit();
}
if (searcher != null) {
sessionFactory.release(searcher);
}
searcher = null;
}
@Override
public void flush() {
commit();
}
private LuceneSearcher getSearcher() {
if (searcher == null) {
searcher = sessionFactory.leaseSearcher();
}
return searcher;
}
private LuceneWriter getWriter(boolean createNew) {
if (readOnly) {
throw new SessionReadOnlyException("Read only session, cannot create writer");
}
if (writer == null) {
writer = sessionFactory.leaseWriter(createNew);
}
return writer;
}
private void checkClosed() {
if (closed) {
throw new SessionClosedException("Session is closed");
}
}
}