/* * Copyright (c) 2002, 2007, 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 org.jboss.com.sun.corba.se.impl.oa.poa; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import org.jboss.com.sun.corba.se.impl.logging.OMGSystemException; import org.jboss.com.sun.corba.se.impl.logging.POASystemException; import org.jboss.com.sun.corba.se.impl.orbutil.ORBConstants; import org.jboss.com.sun.corba.se.spi.ior.ObjectAdapterId; import org.jboss.com.sun.corba.se.spi.logging.CORBALogDomains; import org.jboss.com.sun.corba.se.spi.oa.ObjectAdapter; import org.jboss.com.sun.corba.se.spi.oa.ObjectAdapterFactory; import org.jboss.com.sun.corba.se.spi.orb.ORB; import org.jboss.com.sun.corba.se.spi.orbutil.closure.Closure; import org.jboss.com.sun.corba.se.spi.orbutil.closure.ClosureFactory; import org.omg.CORBA.OBJECT_NOT_EXIST; import org.omg.CORBA.TRANSIENT; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAManager; import org.omg.PortableServer.Servant; public class POAFactory implements ObjectAdapterFactory { // Maps servants to POAs for deactivating servants when unexportObject is called. // Maintained by POAs activate_object and deactivate_object. private Map<Servant, POA> exportedServantsToPOA = new WeakHashMap<Servant, POA>(); private Set<POAManager> poaManagers; private int poaManagerId; private int poaId; private POAImpl rootPOA; private DelegateImpl delegateImpl; private ORB orb; private POASystemException wrapper; private OMGSystemException omgWrapper; private boolean isShuttingDown = false; public POASystemException getWrapper() { return wrapper; } /** * All object adapter factories must have a no-arg constructor. */ public POAFactory() { poaManagers = Collections.synchronizedSet(new HashSet<POAManager>(4)); poaManagerId = 0; poaId = 0; rootPOA = null; delegateImpl = null; orb = null; } public synchronized POA lookupPOA(Servant servant) { return exportedServantsToPOA.get(servant); } public synchronized void registerPOAForServant(POA poa, Servant servant) { exportedServantsToPOA.put(servant, poa); } public synchronized void unregisterPOAForServant(POA poa, Servant servant) { exportedServantsToPOA.remove(servant); } // Implementation of ObjectAdapterFactory interface public void init(ORB orb) { this.orb = orb; wrapper = POASystemException.get(orb, CORBALogDomains.OA_LIFECYCLE); omgWrapper = OMGSystemException.get(orb, CORBALogDomains.OA_LIFECYCLE); delegateImpl = new DelegateImpl(orb, this); registerRootPOA(); POACurrent poaCurrent = new POACurrent(orb); orb.getLocalResolver().register(ORBConstants.POA_CURRENT_NAME, ClosureFactory.makeConstant(poaCurrent)); } public ObjectAdapter find(ObjectAdapterId oaid) { POA poa = null; try { boolean first = true; Iterator<String> iter = oaid.iterator(); poa = getRootPOA(); while (iter.hasNext()) { String name = iter.next(); if (first) { if (!name.equals(ORBConstants.ROOT_POA_NAME)) throw wrapper.makeFactoryNotPoa(name); first = false; } else { poa = poa.find_POA(name, true); } } } catch (org.omg.PortableServer.POAPackage.AdapterNonExistent ex) { throw omgWrapper.noObjectAdaptor(ex); } catch (OBJECT_NOT_EXIST ex) { throw ex; } catch (TRANSIENT ex) { throw ex; } catch (Exception ex) { throw wrapper.poaLookupError(ex); } if (poa == null) throw wrapper.poaLookupError(); return (ObjectAdapter) poa; } public void shutdown(boolean waitForCompletion) { // It is important to copy the list of POAManagers first because pm.deactivate removes itself from poaManagers! Iterator<POAManager> managers = null; synchronized (this) { isShuttingDown = true; managers = (new HashSet<POAManager>(poaManagers)).iterator(); } while (managers.hasNext()) { try { managers.next().deactivate(true, waitForCompletion); } catch (org.omg.PortableServer.POAManagerPackage.AdapterInactive e) { } } } // Special methods used to manipulate global POA related state public synchronized void removePoaManager(POAManager manager) { poaManagers.remove(manager); } public synchronized void addPoaManager(POAManager manager) { poaManagers.add(manager); } synchronized public int newPOAManagerId() { return poaManagerId++; } public void registerRootPOA() { // We delay the evaluation of makeRootPOA until a call to resolve_initial_references( "RootPOA" ). The Future // guarantees that makeRootPOA is only called once. Closure rpClosure = new Closure() { public Object evaluate() { return POAImpl.makeRootPOA(orb); } }; orb.getLocalResolver().register(ORBConstants.ROOT_POA_NAME, ClosureFactory.makeFuture(rpClosure)); } public synchronized POA getRootPOA() { if (rootPOA == null) { // See if we are trying to getRootPOA while shutting down the ORB. if (isShuttingDown) { throw omgWrapper.noObjectAdaptor(); } try { Object obj = orb.resolve_initial_references(ORBConstants.ROOT_POA_NAME); rootPOA = (POAImpl) obj; } catch (InvalidName inv) { throw wrapper.cantResolveRootPoa(inv); } } return rootPOA; } public org.omg.PortableServer.portable.Delegate getDelegateImpl() { return delegateImpl; } synchronized public int newPOAId() { return poaId++; } public ORB getORB() { return orb; } }