/******************************************************************************* * Copyright (c) 2011, 2014 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.tcf.te.tcf.locator.nodes; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; import org.eclipse.tcf.te.tcf.locator.interfaces.IPeerModelListener; import org.eclipse.tcf.te.tcf.locator.interfaces.ITracing; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelLookupService; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelQueryService; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelRefreshService; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelService; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelUpdateService; import org.eclipse.tcf.te.tcf.locator.services.PeerModelLookupService; import org.eclipse.tcf.te.tcf.locator.services.PeerModelQueryService; import org.eclipse.tcf.te.tcf.locator.services.PeerModelRefreshService; import org.eclipse.tcf.te.tcf.locator.services.PeerModelUpdateService; /** * Default peer model implementation. */ public class PeerModel extends PlatformObject implements IPeerModel { // The unique model id private final UUID uniqueId = UUID.randomUUID(); // Flag to mark the model disposed private boolean disposed; // The list of known peer nodes /* default */ final Map<String, IPeerNode> peerNodes = new HashMap<String, IPeerNode>(); // The list of registered model listeners private final List<IPeerModelListener> modelListener = new ArrayList<IPeerModelListener>(); // Reference to the refresh service private final IPeerModelRefreshService refreshService = new PeerModelRefreshService(this); // Reference to the lookup service private final IPeerModelLookupService lookupService = new PeerModelLookupService(this); // Reference to the update service private final IPeerModelUpdateService updateService = new PeerModelUpdateService(this); // Reference to the query service private final IPeerModelQueryService queryService = new PeerModelQueryService(this); /** * Constructor. */ public PeerModel() { super(); disposed = false; } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#addListener(org.eclipse.tcf.te.tcf.locator.core.interfaces.IModelListener) */ @Override public void addListener(IPeerModelListener listener) { Assert.isNotNull(listener); if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITracing.ID_TRACE_PEER_MODEL)) { CoreBundleActivator.getTraceHandler().trace("PeerModel.addListener( " + listener + " )", ITracing.ID_TRACE_PEER_MODEL, this); //$NON-NLS-1$ //$NON-NLS-2$ } if (!modelListener.contains(listener)) modelListener.add(listener); } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#removeListener(org.eclipse.tcf.te.tcf.locator.core.interfaces.IModelListener) */ @Override public void removeListener(IPeerModelListener listener) { Assert.isNotNull(listener); if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITracing.ID_TRACE_PEER_MODEL)) { CoreBundleActivator.getTraceHandler().trace("PeerModel.removeListener( " + listener + " )", ITracing.ID_TRACE_PEER_MODEL, this); //$NON-NLS-1$ //$NON-NLS-2$ } modelListener.remove(listener); } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel#getListener() */ @Override public IPeerModelListener[] getListener() { Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ return modelListener.toArray(new IPeerModelListener[modelListener.size()]); } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#dispose() */ @Override public void dispose() { Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITracing.ID_TRACE_PEER_MODEL)) { CoreBundleActivator.getTraceHandler().trace("PeerModel.dispose()", ITracing.ID_TRACE_PEER_MODEL, this); //$NON-NLS-1$ } // If already disposed, we are done immediately if (disposed) return; disposed = true; final IPeerModelListener[] listeners = getListener(); if (listeners.length > 0) { Protocol.invokeLater(new Runnable() { @Override public void run() { for (IPeerModelListener listener : listeners) { listener.modelDisposed(PeerModel.this); } } }); } modelListener.clear(); peerNodes.clear(); } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#isDisposed() */ @Override public boolean isDisposed() { return disposed; } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#getPeers() */ @Override public IPeerNode[] getPeerNodes() { // We explicitly allow to access the current set of peer nodes // from any thread. The method returns a snapshot of the current // set of peer nodes. List<IPeerNode> values = new ArrayList<IPeerNode>(peerNodes.values()); return values.toArray(new IPeerNode[values.size()]); } /* (non-Javadoc) * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) */ @Override public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(IPeerModelRefreshService.class)) { return refreshService; } if (adapter.isAssignableFrom(IPeerModelLookupService.class)) { return lookupService; } if (adapter.isAssignableFrom(IPeerModelUpdateService.class)) { return updateService; } if (adapter.isAssignableFrom(IPeerModelQueryService.class)) { return queryService; } if (adapter.isAssignableFrom(Map.class)) { return peerNodes; } return super.getAdapter(adapter); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return uniqueId.hashCode(); } /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.locator.core.interfaces.nodes.ILocatorModel#getService(java.lang.Class) */ @Override @SuppressWarnings("unchecked") public <V extends IPeerModelService> V getService(Class<V> serviceInterface) { Assert.isNotNull(serviceInterface); return (V)getAdapter(serviceInterface); } }