X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.management%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fmanagement%2FSessionContext.java;fp=bundles%2Forg.simantics.db.management%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fmanagement%2FSessionContext.java;h=ef5f270531021b890888c3016ae2f08e8ed096f9;hp=7cae775c6a5054e7dcb0d8f103d90bdbd3e34bcc;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.db.management/src/org/simantics/db/management/SessionContext.java b/bundles/org.simantics.db.management/src/org/simantics/db/management/SessionContext.java index 7cae775c6..ef5f27053 100644 --- a/bundles/org.simantics.db.management/src/org/simantics/db/management/SessionContext.java +++ b/bundles/org.simantics.db.management/src/org/simantics/db/management/SessionContext.java @@ -1,391 +1,391 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 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.management; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.UUID; -import java.util.concurrent.TimeoutException; - -import org.eclipse.core.runtime.IStatus; -import org.simantics.db.Disposable; -import org.simantics.db.ReadGraph; -import org.simantics.db.ServerReference; -import org.simantics.db.Session; -import org.simantics.db.SessionManager; -import org.simantics.db.SessionReference; -import org.simantics.db.VirtualGraph; -import org.simantics.db.authentication.UserAuthenticationAgent; -import org.simantics.db.common.processor.MergingDelayedWriteProcessor; -import org.simantics.db.common.processor.MergingGraphRequestProcessor; -import org.simantics.db.common.request.ReadRequest; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.InternalException; -import org.simantics.db.management.internal.Activator; -import org.simantics.db.service.LifecycleSupport; -import org.simantics.db.service.VirtualGraphSupport; -import org.simantics.db.services.GlobalServiceInitializer; -import org.simantics.layer0.Layer0; -import org.simantics.utils.datastructures.disposable.DisposeState; -import org.simantics.utils.datastructures.disposable.IDisposable; -import org.simantics.utils.datastructures.disposable.IDisposeListener; -import org.simantics.utils.datastructures.hints.HintContext; -import org.simantics.utils.threads.IThreadWorkQueue; -import org.simantics.utils.threads.SyncListenerList; - -import fi.vtt.simantics.procore.ProCoreServerReference; -import fi.vtt.simantics.procore.ProCoreSessionReference; -import fi.vtt.simantics.procore.SessionManagerSource; - -/** - * Holds all information that is needed to create and manage a single database - * session in the Simantics workbench UI. - * - * @see org.simantics.ui.SimanticsUI - * @see org.simantics.db.layer0.util.Simantics - * @author Tuukka Lehtonen - */ -public class SessionContext extends HintContext implements ISessionContext, Disposable { - private static final boolean SESSION_DEBUG = false; - -// private final IServerAddress address; - - private Session session; - - private UserAuthenticationAgent authenticator; - - private boolean servicesRegistered = false; - - private IStatus servicesRegisteredStatus = null; - - public static SessionContext create(Session session, boolean initialize) throws DatabaseException { - return new SessionContext(session, initialize); - } - -// public static SessionContext openSession(IServerAddress info, UserAuthenticationAgent auth) throws IOException, DatabaseException { -// return new SessionContext(info, auth, false); -// } -// -// public static SessionContext openAndInitializeSession(IServerAddress info, UserAuthenticationAgent auth) throws IOException, DatabaseException { -// return new SessionContext(info, auth, true); -// } - - private static SessionReference createSessionReference(/*IServerAddress address,*/ long sessionId) throws InternalException { - ProCoreServerReference server = new ProCoreServerReference(); - ProCoreSessionReference ref = new ProCoreSessionReference(server, sessionId); - return ref; - } - -// private SessionContext(IServerAddress addr, UserAuthenticationAgent auth, boolean initialize) throws IOException, DatabaseException { -// if (addr == null) -// throw new IllegalArgumentException("null address"); -//// this.address = addr; -// this.authenticator = auth; -// -// SessionManager sessionManager = SessionManagerProvider.getInstance().getSessionManager(); -// -// if (initialize) { -// initializeSession(sessionManager); -// if (SESSION_DEBUG) { -// System.err.println("Initialized session: " + addr); -// System.err.flush(); -// } -// } else { -// SessionReference ref = createSessionReference(SessionManagerSource.NullSessionId); -// this.session = sessionManager.createSession(ref, auth); -// if (SESSION_DEBUG) { -// System.err.println("Opened session: " + addr); -// System.err.flush(); -// } -// } -// -// } - - private SessionContext(Session session, boolean initialize) throws DatabaseException { - if (initialize) - initializeSession(session); - ServerReference ref = session.getService( LifecycleSupport.class ).getSessionReference().getServerReference(); -// this.address = ref.serverAddress(); - this.session = session; - } - - private void initializeSession(SessionManager sessionManager) throws DatabaseException, IOException { - Session s = null; - boolean success = false; - try { - SessionReference ref = createSessionReference(SessionManagerSource.NullSessionId); - s = sessionManager.createSession(ref, authenticator); - initializeSession(s); - this.session = s; - success = true; - } finally { - if (!success) { - if (s != null) { - LifecycleSupport support = s.getService(LifecycleSupport.class); - support.close(); - } - } - } - } - - private void initializeSession(Session s) throws DatabaseException { - s.registerService(MergingGraphRequestProcessor.class, new MergingGraphRequestProcessor("SessionService", s, 20)); - s.registerService(MergingDelayedWriteProcessor.class, new MergingDelayedWriteProcessor(s, 20)); - s.registerService(VirtualGraph.class, s.getService(VirtualGraphSupport.class).getMemoryPersistent(UUID.randomUUID().toString())); - - // Builtins needs to be initialized for the new session before - // anything useful can be done with it. - s.syncRequest(new ReadRequest() { - @Override - public void run(ReadGraph g) { - // Registers Builtins with the ServiceLocator of the Graph's session. - Layer0.getInstance(g); - } - }); - } - - public void registerServices() { - if (servicesRegistered) - return; - - // Register any services available for the SessionLocator of the new - // Session. - servicesRegisteredStatus = new GlobalServiceInitializer().initialize(session); - if (!servicesRegisteredStatus.isOK()) { - Activator.getDefault().getLog().log(servicesRegisteredStatus); - } - - servicesRegistered = true; - } - -// @Override -// public IServerAddress getAddress() { -// return address; -// } - - @Override - public Session getSession() { - if (session == null) - throw new IllegalStateException("SessionContext is disposed"); - return session; - } - - @Override - public Session peekSession() { - return session; - } - - /** - * Do dispose procedures. This method is invoked at most once. - */ - protected void doDispose() { - try { - doClose(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public void close() throws IllegalStateException, InterruptedException, TimeoutException { - try { - dispose(); - } catch (RuntimeException e) { - Throwable t = e.getCause(); - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } else if (t instanceof Error) { - throw (Error) t; - } else if (t instanceof InterruptedException) { - throw (InterruptedException) t; - } else if (t instanceof TimeoutException) { - throw (TimeoutException) t; - } - throw e; - } - } - - private void doClose() throws DatabaseException { - for (Key k : getHints().keySet()) { - if (k != null) { - Object o = removeHint(k); - if (o instanceof IDisposable) { - ((IDisposable) o).safeDispose(); - } - } - } - - if (session != null) { - if (SESSION_DEBUG) { - System.err.println("Closing session: " + session/*address*/); - System.err.flush(); - } - LifecycleSupport support = session.getService(LifecycleSupport.class); - support.close(0, true); - session = null; - } - } - - @Override - public int hashCode() { - if (session == null) return 0; - return session.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null || getClass() != obj.getClass()) - return false; - final SessionContext other = (SessionContext) obj; -// if (!address.equals(other.address)) -// return false; - return session.equals(other.session); - } - - @Override - public String toString() { - StringBuilder s = new StringBuilder(); - s.append("SessionContext [info=" + session + ", hints="); - s.append(Arrays.toString(getHints().values().toArray())); - s.append("]"); - return s.toString(); - } - - - // IDisposable implementation (AbstractDisposable) - - SyncListenerList disposeListeners = null; - - private DisposeState disposeStatus = DisposeState.Alive; - - protected void assertNotDisposed() { - if (isDisposed()) - throw new AssertionError(this + " is disposed."); - } - - @Override - public DisposeState getDisposeState() { - return disposeStatus; - } - - @Override - public boolean isDisposed() { - return disposeStatus == DisposeState.Disposed; - } - - public boolean isAlive() { - return disposeStatus == DisposeState.Alive; - } - - @Override - public void dispose() { - try { - synchronized (this) { - if (disposeStatus == DisposeState.Disposing) - return; - assertNotDisposed(); - disposeStatus = DisposeState.Disposing; - } - try { - fireDisposed(); - } finally { - doDispose(); - } - } finally { - synchronized(this) { - disposeStatus = DisposeState.Disposed; - } - } - } - - /** - * Disposes if not disposed - */ - @Override - public void safeDispose() { - try { - synchronized (this) { - if (disposeStatus != DisposeState.Alive) - return; - disposeStatus = DisposeState.Disposing; - } - try { - fireDisposed(); - } finally { - doDispose(); - } - } finally { - synchronized(this) { - disposeStatus = DisposeState.Disposed; - } - } - } - - protected boolean hasDisposeListeners() { - return disposeListeners!=null && !disposeListeners.isEmpty(); - } - - private final static Method onDisposed = SyncListenerList.getMethod(IDisposeListener.class, "onDisposed"); - - private void fireDisposed() { - if (disposeListeners==null) return; - disposeListeners.fireEventSync(onDisposed, this); - } - - @SuppressWarnings("unused") - private void fireDisposedAsync() { - if (disposeListeners==null) return; - disposeListeners.fireEventAsync(onDisposed, this); - } - - @Override - public void addDisposeListener(IDisposeListener listener) { - lazyGetListenerList().add(listener); - } - - @Override - public void addDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) { - lazyGetListenerList().add(thread, listener); - } - - @Override - public void removeDisposeListener(IDisposeListener listener) { - if (disposeListeners==null) return; - disposeListeners.remove(listener); - } - - @Override - public void removeDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) { - if (disposeListeners==null) return; - disposeListeners.remove(thread, listener); - } - - private synchronized SyncListenerList lazyGetListenerList() - { - if (disposeListeners==null) - disposeListeners = new SyncListenerList(IDisposeListener.class); - return disposeListeners; - } - - @Override - protected void finalize() throws Throwable { - try { - safeDispose(); - } finally { - super.finalize(); - } - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2011 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.management; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.UUID; +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.runtime.IStatus; +import org.simantics.db.Disposable; +import org.simantics.db.ReadGraph; +import org.simantics.db.ServerReference; +import org.simantics.db.Session; +import org.simantics.db.SessionManager; +import org.simantics.db.SessionReference; +import org.simantics.db.VirtualGraph; +import org.simantics.db.authentication.UserAuthenticationAgent; +import org.simantics.db.common.processor.MergingDelayedWriteProcessor; +import org.simantics.db.common.processor.MergingGraphRequestProcessor; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.InternalException; +import org.simantics.db.management.internal.Activator; +import org.simantics.db.service.LifecycleSupport; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.db.services.GlobalServiceInitializer; +import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.disposable.DisposeState; +import org.simantics.utils.datastructures.disposable.IDisposable; +import org.simantics.utils.datastructures.disposable.IDisposeListener; +import org.simantics.utils.datastructures.hints.HintContext; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.SyncListenerList; + +import fi.vtt.simantics.procore.ProCoreServerReference; +import fi.vtt.simantics.procore.ProCoreSessionReference; +import fi.vtt.simantics.procore.SessionManagerSource; + +/** + * Holds all information that is needed to create and manage a single database + * session in the Simantics workbench UI. + * + * @see org.simantics.ui.SimanticsUI + * @see org.simantics.db.layer0.util.Simantics + * @author Tuukka Lehtonen + */ +public class SessionContext extends HintContext implements ISessionContext, Disposable { + private static final boolean SESSION_DEBUG = false; + +// private final IServerAddress address; + + private Session session; + + private UserAuthenticationAgent authenticator; + + private boolean servicesRegistered = false; + + private IStatus servicesRegisteredStatus = null; + + public static SessionContext create(Session session, boolean initialize) throws DatabaseException { + return new SessionContext(session, initialize); + } + +// public static SessionContext openSession(IServerAddress info, UserAuthenticationAgent auth) throws IOException, DatabaseException { +// return new SessionContext(info, auth, false); +// } +// +// public static SessionContext openAndInitializeSession(IServerAddress info, UserAuthenticationAgent auth) throws IOException, DatabaseException { +// return new SessionContext(info, auth, true); +// } + + private static SessionReference createSessionReference(/*IServerAddress address,*/ long sessionId) throws InternalException { + ProCoreServerReference server = new ProCoreServerReference(); + ProCoreSessionReference ref = new ProCoreSessionReference(server, sessionId); + return ref; + } + +// private SessionContext(IServerAddress addr, UserAuthenticationAgent auth, boolean initialize) throws IOException, DatabaseException { +// if (addr == null) +// throw new IllegalArgumentException("null address"); +//// this.address = addr; +// this.authenticator = auth; +// +// SessionManager sessionManager = SessionManagerProvider.getInstance().getSessionManager(); +// +// if (initialize) { +// initializeSession(sessionManager); +// if (SESSION_DEBUG) { +// System.err.println("Initialized session: " + addr); +// System.err.flush(); +// } +// } else { +// SessionReference ref = createSessionReference(SessionManagerSource.NullSessionId); +// this.session = sessionManager.createSession(ref, auth); +// if (SESSION_DEBUG) { +// System.err.println("Opened session: " + addr); +// System.err.flush(); +// } +// } +// +// } + + private SessionContext(Session session, boolean initialize) throws DatabaseException { + if (initialize) + initializeSession(session); + ServerReference ref = session.getService( LifecycleSupport.class ).getSessionReference().getServerReference(); +// this.address = ref.serverAddress(); + this.session = session; + } + + private void initializeSession(SessionManager sessionManager) throws DatabaseException, IOException { + Session s = null; + boolean success = false; + try { + SessionReference ref = createSessionReference(SessionManagerSource.NullSessionId); + s = sessionManager.createSession(ref, authenticator); + initializeSession(s); + this.session = s; + success = true; + } finally { + if (!success) { + if (s != null) { + LifecycleSupport support = s.getService(LifecycleSupport.class); + support.close(); + } + } + } + } + + private void initializeSession(Session s) throws DatabaseException { + s.registerService(MergingGraphRequestProcessor.class, new MergingGraphRequestProcessor("SessionService", s, 20)); + s.registerService(MergingDelayedWriteProcessor.class, new MergingDelayedWriteProcessor(s, 20)); + s.registerService(VirtualGraph.class, s.getService(VirtualGraphSupport.class).getMemoryPersistent(UUID.randomUUID().toString())); + + // Builtins needs to be initialized for the new session before + // anything useful can be done with it. + s.syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph g) { + // Registers Builtins with the ServiceLocator of the Graph's session. + Layer0.getInstance(g); + } + }); + } + + public void registerServices() { + if (servicesRegistered) + return; + + // Register any services available for the SessionLocator of the new + // Session. + servicesRegisteredStatus = new GlobalServiceInitializer().initialize(session); + if (!servicesRegisteredStatus.isOK()) { + Activator.getDefault().getLog().log(servicesRegisteredStatus); + } + + servicesRegistered = true; + } + +// @Override +// public IServerAddress getAddress() { +// return address; +// } + + @Override + public Session getSession() { + if (session == null) + throw new IllegalStateException("SessionContext is disposed"); + return session; + } + + @Override + public Session peekSession() { + return session; + } + + /** + * Do dispose procedures. This method is invoked at most once. + */ + protected void doDispose() { + try { + doClose(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void close() throws IllegalStateException, InterruptedException, TimeoutException { + try { + dispose(); + } catch (RuntimeException e) { + Throwable t = e.getCause(); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else if (t instanceof Error) { + throw (Error) t; + } else if (t instanceof InterruptedException) { + throw (InterruptedException) t; + } else if (t instanceof TimeoutException) { + throw (TimeoutException) t; + } + throw e; + } + } + + private void doClose() throws DatabaseException { + for (Key k : getHints().keySet()) { + if (k != null) { + Object o = removeHint(k); + if (o instanceof IDisposable) { + ((IDisposable) o).safeDispose(); + } + } + } + + if (session != null) { + if (SESSION_DEBUG) { + System.err.println("Closing session: " + session/*address*/); + System.err.flush(); + } + LifecycleSupport support = session.getService(LifecycleSupport.class); + support.close(0, true); + session = null; + } + } + + @Override + public int hashCode() { + if (session == null) return 0; + return session.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + final SessionContext other = (SessionContext) obj; +// if (!address.equals(other.address)) +// return false; + return session.equals(other.session); + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append("SessionContext [info=" + session + ", hints="); + s.append(Arrays.toString(getHints().values().toArray())); + s.append("]"); + return s.toString(); + } + + + // IDisposable implementation (AbstractDisposable) + + SyncListenerList disposeListeners = null; + + private DisposeState disposeStatus = DisposeState.Alive; + + protected void assertNotDisposed() { + if (isDisposed()) + throw new AssertionError(this + " is disposed."); + } + + @Override + public DisposeState getDisposeState() { + return disposeStatus; + } + + @Override + public boolean isDisposed() { + return disposeStatus == DisposeState.Disposed; + } + + public boolean isAlive() { + return disposeStatus == DisposeState.Alive; + } + + @Override + public void dispose() { + try { + synchronized (this) { + if (disposeStatus == DisposeState.Disposing) + return; + assertNotDisposed(); + disposeStatus = DisposeState.Disposing; + } + try { + fireDisposed(); + } finally { + doDispose(); + } + } finally { + synchronized(this) { + disposeStatus = DisposeState.Disposed; + } + } + } + + /** + * Disposes if not disposed + */ + @Override + public void safeDispose() { + try { + synchronized (this) { + if (disposeStatus != DisposeState.Alive) + return; + disposeStatus = DisposeState.Disposing; + } + try { + fireDisposed(); + } finally { + doDispose(); + } + } finally { + synchronized(this) { + disposeStatus = DisposeState.Disposed; + } + } + } + + protected boolean hasDisposeListeners() { + return disposeListeners!=null && !disposeListeners.isEmpty(); + } + + private final static Method onDisposed = SyncListenerList.getMethod(IDisposeListener.class, "onDisposed"); + + private void fireDisposed() { + if (disposeListeners==null) return; + disposeListeners.fireEventSync(onDisposed, this); + } + + @SuppressWarnings("unused") + private void fireDisposedAsync() { + if (disposeListeners==null) return; + disposeListeners.fireEventAsync(onDisposed, this); + } + + @Override + public void addDisposeListener(IDisposeListener listener) { + lazyGetListenerList().add(listener); + } + + @Override + public void addDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) { + lazyGetListenerList().add(thread, listener); + } + + @Override + public void removeDisposeListener(IDisposeListener listener) { + if (disposeListeners==null) return; + disposeListeners.remove(listener); + } + + @Override + public void removeDisposeListener(IDisposeListener listener, IThreadWorkQueue thread) { + if (disposeListeners==null) return; + disposeListeners.remove(thread, listener); + } + + private synchronized SyncListenerList lazyGetListenerList() + { + if (disposeListeners==null) + disposeListeners = new SyncListenerList(IDisposeListener.class); + return disposeListeners; + } + + @Override + protected void finalize() throws Throwable { + try { + safeDispose(); + } finally { + super.finalize(); + } + } + +}