/*******************************************************************************
* 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.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.jdt.annotation.Nullable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* This class manages adapter factories for traces. An adapter can be specific
* to a given trace type id, or to traces of a given trace class.
*
* @since 2.0
*/
public class TmfTraceAdapterManager {
private static Multimap<String, IAdapterFactory> fFactoriesById = HashMultimap.create();
private static Multimap<Class<? extends ITmfTrace>, IAdapterFactory> fFactoriesByClass = HashMultimap.create();
/**
* Registers the given adapter factory as extending traces with the given
* trace type id.
* </p>
*
* @param factory
* the adapter factory
* @param traceTypeId
* the trace type id of traces being extended
*/
public static void registerFactory(IAdapterFactory factory, String traceTypeId) {
fFactoriesById.put(traceTypeId, factory);
}
/**
* Registers the given adapter factory as extending traces of the given
* class.
* <p>
* If the trace class being extended is a class, the given factory's
* adapters are available on instances of that class and any of its
* subclasses. If it is an interface, the adapters are available to all
* classes that directly or indirectly implement that interface.
* </p>
*
* @param factory
* the adapter factory
* @param traceClass
* the class of traces being extended
*/
public static void registerFactory(IAdapterFactory factory, Class<? extends ITmfTrace> traceClass) {
fFactoriesByClass.put(traceClass, factory);
}
/**
* Removes the given adapter factory completely from the list of registered
* factories.
*
* @param factory
* the adapter factory to remove
* @see #registerFactory(IAdapterFactory, Class)
* @see #registerFactory(IAdapterFactory, String)
*/
public static void unregisterFactory(IAdapterFactory factory) {
fFactoriesById.values().remove(factory);
fFactoriesByClass.values().remove(factory);
}
/**
* Returns a list of object which are instances of the given class
* associated with the given trace. Returns an empty list if no such object
* can be found.
* <p>
*
* @param trace
* the trace being queried
* @param adapterType
* the type of adapter to look up
* @return a list of objects of the given adapter type
*/
public static <T> List<T> getAdapters(ITmfTrace trace, Class<T> adapterType) {
Collection<IAdapterFactory> factoriesById = fFactoriesById.get(trace.getTraceTypeId());
Collection<Entry<Class<? extends ITmfTrace>, IAdapterFactory>> entries = fFactoriesByClass.entries();
List<T> adapters = new ArrayList<>(factoriesById.size() + entries.size());
for (IAdapterFactory factory : factoriesById) {
@Nullable T adapter = factory.getAdapter(trace, adapterType);
if (adapter != null) {
adapters.add(adapter);
}
}
for (Entry<Class<? extends ITmfTrace>, IAdapterFactory> entry : entries) {
if (entry.getKey().isInstance(trace)) {
@Nullable T adapter = entry.getValue().getAdapter(trace, adapterType);
if (adapter != null) {
adapters.add(adapter);
}
}
}
return adapters;
}
}