tmf: Add TmfTraceAdapterFactory
authorPatrick Tasse <patrick.tasse@gmail.com>
Fri, 30 Oct 2015 20:15:04 +0000 (16:15 -0400)
committerPatrick Tasse <patrick.tasse@gmail.com>
Mon, 9 Nov 2015 20:00:53 +0000 (15:00 -0500)
Base class for a trace adapter factory. The factory creates a single
instance of each adapter type per trace, and disposes the adapter when
the trace is closed, if it is an instance of IDisposableAdapter.

Change-Id: Ieec69d17d0cff037f2df0c8dded14eef91db6f97
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/59388
Reviewed-by: Hudson CI
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/AbstractTmfTraceAdapterFactory.java [new file with mode: 0644]

diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/AbstractTmfTraceAdapterFactory.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/AbstractTmfTraceAdapterFactory.java
new file mode 100644 (file)
index 0000000..d515b1b
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Ericsson
+ *
+ * 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:
+ *   Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.core.trace;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+
+/**
+ * Base class for a trace adapter factory. The factory creates a single instance
+ * of each adapter type per trace, and disposes the adapter when the trace is
+ * closed, if it is an instance of {@link IDisposableAdapter}.
+ *
+ * @since 2.0
+ */
+public abstract class AbstractTmfTraceAdapterFactory implements IAdapterFactory {
+
+    /**
+     * Interface for trace adapters that manage resources which must be freed
+     * when the trace is closed.
+     */
+    public interface IDisposableAdapter {
+        /**
+         * Disposes of this trace adapter. All resources must be freed.
+         */
+        void dispose();
+    }
+
+    private final Table<ITmfTrace, Class<?>, Object> fAdapters = HashBasedTable.create();
+
+    /**
+     * Constructor.
+     */
+    public AbstractTmfTraceAdapterFactory() {
+        TmfSignalManager.register(this);
+    }
+
+    /**
+     * Disposes the trace adapter factory's resources and all of its adapters.
+     */
+    public synchronized void dispose() {
+        TmfSignalManager.deregister(this);
+        disposeAdapters(fAdapters.values());
+        fAdapters.clear();
+    }
+
+    private static void disposeAdapters(Collection<Object> adapters) {
+        for (Object adapter : adapters) {
+            if (adapter instanceof IDisposableAdapter) {
+                ((IDisposableAdapter) adapter).dispose();
+            }
+        }
+    }
+
+    @Override
+    public synchronized <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+        if (adaptableObject instanceof ITmfTrace) {
+            ITmfTrace trace = (ITmfTrace) adaptableObject;
+            Object adapter = fAdapters.get(trace, adapterType);
+            if (adapter == null) {
+                adapter = getTraceAdapter(trace, adapterType);
+            }
+            if (adapter != null) {
+                fAdapters.put(trace, adapterType, adapter);
+                return adapterType.cast(adapter);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns an object which is an instance of the given class associated with
+     * the given trace. Returns null if no such object can be found.
+     *
+     * @param trace
+     *            the trace being adapted
+     * @param adapterType
+     *            the type of adapter to look up
+     * @return a object of the given adapter type, or null if this factory does
+     *         not have an adapter of the given type for the given trace
+     */
+    protected abstract <T> @Nullable T getTraceAdapter(@NonNull ITmfTrace trace, Class<T> adapterType);
+
+    /**
+     * Signal handler for the trace closed signal.
+     *
+     * @param signal
+     *            the trace closed signal
+     */
+    @TmfSignalHandler
+    public synchronized void traceClosed(TmfTraceClosedSignal signal) {
+        Map<Class<?>, Object> row = fAdapters.row(signal.getTrace());
+        disposeAdapters(row.values());
+        row.clear();
+    }
+}
This page took 0.028025 seconds and 5 git commands to generate.