package er.neo4jadaptor.storage; import java.util.HashMap; import java.util.Map; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.PropertyContainer; import com.webobjects.eoaccess.EOEntity; import er.neo4jadaptor.ersatz.Ersatz; import er.neo4jadaptor.ersatz.neo4j.Neo4JErsatz; import er.neo4jadaptor.storage.lucene.LuceneStore; import er.neo4jadaptor.storage.neo4j.NodeSpaceManager; import er.neo4jadaptor.storage.neo4j.NodeStore; import er.neo4jadaptor.storage.neo4j.RelationshipStore; import er.neo4jadaptor.storage.neo4j.TemporaryNodePool; /** * Provides Neo4J+Lucene hybrid store for each entity in Neo4J graph database. * * @author Jedrzej Sobanski */ public class StoreFactory { private final Map<String, Store<Ersatz, Neo4JErsatz>> map = new HashMap<String, Store<Ersatz, Neo4JErsatz>>(); private final GraphDatabaseService db; private final NodeSpaceManager spaceManager; private final TemporaryNodePool tempNodePool; /** * Create store factory for the given database. * * @param db graph database * @return store factory */ public static StoreFactory create(GraphDatabaseService db) { return new StoreFactory(db, new NodeSpaceManager(db)); } private StoreFactory(GraphDatabaseService db, NodeSpaceManager spaceManager) { this.db = db; this.spaceManager = spaceManager; tempNodePool = new TemporaryNodePool(db, spaceManager); } /** * Lazy gets store for the given entity. If such a store already exists then it will be returned * instead of recreating. * * @param <Type> * @param entity * @return store that's capable of handling requested entity */ public <Type extends PropertyContainer> Store<Ersatz, Neo4JErsatz> storeForEntity(EOEntity entity) { String label = toLabel(entity); Store<Ersatz, Neo4JErsatz> store = map.get(label); if (store == null) { int countPrimaryKeys = entity.primaryKeyAttributes().count(); Store<Ersatz, Neo4JErsatz> neoStore; LuceneStore<Type> luceneStore = new LuceneStore<>(db, entity); if (countPrimaryKeys == 1) { neoStore = new NodeStore(db, entity, spaceManager, tempNodePool); } else if (countPrimaryKeys == 2) { neoStore = new RelationshipStore(db, entity); } else { throw new IllegalArgumentException(); } store = new CompositeStore<>(neoStore, luceneStore); map.put(label, store); } return store; } private String toLabel(EOEntity entity) { return entity.name(); } public TemporaryNodePool getTemporaryNodePool() { return tempNodePool; } }