/******************************************************************************* * 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 fi.vtt.simantics.procore.internal; import java.io.IOException; import java.nio.file.Path; import java.util.concurrent.ConcurrentHashMap; import org.simantics.db.Database; import org.simantics.db.Session; import org.simantics.db.SessionErrorHandler; import org.simantics.db.SessionManager; import org.simantics.db.SessionReference; import org.simantics.db.authentication.UserAuthenticationAgent; import org.simantics.db.common.utils.Logger; import org.simantics.db.event.SessionEvent; import org.simantics.db.event.SessionListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.server.DatabaseManager; import org.simantics.db.service.LifecycleSupport; import fi.vtt.simantics.procore.ProCoreSessionReference; class SessionManagerImpl implements SessionManager { private ConcurrentHashMap sessionMap = new ConcurrentHashMap(); private ListenerList sessionListeners = new ListenerList(SessionListener.class); private SessionErrorHandler errorHandler; private Database database; SessionManagerImpl() throws IOException { } void finish() { sessionMap = null; sessionListeners = null; } @Override public void addSessionListener(SessionListener listener) { sessionListeners.add(listener); } @Override public Session createSession(SessionReference sessionReference, UserAuthenticationAgent authAgent) throws DatabaseException, IOException { if (!(sessionReference instanceof ProCoreSessionReference)) throw new DatabaseException("Illegal argument. ProCoreSessionReference needed for creation of corresponding session. ref=" + sessionReference); SessionImplDb sessionImpl = new SessionImplDb(this, authAgent); boolean ok = false; try { ProCoreSessionReference pcsr = (ProCoreSessionReference)sessionReference; Path dbFolder = pcsr.serverReference.dbFolder; database = DatabaseManager.getDatabase(dbFolder); Database.Session dbSession = database.newSession(sessionImpl); sessionImpl.connect(sessionReference, dbSession); sessionMap.put(sessionImpl, sessionImpl); fireSessionOpened(sessionImpl); ok = true; } catch (IOException e) { sessionImpl = null; throw e; } catch (Throwable e) { Logger.defaultLogError("Connection failed. See exception for details.", e); try { fireSessionClosed(sessionImpl, e); sessionMap.remove(sessionImpl); sessionImpl = null; } catch (Throwable t) { } throw new DatabaseException(e); } finally { if (!ok && null != sessionImpl) sessionImpl.getService(LifecycleSupport.class).close(); } return sessionImpl; } @Override public void removeSessionListener(SessionListener listener) { sessionListeners.remove(listener); } private void fireSessionOpened(SessionImplSocket session) { SessionEvent se = new SessionEvent(session, null); for (SessionListener listener : sessionListeners.getListeners()) { listener.sessionOpened(se); } } private void fireSessionClosed(SessionImplSocket session, Throwable cause) { SessionEvent se = new SessionEvent(session, cause); for (SessionListener listener : sessionListeners.getListeners()) { listener.sessionClosed(se); } } @Override public void shutdown(Session s, Throwable cause) { SessionImplSocket sis = sessionMap.get(s); if (null == sis) return; try { fireSessionClosed(sis, cause); } finally { sessionMap.remove(s); } } @Override public SessionErrorHandler getErrorHandler() { return errorHandler; } @Override public void setErrorHandler(SessionErrorHandler errorHandler) { this.errorHandler = errorHandler; } @Override public Database getDatabase() { return database; } }