ActiveObjectMap.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.corba.se.impl.oa.poa;
27
28import java.util.Set ;
29import java.util.HashSet ;
30import java.util.Map ;
31import java.util.HashMap ;
32import java.util.Iterator ;
33import java.util.Vector ;
34
35import org.omg.PortableServer.Servant ;
36import org.omg.PortableServer.POAPackage.WrongPolicy ;
37import org.omg.CORBA.INTERNAL ;
38
39/**  The ActiveObjectMap maintains associations between servants and
40 * their keys.  There are two variants, to support whether or not
41 * multiple IDs per servant are allowed.  This class suppots bidirectional
42 * traversal of the key-servant association.  Access to an instance of this
43 * class is serialized by the POA mutex.
44 */
45public abstract class ActiveObjectMap
46{
47    public static class Key {
48        public byte[] id;
49
50        Key(byte[] id) {
51            this.id = id;
52        }
53
54        public String toString() {
55            StringBuffer buffer = new StringBuffer();
56            for(int i = 0; i < id.length; i++) {
57                buffer.append(Integer.toString((int) id[i], 16));
58                if (i != id.length-1)
59                    buffer.append(":");
60            }
61            return buffer.toString();
62        }
63
64        public boolean equals(java.lang.Object key) {
65            if (!(key instanceof Key))
66                return false;
67            Key k = (Key) key;
68            if (k.id.length != this.id.length)
69                return false;
70            for(int i = 0; i < this.id.length; i++)
71                if (this.id[i] != k.id[i])
72                    return false;
73            return true;
74        }
75
76        // Use the same hash function as for String
77        public int hashCode() {
78            int h = 0;
79            for (int i = 0; i < id.length; i++)
80                h = 31*h + id[i];
81            return h;
82        }
83    }
84
85    protected POAImpl poa ;
86
87    protected ActiveObjectMap( POAImpl poa )
88    {
89        this.poa = poa ;
90    }
91
92    public static ActiveObjectMap create( POAImpl poa, boolean multipleIDsAllowed )
93    {
94        if (multipleIDsAllowed)
95            return new MultipleObjectMap( poa ) ;
96        else
97            return new SingleObjectMap(poa ) ;
98    }
99
100    private Map keyToEntry = new HashMap() ;     // Map< Key, AOMEntry >
101    private Map entryToServant = new HashMap() ; // Map< AOMEntry, Servant >
102    private Map servantToEntry = new HashMap() ; // Map< Servant, AOMEntry >
103
104    public final boolean contains(Servant value)
105    {
106        return servantToEntry.containsKey( value ) ;
107    }
108
109    public final boolean containsKey(Key key)
110    {
111        return keyToEntry.containsKey(key);
112    }
113
114    /** get Returbs the entry assigned to the key, or creates a new
115    * entry in state INVALID if none is present.
116    */
117    public final AOMEntry get(Key key)
118    {
119        AOMEntry result = (AOMEntry)keyToEntry.get(key);
120        if (result == null) {
121            result = new AOMEntry( poa ) ;
122            putEntry( key, result ) ;
123        }
124
125        return result ;
126    }
127
128    public final Servant getServant( AOMEntry entry )
129    {
130        return (Servant)entryToServant.get( entry ) ;
131    }
132
133    public abstract Key getKey(AOMEntry value) throws WrongPolicy ;
134
135    public Key getKey(Servant value) throws WrongPolicy
136    {
137        AOMEntry entry = (AOMEntry)servantToEntry.get( value ) ;
138        return getKey( entry ) ;
139    }
140
141    protected void putEntry( Key key, AOMEntry value )
142    {
143        keyToEntry.put( key, value ) ;
144    }
145
146    public final void putServant( Servant servant, AOMEntry value )
147    {
148        entryToServant.put( value, servant ) ;
149        servantToEntry.put( servant, value ) ;
150    }
151
152    protected abstract void removeEntry( AOMEntry entry, Key key ) ;
153
154    public final void remove( Key key )
155    {
156        AOMEntry entry = (AOMEntry)keyToEntry.remove( key ) ;
157        Servant servant = (Servant)entryToServant.remove( entry ) ;
158        if (servant != null)
159            servantToEntry.remove( servant ) ;
160
161        removeEntry( entry, key ) ;
162    }
163
164    public abstract boolean hasMultipleIDs(AOMEntry value) ;
165
166    protected  void clear()
167    {
168        keyToEntry.clear();
169    }
170
171    public final Set keySet()
172    {
173        return keyToEntry.keySet() ;
174    }
175}
176
177class SingleObjectMap extends ActiveObjectMap
178{
179    private Map entryToKey = new HashMap() ;    // Map< AOMEntry, Key >
180
181    public SingleObjectMap( POAImpl poa )
182    {
183        super( poa ) ;
184    }
185
186    public  Key getKey(AOMEntry value) throws WrongPolicy
187    {
188        return (Key)entryToKey.get( value ) ;
189    }
190
191    protected void putEntry(Key key, AOMEntry value)
192    {
193        super.putEntry( key, value);
194
195        entryToKey.put( value, key ) ;
196    }
197
198    public  boolean hasMultipleIDs(AOMEntry value)
199    {
200        return false;
201    }
202
203    // This case does not need the key.
204    protected void removeEntry(AOMEntry entry, Key key)
205    {
206        entryToKey.remove( entry ) ;
207    }
208
209    public  void clear()
210    {
211        super.clear() ;
212        entryToKey.clear() ;
213    }
214}
215
216class MultipleObjectMap extends ActiveObjectMap
217{
218    private Map entryToKeys = new HashMap() ;   // Map< AOMEntry, Set< Key > >
219
220    public MultipleObjectMap( POAImpl poa )
221    {
222        super( poa ) ;
223    }
224
225    public  Key getKey(AOMEntry value) throws WrongPolicy
226    {
227        throw new WrongPolicy() ;
228    }
229
230    protected void putEntry(Key key, AOMEntry value)
231    {
232        super.putEntry( key, value);
233
234        Set set = (Set)entryToKeys.get( value ) ;
235        if (set == null) {
236            set = new HashSet() ;
237            entryToKeys.put( value, set ) ;
238        }
239        set.add( key ) ;
240    }
241
242    public  boolean hasMultipleIDs(AOMEntry value)
243    {
244        Set set = (Set)entryToKeys.get( value ) ;
245        if (set == null)
246            return false ;
247        return set.size() > 1 ;
248    }
249
250    protected void removeEntry(AOMEntry entry, Key key)
251    {
252        Set keys = (Set)entryToKeys.get( entry ) ;
253        if (keys != null) {
254            keys.remove( key ) ;
255            if (keys.isEmpty())
256                entryToKeys.remove( entry ) ;
257        }
258    }
259
260    public  void clear()
261    {
262        super.clear() ;
263        entryToKeys.clear() ;
264    }
265}
266