package net.ion.craken.node.crud;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import net.ion.craken.node.Credential;
import net.ion.craken.node.ReadSession;
import net.ion.craken.node.Repository;
import net.ion.craken.node.Workspace;
import net.ion.craken.node.convert.rows.ColumnParser;
import net.ion.craken.node.crud.store.OldFileConfigBuilder;
import net.ion.craken.node.crud.store.WorkspaceConfigBuilder;
import net.ion.craken.node.crud.tree.impl.PropertyId;
import net.ion.craken.node.crud.tree.impl.PropertyValue;
import net.ion.framework.schedule.IExecutor;
import net.ion.framework.util.MapUtil;
import net.ion.framework.util.ObjectUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.infinispan.Cache;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import com.google.common.cache.CacheBuilder;
public class Craken implements Repository {
private IExecutor executor;
private com.google.common.cache.Cache<String, Workspace> workspaceCache = CacheBuilder.newBuilder().maximumSize(20).build();
private DefaultCacheManager dm;
private Map<String, Object> attrs = MapUtil.newMap();
private final Log log = LogFactory.getLog(Repository.class);
private String repoId;
private Craken(DefaultCacheManager dm, String repoId) {
this.dm = dm;
this.repoId = repoId ;
this.executor = new IExecutor(0, 3);
putAttribute(ColumnParser.class.getCanonicalName(), new ColumnParser());
}
public static Craken create() throws IOException {
return create(new DefaultCacheManager("./resource/config/craken-cache-config.xml"), "emanon");
}
public static Craken local() throws IOException {
return create(new DefaultCacheManager(), "emanon");
}
public static Craken create(DefaultCacheManager dcm, String repoId){
return new Craken(dcm, repoId);
}
public static Craken inmemoryCreateWithTest() throws CorruptIndexException, IOException {
System.setProperty("log4j.configuration", "file:./resource/log4j.properties") ;
Craken result = local();
return (Craken)result.createWorkspace("test", WorkspaceConfigBuilder.memoryDir());
}
public String memberId() {
return repoId;
}
public String addressId(){
return ObjectUtil.coalesce(dm.getAddress(), "inmemory").toString() ;
}
public List<Address> memberAddress(){
return dm.getMembers() ;
}
public Set<String> workspaceNames() {
return workspaceCache.asMap().keySet() ;
}
// only use for test
public DefaultCacheManager dm() {
return dm;
}
public <T> T getAttribute(String key, Class<T> clz) {
final Object result = attrs.get(key);
if (result == null)
throw new IllegalArgumentException(key + " not found.");
if (clz.isInstance(result))
return clz.cast(result);
throw new IllegalArgumentException(key + " not found.");
}
public Craken putAttribute(String key, Object value) {
attrs.put(key, value);
return this;
}
private boolean started;
public synchronized Repository start() {
if (this.started) return this;
dm.start();
Runtime.getRuntime().addShutdownHook(new Thread(){
public void run(){
Craken.this.shutdown() ;
}
}) ;
started = true ;
log.info(memberId() +" started") ;
return this;
}
public Repository shutdown() {
if (!started) return this ;
for (Workspace ws : workspaceCache.asMap().values()) {
ws.close();
}
workspaceCache.cleanUp();
// dm.<String, StringBuilder> getCache("craken-log").stop();
executor.awaitUnInterupt(500, TimeUnit.MILLISECONDS);
executor.shutdown();
dm.stop();
log.info(memberId() +" shutdowned") ;
this.started = false ;
return this;
}
public IExecutor executor() {
return executor;
}
public Log getLogger(){
return log ;
}
public ReadSession login(String wsname) throws IOException {
return login(Credential.EMANON, wsname, null);
}
public ReadSession login(String wsname, Analyzer queryAnalyzer) throws IOException {
return login(Credential.EMANON, wsname, queryAnalyzer);
}
public ReadSession login(Credential credential, final String wsName, Analyzer queryAnalyzer) throws IOException {
if (! this.started) this.start() ;
Workspace found = workspaceCache.getIfPresent(wsName) ;
if (found == null) throw new IllegalArgumentException("not found workspace : " + wsName) ;
return new ReadSessionImpl(credential, found, ObjectUtil.coalesce(queryAnalyzer, found.central().searchConfig().queryAnalyzer()));
}
public synchronized Repository createWorkspace(String wsName) throws IOException {
return createWorkspace(wsName, OldFileConfigBuilder.directory("")) ;
}
public synchronized Repository createWorkspace(String wsName, WorkspaceConfigBuilder wconfig) throws IOException {
if (workspaceCache.getIfPresent(wsName) != null) throw new IllegalArgumentException("already defined workspace : " + wsName) ;
wconfig.build(dm, wsName) ;
Cache<PropertyId, PropertyValue> cache = dm.getCache(wsName) ;
workspaceCache.put(wsName, wconfig.createWorkspace(this, cache.getAdvancedCache()));
log.info("Workspace[" + wsName + "] defined");
return this ;
}
public boolean isStarted() {
return this.started ;
}
public void stop() {
shutdown() ;
}
}