| /******************************************************************************* |
| * Copyright (c) 2015 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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(); |
| } |
| } |