/* * 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. */ package org.apache.jena.sdb.store; import static java.lang.String.format ; import static org.apache.jena.sdb.store.DatabaseType.* ; import static org.apache.jena.sdb.store.LayoutType.* ; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.jena.sdb.SDB ; import org.apache.jena.sdb.Store ; import org.apache.jena.sdb.StoreDesc ; import org.apache.jena.sdb.layout1.* ; import org.apache.jena.sdb.layout2.hash.* ; import org.apache.jena.sdb.layout2.index.* ; import org.apache.jena.sdb.sql.SDBConnection ; import org.apache.jena.sdb.sql.SDBConnectionDesc ; import org.apache.jena.sdb.sql.SDBConnectionFactory ; import org.apache.jena.sdb.util.Pair ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Construct Stores */ public class StoreFactory { private static Logger log = LoggerFactory.getLogger(StoreFactory.class) ; static { SDB.init() ; } /** * Create a store, based on the store description and * connection information read from the file. * @param filename * @return Store */ public static Store create(String filename) { return create(StoreDesc.read(filename), null) ; } /** * Create a store, based on connection, layout type and database type. * * @param sdb * @param layout * @param dbType * @return Store */ public static Store create(SDBConnection sdb, LayoutType layout, DatabaseType dbType) { StoreDesc desc = new StoreDesc(layout, dbType) ; return create(desc, sdb) ; } /** * Create a store, based on the store description. * The store description must include connection details if to be used to actually connect. */ public static Store create(LayoutType layout, DatabaseType dbType) { StoreDesc desc = new StoreDesc(layout, dbType) ; return create(desc, null) ; } /** * Create a store, based on the store description. * The store description must include connection details if to be used to actually connect. */ public static Store create(StoreDesc desc) { return create(desc, null) ; } /** * Create a store, based on the store description and connection. */ public static Store create(StoreDesc desc, SDBConnection sdb) { Store store = _create(sdb, desc) ; return store ; } private static Store _create(SDBConnection sdb, StoreDesc desc) { if ( sdb == null && desc.connDesc == null ) desc.connDesc = SDBConnectionDesc.none() ; if ( sdb == null && desc.connDesc.getType() == null && desc.getDbType() != null ) desc.connDesc.setType(desc.getDbType().getName()) ; if ( sdb == null && desc.connDesc != null) sdb = SDBConnectionFactory.create(desc.connDesc) ; DatabaseType dbType = desc.getDbType() ; LayoutType layoutType = desc.getLayout() ; return _create(desc, sdb, dbType, layoutType) ; } private static Store _create(StoreDesc desc, SDBConnection sdb, DatabaseType dbType, LayoutType layoutType) { StoreMaker f = registry.get(dbType, layoutType) ; if ( f == null ) { log.warn(format("No factory for (%s, %s)", dbType.getName(), layoutType.getName())) ; return null ; } return f.create(sdb, desc) ; } // Need to sort out that SDBConnection needs the type as well /** Register a new store maker for a given database/layout pair. * Overwrites any previous StoreMaker for this pair. * Only used when adding a new database or layout - the standard * ones are automatically registered. */ public static void register(DatabaseType dbType, LayoutType layoutType, StoreMaker factory) { registry.put(dbType, layoutType, factory) ; } private static class Registry extends MapK2<DatabaseType, LayoutType, StoreMaker> {} private static Registry registry = new Registry() ; static { setRegistry() ; checkRegistry() ; } static private void setRegistry() { // registry.clear() ; // -- Hash layout register(Derby, LayoutTripleNodesHash, new StoreMaker(){ @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashDerby(conn, desc) ; } }) ; register(HSQLDB, LayoutTripleNodesHash, new StoreMaker(){ @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashHSQL(conn, desc) ; }} ) ; /* H2 contribution from Martin HEIN (m#)/March 2008 */ register(H2, LayoutTripleNodesHash, new StoreMaker(){ @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashH2(conn, desc) ; }} ) ; register(MySQL, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashMySQL(conn, desc, desc.engineType) ; } }) ; // Treat as MySQL register(MariaDB, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashMySQL(conn, desc, desc.engineType) ; } }) ; register(PostgreSQL, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashPGSQL(conn, desc) ; } }) ; register(SQLServer, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashSQLServer(conn, desc) ; } }) ; register(Oracle, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashOracle(conn, desc) ; } }) ; register(DB2, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashDB2(conn, desc) ; } }) ; /* SAP contribution from Fergal Monaghan (m#)/May 2012 */ register(SAP, LayoutTripleNodesHash, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesHashSAP(conn, desc, desc.storageType) ; } }) ; // -- Index layout register(Derby, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexDerby(conn, desc) ; } }) ; register(HSQLDB, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexHSQL(conn, desc) ; } }) ; register(H2, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexH2(conn, desc) ; } }) ; register(MySQL, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexMySQL(conn, desc, desc.engineType) ; } }) ; register(MariaDB, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexMySQL(conn, desc, desc.engineType) ; } }) ; register(PostgreSQL, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexPGSQL(conn, desc) ; } }) ; register(SQLServer, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexSQLServer(conn, desc) ; } }) ; register(Oracle, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexOracle(conn, desc) ; } }) ; register(DB2, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexDB2(conn, desc) ; } }) ; register(SAP, LayoutTripleNodesIndex, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreTriplesNodesIndexSAP(conn, desc, desc.storageType) ; } }) ; // -- Simple layout register(Derby, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleDerby(conn, desc) ; } }) ; register(HSQLDB, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleHSQL(conn, desc) ; } }) ; register(H2, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleH2(conn, desc) ; } }) ; register(MySQL, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleMySQL(conn, desc, desc.engineType) ; } }) ; register(MariaDB, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleMySQL(conn, desc, desc.engineType) ; } }) ; register(PostgreSQL, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimplePGSQL(conn, desc) ; } }) ; register(SQLServer, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleSQLServer(conn, desc) ; } }) ; register(Oracle, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleOracle(conn, desc) ; } }) ; register(DB2, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleDB2(conn, desc) ; } }) ; register(SAP, LayoutSimple, new StoreMaker() { @Override public Store create(SDBConnection conn, StoreDesc desc) { return new StoreSimpleSAP(conn, desc, desc.storageType) ; } }) ; } static private void checkRegistry() { DatabaseType[] dbTypes = {Derby, HSQLDB, H2, MySQL, MariaDB, PostgreSQL, SQLServer, Oracle, SAP} ; LayoutType[] layoutTypes = {LayoutTripleNodesHash, LayoutTripleNodesIndex, LayoutSimple} ; Set <StoreMaker> seen = new HashSet<StoreMaker>() ; for ( DatabaseType k1 : dbTypes ) for ( LayoutType k2 : layoutTypes ) { if ( ! registry.containsKey(k1, k2) ) log.warn(format("Missing store maker: (%s, %s)", k1.getName(), k2.getName())) ; StoreMaker x = registry.get(k1, k2) ; if ( seen.contains(x) ) log.warn(format("Duplicate store maker: (%s, %s)", k1.getName(), k2.getName())) ; seen.add(x) ; } } // Convenience. static class MapK2<K1, K2, V> { private Map <Pair<K1, K2>, V> map = null ; public MapK2() { map = new HashMap<Pair<K1, K2>, V>() ; } public MapK2(Map <Pair<K1, K2>, V> map) { this.map = map ; } public V get(K1 key1, K2 key2) { return map.get(new Pair<K1, K2>(key1, key2)) ; } public void put(K1 key1, K2 key2, V value) { map.put(new Pair<K1, K2>(key1, key2), value) ; } public boolean containsKey(K1 key1, K2 key2) { return map.containsKey(new Pair<K1, K2>(key1, key2)) ; } public boolean containsValue(V value) { return map.containsValue(value) ; } public int size() { return map.size() ; } public boolean isEmpty() { return map.isEmpty() ; } public void clear() { map.clear() ; } } }