POAFactory.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2002, 2009, 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.Collections ;
31import java.util.Iterator ;
32import java.util.Map ;
33import java.util.WeakHashMap ;
34
35import org.omg.CORBA.OBJECT_NOT_EXIST ;
36import org.omg.CORBA.TRANSIENT ;
37
38import org.omg.CORBA.ORBPackage.InvalidName ;
39
40import org.omg.PortableServer.Servant ;
41import org.omg.PortableServer.POA ;
42import org.omg.PortableServer.POAManager ;
43
44import com.sun.corba.se.spi.oa.ObjectAdapter ;
45import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;
46
47import com.sun.corba.se.spi.ior.ObjectAdapterId ;
48
49import com.sun.corba.se.spi.orb.ORB ;
50
51import com.sun.corba.se.spi.orbutil.closure.Closure ;
52import com.sun.corba.se.spi.orbutil.closure.ClosureFactory ;
53
54import com.sun.corba.se.spi.protocol.PIHandler ;
55
56import com.sun.corba.se.spi.logging.CORBALogDomains ;
57
58import com.sun.corba.se.impl.logging.POASystemException ;
59import com.sun.corba.se.impl.logging.OMGSystemException ;
60
61import com.sun.corba.se.impl.orbutil.ORBConstants ;
62
63import com.sun.corba.se.impl.oa.poa.POAManagerImpl ;
64
65public class POAFactory implements ObjectAdapterFactory
66{
67    // Maps servants to POAs for deactivating servants when unexportObject is called.
68    // Maintained by POAs activate_object and deactivate_object.
69    private Map exportedServantsToPOA = new WeakHashMap();
70
71    private Set poaManagers ;
72    private int poaManagerId ;
73    private int poaId ;
74    private POAImpl rootPOA ;
75    private DelegateImpl delegateImpl;
76    private ORB orb ;
77    private POASystemException wrapper ;
78    private OMGSystemException omgWrapper ;
79    private boolean isShuttingDown = false;
80
81    public POASystemException getWrapper()
82    {
83        return wrapper ;
84    }
85
86    /** All object adapter factories must have a no-arg constructor.
87    */
88    public POAFactory()
89    {
90        poaManagers = Collections.synchronizedSet(new HashSet(4));
91        poaManagerId = 0 ;
92        poaId = 0 ;
93        rootPOA = null ;
94        delegateImpl = null ;
95        orb = null ;
96    }
97
98    public synchronized POA lookupPOA (Servant servant)
99    {
100        return (POA)exportedServantsToPOA.get(servant);
101    }
102
103    public synchronized void registerPOAForServant(POA poa, Servant servant)
104    {
105        exportedServantsToPOA.put(servant, poa);
106    }
107
108    public synchronized void unregisterPOAForServant(POA poa, Servant servant)
109    {
110        exportedServantsToPOA.remove(servant);
111    }
112
113// Implementation of ObjectAdapterFactory interface
114
115    public void init( ORB orb )
116    {
117        this.orb = orb ;
118        wrapper = POASystemException.get( orb,
119            CORBALogDomains.OA_LIFECYCLE ) ;
120        omgWrapper = OMGSystemException.get( orb,
121            CORBALogDomains.OA_LIFECYCLE ) ;
122        delegateImpl = new DelegateImpl( orb, this ) ;
123        registerRootPOA() ;
124
125        POACurrent poaCurrent = new POACurrent(orb);
126        orb.getLocalResolver().register( ORBConstants.POA_CURRENT_NAME,
127            ClosureFactory.makeConstant( poaCurrent ) ) ;
128    }
129
130    public ObjectAdapter find( ObjectAdapterId oaid )
131    {
132        POA poa=null;
133        try {
134            boolean first = true ;
135            Iterator iter = oaid.iterator() ;
136            poa = getRootPOA();
137            while (iter.hasNext()) {
138                String name = (String)(iter.next()) ;
139
140                if (first) {
141                    if (!name.equals( ORBConstants.ROOT_POA_NAME ))
142                        throw wrapper.makeFactoryNotPoa( name ) ;
143                    first = false ;
144                } else {
145                    poa = poa.find_POA( name, true ) ;
146                }
147            }
148        } catch ( org.omg.PortableServer.POAPackage.AdapterNonExistent ex ){
149            throw omgWrapper.noObjectAdaptor( ex ) ;
150        } catch ( OBJECT_NOT_EXIST ex ) {
151            throw ex;
152        } catch ( TRANSIENT ex ) {
153            throw ex;
154        } catch ( Exception ex ) {
155            throw wrapper.poaLookupError( ex ) ;
156        }
157
158        if ( poa == null )
159            throw wrapper.poaLookupError() ;
160
161        return (ObjectAdapter)poa;
162    }
163
164    public void shutdown( boolean waitForCompletion )
165    {
166        // It is important to copy the list of POAManagers first because
167        // pm.deactivate removes itself from poaManagers!
168        Iterator managers = null ;
169        synchronized (this) {
170            isShuttingDown = true ;
171            managers = (new HashSet(poaManagers)).iterator();
172        }
173
174        while ( managers.hasNext() ) {
175            try {
176                ((POAManager)managers.next()).deactivate(true, waitForCompletion);
177            } catch ( org.omg.PortableServer.POAManagerPackage.AdapterInactive e ) {}
178        }
179    }
180
181// Special methods used to manipulate global POA related state
182
183    public synchronized void removePoaManager( POAManager manager )
184    {
185        poaManagers.remove(manager);
186    }
187
188    public synchronized void addPoaManager( POAManager manager )
189    {
190        poaManagers.add(manager);
191    }
192
193    synchronized public int newPOAManagerId()
194    {
195        return poaManagerId++ ;
196    }
197
198    public void registerRootPOA()
199    {
200        // We delay the evaluation of makeRootPOA until
201        // a call to resolve_initial_references( "RootPOA" ).
202        // The Future guarantees that makeRootPOA is only called once.
203        Closure rpClosure = new Closure() {
204            public Object evaluate() {
205                return POAImpl.makeRootPOA( orb ) ;
206            }
207        } ;
208
209        orb.getLocalResolver().register( ORBConstants.ROOT_POA_NAME,
210            ClosureFactory.makeFuture( rpClosure ) ) ;
211    }
212
213
214    public synchronized POA getRootPOA()
215    {
216        if (rootPOA == null) {
217            // See if we are trying to getRootPOA while shutting down the ORB.
218            if (isShuttingDown) {
219                throw omgWrapper.noObjectAdaptor( ) ;
220            }
221
222            try {
223                Object obj = orb.resolve_initial_references(
224                    ORBConstants.ROOT_POA_NAME ) ;
225                rootPOA = (POAImpl)obj ;
226            } catch (InvalidName inv) {
227                throw wrapper.cantResolveRootPoa( inv ) ;
228            }
229        }
230
231        return rootPOA;
232    }
233
234    public org.omg.PortableServer.portable.Delegate getDelegateImpl()
235    {
236        return delegateImpl ;
237    }
238
239    synchronized public int newPOAId()
240    {
241        return poaId++ ;
242    }
243
244    public ORB getORB()
245    {
246        return orb ;
247    }
248}
249