/************************************************************************ * Copyright (c) 2014-2016 IoT-Solutions e.U. * * Licensed 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 iot.jcypher.database; import java.lang.reflect.Method; import java.util.Properties; import org.neo4j.driver.v1.AuthToken; import iot.jcypher.database.remote.BoltDBAccess; /** * A Factory for creating accessors to Neo4j databases. * */ public class DBAccessFactory { /** * create an IDBAccess (an accessor) for a specific database. * @param dbType the type of database to access. Can be * <br/>DBType.REMOTE or DBType.EMBEDDED or DBType.IN_MEMORY * @param properties to configure the database connection. * <br/>The appropriate database access class will pick the properties it needs. * <br/>See also: DBProperties interface for required and optional properties. * @return an instance of IDBAccess */ public static IDBAccess createDBAccess(DBType dbType, Properties properties) { return createDBAccess(dbType, properties, null, null, null); } /** * create an IDBAccess (an accessor) for a specific database, * supports authentication. * @param dbType the type of database to access. Can be * <br/>DBType.REMOTE or DBType.EMBEDDED or DBType.IN_MEMORY * @param properties to configure the database connection. * <br/>The appropriate database access class will pick the properties it needs. * <br/>See also: DBProperties interface for required and optional properties. * @param userId * @param password * @return an instance of IDBAccess */ public static IDBAccess createDBAccess(DBType dbType, Properties properties, String userId, String password) { return createDBAccess(dbType, properties, userId, password, null); } /** * create an IDBAccess (an accessor) for a specific database, * supports authentication. * @param dbType the type of database to access. Can be * <br/>DBType.REMOTE or DBType.EMBEDDED or DBType.IN_MEMORY * @param properties to configure the database connection. * <br/>The appropriate database access class will pick the properties it needs. * <br/>See also: DBProperties interface for required and optional properties. * @param authToken * @return an instance of IDBAccess */ public static IDBAccess createDBAccess(DBType dbType, Properties properties, AuthToken authToken) { return createDBAccess(dbType, properties, null, null, authToken); } @SuppressWarnings("unchecked") private static IDBAccess createDBAccess(DBType dbType, Properties properties, String userId, String password, AuthToken authToken) { Class<? extends IDBAccess> dbAccessClass = null; IDBAccess dbAccess = null; try { switch(dbType) { case REMOTE: if (properties == null) throw new RuntimeException("missing properties in database configuration"); boolean bolt = BoltDBAccess.isBoltProtocol(properties.getProperty(DBProperties.SERVER_ROOT_URI)); if (!DBVersion.Neo4j_Version.startsWith("2") && bolt) dbAccessClass = (Class<? extends IDBAccess>) Class.forName("iot.jcypher.database.remote.BoltDBAccess"); else dbAccessClass = (Class<? extends IDBAccess>) Class.forName("iot.jcypher.database.remote.RemoteDBAccess"); break; case EMBEDDED: if (properties == null) throw new RuntimeException("missing properties in database configuration"); dbAccessClass = (Class<? extends IDBAccess>) Class.forName("iot.jcypher.database.embedded.EmbeddedDBAccess"); break; case IN_MEMORY: dbAccessClass = (Class<? extends IDBAccess>) Class.forName("iot.jcypher.database.embedded.InMemoryDBAccess"); break; default: throw new UnsupportedOperationException("Unexpected DBType: " + dbType); } } catch (Throwable e) { throw new RuntimeException(e); } if (dbAccessClass != null) { try { Method init = dbAccessClass.getMethod("initialize", new Class[] {Properties.class}); dbAccess = dbAccessClass.newInstance(); init.invoke(dbAccess, new Object[] {properties}); if (dbType == DBType.REMOTE) { // authentication only applies to remote db access if (userId != null && password != null) { Method setAuth = dbAccessClass.getDeclaredMethod("setAuth", new Class[] {String.class, String.class}); setAuth.invoke(dbAccess, new Object[] {userId, password}); } else if (authToken != null) { Method setAuth = dbAccessClass.getDeclaredMethod("setAuth", new Class[] {AuthToken.class}); setAuth.invoke(dbAccess, new Object[] {authToken}); } } } catch (Throwable e) { throw new RuntimeException(e); } } return dbAccess; } }