[573570] Provide convenient client->server conversion methods in CDOServerUtil

https://bugs.eclipse.org/bugs/show_bug.cgi?id=573570
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index f19963c..a90588e 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -166,6 +166,8 @@
   private static final boolean DISABLE_FEATURE_MAP_CHECKS = OMPlatform.INSTANCE
       .isProperty("org.eclipse.emf.cdo.internal.server.Repository.DISABLE_FEATURE_MAP_CHECKS");
 
+  private static final Map<String, Repository> REPOSITORIES = new HashMap<>();
+
   private String name;
 
   private String uuid;
@@ -2739,11 +2741,24 @@
 
     LifecycleUtil.activate(lockingManager); // Needs an initialized main branch / branch manager
     setPostActivateState();
+
+    synchronized (REPOSITORIES)
+    {
+      if (REPOSITORIES.putIfAbsent(uuid, this) != null)
+      {
+        OM.LOG.warn("Attempt to register repository with duplicate UUID: " + uuid);
+      }
+    }
   }
 
   @Override
   protected void doDeactivate() throws Exception
   {
+    synchronized (REPOSITORIES)
+    {
+      REPOSITORIES.remove(uuid);
+    }
+
     LifecycleUtil.deactivate(unitManager);
     LifecycleUtil.deactivate(lockingManager);
     LifecycleUtil.deactivate(queryHandlerProvider);
@@ -2758,6 +2773,14 @@
     super.doDeactivate();
   }
 
+  public static Repository get(String uuid)
+  {
+    synchronized (REPOSITORIES)
+    {
+      return REPOSITORIES.get(uuid);
+    }
+  }
+
   /**
    * @author Eike Stepper
    * @since 2.0
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
index a4d1eb0..3579f9a 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/ServerCDOView.java
@@ -148,6 +148,11 @@
     return session.getInternalSession();
   }
 
+  public CDORevisionProvider getRevisionProvider()
+  {
+    return revisionProvider;
+  }
+
   @Override
   public ExecutorService getExecutorService()
   {
@@ -604,7 +609,7 @@
   /**
    * @author Eike Stepper
    */
-  private final class ServerCDOSession extends PlatformObject implements InternalCDOSession, CDORepositoryInfo, org.eclipse.emf.cdo.session.CDOSession.Options
+  public final class ServerCDOSession extends PlatformObject implements InternalCDOSession, CDORepositoryInfo, org.eclipse.emf.cdo.session.CDOSession.Options
   {
     private final IRegistry<String, Object> properties = new HashMapRegistry.AutoCommit<>();
 
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
index ba38623..54396e3 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerUtil.java
@@ -17,11 +17,13 @@
 import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
 import org.eclipse.emf.cdo.internal.server.Repository;
 import org.eclipse.emf.cdo.internal.server.ServerCDOView;
+import org.eclipse.emf.cdo.internal.server.ServerCDOView.ServerCDOSession;
 import org.eclipse.emf.cdo.internal.server.SessionManager;
 import org.eclipse.emf.cdo.internal.server.bundle.OM;
 import org.eclipse.emf.cdo.internal.server.syncing.FailoverParticipant;
 import org.eclipse.emf.cdo.internal.server.syncing.OfflineClone;
 import org.eclipse.emf.cdo.internal.server.syncing.RepositorySynchronizer;
+import org.eclipse.emf.cdo.session.CDOSession;
 import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
 import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
 import org.eclipse.emf.cdo.spi.common.revision.ManagedRevisionProvider;
@@ -30,6 +32,7 @@
 import org.eclipse.emf.cdo.spi.server.InternalSession;
 import org.eclipse.emf.cdo.spi.server.InternalStore;
 import org.eclipse.emf.cdo.spi.server.RepositoryFactory;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
 import org.eclipse.emf.cdo.view.CDOView;
 
 import org.eclipse.net4j.util.ObjectUtil;
@@ -54,6 +57,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
 
 /**
  * Various static methods that may help with CDO {@link IRepository repositories} and server-side {@link CDOView views}.
@@ -66,44 +70,6 @@
   {
   }
 
-  // /**
-  // * @since 4.2
-  // */
-  // public static CDOView openView(ISession session, CDOBranchPoint branchPoint, CDORevisionProvider revisionProvider)
-  // {
-  // return new ServerCDOView((InternalSession)session, branchPoint, revisionProvider);
-  // }
-  //
-  // /**
-  // * @since 4.2
-  // */
-  // public static CDOView openView(ISession session, CDOBranchPoint branchPoint)
-  // {
-  // CDORevisionManager revisionManager = session.getManager().getRepository().getRevisionManager();
-  // CDORevisionProvider revisionProvider = new ManagedRevisionProvider(revisionManager, branchPoint);
-  // return new ServerCDOView((InternalSession)session, branchPoint, revisionProvider);
-  // }
-  //
-  // /**
-  // * @since 4.2
-  // */
-  // public static CDOView openView(IView view)
-  // {
-  // ISession session = view.getSession();
-  // CDOBranchPoint branchPoint = CDOBranchUtil.copyBranchPoint(view);
-  // return openView(session, branchPoint, view);
-  // }
-  //
-  // /**
-  // * @since 4.2
-  // */
-  // public static CDOView openView(IStoreAccessor.CommitContext commitContext)
-  // {
-  // ISession session = commitContext.getTransaction().getSession();
-  // CDOBranchPoint branchPoint = commitContext.getBranchPoint();
-  // return openView(session, branchPoint, commitContext);
-  // }
-
   /**
    * @since 4.2
    */
@@ -183,6 +149,43 @@
   }
 
   /**
+   * @since 4.13
+   */
+  public static ITransaction getServerTransaction(CDOTransaction transaction)
+  {
+    IView serverView = getServerView(transaction);
+    if (serverView instanceof ITransaction)
+    {
+      return (ITransaction)serverView;
+    }
+
+    return null;
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static IView getServerView(CDOView view)
+  {
+    if (view instanceof ServerCDOView)
+    {
+      CDORevisionProvider revisionProvider = ((ServerCDOView)view).getRevisionProvider();
+      if (revisionProvider instanceof IView)
+      {
+        return (IView)revisionProvider;
+      }
+    }
+
+    ISession session = getServerSession(view);
+    if (session != null)
+    {
+      return session.getView(view.getViewID());
+    }
+
+    return null;
+  }
+
+  /**
    * @since 4.11
    */
   public static ISession getServerSession(CDOView view)
@@ -192,6 +195,25 @@
       return ((ServerCDOView)view).getServerSession();
     }
 
+    return getServerSession(view.getSession());
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static ISession getServerSession(CDOSession session)
+  {
+    if (session instanceof ServerCDOSession)
+    {
+      return ((ServerCDOSession)session).getInternalSession();
+    }
+
+    IRepository repository = getRepository(session);
+    if (repository != null)
+    {
+      return repository.getSessionManager().getSession(session.getSessionID());
+    }
+
     return null;
   }
 
@@ -302,6 +324,23 @@
     return RepositoryFactory.get(container, name);
   }
 
+  /**
+   * @since 4.13
+   */
+  public static IRepository getRepository(String uuid)
+  {
+    return Repository.get(uuid);
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static IRepository getRepository(CDOSession session)
+  {
+    String uuid = session.getRepositoryInfo().getUUID();
+    return getRepository(uuid);
+  }
+
   public static Element getRepositoryConfig(String repositoryName) throws ParserConfigurationException, SAXException, IOException
   {
     File configFile = OMPlatform.INSTANCE.getConfigFile("cdo-server.xml"); //$NON-NLS-1$
@@ -328,6 +367,40 @@
   }
 
   /**
+   * @since 4.13
+   */
+  public static void run(ISession context, Runnable runnable)
+  {
+    StoreThreadLocal.wrap(context, runnable).run();
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static void run(CDOSession context, Runnable runnable)
+  {
+    ISession serverSession = getServerSession(context);
+    run(serverSession, runnable);
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static <T> T call(ISession context, Callable<T> callable) throws Exception
+  {
+    return StoreThreadLocal.wrap(context, callable).call();
+  }
+
+  /**
+   * @since 4.13
+   */
+  public static <T> T call(CDOSession context, Callable<T> callable) throws Exception
+  {
+    ISession serverSession = getServerSession(context);
+    return call(serverSession, callable);
+  }
+
+  /**
    * An abstract {@link IRepository.ReadAccessHandler read-access handler} that grants or denies access to single
    * {@link CDORevision revisions}.
    *
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
index 5256b86..9c3fb17 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ISession.java
@@ -50,6 +50,18 @@
   public boolean isSubscribed();
 
   /**
+   * @since 4.13
+   */
+  @Override
+  public IView[] getViews();
+
+  /**
+   * @since 4.13
+   */
+  @Override
+  public IView getView(int viewID);
+
+  /**
    * @since 3.0
    */
   public IView openView(int viewID, CDOBranchPoint branchPoint);