From 3eb3aac3d8ba18a4614a510cb222d60406fe9000 Mon Sep 17 00:00:00 2001 From: ustieber Date: Mon, 9 May 2011 08:42:45 +0000 Subject: Target Explorer: Add lookup locations for user defined static peers --- .../tcf/locator/activator/CoreBundleActivator.java | 44 ++--- .../interfaces/preferences/IPreferenceKeys.java | 16 +- .../services/LocatorModelRefreshService.java | 197 ++++++++++++++++++--- 3 files changed, 211 insertions(+), 46 deletions(-) diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java index d6426c304..e73cc1cf8 100644 --- a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java +++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java @@ -3,54 +3,56 @@ * 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: * Uwe Stieber (Wind River) - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.tcf.locator.activator; -import org.osgi.framework.BundleActivator; +import org.eclipse.core.runtime.Plugin; import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle */ -public class CoreBundleActivator implements BundleActivator { - // The bundle context - private static BundleContext context; +public class CoreBundleActivator extends Plugin { + // The shared instance + private static CoreBundleActivator plugin; /** - * Returns the bundle context + * Returns the shared instance * - * @return the bundle context + * @return the shared instance */ - public static BundleContext getContext() { - return context; + public static CoreBundleActivator getDefault() { + return plugin; } /** * Convenience method which returns the unique identifier of this plugin. */ public static String getUniqueIdentifier() { - if (getContext() != null && getContext().getBundle() != null) { - return getContext().getBundle().getSymbolicName(); + if (getDefault() != null && getDefault().getBundle() != null) { + return getDefault().getBundle().getSymbolicName(); } return null; } - /* - * (non-Javadoc) - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + /* (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext bundleContext) throws Exception { - CoreBundleActivator.context = bundleContext; + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; } - /* - * (non-Javadoc) - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + /* (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext bundleContext) throws Exception { - CoreBundleActivator.context = null; + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); } } diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java index d4a5e24c8..2d3e173bf 100644 --- a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java +++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java @@ -3,12 +3,14 @@ * 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: * Uwe Stieber (Wind River) - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.tcf.locator.interfaces.preferences; +import java.io.File; + /** * The locator model bundle preference key identifiers.. */ @@ -22,4 +24,16 @@ public interface IPreferenceKeys { * If set to true, peers having the same agent id are filtered. */ public final String PREF_FILTER_BY_AGENT_ID = PREFIX + "model.filter.agentid"; //$NON-NLS-1$ + + /** + * If set, the preference is defining a list of root locations where + * to lookup the static peer definitions. The single entries in the list + * are separated by the system dependent path separator character. + *

+ * Note: If set, the given list of root locations replaces the default + * list of root locations. + * + * @see File#pathSeparatorChar + */ + public final String PREF_STATIC_PEERS_ROOT_LOCATIONS = PREFIX + "model.peers.rootLocations"; //$NON-NLS-1$ } diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java index 4c6b95801..42801cb84 100644 --- a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java +++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java @@ -3,24 +3,36 @@ * 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: * Uwe Stieber (Wind River) - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.tcf.locator.services; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tm.tcf.core.TransientPeer; import org.eclipse.tm.tcf.protocol.IPeer; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.ILocator; import org.eclipse.tm.te.tcf.core.Tcf; import org.eclipse.tm.te.tcf.locator.ScannerRunnable; +import org.eclipse.tm.te.tcf.locator.activator.CoreBundleActivator; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel; +import org.eclipse.tm.te.tcf.locator.interfaces.preferences.IPreferenceKeys; import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService; import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelRefreshService; import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService; @@ -67,34 +79,171 @@ public class LocatorModelRefreshService extends AbstractLocatorModelService impl if (model instanceof LocatorModel) ((LocatorModel)model).checkLocatorListener(); // Get the map of peers known to the locator service. Map peers = locatorService.getPeers(); - for (String peerId : peers.keySet()) { - // Get the peer instance for the current peer id - IPeer peer = peers.get(peerId); - // Try to find an existing peer node first - IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peerId); - // And create a new one if we cannot find it - if (peerNode == null) peerNode = new PeerModel(model, peer); - else oldChildren.remove(peerNode); - // Validate the peer node before adding - if (peerNode != null) peerNode = model.validatePeerNodeForAdd(peerNode); - if (peerNode != null) { - // Add the peer node to model - model.getService(ILocatorModelUpdateService.class).add(peerNode); - // And schedule for immediate status update - Runnable runnable = new ScannerRunnable(model.getScanner(), peerNode); - Protocol.invokeLater(runnable); - } - } + // Process the peers + processPeers(peers, oldChildren, model); } + // Refresh the static peer definitions + refreshStaticPeers(oldChildren, model); + // If there are remaining old children, remove them from the model (non-recursive) for (IPeerModel oldChild : oldChildren) model.getService(ILocatorModelUpdateService.class).remove(oldChild); + } + + /** + * Process the given map of peers and update the given locator model. + * + * @param peers The map of peers to process. Must not be null. + * @param oldChildren The list of old children. Must not be null. + * @param model The locator model. Must not be null. + */ + protected void processPeers(Map peers, List oldChildren, ILocatorModel model) { + assert peers != null && oldChildren != null && model != null; + + for (String peerId : peers.keySet()) { + // Get the peer instance for the current peer id + IPeer peer = peers.get(peerId); + // Try to find an existing peer node first + IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peerId); + // And create a new one if we cannot find it + if (peerNode == null) peerNode = new PeerModel(model, peer); + else oldChildren.remove(peerNode); + // Validate the peer node before adding + if (peerNode != null) peerNode = model.validatePeerNodeForAdd(peerNode); + if (peerNode != null) { + // Add the peer node to model + model.getService(ILocatorModelUpdateService.class).add(peerNode); + // And schedule for immediate status update + Runnable runnable = new ScannerRunnable(model.getScanner(), peerNode); + Protocol.invokeLater(runnable); + } + } + } + + /** + * Refresh the static peer definitions. + * + * @param oldChildren The list of old children. Must not be null. + * @param model The locator model. Must not be null. + */ + protected void refreshStaticPeers(List oldChildren, ILocatorModel model) { + assert oldChildren != null && model != null; + + // Get the root locations to lookup the static peer definitions + File[] roots = getStaticPeerLookupDirectories(); + if (roots.length > 0) { + // The map of peers created from the static definitions + Map peers = new HashMap(); + // Process the root locations + for (File root : roots) { + // List all "*.ini" files within the root location + File[] candidates = root.listFiles(new FileFilter() { + public boolean accept(File pathname) { + IPath path = new Path(pathname.getAbsolutePath()); + return path.getFileExtension() != null && path.getFileExtension().toLowerCase().equals("ini"); //$NON-NLS-1$ + } + }); + // If there are ini files to read, process them + if (candidates != null && candidates.length > 0) { + + for (File candidate : candidates) { + try { + Properties properties = new Properties(); + properties.load(new FileInputStream(candidate)); + + // Validate the name attribute. If not set, set + // it to the file name without the .ini extension. + String name = properties.getProperty(IPeer.ATTR_NAME); + if (name == null || (name != null && "".equals(name.trim()))) { //$NON-NLS-1$ + name = new Path(candidate.getAbsolutePath()).removeFileExtension().lastSegment(); + properties.setProperty(IPeer.ATTR_NAME, name); + } - // Create and fire the notification event if non null -// if (dirty) { -// IWRNotificationEvent event = model.getFactory().newPropertyChangeEvent(model, IContainerModelNode.PROPERTY_CHANGED, null, null); -// if (event != null) WRNotificationManager.getInstance().fireEvent(event); -// } + // Validate the id attribute. If not set, generate one. + String id = properties.getProperty(IPeer.ATTR_ID); + if (id == null || (id != null & "".equals(id.trim()))) { //$NON-NLS-1$ + String transport = properties.getProperty(IPeer.ATTR_TRANSPORT_NAME); + String host = properties.getProperty(IPeer.ATTR_IP_HOST); + String port = properties.getProperty(IPeer.ATTR_IP_PORT); + + if (transport != null && host != null) { + id = transport.trim() + ":" + host.trim(); //$NON-NLS-1$ + id += port != null ? ":" + port.trim() : ":1534"; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + id = "USR:" + System.currentTimeMillis(); //$NON-NLS-1$ + // If the key is not unique, we have to wait a little bit an try again + while (peers.containsKey(id)) { + try { Thread.sleep(20); } catch (InterruptedException e) { /* ignored on purpose */ } + id = "USR:" + System.currentTimeMillis(); //$NON-NLS-1$ + } + } + properties.put(IPeer.ATTR_ID, id); + } + + // Copy all string attributes + Map attrs = new HashMap(); + for (Object key : properties.keySet()) { + if (key instanceof String && properties.get(key) instanceof String) { + attrs.put((String)key, (String)properties.get(key)); + } + } + + // Construct the peer from the attributes + IPeer peer = new TransientPeer(attrs); + // Add the constructed peer to the peers map + peers.put(peer.getID(), peer); + } catch (IOException e) { + /* ignored on purpose */ + } + } + } + } + // Process the read peers + if (!peers.isEmpty()) processPeers(peers, oldChildren, model); + } } + /** + * Returns the list of root locations to lookup for static peers definitions. + * + * @return The list of root locations or an empty list. + */ + protected File[] getStaticPeerLookupDirectories() { + // The list defining the root locations + List rootLocations = new ArrayList(); + + // Check on the peers root locations preference setting + String roots = Platform.getPreferencesService().getString(CoreBundleActivator.getUniqueIdentifier(), + IPreferenceKeys.PREF_STATIC_PEERS_ROOT_LOCATIONS, + null, null); + // If set, split it in its single components + if (roots != null) { + String[] candidates = roots.split(File.pathSeparator); + // Check on each candidate to denote an existing directory + for (String candidate : candidates) { + File file = new File(candidate); + if (file.canRead() && file.isDirectory() && !rootLocations.contains(file)) { + rootLocations.add(file); + } + } + } else { + // Try the bundles state location first (not available if launched with -data @none). + try { + File file = CoreBundleActivator.getDefault().getStateLocation().append(".peers").toFile(); //$NON-NLS-1$ + if (file.canRead() && file.isDirectory() && !rootLocations.contains(file)) { + rootLocations.add(file); + } + } catch (IllegalStateException e) { + /* ignored on purpose */ + } + + // The users local peers lookup directory is $HOME/.tcf/.peers. + File file = new Path(System.getProperty("user.home")).append(".tcf/.peers").toFile(); //$NON-NLS-1$ //$NON-NLS-2$ + if (file.canRead() && file.isDirectory() && !rootLocations.contains(file)) { + rootLocations.add(file); + } + } + + return rootLocations.toArray(new File[rootLocations.size()]); + } } -- cgit v1.2.3