blob: f1136df23254ad9274121f983f378d04270477c2 [file] [log] [blame]
/*
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.corba.se.impl.oa.poa;
import java.util.Set ;
import java.util.HashSet ;
import java.util.Map ;
import java.util.HashMap ;
import java.util.Iterator ;
import java.util.Vector ;
import org.omg.PortableServer.Servant ;
import org.omg.PortableServer.POAPackage.WrongPolicy ;
import org.omg.CORBA.INTERNAL ;
/** The ActiveObjectMap maintains associations between servants and
* their keys. There are two variants, to support whether or not
* multiple IDs per servant are allowed. This class suppots bidirectional
* traversal of the key-servant association. Access to an instance of this
* class is serialized by the POA mutex.
*/
public abstract class ActiveObjectMap
{
public static class Key {
public byte[] id;
Key(byte[] id) {
this.id = id;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for(int i = 0; i < id.length; i++) {
buffer.append(Integer.toString((int) id[i], 16));
if (i != id.length-1)
buffer.append(":");
}
return buffer.toString();
}
public boolean equals(java.lang.Object key) {
if (!(key instanceof Key))
return false;
Key k = (Key) key;
if (k.id.length != this.id.length)
return false;
for(int i = 0; i < this.id.length; i++)
if (this.id[i] != k.id[i])
return false;
return true;
}
// Use the same hash function as for String
public int hashCode() {
int h = 0;
for (int i = 0; i < id.length; i++)
h = 31*h + id[i];
return h;
}
}
protected POAImpl poa ;
protected ActiveObjectMap( POAImpl poa )
{
this.poa = poa ;
}
public static ActiveObjectMap create( POAImpl poa, boolean multipleIDsAllowed )
{
if (multipleIDsAllowed)
return new MultipleObjectMap( poa ) ;
else
return new SingleObjectMap(poa ) ;
}
private Map keyToEntry = new HashMap() ; // Map< Key, AOMEntry >
private Map entryToServant = new HashMap() ; // Map< AOMEntry, Servant >
private Map servantToEntry = new HashMap() ; // Map< Servant, AOMEntry >
public final boolean contains(Servant value)
{
return servantToEntry.containsKey( value ) ;
}
public final boolean containsKey(Key key)
{
return keyToEntry.containsKey(key);
}
/** get Returbs the entry assigned to the key, or creates a new
* entry in state INVALID if none is present.
*/
public final AOMEntry get(Key key)
{
AOMEntry result = (AOMEntry)keyToEntry.get(key);
if (result == null) {
result = new AOMEntry( poa ) ;
putEntry( key, result ) ;
}
return result ;
}
public final Servant getServant( AOMEntry entry )
{
return (Servant)entryToServant.get( entry ) ;
}
public abstract Key getKey(AOMEntry value) throws WrongPolicy ;
public Key getKey(Servant value) throws WrongPolicy
{
AOMEntry entry = (AOMEntry)servantToEntry.get( value ) ;
return getKey( entry ) ;
}
protected void putEntry( Key key, AOMEntry value )
{
keyToEntry.put( key, value ) ;
}
public final void putServant( Servant servant, AOMEntry value )
{
entryToServant.put( value, servant ) ;
servantToEntry.put( servant, value ) ;
}
protected abstract void removeEntry( AOMEntry entry, Key key ) ;
public final void remove( Key key )
{
AOMEntry entry = (AOMEntry)keyToEntry.remove( key ) ;
Servant servant = (Servant)entryToServant.remove( entry ) ;
if (servant != null)
servantToEntry.remove( servant ) ;
removeEntry( entry, key ) ;
}
public abstract boolean hasMultipleIDs(AOMEntry value) ;
protected void clear()
{
keyToEntry.clear();
}
public final Set keySet()
{
return keyToEntry.keySet() ;
}
}
class SingleObjectMap extends ActiveObjectMap
{
private Map entryToKey = new HashMap() ; // Map< AOMEntry, Key >
public SingleObjectMap( POAImpl poa )
{
super( poa ) ;
}
public Key getKey(AOMEntry value) throws WrongPolicy
{
return (Key)entryToKey.get( value ) ;
}
protected void putEntry(Key key, AOMEntry value)
{
super.putEntry( key, value);
entryToKey.put( value, key ) ;
}
public boolean hasMultipleIDs(AOMEntry value)
{
return false;
}
// This case does not need the key.
protected void removeEntry(AOMEntry entry, Key key)
{
entryToKey.remove( entry ) ;
}
public void clear()
{
super.clear() ;
entryToKey.clear() ;
}
}
class MultipleObjectMap extends ActiveObjectMap
{
private Map entryToKeys = new HashMap() ; // Map< AOMEntry, Set< Key > >
public MultipleObjectMap( POAImpl poa )
{
super( poa ) ;
}
public Key getKey(AOMEntry value) throws WrongPolicy
{
throw new WrongPolicy() ;
}
protected void putEntry(Key key, AOMEntry value)
{
super.putEntry( key, value);
Set set = (Set)entryToKeys.get( value ) ;
if (set == null) {
set = new HashSet() ;
entryToKeys.put( value, set ) ;
}
set.add( key ) ;
}
public boolean hasMultipleIDs(AOMEntry value)
{
Set set = (Set)entryToKeys.get( value ) ;
if (set == null)
return false ;
return set.size() > 1 ;
}
protected void removeEntry(AOMEntry entry, Key key)
{
Set keys = (Set)entryToKeys.get( entry ) ;
if (keys != null) {
keys.remove( key ) ;
if (keys.isEmpty())
entryToKeys.remove( entry ) ;
}
}
public void clear()
{
super.clear() ;
entryToKeys.clear() ;
}
}