Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Winkler2012-05-08 10:23:17 -0400
committerStefan Winkler2012-05-08 10:23:17 -0400
commit984e9ceb73145f4e8e49199916ac8a9c06b49eea (patch)
tree2249cd32f8eee2fee1f4b7e87ac2aaab23d7f415
parenta57960d211698a2d8c5ed0f2abb3b23a87fd197a (diff)
parent6477e2b476c91f0a5e8e81dbaa827fe34172c017 (diff)
downloadcdo-bugs/377727.tar.gz
cdo-bugs/377727.tar.xz
cdo-bugs/377727.zip
Merge branch 'master' of git://git.eclipse.org/gitroot/cdo/cdo.git into bugs/377727bugs/377727
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/HibernateCommandProvider.java164
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/OM.java96
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerBrowser.java2544
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java6
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/container/PluginContainer.java146
5 files changed, 1563 insertions, 1393 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/HibernateCommandProvider.java b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/HibernateCommandProvider.java
new file mode 100644
index 0000000000..7111ae539b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/HibernateCommandProvider.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Erdal Karaca - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.hibernate.internal.teneo.bundle;
+
+import org.eclipse.emf.cdo.server.hibernate.teneo.CDOMappingGenerator;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.RepositoryFactory;
+
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.io.IOUtil;
+
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+
+import org.osgi.framework.BundleContext;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * Provides a command to export the hbm file directly from the osgi prompt.
+ *
+ * See:
+ *
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=378797
+ *
+ * Exports the hbm through the following osgi command:
+ * hibernate mapping repo1 /tmp/hbm.xml
+ *
+ * @author Erdal Karaca
+ */
+public class HibernateCommandProvider implements CommandProvider
+{
+ private static final String NEW_LINE = "\r\n"; //$NON-NLS-1$
+
+ private static final String INDENT = " "; //$NON-NLS-1$
+
+ public HibernateCommandProvider(BundleContext bundleContext)
+ {
+ bundleContext.registerService(CommandProvider.class.getName(), this, null);
+ }
+
+ public String getHelp()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("---CDO Hibernate commands---" + NEW_LINE);
+ buffer.append(INDENT + "hibernate mapping - export generated hibernate file" + NEW_LINE);
+ return buffer.toString();
+ }
+
+ public Object _hibernate(CommandInterpreter interpreter)
+ {
+ try
+ {
+ String cmd = interpreter.nextArgument();
+ if ("mapping".equals(cmd))
+ {
+ exportHbm(interpreter);
+ return null;
+ }
+
+ interpreter.println(getHelp());
+ }
+ catch (CommandException ex)
+ {
+ interpreter.println(ex.getMessage());
+ }
+ catch (Exception ex)
+ {
+ interpreter.printStackTrace(ex);
+ }
+
+ return null;
+ }
+
+ private void exportHbm(CommandInterpreter interpreter) throws Exception
+ {
+ String syntax = "Syntax: hibernate mapping <repository-name> <export-file>";
+ InternalRepository repository = getRepository(interpreter, syntax);
+ String exportFile = nextArgument(interpreter, syntax);
+ OutputStream out = null;
+
+ try
+ {
+ out = new FileOutputStream(exportFile);
+ Properties props = new Properties();
+ props.putAll(repository.getProperties());
+ final EPackage[] ePackages = repository.getPackageRegistry().values().toArray(new EPackage[0]);
+
+ final CDOMappingGenerator mappingGenerator = new CDOMappingGenerator();
+ final String mapping = mappingGenerator.generateMapping(ePackages, props);
+ out.write(mapping.getBytes());
+ interpreter.println("Hibernate mapping exported");
+ }
+ finally
+ {
+ IOUtil.close(out);
+ }
+ }
+
+ private String nextArgument(CommandInterpreter interpreter, String syntax)
+ {
+ String argument = interpreter.nextArgument();
+ if (argument == null && syntax != null)
+ {
+ throw new CommandException(syntax);
+ }
+
+ return argument;
+ }
+
+ private InternalRepository getRepository(CommandInterpreter interpreter, String syntax)
+ {
+ String repositoryName = nextArgument(interpreter, syntax);
+ InternalRepository repository = getRepository(repositoryName);
+ if (repository == null)
+ {
+ throw new CommandException("Repository not found: " + repositoryName);
+ }
+
+ return repository;
+ }
+
+ private InternalRepository getRepository(String name)
+ {
+ for (Object element : IPluginContainer.INSTANCE.getElements(RepositoryFactory.PRODUCT_GROUP))
+ {
+ if (element instanceof InternalRepository)
+ {
+ InternalRepository repository = (InternalRepository)element;
+ if (repository.getName().equals(name))
+ {
+ return repository;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class CommandException extends RuntimeException
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CommandException(String message)
+ {
+ super(message);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/OM.java b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/OM.java
index 111f81fd23..bb4945a434 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/OM.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/internal/teneo/bundle/OM.java
@@ -1,44 +1,52 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server.hibernate.internal.teneo.bundle;
-
-import org.eclipse.net4j.util.om.OMBundle;
-import org.eclipse.net4j.util.om.OMPlatform;
-import org.eclipse.net4j.util.om.OSGiActivator;
-import org.eclipse.net4j.util.om.log.OMLogger;
-import org.eclipse.net4j.util.om.trace.OMTracer;
-
-/**
- * The <em>Operations & Maintenance</em> class of this bundle.
- *
- * @author Eike Stepper
- */
-public abstract class OM
-{
- public static final String BUNDLE_ID = "org.eclipse.emf.cdo.server.hibernate.teneo"; //$NON-NLS-1$
-
- public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, OM.class);
-
- public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$
-
- public static final OMLogger LOG = BUNDLE.logger();
-
- /**
- * @author Eike Stepper
- */
- public static final class Activator extends OSGiActivator
- {
- public Activator()
- {
- super(BUNDLE);
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Eike Stepper - initial API and implementation
+ * Erdal Karaca - added HibernateCommandProvider
+ */
+package org.eclipse.emf.cdo.server.hibernate.internal.teneo.bundle;
+
+import org.eclipse.net4j.util.om.OMBundle;
+import org.eclipse.net4j.util.om.OMPlatform;
+import org.eclipse.net4j.util.om.OSGiActivator;
+import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.om.trace.OMTracer;
+
+/**
+ * The <em>Operations & Maintenance</em> class of this bundle.
+ *
+ * @author Eike Stepper
+ */
+public abstract class OM
+{
+ public static final String BUNDLE_ID = "org.eclipse.emf.cdo.server.hibernate.teneo"; //$NON-NLS-1$
+
+ public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, OM.class);
+
+ public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$
+
+ public static final OMLogger LOG = BUNDLE.logger();
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Activator extends OSGiActivator
+ {
+ public Activator()
+ {
+ super(BUNDLE);
+ }
+
+ @Override
+ protected void doStart() throws Exception
+ {
+ new HibernateCommandProvider(bundleContext);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerBrowser.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerBrowser.java
index 3a466fdf87..690462f755 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerBrowser.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/CDOServerBrowser.java
@@ -1,1269 +1,1275 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.server;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
-import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
-import org.eclipse.emf.cdo.common.revision.CDOAllRevisionsProvider;
-import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil.AllRevisionsDumper;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
-import org.eclipse.emf.cdo.internal.server.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.util.HexUtil;
-import org.eclipse.net4j.util.StringUtil;
-import org.eclipse.net4j.util.WrappedException;
-import org.eclipse.net4j.util.concurrent.Worker;
-import org.eclipse.net4j.util.container.ContainerEventAdapter;
-import org.eclipse.net4j.util.container.IContainer;
-import org.eclipse.net4j.util.container.IManagedContainer;
-import org.eclipse.net4j.util.container.IPluginContainer;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.factory.ProductCreationException;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.Writer;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A simple HTTP server that web browsers can connect to in order to render internal server data for debugging purposes.
- * <p>
- * Actual content is contributed through pluggable {@link CDOServerBrowser.Page pages}.
- * <p>
- * <b>Note:</b> Don't use this server in production, it's unsecure and does not perform or scale!
- *
- * @author Eike Stepper
- * @since 4.0
- */
-public class CDOServerBrowser extends Worker
-{
- private static final String REQUEST_PREFIX = "GET ";
-
- private static final String REQUEST_SUFFIX = " HTTP/1.1";
-
- private ThreadLocal<Map<String, String>> params = new InheritableThreadLocal<Map<String, String>>()
- {
- @Override
- protected Map<String, String> initialValue()
- {
- return new HashMap<String, String>();
- }
- };
-
- private int port = 7777;
-
- private ServerSocket serverSocket;
-
- private Map<String, InternalRepository> repositories;
-
- private List<Page> pages = new ArrayList<Page>();
-
- public CDOServerBrowser(Map<String, InternalRepository> repositories)
- {
- this.repositories = repositories;
- setDaemon(true);
- }
-
- public Map<String, InternalRepository> getRepositories()
- {
- return repositories;
- }
-
- public int getPort()
- {
- return port;
- }
-
- public void setPort(int port)
- {
- this.port = port;
- }
-
- @Override
- protected void work(WorkContext context) throws Exception
- {
- Socket socket = null;
-
- try
- {
- socket = serverSocket.accept();
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- OutputStream out = new BufferedOutputStream(socket.getOutputStream());
- PrintStream pout = new PrintStream(out);
- printHeader(pout);
-
- String line;
- while ((line = in.readLine()) != null)
- {
- if (line.startsWith(REQUEST_PREFIX) && line.endsWith(REQUEST_SUFFIX))
- {
- String request = line.substring(REQUEST_PREFIX.length(), line.length() - REQUEST_SUFFIX.length()).trim();
- String resource = request;
- String params = "";
- int pos = request.indexOf('?');
- if (pos != -1)
- {
- resource = request.substring(0, pos);
- params = request.substring(pos + 1);
- }
-
- initParams(params);
- if ("/".equals(resource))
- {
- showMenu(pout);
- }
- else
- {
- String pageName = resource.substring(1);
- for (Page page : pages)
- {
- if (page.getName().equals(pageName))
- {
- showPage(pout, page);
- }
- }
- }
- }
-
- out.flush();
- return;
- }
- }
- catch (Exception ex)
- {
- if (isActive())
- {
- ex.printStackTrace();
- }
- }
- finally
- {
- params.remove();
- if (socket != null)
- {
- socket.close();
- }
- }
- }
-
- protected void initParams(String params)
- {
- Map<String, String> map = this.params.get();
- for (String param : params.split("&"))
- {
- if (param.length() != 0)
- {
- String[] keyValue = param.split("=");
- map.put(keyValue[0], keyValue[1]);
- }
- }
- }
-
- protected void clearParams()
- {
- Map<String, String> map = params.get();
- map.clear();
- }
-
- public void removeParam(String key)
- {
- Map<String, String> map = params.get();
- map.remove(key);
- }
-
- public String getParam(String key)
- {
- Map<String, String> map = params.get();
- return map.get(key);
- }
-
- public String href(String label, String resource, String... params)
- {
- Map<String, String> map = new HashMap<String, String>(this.params.get());
- for (int i = 0; i < params.length;)
- {
- map.put(params[i++], params[i++]);
- }
-
- List<String> list = new ArrayList<String>(map.keySet());
- Collections.sort(list);
-
- StringBuilder builder = new StringBuilder();
- for (String key : list)
- {
- String value = map.get(key);
- if (value != null)
- {
- if (builder.length() != 0)
- {
- builder.append("&");
- }
-
- builder.append(key);
- builder.append("=");
- builder.append(value);
- }
- }
-
- return "<a href=\"/" + escape(resource) + "?" + escape(builder.toString()) + "\">" + escape(label) + "</a>";
- }
-
- public String escape(String raw)
- {
- if (raw == null)
- {
- return "null";
- }
-
- return raw.replace("<", "&lt;");
- }
-
- protected void printHeader(PrintStream pout)
- {
- pout.print("HTTP/1.1 200 OK\r\n");
- pout.print("Content-Type: text/html\r\n");
- pout.print("Date: " + new Date() + "\r\n");
- pout.print("Server: DBBrowser 3.0\r\n");
- pout.print("\r\n");
- }
-
- protected void showMenu(PrintStream pout)
- {
- clearParams();
- pout.print("<h1>CDO Server Browser 4.0</h1><hr>\r\n");
-
- for (Page page : pages)
- {
- pout.println("<h3>" + href(page.getLabel(), page.getName()) + "</h3>");
- }
- }
-
- protected void showPage(PrintStream pout, Page page)
- {
- String repo = getParam("repo");
-
- List<String> repoNames = new ArrayList<String>(getRepositoryNames());
- Collections.sort(repoNames);
-
- pout.print("<h3><a href=\"/\">" + page.getLabel() + "</a>:&nbsp;&nbsp;");
- for (String repoName : repoNames)
- {
- InternalRepository repository = getRepository(repoName);
- if (!page.canDisplay(repository))
- {
- continue;
- }
-
- if (repo == null)
- {
- repo = repoName;
- }
-
- if (repoName.equals(repo))
- {
- pout.print("<b>" + escape(repoName) + "</b>&nbsp;&nbsp;");
- }
- else
- {
- pout.print(href(repoName, page.getName(), "repo", repoName) + "&nbsp;&nbsp;");
- }
- }
-
- pout.print("</h3>");
-
- InternalRepository repository = getRepository(repo);
- if (repository != null)
- {
- pout.print("<p>\r\n");
- page.display(this, repository, pout);
- }
- }
-
- protected Set<String> getRepositoryNames()
- {
- return repositories.keySet();
- }
-
- protected InternalRepository getRepository(String name)
- {
- return repositories.get(name);
- }
-
- @Override
- protected String getThreadName()
- {
- return "DBBrowser";
- }
-
- protected void initPages(List<Page> pages)
- {
- pages.add(new PackagesPage());
- pages.add(new RevisionsPage.FromCache());
- pages.add(new RevisionsPage.FromStore());
- pages.add(new LobsPage());
- pages.add(new HistoryPage());
-
- IManagedContainer container = getPagesContainer();
- Set<String> factoryTypes = container.getFactoryTypes(Page.PRODUCT_GROUP);
- for (String factoryType : factoryTypes)
- {
- Page page = (Page)container.getElement(Page.PRODUCT_GROUP, factoryType, null);
- pages.add(page);
- }
- }
-
- /**
- * @since 4.1
- */
- protected IManagedContainer getPagesContainer()
- {
- return IPluginContainer.INSTANCE;
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- initPages(pages);
-
- try
- {
- serverSocket = new ServerSocket(port);
- }
- catch (Exception ex)
- {
- throw new IllegalStateException("Could not open socket on port " + port, ex);
- }
-
- super.doActivate();
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- serverSocket.close();
- super.doDeactivate();
- }
-
- /**
- * A {@link CDOServerBrowser server browser} for the repositories in a {@link IManagedContainer managed container}.
- *
- * @author Eike Stepper
- */
- public static class ContainerBased extends CDOServerBrowser
- {
- private IContainer<?> container;
-
- private IListener containerListener = new ContainerEventAdapter<Object>()
- {
- @Override
- protected void onAdded(IContainer<Object> container, Object element)
- {
- addElement(element);
- }
-
- @Override
- protected void onRemoved(IContainer<Object> container, Object element)
- {
- removeElement(element);
- }
- };
-
- public ContainerBased(IContainer<?> container)
- {
- super(new HashMap<String, InternalRepository>());
- this.container = container;
- }
-
- public ContainerBased()
- {
- this(IPluginContainer.INSTANCE);
- }
-
- public IContainer<?> getContainer()
- {
- return container;
- }
-
- @Override
- protected IManagedContainer getPagesContainer()
- {
- if (container instanceof IManagedContainer)
- {
- return (IManagedContainer)container;
- }
-
- return IPluginContainer.INSTANCE;
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
- for (Object element : container.getElements())
- {
- addElement(element);
- }
-
- container.addListener(containerListener);
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- container.removeListener(containerListener);
- super.doDeactivate();
- }
-
- private void addElement(Object element)
- {
- if (element instanceof InternalRepository)
- {
- InternalRepository repository = (InternalRepository)element;
- getRepositories().put(repository.getName(), repository);
- }
- }
-
- private void removeElement(Object element)
- {
- if (element instanceof InternalRepository)
- {
- InternalRepository repository = (InternalRepository)element;
- getRepositories().remove(repository.getName());
- }
- }
-
- /**
- * Creates {@link CDOServerBrowser server browsers} for the repositories in a {@link IManagedContainer managed
- * container}.
- *
- * @author Eike Stepper
- */
- public static class Factory extends org.eclipse.net4j.util.factory.Factory
- {
- public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.browsers";
-
- public static final String TYPE = "default";
-
- private IContainer<?> container;
-
- public Factory()
- {
- this(IPluginContainer.INSTANCE);
- }
-
- public Factory(IContainer<?> container)
- {
- super(PRODUCT_GROUP, TYPE);
- this.container = container;
- }
-
- public CDOServerBrowser.ContainerBased create(String description) throws ProductCreationException
- {
- CDOServerBrowser.ContainerBased browser = new CDOServerBrowser.ContainerBased(container);
-
- try
- {
- if (!StringUtil.isEmpty(description))
- {
- browser.setPort(Integer.valueOf(description));
- }
- }
- catch (Exception ex)
- {
- OM.LOG.warn(ex);
- }
-
- return browser;
- }
- }
- }
-
- /**
- * Represents pluggable content for a {@link CDOServerBrowser server browser}.
- *
- * @author Eike Stepper
- */
- public static interface Page
- {
- public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.browserPages";
-
- public String getName();
-
- public String getLabel();
-
- public boolean canDisplay(InternalRepository repository);
-
- public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out);
- }
-
- /**
- * An abstract base implementation of a {@link Page server browser page}.
- *
- * @author Eike Stepper
- */
- public static abstract class AbstractPage implements Page
- {
- private String name;
-
- private String label;
-
- public AbstractPage(String name, String label)
- {
- this.name = name;
- this.label = label;
- }
-
- public String getName()
- {
- return name;
- }
-
- public String getLabel()
- {
- return label;
- }
- }
-
- /**
- * A {@link Page server browser page} that renders the package registry contents of a repository.
- *
- * @author Eike Stepper
- */
- public static class PackagesPage extends AbstractPage
- {
- public static final String NAME = "packages";
-
- public PackagesPage()
- {
- super(NAME, "Packages and Classes");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return true;
- }
-
- public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out)
- {
- String param = browser.getParam("classifier");
- InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false);
- for (InternalCDOPackageUnit unit : packageRegistry.getPackageUnits())
- {
- param = showPackage(unit.getTopLevelPackageInfo(), packageRegistry, browser, param, out, "&nbsp;&nbsp;");
- }
- }
-
- protected String showPackage(InternalCDOPackageInfo info, InternalCDOPackageRegistry packageRegistry,
- CDOServerBrowser browser, String param, PrintStream out, String prefix)
- {
- EPackage ePackage = info.getEPackage();
- out.println("<h3>" + prefix + ePackage.getName() + "&nbsp;&nbsp;[" + ePackage.getNsURI() + "]</h3>");
-
- for (EClassifier classifier : ePackage.getEClassifiers())
- {
- String name = classifier.getName();
- if (param == null)
- {
- param = name;
- }
-
- String label = name.equals(param) ? name : browser.href(name, getName(), "classifier", name);
- out.print(prefix + "&nbsp;&nbsp;<b>" + label);
-
- if (classifier instanceof EEnum)
- {
- EEnum eenum = (EEnum)classifier;
- out.print("&nbsp;&nbsp;" + eenum.getELiterals());
- }
- else if (classifier instanceof EDataType)
- {
- EDataType eDataType = (EDataType)classifier;
- out.print("&nbsp;&nbsp;" + eDataType.getInstanceClassName());
- }
-
- out.println("</b><br>");
- }
-
- for (EPackage sub : ePackage.getESubpackages())
- {
- InternalCDOPackageInfo subInfo = packageRegistry.getPackageInfo(sub);
- param = showPackage(subInfo, packageRegistry, browser, param, out, prefix + "&nbsp;&nbsp;");
- }
-
- return param;
- }
- }
-
- /**
- * A {@link Page server browser page} that renders {@link CDORevision revisions}.
- *
- * @author Eike Stepper
- */
- public static abstract class RevisionsPage extends AbstractPage
- {
- public RevisionsPage(String name, String label)
- {
- super(name, label);
- }
-
- public void display(final CDOServerBrowser browser, InternalRepository repository, PrintStream out)
- {
- Map<CDOBranch, List<CDORevision>> allRevisions = getAllRevisions(repository);
- Map<CDOID, List<CDORevision>> ids = getAllIDs(allRevisions);
-
- out.print("<table border=\"0\">\r\n");
- out.print("<tr>\r\n");
-
- out.print("<td valign=\"top\">\r\n");
- out.print("<table border=\"1\" cellpadding=\"2\"><tr><td>\r\n");
- final String[] revision = { browser.getParam("revision") };
- new AllRevisionsDumper.Stream.Html(allRevisions, out)
- {
- private StringBuilder versionsBuilder;
-
- private CDORevision lastRevision;
-
- @Override
- protected void dumpEnd(List<CDOBranch> branches)
- {
- dumpLastRevision();
- super.dumpEnd(branches);
- }
-
- @Override
- protected void dumpBranch(CDOBranch branch)
- {
- dumpLastRevision();
- super.dumpBranch(branch);
- }
-
- @Override
- protected void dumpRevision(CDORevision rev)
- {
- CDOID id = rev.getID();
- if (lastRevision != null && !id.equals(lastRevision.getID()))
- {
- dumpLastRevision();
- }
-
- if (versionsBuilder == null)
- {
- versionsBuilder = new StringBuilder();
- }
- else
- {
- versionsBuilder.append(" ");
- if (versionsBuilder.length() > 64)
- {
- versionsBuilder.append("<br>");
- }
- }
-
- String key = CDORevisionUtil.formatRevisionKey(rev);
- if (revision[0] == null)
- {
- revision[0] = key;
- }
-
- String version = getVersionPrefix(rev) + rev.getVersion();
- if (key.equals(revision[0]))
- {
- versionsBuilder.append("<b>" + version + "</b>");
- }
- else
- {
- versionsBuilder.append(browser.href(version, getName(), "revision", key));
- }
-
- lastRevision = rev;
- }
-
- protected void dumpLastRevision()
- {
- if (versionsBuilder != null)
- {
- PrintStream out = out();
-
- out.println("<tr>");
- out.println("<td valign=\"top\">&nbsp;&nbsp;&nbsp;&nbsp;");
- out.println(getCDOIDLabel(lastRevision));
- out.println("&nbsp;&nbsp;&nbsp;&nbsp;</td>");
-
- out.println("<td>");
- out.println(versionsBuilder.toString());
- out.println("</td>");
- out.println("</tr>");
-
- lastRevision = null;
- versionsBuilder = null;
- }
- }
- }.dump();
-
- out.print("</td></tr></table></td>\r\n");
- out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
-
- if (revision[0] != null)
- {
- out.print("<td valign=\"top\">\r\n");
- showRevision(out, browser, allRevisions, ids, revision[0], repository);
- out.print("</td>\r\n");
- }
-
- out.print("</tr>\r\n");
- out.print("</table>\r\n");
- }
-
- /**
- * @since 4.0
- */
- protected void showRevision(PrintStream pout, CDOServerBrowser browser,
- Map<CDOBranch, List<CDORevision>> allRevisions, Map<CDOID, List<CDORevision>> ids, String key,
- InternalRepository repository)
- {
- CDORevisionKey revisionKey = CDORevisionUtil.parseRevisionKey(key, repository.getBranchManager());
- for (CDORevision revision : allRevisions.get(revisionKey.getBranch()))
- {
- if (revision.getVersion() == revisionKey.getVersion() && revision.getID().equals(revisionKey.getID()))
- {
- showRevision(pout, browser, ids, (InternalCDORevision)revision);
- return;
- }
- }
- }
-
- /**
- * @since 4.0
- */
- protected void showRevision(PrintStream pout, CDOServerBrowser browser, Map<CDOID, List<CDORevision>> ids,
- InternalCDORevision revision)
- {
- String className = revision.getEClass().toString();
- className = className.substring(className.indexOf(' '));
- className = StringUtil.replace(className, new String[] { "(", ")", "," }, new String[] { "<br>", "", "<br>" });
- className = className.substring("<br>".length() + 1);
-
- String created = CDOCommonUtil.formatTimeStamp(revision.getTimeStamp());
- String commitInfo = browser.href(created, HistoryPage.NAME, "time", String.valueOf(revision.getTimeStamp()));
-
- pout.print("<table border=\"1\" cellpadding=\"2\">\r\n");
- showKeyValue(pout, true, "type", "<b>" + revision.getClass().getSimpleName() + "</b>");
- showKeyValue(pout, true, "class", className);
- showKeyValue(pout, true, "id", getRevisionValue(revision.getID(), browser, ids, revision));
- showKeyValue(pout, true, "branch", revision.getBranch().getName() + "[" + revision.getBranch().getID() + "]");
- showKeyValue(pout, true, "version", revision.getVersion());
- showKeyValue(pout, true, "created", commitInfo);
- showKeyValue(pout, true, "revised", CDOCommonUtil.formatTimeStamp(revision.getRevised()));
- if (!(revision instanceof SyntheticCDORevision))
- {
- showKeyValue(pout, true, "resource", getRevisionValue(revision.getResourceID(), browser, ids, revision));
- showKeyValue(pout, true, "container", getRevisionValue(revision.getContainerID(), browser, ids, revision));
- showKeyValue(pout, true, "feature", revision.getContainingFeatureID());
-
- for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures())
- {
- Object value = revision.getValue(feature);
- showKeyValue(pout, false, feature.getName(), getRevisionValue(value, browser, ids, revision));
- }
- }
-
- pout.print("</table>\r\n");
- }
-
- /**
- * @since 4.0
- */
- protected Object getRevisionValue(Object value, CDOServerBrowser browser, Map<CDOID, List<CDORevision>> ids,
- InternalCDORevision context)
- {
- if (value instanceof CDOID)
- {
- List<CDORevision> revisions = ids.get(value);
- if (revisions != null)
- {
- StringBuilder builder = new StringBuilder();
- builder.append(getCDOIDLabel(revisions.get(0)));
-
- if (browser != null)
- {
- builder.append("&nbsp;&nbsp;");
- for (CDORevision revision : revisions)
- {
- String label = getVersionPrefix(revision) + revision.getVersion();
- String branchName = revision.getBranch().getName();
- if (!CDOBranch.MAIN_BRANCH_NAME.equals(branchName))
- {
- label += "[" + branchName + "]";
- }
-
- builder.append(" ");
- if (revision == context)
- {
- builder.append(label);
- }
- else
- {
- builder.append(browser.href(label, getName(), "revision", CDORevisionUtil.formatRevisionKey(revision)));
- }
- }
- }
-
- return builder.toString();
- }
- }
-
- if (value instanceof Collection)
- {
- StringBuilder builder = new StringBuilder();
- for (Object element : (Collection<?>)value)
- {
- builder.append(builder.length() == 0 ? "" : "<br>");
- builder.append(getRevisionValue(element, browser, ids, context));
- }
-
- return builder.toString();
- }
-
- return value;
- }
-
- private String getVersionPrefix(CDORevision revision)
- {
- if (revision instanceof PointerCDORevision)
- {
- return "p";
- }
-
- if (revision instanceof DetachedCDORevision)
- {
- return "d";
- }
-
- return "v";
- }
-
- /**
- * @since 4.0
- */
- protected void showKeyValue(PrintStream pout, boolean bg, String key, Object value)
- {
- String color = bg ? "EEEEEE" : "FFFFFF";
- pout.print("<tr bgcolor=\"" + color + "\">\r\n");
- pout.print("<td valign=\"top\"><b>" + key + "</b></td>\r\n");
- pout.print("<td valign=\"top\">");
- pout.print(value);
- pout.print("</td>\r\n");
- pout.print("</tr>\r\n");
- }
-
- protected abstract Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository);
-
- private Map<CDOID, List<CDORevision>> getAllIDs(Map<CDOBranch, List<CDORevision>> allRevisions)
- {
- Map<CDOID, List<CDORevision>> ids = new HashMap<CDOID, List<CDORevision>>();
- for (List<CDORevision> list : allRevisions.values())
- {
- for (CDORevision revision : list)
- {
- CDOID id = revision.getID();
- List<CDORevision> revisions = ids.get(id);
- if (revisions == null)
- {
- revisions = new ArrayList<CDORevision>();
- ids.put(id, revisions);
- }
-
- revisions.add(revision);
- }
- }
-
- return ids;
- }
-
- protected String getCDOIDLabel(CDORevision revision)
- {
- String label = revision.toString();
- return label.substring(0, label.indexOf(':'));
- }
-
- /**
- * A {@link Page server browser page} that renders the {@link CDORevision revisions} in a revision cache.
- *
- * @author Eike Stepper
- */
- public static class FromCache extends RevisionsPage
- {
- public static final String NAME = "crevisions";
-
- public FromCache()
- {
- super(NAME, "Revisions From Cache");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return true;
- }
-
- @Override
- protected Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository)
- {
- return repository.getRevisionManager().getCache().getAllRevisions();
- }
- }
-
- /**
- * A {@link Page server browser page} that renders the {@link CDORevision revisions} in a {@link IStore store}.
- *
- * @author Eike Stepper
- */
- public static class FromStore extends RevisionsPage
- {
- public static final String NAME = "srevisions";
-
- public FromStore()
- {
- super(NAME, "Revisions From Store");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return repository.getStore() instanceof CDOAllRevisionsProvider;
- }
-
- @Override
- protected Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository)
- {
- return ((CDOAllRevisionsProvider)repository.getStore()).getAllRevisions();
- }
- }
- }
-
- /**
- * A {@link Page server browser page} that renders {@link CDOLobInfo large object infos}.
- *
- * @author Eike Stepper
- */
- public static class LobsPage extends AbstractPage
- {
- public static final String NAME = "lobs";
-
- public LobsPage()
- {
- super(NAME, "Large Objects");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return true;
- }
-
- public void display(final CDOServerBrowser browser, InternalRepository repository, final PrintStream out)
- {
- out.print("<table border=\"0\">\r\n");
- out.print("<tr>\r\n");
- out.print("<td valign=\"top\">\r\n");
-
- IStoreAccessor accessor = repository.getStore().getReader(null);
- StoreThreadLocal.setAccessor(accessor);
-
- final String param = browser.getParam("id");
- final Object[] details = { null, null, null };
-
- try
- {
- repository.handleLobs(0, 0, new CDOLobHandler()
- {
- public OutputStream handleBlob(byte[] id, long size)
- {
- if (showLob(out, "Blob", id, size, browser, param))
- {
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- details[0] = result;
- details[1] = param;
- details[2] = size;
- return result;
- }
-
- return null;
- }
-
- public Writer handleClob(byte[] id, long size)
- {
- if (showLob(out, "Clob", id, size, browser, param))
- {
- CharArrayWriter result = new CharArrayWriter();
- details[0] = result;
- details[1] = param;
- details[2] = size;
- return result;
- }
-
- return null;
- }
- });
- }
- catch (IOException ex)
- {
- throw WrappedException.wrap(ex);
- }
- finally
- {
- StoreThreadLocal.release();
- }
-
- out.print("</td>\r\n");
-
- if (details[0] != null)
- {
- out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
- out.print("<td valign=\"top\">\r\n");
- if (details[0] instanceof ByteArrayOutputStream)
- {
- ByteArrayOutputStream baos = (ByteArrayOutputStream)details[0];
- String hex = HexUtil.bytesToHex(baos.toByteArray());
-
- out.println("<h3>Blob " + details[1] + " (" + details[2] + ")</h3>");
- out.println("<pre>\r\n");
- for (int i = 0; i < hex.length(); i++)
- {
- out.print(hex.charAt(i));
- if ((i + 1) % 32 == 0)
- {
- out.print("\r\n");
- }
- else if ((i + 1) % 16 == 0)
- {
- out.print(" ");
- }
- else if ((i + 1) % 2 == 0)
- {
- out.print(" ");
- }
- }
-
- out.println("</pre>\r\n");
- }
- else
- {
- CharArrayWriter caw = (CharArrayWriter)details[0];
- out.println("<h3>Clob " + details[1] + " (" + details[2] + ")</h3>");
- out.println("<pre>" + caw + "</pre>");
- }
-
- out.print("</td>\r\n");
- }
-
- out.print("</tr>\r\n");
- out.print("</table>\r\n");
- }
-
- protected boolean showLob(PrintStream out, String type, byte[] id, long size, CDOServerBrowser browser, String param)
- {
- String hex = HexUtil.bytesToHex(id);
- boolean selected = hex.equals(param);
- String label = selected ? hex : browser.href(hex, getName(), "id", hex);
- out.println(type + " " + label + " (" + size + ")");
- return selected;
- }
- }
-
- /**
- * A {@link Page server browser page} that renders {@link CDOCommitInfo commit infos}.
- *
- * @author Eike Stepper
- */
- public static class HistoryPage extends AbstractPage
- {
- public static final String NAME = "history";
-
- public HistoryPage()
- {
- super(NAME, "Commit Infos");
- }
-
- public boolean canDisplay(InternalRepository repository)
- {
- return true;
- }
-
- public void display(final CDOServerBrowser browser, InternalRepository repository, final PrintStream out)
- {
- out.print("<table border=\"0\">\r\n");
- out.print("<tr>\r\n");
- out.print("<td valign=\"top\">\r\n");
-
- IStoreAccessor accessor = repository.getStore().getReader(null);
- StoreThreadLocal.setAccessor(accessor);
-
- final String param = browser.getParam("time");
-
- out.print("<table border=\"1\" cellpadding=\"2\">\r\n");
- out.print("<tr>\r\n");
- out.print("<td valign=\"top\">Time</td>\r\n");
- out.print("<td valign=\"top\">Branch</td>\r\n");
- out.print("<td valign=\"top\">User</td>\r\n");
- out.print("<td valign=\"top\">Comment</td>\r\n");
- out.print("</tr>\r\n");
-
- final CDOCommitInfo[] details = { null };
-
- try
- {
- final boolean auditing = repository.isSupportingAudits();
- repository.getCommitInfoManager().getCommitInfos(null, 0L, 0L, new CDOCommitInfoHandler()
- {
- public void handleCommitInfo(CDOCommitInfo commitInfo)
- {
- if (showCommitInfo(out, commitInfo, browser, param, auditing))
- {
- details[0] = commitInfo;
- }
- }
- });
-
- out.print("</table>\r\n");
- out.print("</td>\r\n");
- out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
- out.print("<td valign=\"top\">\r\n");
-
- if (auditing)
- {
- CDOCommitInfo commitInfo = details[0];
- if (commitInfo != null)
- {
- out.print("<h3>Commit Info " + commitInfo.getTimeStamp() + "</h3>\r\n");
- showCommitData(out, commitInfo, browser);
- }
- }
- else
- {
- out.print("<h3>No audit data available in this repository.</h3>\r\n");
- }
-
- out.print("</td>\r\n");
- out.print("</tr>\r\n");
- out.print("</table>\r\n");
- }
- finally
- {
- StoreThreadLocal.release();
- }
- }
-
- protected boolean showCommitInfo(PrintStream out, CDOCommitInfo commitInfo, CDOServerBrowser browser, String param,
- boolean auditing)
- {
- String timeStamp = String.valueOf(commitInfo.getTimeStamp());
- boolean selected = timeStamp.equals(param);
-
- String formatted = CDOCommonUtil.formatTimeStamp(commitInfo.getTimeStamp()).replaceAll(" ", "&nbsp;");
- String label = formatted;
- if (!selected && auditing)
- {
- label = browser.href(formatted, getName(), "time", timeStamp);
- }
-
- out.print("<tr>\r\n");
- out.print("<td valign=\"top\">\r\n");
- out.print(label);
- out.print("</td>\r\n");
-
- CDOBranch branch = commitInfo.getBranch();
- out.print("<td valign=\"top\">\r\n");
- out.print(branch.getName() + "[" + branch.getID() + "]");
- out.print("</td>\r\n");
-
- String userID = commitInfo.getUserID();
- out.print("<td valign=\"top\">\r\n");
- out.print(StringUtil.isEmpty(userID) ? "&nbsp;" : browser.escape(userID));
- out.print("</td>\r\n");
-
- String comment = commitInfo.getComment();
- out.print("<td valign=\"top\">\r\n");
- out.print(StringUtil.isEmpty(comment) ? "&nbsp;" : browser.escape(comment));
- out.print("</td>\r\n");
-
- out.print("</tr>\r\n");
- return selected;
- }
-
- protected void showCommitData(PrintStream out, CDOCommitInfo commitInfo, CDOServerBrowser browser)
- {
- out.print("<h4>New Objects:</h4>\r\n");
- out.print("<ul>\r\n");
- for (CDOIDAndVersion key : commitInfo.getNewObjects())
- {
- CDORevision newObject = (CDORevision)key;
- out.print("<li>"
- + browser.href(newObject.toString(), RevisionsPage.FromStore.NAME, "revision",
- CDORevisionUtil.formatRevisionKey(newObject)) + "<br>\r\n");
- }
-
- out.print("</ul>\r\n");
- out.print("<h4>Changed Objects:</h4>\r\n");
- out.print("<ul>\r\n");
- for (CDORevisionKey key : commitInfo.getChangedObjects())
- {
- CDORevisionDelta changedObject = (CDORevisionDelta)key;
- out.print("<li>" + changedObject.toString() + "<br>\r\n");
- }
-
- out.print("</ul>\r\n");
- out.print("<h4>Detached Objects:</h4>\r\n");
- out.print("<ul>\r\n");
- for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
- {
- out.print("<li>" + key.toString() + "<br>\r\n");
- }
-
- out.print("</ul>\r\n");
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
+import org.eclipse.emf.cdo.common.revision.CDOAllRevisionsProvider;
+import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil.AllRevisionsDumper;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+
+import org.eclipse.net4j.util.HexUtil;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.concurrent.Worker;
+import org.eclipse.net4j.util.container.ContainerEventAdapter;
+import org.eclipse.net4j.util.container.IContainer;
+import org.eclipse.net4j.util.container.IManagedContainer;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.factory.ProductCreationException;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Writer;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A simple HTTP server that web browsers can connect to in order to render internal server data for debugging purposes.
+ * <p>
+ * Actual content is contributed through pluggable {@link CDOServerBrowser.Page pages}.
+ * <p>
+ * <b>Note:</b> Don't use this server in production, it's unsecure and does not perform or scale!
+ *
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public class CDOServerBrowser extends Worker
+{
+ private static final String REQUEST_PREFIX = "GET ";
+
+ private static final String REQUEST_SUFFIX = " HTTP/1.1";
+
+ private ThreadLocal<Map<String, String>> params = new InheritableThreadLocal<Map<String, String>>()
+ {
+ @Override
+ protected Map<String, String> initialValue()
+ {
+ return new HashMap<String, String>();
+ }
+ };
+
+ private int port = 7777;
+
+ private ServerSocket serverSocket;
+
+ private Map<String, InternalRepository> repositories;
+
+ private List<Page> pages = new ArrayList<Page>();
+
+ public CDOServerBrowser(Map<String, InternalRepository> repositories)
+ {
+ this.repositories = repositories;
+ setDaemon(true);
+ }
+
+ public Map<String, InternalRepository> getRepositories()
+ {
+ return repositories;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public void setPort(int port)
+ {
+ this.port = port;
+ }
+
+ @Override
+ protected void work(WorkContext context) throws Exception
+ {
+ Socket socket = null;
+
+ try
+ {
+ socket = serverSocket.accept();
+ BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ OutputStream out = new BufferedOutputStream(socket.getOutputStream());
+ PrintStream pout = new PrintStream(out);
+ printHeader(pout);
+
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ if (line.startsWith(REQUEST_PREFIX) && line.endsWith(REQUEST_SUFFIX))
+ {
+ String request = line.substring(REQUEST_PREFIX.length(), line.length() - REQUEST_SUFFIX.length()).trim();
+ String resource = request;
+ String params = "";
+ int pos = request.indexOf('?');
+ if (pos != -1)
+ {
+ resource = request.substring(0, pos);
+ params = request.substring(pos + 1);
+ }
+
+ initParams(params);
+ if ("/".equals(resource))
+ {
+ showMenu(pout);
+ }
+ else
+ {
+ String pageName = resource.substring(1);
+ for (Page page : pages)
+ {
+ if (page.getName().equals(pageName))
+ {
+ showPage(pout, page);
+ }
+ }
+ }
+ }
+
+ out.flush();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ if (isActive())
+ {
+ ex.printStackTrace();
+ }
+ }
+ finally
+ {
+ params.remove();
+ if (socket != null)
+ {
+ socket.close();
+ }
+ }
+ }
+
+ protected void initParams(String params)
+ {
+ Map<String, String> map = this.params.get();
+ for (String param : params.split("&"))
+ {
+ if (param.length() != 0)
+ {
+ String[] keyValue = param.split("=");
+ map.put(keyValue[0], keyValue[1]);
+ }
+ }
+ }
+
+ protected void clearParams()
+ {
+ Map<String, String> map = params.get();
+ map.clear();
+ }
+
+ public void removeParam(String key)
+ {
+ Map<String, String> map = params.get();
+ map.remove(key);
+ }
+
+ public String getParam(String key)
+ {
+ Map<String, String> map = params.get();
+ return map.get(key);
+ }
+
+ public String href(String label, String resource, String... params)
+ {
+ Map<String, String> map = new HashMap<String, String>(this.params.get());
+ for (int i = 0; i < params.length;)
+ {
+ map.put(params[i++], params[i++]);
+ }
+
+ List<String> list = new ArrayList<String>(map.keySet());
+ Collections.sort(list);
+
+ StringBuilder builder = new StringBuilder();
+ for (String key : list)
+ {
+ String value = map.get(key);
+ if (value != null)
+ {
+ if (builder.length() != 0)
+ {
+ builder.append("&");
+ }
+
+ builder.append(key);
+ builder.append("=");
+ builder.append(value);
+ }
+ }
+
+ return "<a href=\"/" + escape(resource) + "?" + escape(builder.toString()) + "\">" + escape(label) + "</a>";
+ }
+
+ public String escape(String raw)
+ {
+ if (raw == null)
+ {
+ return "null";
+ }
+
+ return raw.replace("<", "&lt;");
+ }
+
+ protected void printHeader(PrintStream pout)
+ {
+ pout.print("HTTP/1.1 200 OK\r\n");
+ pout.print("Content-Type: text/html\r\n");
+ pout.print("Date: " + new Date() + "\r\n");
+ pout.print("Server: DBBrowser 3.0\r\n");
+ pout.print("\r\n");
+ }
+
+ protected void showMenu(PrintStream pout)
+ {
+ clearParams();
+ pout.print("<h1>CDO Server Browser 4.0</h1><hr>\r\n");
+
+ for (Page page : pages)
+ {
+ pout.println("<h3>" + href(page.getLabel(), page.getName()) + "</h3>");
+ }
+ }
+
+ protected void showPage(PrintStream pout, Page page)
+ {
+ String repo = getParam("repo");
+
+ List<String> repoNames = new ArrayList<String>(getRepositoryNames());
+ Collections.sort(repoNames);
+
+ pout.print("<h3><a href=\"/\">" + page.getLabel() + "</a>:&nbsp;&nbsp;");
+ for (String repoName : repoNames)
+ {
+ InternalRepository repository = getRepository(repoName);
+ if (!page.canDisplay(repository))
+ {
+ continue;
+ }
+
+ if (repo == null)
+ {
+ repo = repoName;
+ }
+
+ if (repoName.equals(repo))
+ {
+ pout.print("<b>" + escape(repoName) + "</b>&nbsp;&nbsp;");
+ }
+ else
+ {
+ pout.print(href(repoName, page.getName(), "repo", repoName) + "&nbsp;&nbsp;");
+ }
+ }
+
+ pout.print("</h3>");
+
+ InternalRepository repository = getRepository(repo);
+ if (repository != null)
+ {
+ pout.print("<p>\r\n");
+ page.display(this, repository, pout);
+ }
+ }
+
+ protected Set<String> getRepositoryNames()
+ {
+ return repositories.keySet();
+ }
+
+ protected InternalRepository getRepository(String name)
+ {
+ return repositories.get(name);
+ }
+
+ @Override
+ protected String getThreadName()
+ {
+ return "DBBrowser";
+ }
+
+ protected void initPages(List<Page> pages)
+ {
+ pages.add(new PackagesPage());
+ pages.add(new RevisionsPage.FromCache());
+ pages.add(new RevisionsPage.FromStore());
+ pages.add(new LobsPage());
+ pages.add(new HistoryPage());
+
+ IManagedContainer container = getPagesContainer();
+ for (String factoryType : container.getFactoryTypes(Page.PRODUCT_GROUP))
+ {
+ try
+ {
+ Page page = (Page)container.getElement(Page.PRODUCT_GROUP, factoryType, null);
+ pages.add(page);
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+
+ /**
+ * @since 4.1
+ */
+ protected IManagedContainer getPagesContainer()
+ {
+ return IPluginContainer.INSTANCE;
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ initPages(pages);
+
+ try
+ {
+ serverSocket = new ServerSocket(port);
+ }
+ catch (Exception ex)
+ {
+ throw new IllegalStateException("Could not open socket on port " + port, ex);
+ }
+
+ super.doActivate();
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ serverSocket.close();
+ super.doDeactivate();
+ }
+
+ /**
+ * A {@link CDOServerBrowser server browser} for the repositories in a {@link IManagedContainer managed container}.
+ *
+ * @author Eike Stepper
+ */
+ public static class ContainerBased extends CDOServerBrowser
+ {
+ private IContainer<?> container;
+
+ private IListener containerListener = new ContainerEventAdapter<Object>()
+ {
+ @Override
+ protected void onAdded(IContainer<Object> container, Object element)
+ {
+ addElement(element);
+ }
+
+ @Override
+ protected void onRemoved(IContainer<Object> container, Object element)
+ {
+ removeElement(element);
+ }
+ };
+
+ public ContainerBased(IContainer<?> container)
+ {
+ super(new HashMap<String, InternalRepository>());
+ this.container = container;
+ }
+
+ public ContainerBased()
+ {
+ this(IPluginContainer.INSTANCE);
+ }
+
+ public IContainer<?> getContainer()
+ {
+ return container;
+ }
+
+ @Override
+ protected IManagedContainer getPagesContainer()
+ {
+ if (container instanceof IManagedContainer)
+ {
+ return (IManagedContainer)container;
+ }
+
+ return IPluginContainer.INSTANCE;
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+ for (Object element : container.getElements())
+ {
+ addElement(element);
+ }
+
+ container.addListener(containerListener);
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ container.removeListener(containerListener);
+ super.doDeactivate();
+ }
+
+ private void addElement(Object element)
+ {
+ if (element instanceof InternalRepository)
+ {
+ InternalRepository repository = (InternalRepository)element;
+ getRepositories().put(repository.getName(), repository);
+ }
+ }
+
+ private void removeElement(Object element)
+ {
+ if (element instanceof InternalRepository)
+ {
+ InternalRepository repository = (InternalRepository)element;
+ getRepositories().remove(repository.getName());
+ }
+ }
+
+ /**
+ * Creates {@link CDOServerBrowser server browsers} for the repositories in a {@link IManagedContainer managed
+ * container}.
+ *
+ * @author Eike Stepper
+ */
+ public static class Factory extends org.eclipse.net4j.util.factory.Factory
+ {
+ public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.browsers";
+
+ public static final String TYPE = "default";
+
+ private IContainer<?> container;
+
+ public Factory()
+ {
+ this(IPluginContainer.INSTANCE);
+ }
+
+ public Factory(IContainer<?> container)
+ {
+ super(PRODUCT_GROUP, TYPE);
+ this.container = container;
+ }
+
+ public CDOServerBrowser.ContainerBased create(String description) throws ProductCreationException
+ {
+ CDOServerBrowser.ContainerBased browser = new CDOServerBrowser.ContainerBased(container);
+
+ try
+ {
+ if (!StringUtil.isEmpty(description))
+ {
+ browser.setPort(Integer.valueOf(description));
+ }
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.warn(ex);
+ }
+
+ return browser;
+ }
+ }
+ }
+
+ /**
+ * Represents pluggable content for a {@link CDOServerBrowser server browser}.
+ *
+ * @author Eike Stepper
+ */
+ public static interface Page
+ {
+ public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.server.browserPages";
+
+ public String getName();
+
+ public String getLabel();
+
+ public boolean canDisplay(InternalRepository repository);
+
+ public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out);
+ }
+
+ /**
+ * An abstract base implementation of a {@link Page server browser page}.
+ *
+ * @author Eike Stepper
+ */
+ public static abstract class AbstractPage implements Page
+ {
+ private String name;
+
+ private String label;
+
+ public AbstractPage(String name, String label)
+ {
+ this.name = name;
+ this.label = label;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getLabel()
+ {
+ return label;
+ }
+ }
+
+ /**
+ * A {@link Page server browser page} that renders the package registry contents of a repository.
+ *
+ * @author Eike Stepper
+ */
+ public static class PackagesPage extends AbstractPage
+ {
+ public static final String NAME = "packages";
+
+ public PackagesPage()
+ {
+ super(NAME, "Packages and Classes");
+ }
+
+ public boolean canDisplay(InternalRepository repository)
+ {
+ return true;
+ }
+
+ public void display(CDOServerBrowser browser, InternalRepository repository, PrintStream out)
+ {
+ String param = browser.getParam("classifier");
+ InternalCDOPackageRegistry packageRegistry = repository.getPackageRegistry(false);
+ for (InternalCDOPackageUnit unit : packageRegistry.getPackageUnits())
+ {
+ param = showPackage(unit.getTopLevelPackageInfo(), packageRegistry, browser, param, out, "&nbsp;&nbsp;");
+ }
+ }
+
+ protected String showPackage(InternalCDOPackageInfo info, InternalCDOPackageRegistry packageRegistry,
+ CDOServerBrowser browser, String param, PrintStream out, String prefix)
+ {
+ EPackage ePackage = info.getEPackage();
+ out.println("<h3>" + prefix + ePackage.getName() + "&nbsp;&nbsp;[" + ePackage.getNsURI() + "]</h3>");
+
+ for (EClassifier classifier : ePackage.getEClassifiers())
+ {
+ String name = classifier.getName();
+ if (param == null)
+ {
+ param = name;
+ }
+
+ String label = name.equals(param) ? name : browser.href(name, getName(), "classifier", name);
+ out.print(prefix + "&nbsp;&nbsp;<b>" + label);
+
+ if (classifier instanceof EEnum)
+ {
+ EEnum eenum = (EEnum)classifier;
+ out.print("&nbsp;&nbsp;" + eenum.getELiterals());
+ }
+ else if (classifier instanceof EDataType)
+ {
+ EDataType eDataType = (EDataType)classifier;
+ out.print("&nbsp;&nbsp;" + eDataType.getInstanceClassName());
+ }
+
+ out.println("</b><br>");
+ }
+
+ for (EPackage sub : ePackage.getESubpackages())
+ {
+ InternalCDOPackageInfo subInfo = packageRegistry.getPackageInfo(sub);
+ param = showPackage(subInfo, packageRegistry, browser, param, out, prefix + "&nbsp;&nbsp;");
+ }
+
+ return param;
+ }
+ }
+
+ /**
+ * A {@link Page server browser page} that renders {@link CDORevision revisions}.
+ *
+ * @author Eike Stepper
+ */
+ public static abstract class RevisionsPage extends AbstractPage
+ {
+ public RevisionsPage(String name, String label)
+ {
+ super(name, label);
+ }
+
+ public void display(final CDOServerBrowser browser, InternalRepository repository, PrintStream out)
+ {
+ Map<CDOBranch, List<CDORevision>> allRevisions = getAllRevisions(repository);
+ Map<CDOID, List<CDORevision>> ids = getAllIDs(allRevisions);
+
+ out.print("<table border=\"0\">\r\n");
+ out.print("<tr>\r\n");
+
+ out.print("<td valign=\"top\">\r\n");
+ out.print("<table border=\"1\" cellpadding=\"2\"><tr><td>\r\n");
+ final String[] revision = { browser.getParam("revision") };
+ new AllRevisionsDumper.Stream.Html(allRevisions, out)
+ {
+ private StringBuilder versionsBuilder;
+
+ private CDORevision lastRevision;
+
+ @Override
+ protected void dumpEnd(List<CDOBranch> branches)
+ {
+ dumpLastRevision();
+ super.dumpEnd(branches);
+ }
+
+ @Override
+ protected void dumpBranch(CDOBranch branch)
+ {
+ dumpLastRevision();
+ super.dumpBranch(branch);
+ }
+
+ @Override
+ protected void dumpRevision(CDORevision rev)
+ {
+ CDOID id = rev.getID();
+ if (lastRevision != null && !id.equals(lastRevision.getID()))
+ {
+ dumpLastRevision();
+ }
+
+ if (versionsBuilder == null)
+ {
+ versionsBuilder = new StringBuilder();
+ }
+ else
+ {
+ versionsBuilder.append(" ");
+ if (versionsBuilder.length() > 64)
+ {
+ versionsBuilder.append("<br>");
+ }
+ }
+
+ String key = CDORevisionUtil.formatRevisionKey(rev);
+ if (revision[0] == null)
+ {
+ revision[0] = key;
+ }
+
+ String version = getVersionPrefix(rev) + rev.getVersion();
+ if (key.equals(revision[0]))
+ {
+ versionsBuilder.append("<b>" + version + "</b>");
+ }
+ else
+ {
+ versionsBuilder.append(browser.href(version, getName(), "revision", key));
+ }
+
+ lastRevision = rev;
+ }
+
+ protected void dumpLastRevision()
+ {
+ if (versionsBuilder != null)
+ {
+ PrintStream out = out();
+
+ out.println("<tr>");
+ out.println("<td valign=\"top\">&nbsp;&nbsp;&nbsp;&nbsp;");
+ out.println(getCDOIDLabel(lastRevision));
+ out.println("&nbsp;&nbsp;&nbsp;&nbsp;</td>");
+
+ out.println("<td>");
+ out.println(versionsBuilder.toString());
+ out.println("</td>");
+ out.println("</tr>");
+
+ lastRevision = null;
+ versionsBuilder = null;
+ }
+ }
+ }.dump();
+
+ out.print("</td></tr></table></td>\r\n");
+ out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
+
+ if (revision[0] != null)
+ {
+ out.print("<td valign=\"top\">\r\n");
+ showRevision(out, browser, allRevisions, ids, revision[0], repository);
+ out.print("</td>\r\n");
+ }
+
+ out.print("</tr>\r\n");
+ out.print("</table>\r\n");
+ }
+
+ /**
+ * @since 4.0
+ */
+ protected void showRevision(PrintStream pout, CDOServerBrowser browser,
+ Map<CDOBranch, List<CDORevision>> allRevisions, Map<CDOID, List<CDORevision>> ids, String key,
+ InternalRepository repository)
+ {
+ CDORevisionKey revisionKey = CDORevisionUtil.parseRevisionKey(key, repository.getBranchManager());
+ for (CDORevision revision : allRevisions.get(revisionKey.getBranch()))
+ {
+ if (revision.getVersion() == revisionKey.getVersion() && revision.getID().equals(revisionKey.getID()))
+ {
+ showRevision(pout, browser, ids, (InternalCDORevision)revision);
+ return;
+ }
+ }
+ }
+
+ /**
+ * @since 4.0
+ */
+ protected void showRevision(PrintStream pout, CDOServerBrowser browser, Map<CDOID, List<CDORevision>> ids,
+ InternalCDORevision revision)
+ {
+ String className = revision.getEClass().toString();
+ className = className.substring(className.indexOf(' '));
+ className = StringUtil.replace(className, new String[] { "(", ")", "," }, new String[] { "<br>", "", "<br>" });
+ className = className.substring("<br>".length() + 1);
+
+ String created = CDOCommonUtil.formatTimeStamp(revision.getTimeStamp());
+ String commitInfo = browser.href(created, HistoryPage.NAME, "time", String.valueOf(revision.getTimeStamp()));
+
+ pout.print("<table border=\"1\" cellpadding=\"2\">\r\n");
+ showKeyValue(pout, true, "type", "<b>" + revision.getClass().getSimpleName() + "</b>");
+ showKeyValue(pout, true, "class", className);
+ showKeyValue(pout, true, "id", getRevisionValue(revision.getID(), browser, ids, revision));
+ showKeyValue(pout, true, "branch", revision.getBranch().getName() + "[" + revision.getBranch().getID() + "]");
+ showKeyValue(pout, true, "version", revision.getVersion());
+ showKeyValue(pout, true, "created", commitInfo);
+ showKeyValue(pout, true, "revised", CDOCommonUtil.formatTimeStamp(revision.getRevised()));
+ if (!(revision instanceof SyntheticCDORevision))
+ {
+ showKeyValue(pout, true, "resource", getRevisionValue(revision.getResourceID(), browser, ids, revision));
+ showKeyValue(pout, true, "container", getRevisionValue(revision.getContainerID(), browser, ids, revision));
+ showKeyValue(pout, true, "feature", revision.getContainingFeatureID());
+
+ for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures())
+ {
+ Object value = revision.getValue(feature);
+ showKeyValue(pout, false, feature.getName(), getRevisionValue(value, browser, ids, revision));
+ }
+ }
+
+ pout.print("</table>\r\n");
+ }
+
+ /**
+ * @since 4.0
+ */
+ protected Object getRevisionValue(Object value, CDOServerBrowser browser, Map<CDOID, List<CDORevision>> ids,
+ InternalCDORevision context)
+ {
+ if (value instanceof CDOID)
+ {
+ List<CDORevision> revisions = ids.get(value);
+ if (revisions != null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getCDOIDLabel(revisions.get(0)));
+
+ if (browser != null)
+ {
+ builder.append("&nbsp;&nbsp;");
+ for (CDORevision revision : revisions)
+ {
+ String label = getVersionPrefix(revision) + revision.getVersion();
+ String branchName = revision.getBranch().getName();
+ if (!CDOBranch.MAIN_BRANCH_NAME.equals(branchName))
+ {
+ label += "[" + branchName + "]";
+ }
+
+ builder.append(" ");
+ if (revision == context)
+ {
+ builder.append(label);
+ }
+ else
+ {
+ builder.append(browser.href(label, getName(), "revision", CDORevisionUtil.formatRevisionKey(revision)));
+ }
+ }
+ }
+
+ return builder.toString();
+ }
+ }
+
+ if (value instanceof Collection)
+ {
+ StringBuilder builder = new StringBuilder();
+ for (Object element : (Collection<?>)value)
+ {
+ builder.append(builder.length() == 0 ? "" : "<br>");
+ builder.append(getRevisionValue(element, browser, ids, context));
+ }
+
+ return builder.toString();
+ }
+
+ return value;
+ }
+
+ private String getVersionPrefix(CDORevision revision)
+ {
+ if (revision instanceof PointerCDORevision)
+ {
+ return "p";
+ }
+
+ if (revision instanceof DetachedCDORevision)
+ {
+ return "d";
+ }
+
+ return "v";
+ }
+
+ /**
+ * @since 4.0
+ */
+ protected void showKeyValue(PrintStream pout, boolean bg, String key, Object value)
+ {
+ String color = bg ? "EEEEEE" : "FFFFFF";
+ pout.print("<tr bgcolor=\"" + color + "\">\r\n");
+ pout.print("<td valign=\"top\"><b>" + key + "</b></td>\r\n");
+ pout.print("<td valign=\"top\">");
+ pout.print(value);
+ pout.print("</td>\r\n");
+ pout.print("</tr>\r\n");
+ }
+
+ protected abstract Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository);
+
+ private Map<CDOID, List<CDORevision>> getAllIDs(Map<CDOBranch, List<CDORevision>> allRevisions)
+ {
+ Map<CDOID, List<CDORevision>> ids = new HashMap<CDOID, List<CDORevision>>();
+ for (List<CDORevision> list : allRevisions.values())
+ {
+ for (CDORevision revision : list)
+ {
+ CDOID id = revision.getID();
+ List<CDORevision> revisions = ids.get(id);
+ if (revisions == null)
+ {
+ revisions = new ArrayList<CDORevision>();
+ ids.put(id, revisions);
+ }
+
+ revisions.add(revision);
+ }
+ }
+
+ return ids;
+ }
+
+ protected String getCDOIDLabel(CDORevision revision)
+ {
+ String label = revision.toString();
+ return label.substring(0, label.indexOf(':'));
+ }
+
+ /**
+ * A {@link Page server browser page} that renders the {@link CDORevision revisions} in a revision cache.
+ *
+ * @author Eike Stepper
+ */
+ public static class FromCache extends RevisionsPage
+ {
+ public static final String NAME = "crevisions";
+
+ public FromCache()
+ {
+ super(NAME, "Revisions From Cache");
+ }
+
+ public boolean canDisplay(InternalRepository repository)
+ {
+ return true;
+ }
+
+ @Override
+ protected Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository)
+ {
+ return repository.getRevisionManager().getCache().getAllRevisions();
+ }
+ }
+
+ /**
+ * A {@link Page server browser page} that renders the {@link CDORevision revisions} in a {@link IStore store}.
+ *
+ * @author Eike Stepper
+ */
+ public static class FromStore extends RevisionsPage
+ {
+ public static final String NAME = "srevisions";
+
+ public FromStore()
+ {
+ super(NAME, "Revisions From Store");
+ }
+
+ public boolean canDisplay(InternalRepository repository)
+ {
+ return repository.getStore() instanceof CDOAllRevisionsProvider;
+ }
+
+ @Override
+ protected Map<CDOBranch, List<CDORevision>> getAllRevisions(InternalRepository repository)
+ {
+ return ((CDOAllRevisionsProvider)repository.getStore()).getAllRevisions();
+ }
+ }
+ }
+
+ /**
+ * A {@link Page server browser page} that renders {@link CDOLobInfo large object infos}.
+ *
+ * @author Eike Stepper
+ */
+ public static class LobsPage extends AbstractPage
+ {
+ public static final String NAME = "lobs";
+
+ public LobsPage()
+ {
+ super(NAME, "Large Objects");
+ }
+
+ public boolean canDisplay(InternalRepository repository)
+ {
+ return true;
+ }
+
+ public void display(final CDOServerBrowser browser, InternalRepository repository, final PrintStream out)
+ {
+ out.print("<table border=\"0\">\r\n");
+ out.print("<tr>\r\n");
+ out.print("<td valign=\"top\">\r\n");
+
+ IStoreAccessor accessor = repository.getStore().getReader(null);
+ StoreThreadLocal.setAccessor(accessor);
+
+ final String param = browser.getParam("id");
+ final Object[] details = { null, null, null };
+
+ try
+ {
+ repository.handleLobs(0, 0, new CDOLobHandler()
+ {
+ public OutputStream handleBlob(byte[] id, long size)
+ {
+ if (showLob(out, "Blob", id, size, browser, param))
+ {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ details[0] = result;
+ details[1] = param;
+ details[2] = size;
+ return result;
+ }
+
+ return null;
+ }
+
+ public Writer handleClob(byte[] id, long size)
+ {
+ if (showLob(out, "Clob", id, size, browser, param))
+ {
+ CharArrayWriter result = new CharArrayWriter();
+ details[0] = result;
+ details[1] = param;
+ details[2] = size;
+ return result;
+ }
+
+ return null;
+ }
+ });
+ }
+ catch (IOException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+
+ out.print("</td>\r\n");
+
+ if (details[0] != null)
+ {
+ out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
+ out.print("<td valign=\"top\">\r\n");
+ if (details[0] instanceof ByteArrayOutputStream)
+ {
+ ByteArrayOutputStream baos = (ByteArrayOutputStream)details[0];
+ String hex = HexUtil.bytesToHex(baos.toByteArray());
+
+ out.println("<h3>Blob " + details[1] + " (" + details[2] + ")</h3>");
+ out.println("<pre>\r\n");
+ for (int i = 0; i < hex.length(); i++)
+ {
+ out.print(hex.charAt(i));
+ if ((i + 1) % 32 == 0)
+ {
+ out.print("\r\n");
+ }
+ else if ((i + 1) % 16 == 0)
+ {
+ out.print(" ");
+ }
+ else if ((i + 1) % 2 == 0)
+ {
+ out.print(" ");
+ }
+ }
+
+ out.println("</pre>\r\n");
+ }
+ else
+ {
+ CharArrayWriter caw = (CharArrayWriter)details[0];
+ out.println("<h3>Clob " + details[1] + " (" + details[2] + ")</h3>");
+ out.println("<pre>" + caw + "</pre>");
+ }
+
+ out.print("</td>\r\n");
+ }
+
+ out.print("</tr>\r\n");
+ out.print("</table>\r\n");
+ }
+
+ protected boolean showLob(PrintStream out, String type, byte[] id, long size, CDOServerBrowser browser, String param)
+ {
+ String hex = HexUtil.bytesToHex(id);
+ boolean selected = hex.equals(param);
+ String label = selected ? hex : browser.href(hex, getName(), "id", hex);
+ out.println(type + " " + label + " (" + size + ")");
+ return selected;
+ }
+ }
+
+ /**
+ * A {@link Page server browser page} that renders {@link CDOCommitInfo commit infos}.
+ *
+ * @author Eike Stepper
+ */
+ public static class HistoryPage extends AbstractPage
+ {
+ public static final String NAME = "history";
+
+ public HistoryPage()
+ {
+ super(NAME, "Commit Infos");
+ }
+
+ public boolean canDisplay(InternalRepository repository)
+ {
+ return true;
+ }
+
+ public void display(final CDOServerBrowser browser, InternalRepository repository, final PrintStream out)
+ {
+ out.print("<table border=\"0\">\r\n");
+ out.print("<tr>\r\n");
+ out.print("<td valign=\"top\">\r\n");
+
+ IStoreAccessor accessor = repository.getStore().getReader(null);
+ StoreThreadLocal.setAccessor(accessor);
+
+ final String param = browser.getParam("time");
+
+ out.print("<table border=\"1\" cellpadding=\"2\">\r\n");
+ out.print("<tr>\r\n");
+ out.print("<td valign=\"top\">Time</td>\r\n");
+ out.print("<td valign=\"top\">Branch</td>\r\n");
+ out.print("<td valign=\"top\">User</td>\r\n");
+ out.print("<td valign=\"top\">Comment</td>\r\n");
+ out.print("</tr>\r\n");
+
+ final CDOCommitInfo[] details = { null };
+
+ try
+ {
+ final boolean auditing = repository.isSupportingAudits();
+ repository.getCommitInfoManager().getCommitInfos(null, 0L, 0L, new CDOCommitInfoHandler()
+ {
+ public void handleCommitInfo(CDOCommitInfo commitInfo)
+ {
+ if (showCommitInfo(out, commitInfo, browser, param, auditing))
+ {
+ details[0] = commitInfo;
+ }
+ }
+ });
+
+ out.print("</table>\r\n");
+ out.print("</td>\r\n");
+ out.print("<td>&nbsp;&nbsp;&nbsp;</td>\r\n");
+ out.print("<td valign=\"top\">\r\n");
+
+ if (auditing)
+ {
+ CDOCommitInfo commitInfo = details[0];
+ if (commitInfo != null)
+ {
+ out.print("<h3>Commit Info " + commitInfo.getTimeStamp() + "</h3>\r\n");
+ showCommitData(out, commitInfo, browser);
+ }
+ }
+ else
+ {
+ out.print("<h3>No audit data available in this repository.</h3>\r\n");
+ }
+
+ out.print("</td>\r\n");
+ out.print("</tr>\r\n");
+ out.print("</table>\r\n");
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ protected boolean showCommitInfo(PrintStream out, CDOCommitInfo commitInfo, CDOServerBrowser browser, String param,
+ boolean auditing)
+ {
+ String timeStamp = String.valueOf(commitInfo.getTimeStamp());
+ boolean selected = timeStamp.equals(param);
+
+ String formatted = CDOCommonUtil.formatTimeStamp(commitInfo.getTimeStamp()).replaceAll(" ", "&nbsp;");
+ String label = formatted;
+ if (!selected && auditing)
+ {
+ label = browser.href(formatted, getName(), "time", timeStamp);
+ }
+
+ out.print("<tr>\r\n");
+ out.print("<td valign=\"top\">\r\n");
+ out.print(label);
+ out.print("</td>\r\n");
+
+ CDOBranch branch = commitInfo.getBranch();
+ out.print("<td valign=\"top\">\r\n");
+ out.print(branch.getName() + "[" + branch.getID() + "]");
+ out.print("</td>\r\n");
+
+ String userID = commitInfo.getUserID();
+ out.print("<td valign=\"top\">\r\n");
+ out.print(StringUtil.isEmpty(userID) ? "&nbsp;" : browser.escape(userID));
+ out.print("</td>\r\n");
+
+ String comment = commitInfo.getComment();
+ out.print("<td valign=\"top\">\r\n");
+ out.print(StringUtil.isEmpty(comment) ? "&nbsp;" : browser.escape(comment));
+ out.print("</td>\r\n");
+
+ out.print("</tr>\r\n");
+ return selected;
+ }
+
+ protected void showCommitData(PrintStream out, CDOCommitInfo commitInfo, CDOServerBrowser browser)
+ {
+ out.print("<h4>New Objects:</h4>\r\n");
+ out.print("<ul>\r\n");
+ for (CDOIDAndVersion key : commitInfo.getNewObjects())
+ {
+ CDORevision newObject = (CDORevision)key;
+ out.print("<li>"
+ + browser.href(newObject.toString(), RevisionsPage.FromStore.NAME, "revision",
+ CDORevisionUtil.formatRevisionKey(newObject)) + "<br>\r\n");
+ }
+
+ out.print("</ul>\r\n");
+ out.print("<h4>Changed Objects:</h4>\r\n");
+ out.print("<ul>\r\n");
+ for (CDORevisionKey key : commitInfo.getChangedObjects())
+ {
+ CDORevisionDelta changedObject = (CDORevisionDelta)key;
+ out.print("<li>" + changedObject.toString() + "<br>\r\n");
+ }
+
+ out.print("</ul>\r\n");
+ out.print("<h4>Detached Objects:</h4>\r\n");
+ out.print("<ul>\r\n");
+ for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
+ {
+ out.print("<li>" + key.toString() + "<br>\r\n");
+ }
+
+ out.print("</ul>\r\n");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
index 69c45035b5..fd2cc703bc 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/config/impl/RepositoryConfig.java
@@ -98,8 +98,8 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
private static final boolean LOG_MULTI_VIEW_COMMIT = false;
- private static final Boolean disableServerBrowser = Boolean.valueOf(System.getProperty(
- "org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.disableServerBrowser", "false"));
+ private static final Boolean enableServerBrowser = Boolean.valueOf(System.getProperty(
+ "org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig.enableServerBrowser", "false"));
private static final long serialVersionUID = 1L;
@@ -352,7 +352,7 @@ public abstract class RepositoryConfig extends Config implements IRepositoryConf
// Start default repository
getRepository(REPOSITORY_NAME);
- if (!disableServerBrowser)
+ if (enableServerBrowser)
{
serverBrowser = new CDOServerBrowser(repositories);
serverBrowser.activate();
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/container/PluginContainer.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/container/PluginContainer.java
index 2a245e1c2c..07ec240950 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/container/PluginContainer.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/internal/util/container/PluginContainer.java
@@ -1,77 +1,69 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- * Eike Stepper - initial API and implementation
- */
-package org.eclipse.net4j.internal.util.container;
-
-import org.eclipse.net4j.internal.util.bundle.OM;
-import org.eclipse.net4j.internal.util.factory.PluginFactoryRegistry;
-import org.eclipse.net4j.util.container.IElementProcessor;
-import org.eclipse.net4j.util.container.IPluginContainer;
-import org.eclipse.net4j.util.container.ManagedContainer;
-import org.eclipse.net4j.util.factory.IFactory;
-import org.eclipse.net4j.util.factory.IFactoryKey;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.log.OMLogger;
-import org.eclipse.net4j.util.registry.IRegistry;
-
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class PluginContainer extends ManagedContainer implements IPluginContainer
-{
- private static PluginContainer instance;
-
- private PluginContainer()
- {
- }
-
- @Override
- protected IRegistry<IFactoryKey, IFactory> createFactoryRegistry()
- {
- return new PluginFactoryRegistry();
- }
-
- @Override
- protected List<IElementProcessor> createPostProcessors()
- {
- return new PluginElementProcessorList();
- }
-
- public static void dispose()
- {
- if (instance != null)
- {
- LifecycleUtil.deactivate(instance, OMLogger.Level.WARN);
- instance = null;
- }
- }
-
- public static synchronized PluginContainer getInstance()
- {
- if (instance == null)
- {
- instance = new PluginContainer();
-
- try
- {
- instance.activate();
- }
- catch (Exception ex)
- {
- OM.LOG.error(ex);
- instance = null;
- }
- }
-
- return instance;
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.net4j.internal.util.container;
+
+import org.eclipse.net4j.internal.util.factory.PluginFactoryRegistry;
+import org.eclipse.net4j.util.container.IElementProcessor;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.container.ManagedContainer;
+import org.eclipse.net4j.util.factory.IFactory;
+import org.eclipse.net4j.util.factory.IFactoryKey;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.registry.IRegistry;
+
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public class PluginContainer extends ManagedContainer implements IPluginContainer
+{
+ private static PluginContainer instance;
+
+ private PluginContainer()
+ {
+ }
+
+ @Override
+ protected IRegistry<IFactoryKey, IFactory> createFactoryRegistry()
+ {
+ return new PluginFactoryRegistry();
+ }
+
+ @Override
+ protected List<IElementProcessor> createPostProcessors()
+ {
+ return new PluginElementProcessorList();
+ }
+
+ public static void dispose()
+ {
+ if (instance != null)
+ {
+ LifecycleUtil.deactivate(instance, OMLogger.Level.WARN);
+ instance = null;
+ }
+ }
+
+ public static synchronized PluginContainer getInstance()
+ {
+ if (instance == null)
+ {
+ PluginContainer container = new PluginContainer();
+ container.activate();
+
+ instance = container; // Leave instance==null in case of a Throwable in activate()
+ }
+
+ return instance;
+ }
+}

Back to the top