/******************************************************************************* * Copyright (c) 2011 Wind River Systems, Inc. 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.core.connection.managers; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.tm.te.core.connection.interfaces.IConnectStrategy; import org.eclipse.tm.te.core.connection.interfaces.IConnectionType; /** * Connection type bindings extension point manager implementation. */ public class ConnectionTypeBindingsManager { /** * Immutable class describing a connect strategy binding. */ private final static class ConnectStrategyBinding { public final String id; public final String overwrite; public ConnectStrategyBinding(String id, String overwrite) { this.id = id; this.overwrite = overwrite; } } // Flag to remember if the extension point got already read and processed. private boolean initialized; // The map between connection type id's and their associated connect strategies. private final Map<String, List<ConnectStrategyBinding>> typeIdToStrategyId = new LinkedHashMap<String, List<ConnectStrategyBinding>>(); // The sub extension point manager instances private final ConnectionTypeExtensionPointManager connectionTypeManger = new ConnectionTypeExtensionPointManager(); /* * Thread save singleton instance creation. */ private static class LazyConnectionTypeBindingsManager { public static ConnectionTypeBindingsManager instance = new ConnectionTypeBindingsManager(); } /** * Returns the singleton instance for the connection type bindings manager. */ public static ConnectionTypeBindingsManager getInstance() { return LazyConnectionTypeBindingsManager.instance; } /** * Constructor. */ ConnectionTypeBindingsManager() { initialized = false; initialize(); } /** * Initialize the connection type bindings manager and triggers to load and read the managed * extension points. */ public void initialize() { if (initialized) { return; } // load and register the connection type bindings loadConnectionTypeBindings(); initialized = true; } // ***** BEGIN: Section extension point management ***** /** * Load and register all connection type id shortcuts. */ private void loadConnectionTypeBindings() { // load all target connection type bindings and register them IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint point = registry.getExtensionPoint("org.eclipse.tm.te.core.connectionTypeBindings"); //$NON-NLS-1$ if (point != null) { // load target connection type bindings IExtension[] typeBindings = point.getExtensions(); for (IExtension typeBinding : typeBindings) { // load configuration elements IConfigurationElement[] configElements = typeBinding.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { // handle connection type binding if ("connectionTypeBinding".equals(configElement.getName())) { //$NON-NLS-1$ String connectionTypeId = configElement.getAttribute("connectionTypeId"); //$NON-NLS-1$ // load connect strategy binding IConfigurationElement[] connectStrategy = configElement.getChildren("connectStrategy"); //$NON-NLS-1$ for (IConfigurationElement element : connectStrategy) { String connectStrategyId = element.getAttribute("id"); //$NON-NLS-1$ String connectStrategyOverwrite = element.getAttribute("overwrite"); //$NON-NLS-1$ if (connectStrategyId != null && connectStrategyId.length() > 0) { registerConnectStrategyBinding(connectionTypeId.trim(), connectStrategyId.trim(), connectStrategyOverwrite != null ? connectStrategyOverwrite.trim() : null); } } } } } } } // ***** END: Section extension point management ***** // ***** BEGIN: Section connect strategy management ***** /** * Register a binding between a connection type id and a connect strategy id. Bindings * registered for the same connection type will be overwritten using the overwrite attribute. If * the connect strategy id is <code>null</code>, possibly registered bindings are removed. * * @param typeId The connection type id. Must not be <code>null</code> and not empty. * @param strategyId The connect strategy id or <code>null</code>. * @param overwrite The connect strategy id that should be overwritten by this id. */ public void registerConnectStrategyBinding(String typeId, String strategyId, String overwrite) { Assert.isNotNull(typeId); Assert.isTrue(typeId.trim().length() > 0); if (strategyId != null && strategyId.trim().length() > 0) { List<ConnectStrategyBinding> bindings = typeIdToStrategyId.get(typeId.trim()); if (bindings == null) { bindings = new ArrayList<ConnectStrategyBinding>(); typeIdToStrategyId.put(typeId.trim(), bindings); } ConnectStrategyBinding binding = new ConnectStrategyBinding(strategyId.trim(), overwrite != null ? overwrite.trim() : null); bindings.add(binding); Collections.sort(bindings, new Comparator<ConnectStrategyBinding>() { @Override public int compare(ConnectStrategyBinding o1, ConnectStrategyBinding o2) { // handle multiple id's without overwrite (alphabetical order) if (o1.overwrite == null && o2.overwrite == null) { return o1.id.compareTo(o2.id); } // handle overwrite the same id twice (alphabetical order) if (o1.overwrite != null && o2.overwrite != null && o1.overwrite.equals(o2.overwrite)) { return o1.id.compareTo(o2.id); } // handle recursive overwrite (alphabetical order) if (o1.overwrite != null && o1.overwrite.equals(o2.id) && o2.overwrite != null && o2.overwrite.equals(o1.id)) { return o1.id.compareTo(o2.id); } // o1 overwrites o2 if (o1.overwrite != null && o1.overwrite.equals(o2.id)) { return -1; } // o2 overwrites o1 if (o2.overwrite != null && o2.overwrite.equals(o1.id)) { return 1; } // fallback alphabetical order return o1.id.compareTo(o2.id); } }); } else if (strategyId == null) { typeIdToStrategyId.remove(typeId.trim()); } } /** * Returns the corresponding connect strategy id for the given connection type id. * * @param typeId The connection type id. Must not be <code>null</code> and not empty! * @return The connect strategy id if registered or <code>null</code>. */ public String getConnectStrategyId(String typeId) { if (typeId != null && typeId.trim().length() > 0) { List<ConnectStrategyBinding> bindings = typeIdToStrategyId.get(typeId.trim()); return bindings != null && !bindings.isEmpty() ? bindings.get(0).id : null; } return null; } /** * Returns the corresponding <code>IConnectStrategy</code> for the given connection type id. * * @param typeId The connection type id. Must not be <code>null</code>. * @return The corresponding connect strategy object or <code>null</code>. */ public IConnectStrategy getConnectStrategy(String typeId) { Assert.isNotNull(typeId); String connectStrategyId = getConnectStrategyId(typeId); return ConnectStrategyExtensionPointManager.getInstance().getConnectStrategy(connectStrategyId); } // ***** END: Section connect strategy management ***** // ***** BEGIN: Section connection type management ***** /** * Returns the list of all contributed connection types. * * @return The list of contributed connection types, or an empty array. */ public IConnectionType[] getConnectionTypes() { return connectionTypeManger.getConnectionTypes(); } /** * Returns the corresponding <code>IConnectionType</code> for the given connection type id. * * @param typeId The connection type id. Must not be <code>null</code>. * @return The corresponding connection type object or <code>null</code>. */ public IConnectionType getConnectionType(String typeId) { Assert.isNotNull(typeId); return connectionTypeManger.getConnectionType(typeId); } /** * Returns the corresponding <code>IConnectionType</code> for the given connectable context object. * * @param context The connectable context object. Must not be <code>null</code> * @return The corresponding target connection type object or <code>null</code>. */ public IConnectionType getConnectionType(Object context) { Assert.isNotNull(context); return null; } /** * Checks if the connection type, specified by the given type id, is enabled. * <p> * A connection type is enabled when at least one enablement evaluates to <code>true</code>. * * @param typeId The connection type id. Must not be <code>null</code>. * @return <code>True</code> if the connection type is enabled, <code>false</code> otherwise. */ public boolean isConnectionTypeEnabled(String typeId) { Assert.isNotNull(typeId); return true; } // ***** END: Section connection type management ***** }