/*
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2002
* Copyright by ESO (in the framework of the ALMA collaboration),
* All rights reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
package alma.acs.container;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Synchronized type-safe map for loaded components.
* Keys are component handles, values are ComponentAdapter
s.
* The map entries are sorted by insertion order, or by the handle sequence given to {@link #sort(int[])}.
*
* Note that it is not sufficient to use something like
*
* @TODO: There seems to be an error case where the manager sends a second activation request for the same component curl,
* but using a different component handle. This seems to happen after the first activation request timed out
* from the point of view of the manager, but continues to run inside the container.
* See http://jira.alma.cl/browse/COMP-1863.
* @param compHandle
* @return true if this handle could be reserved
*/
synchronized boolean reserveComponent(int compHandle) {
boolean ret = false;
Integer handleObj = new Integer(compHandle);
// need to check if it's an old ComponentAdapter we want to overwrite, or a reservation (null)
if (!m_map.containsKey(handleObj) || m_map.get(handleObj) != null ) {
m_map.put(handleObj, null);
ret = true;
}
return ret;
}
/**
*
* @param compHandle
* @param compAdapter
* @return previously stored adapter, possibly null
* @see Map#put(java.lang.Object, java.lang.Object)
*/
synchronized ComponentAdapter put(int compHandle, ComponentAdapter compAdapter)
{
return ( m_map.put(compHandle, compAdapter) );
}
/**
* Sorts the entries in the order given by
* @param sortedHandles
*/
synchronized void sort(int[] sortedHandles) {
Map
* Unlike {@link Map#values()}, the returned array contains
* a snapshot of the map contents,
* rather than a view backed by the map.
*
* @param compHandles handles of those components whose adapters should be returned.
* @return adapters for all components in the map whose handles match
* Notice that
* TODO: check if it's ok to include handles for reserved component adapters (value still null)
*
* @return keys for all component (adapters) in the map
* @see Map#keySet()
*/
synchronized int[] getAllHandles()
{
CollectionCollections.synchronizedMap(new HashMap())
,
* since reading out the keys or values of such a map with an iterator
* is still backed by the original instance and therefore not thread-safe.
* See {@link Collections#synchronizedMap(java.util.Map)}.
*
* @author hsommer
* created Oct 30, 2003 10:04:28 AM
*/
class ComponentMap
{
/**
* The map that backs this class.
*/
private LinkedHashMapComponentAdapter
based on the component handle.
* Can be used to avoid concurrent multiple activation of the same component (which also manager should prevent).
* sortedHandles
.
* The sorted component handles will be received from the manager.
* Before this method is called, the iteration order is that of insertion order.
* ComponentAdapter
with that handle, or null
* @see Map#remove(java.lang.Object)
*/
synchronized ComponentAdapter remove(int compHandle)
{
return m_map.remove(new Integer(compHandle));
}
/**
* Returns the component adapter for a given component handle,
* or null
if either the component handle is unknown, or if the corresponding
* component is still under construction (which means that the handle is just for a 'reservation'.
*
* @param compHandle
* @return component adapter, or null
* @see Map#get(java.lang.Object)
*/
synchronized ComponentAdapter get(int compHandle)
{
return m_map.get(new Integer(compHandle));
}
/**
* Gets component adapters with the specified handles out of the map.
* Ignores handles for which no components are stored.
* The order of the returned component adapters matches the order of the handles.
* compHandles
.
* Possibly an empty array (if compHandles is null or empty or contains wrong handles), but never null.
* @see Map#values()
*/
synchronized ComponentAdapter[] getComponentAdapters(int[] compHandles)
{
Listnull
adapters for {@link #reserveComponent(int) reserved} components
* are not included in the returned array of adapters.
*
* @return adapters for all components in the map
* @see Map#values()
*/
synchronized ComponentAdapter[] getAllComponentAdapters()
{
List