/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.procore; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Properties; import org.simantics.db.Database; import org.simantics.db.DatabaseUserAgent; import org.simantics.db.Driver; import org.simantics.db.Driver.Management; import org.simantics.db.ServerI; import org.simantics.db.Session; import org.simantics.db.authentication.UserAuthenticationAgent; import org.simantics.db.authentication.UserAuthenticator; import org.simantics.db.common.auth.UserAuthenticationAgents; import org.simantics.db.common.auth.UserAuthenticators; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InternalException; import org.simantics.db.exception.SDBException; import org.simantics.db.server.DatabaseManager; import org.simantics.db.server.ProCoreException; import fi.vtt.simantics.procore.BackdoorAuthenticator; import fi.vtt.simantics.procore.ProCoreServerReference; import fi.vtt.simantics.procore.ProCoreSessionReference; import fi.vtt.simantics.procore.SessionManagerSource; public class ProCoreDriver implements Driver { private static long sessionId = SessionManagerSource.NullSessionId; public static final String ProCoreDriverName = "procore"; public static final String ProCoreDriverNameVirtual = "virtual"; @Override public final String getName() { return ProCoreDriverName; } @Override public DatabaseUserAgent getDatabaseUserAgent(String address) throws DatabaseException { Path dbFolder = Paths.get(address); return DatabaseManager.getDatabase(dbFolder).getUserAgent(); } @Override public void setDatabaseUserAgent(String address, DatabaseUserAgent dbUserAgent) throws DatabaseException { Path dbFolder = Paths.get(address); DatabaseManager.getDatabase(dbFolder).setUserAgent(dbUserAgent); } @Override public Session getSession(String address, Properties properties) throws SDBException { Path dbFolder = Paths.get(address); if (!Files.isDirectory(dbFolder)) throw new ProCoreException("Database folder does not exist. folder=" + dbFolder); Database db = DatabaseManager.getDatabase(dbFolder); if (!db.isFolderOk()) throw new ProCoreException("Database folder is not ok. folder=" + dbFolder); if (!db.isRunning()) db.start(); if (!db.isConnected()) db.connect(); Session session; ProCoreServerReference serverReference = new ProCoreServerReference(dbFolder); ProCoreSessionReference sessionReference = new ProCoreSessionReference(serverReference, ++sessionId); try { String user = properties.getProperty("user"); String password= properties.getProperty("password"); if (user == null) throw new ProCoreException("'user' property not provided"); if (password == null) throw new ProCoreException("'password' property not provided"); UserAuthenticator authenticator = UserAuthenticators.byNameAndPassword(user, password); // FIXME: remove this hack once the server gets proper authentication if (properties.getProperty("hyshys") != null) authenticator = new BackdoorAuthenticator(); UserAuthenticationAgent agent = UserAuthenticationAgents.staticAgent(authenticator); session = SessionManagerSource.getSessionManager().createSession(sessionReference, agent); if (!properties.containsKey("clientId")) properties.put("clientId", dbFolder.toFile().getAbsolutePath()); session.registerService(Properties.class, properties); Session s = session.peekService(Session.class); if (null == s) session.registerService(Session.class, session); return session; } catch (IOException e) { throw new ProCoreException("Connect failed. address=" + serverReference.toString(), e); } catch (org.simantics.db.exception.DatabaseException e) { throw new ProCoreException("Connect failed. address=" + serverReference.toString(), e); } } @Override public ServerI getServer(String address, Properties notUsed) throws ProCoreException { Path dbFolder = Paths.get(address); return new ProCoreServer(dbFolder.toFile()); } @Override public Management getManagement(String address, Properties properties) throws DatabaseException { Path dbFolder = Paths.get(address); return new ProCoreManagement(dbFolder, properties); } } class ProCoreServer implements ServerI { private final Database db; ProCoreServer(File dbFolder) throws ProCoreException { db = DatabaseManager.getDatabase(dbFolder.toPath()); } @Override public String execute(String aCommand) throws InternalException { return db.execute(aCommand); } @Override public String executeAndDisconnect(String command) throws InternalException { String t = ""; try { t = execute(command); } finally { db.disconnect(); } return t; } @Override public boolean isActive() throws InternalException { try { db.execute(""); return true; } catch (InternalException e) { return false; } } @Override public synchronized void start() throws InternalException { db.start(); } @Override public synchronized void stop() throws InternalException { if (!db.tryToStop()) throw new InternalException("Could not stop database."); } @Override public String getAddress() throws DatabaseException { return db.getFolder().getAbsolutePath(); } // @Override // public synchronized IServerAddress getServerAddress() throws InternalException { // return new ServerAddress("127.0.0.1:0", db.getFolder().getAbsolutePath()); // } } class ProCoreManagement implements Management { private final Database db; private final Properties properties; ProCoreManagement(Path dbFolder, Properties properties) throws ProCoreException { db = DatabaseManager.getDatabase(dbFolder); this.properties = properties; } @Override public boolean exist() throws DatabaseException { return db.isFolderOk(); } @Override public void delete() throws DatabaseException { db.deleteFiles(); if (exist()) throw new DatabaseException("Failed to delete database. folder=" + db.getFolder()); } @Override public void create() throws DatabaseException { db.initFolder(properties); if (!exist()) throw new DatabaseException("Failed to create ProCore database. folder=" + db.getFolder()); } @Override public void purge() throws DatabaseException { db.purgeDatabase(); } @Override public void shutdown() throws DatabaseException { db.tryToStop(); db.disconnect(); } }