alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (POAImpl.java)

This example Java source code file (POAImpl.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

adapteractivator, calling, condvar, corba, destroythread, exiting, poa, poaimpl, poamanagerimpl, servant, state_destroying, state_run, state_start, string, util, wrongpolicy

The POAImpl.java Java example source code

/*
 * Copyright (c) 1997, 2004, 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.Collection ;
import java.util.Set ;
import java.util.HashSet ;
import java.util.Map ;
import java.util.HashMap ;
import java.util.Iterator ;

import org.omg.CORBA.Policy ;
import org.omg.CORBA.SystemException ;

import org.omg.PortableServer.POA ;
import org.omg.PortableServer.Servant ;
import org.omg.PortableServer.POAManager ;
import org.omg.PortableServer.AdapterActivator ;
import org.omg.PortableServer.ServantManager ;
import org.omg.PortableServer.ForwardRequest ;
import org.omg.PortableServer.ThreadPolicy;
import org.omg.PortableServer.LifespanPolicy;
import org.omg.PortableServer.IdUniquenessPolicy;
import org.omg.PortableServer.IdAssignmentPolicy;
import org.omg.PortableServer.ImplicitActivationPolicy;
import org.omg.PortableServer.ServantRetentionPolicy;
import org.omg.PortableServer.RequestProcessingPolicy;
import org.omg.PortableServer.ThreadPolicyValue ;
import org.omg.PortableServer.LifespanPolicyValue ;
import org.omg.PortableServer.IdUniquenessPolicyValue ;
import org.omg.PortableServer.IdAssignmentPolicyValue ;
import org.omg.PortableServer.ImplicitActivationPolicyValue ;
import org.omg.PortableServer.ServantRetentionPolicyValue ;
import org.omg.PortableServer.RequestProcessingPolicyValue ;
import org.omg.PortableServer.POAPackage.AdapterAlreadyExists ;
import org.omg.PortableServer.POAPackage.AdapterNonExistent ;
import org.omg.PortableServer.POAPackage.InvalidPolicy ;
import org.omg.PortableServer.POAPackage.WrongPolicy ;
import org.omg.PortableServer.POAPackage.WrongAdapter ;
import org.omg.PortableServer.POAPackage.NoServant ;
import org.omg.PortableServer.POAPackage.ServantAlreadyActive ;
import org.omg.PortableServer.POAPackage.ObjectAlreadyActive ;
import org.omg.PortableServer.POAPackage.ServantNotActive ;
import org.omg.PortableServer.POAPackage.ObjectNotActive ;

import org.omg.PortableInterceptor.ObjectReferenceFactory ;
import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
import org.omg.PortableInterceptor.NON_EXISTENT ;

import org.omg.IOP.TAG_INTERNET_IOP ;

import com.sun.corba.se.spi.copyobject.CopierManager ;
import com.sun.corba.se.spi.copyobject.ObjectCopier ;
import com.sun.corba.se.spi.copyobject.ObjectCopierFactory ;
import com.sun.corba.se.spi.oa.OADestroyed ;
import com.sun.corba.se.spi.oa.OAInvocationInfo ;
import com.sun.corba.se.spi.oa.ObjectAdapter ;
import com.sun.corba.se.spi.oa.ObjectAdapterBase ;
import com.sun.corba.se.spi.oa.ObjectAdapterFactory ;
import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
import com.sun.corba.se.spi.ior.ObjectId ;
import com.sun.corba.se.spi.ior.ObjectAdapterId ;
import com.sun.corba.se.spi.ior.IOR ;
import com.sun.corba.se.spi.ior.IORFactories ;
import com.sun.corba.se.spi.ior.IORTemplate ;
import com.sun.corba.se.spi.ior.IORTemplateList ;
import com.sun.corba.se.spi.ior.TaggedProfile ;
import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
import com.sun.corba.se.spi.orb.ORB ;
import com.sun.corba.se.spi.protocol.ForwardException ;
import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;

import com.sun.corba.se.impl.ior.POAObjectKeyTemplate ;
import com.sun.corba.se.impl.ior.ObjectAdapterIdArray ;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.concurrent.Sync ;
import com.sun.corba.se.impl.orbutil.concurrent.SyncUtil ;
import com.sun.corba.se.impl.orbutil.concurrent.ReentrantMutex ;
import com.sun.corba.se.impl.orbutil.concurrent.CondVar ;

/**
 * POAImpl is the implementation of the Portable Object Adapter. It
 * contains an implementation of the POA interfaces specified in
 * COBRA 2.3.1 chapter 11 (formal/99-10-07).  This implementation
 * is moving to comply with CORBA 3.0 due to the many clarifications
 * that have been made to the POA semantics since CORBA 2.3.1.
 * Specific comments have been added where 3.0 applies, but note that
 * we do not have the new 3.0 APIs yet.
 */
public class POAImpl extends ObjectAdapterBase implements POA
{
    private boolean debug ;

    /* POA creation takes place in 2 stages: first, the POAImpl constructor is
       called, then the initialize method is called.  This separation is
       needed because an AdapterActivator does not know the POAManager or
       the policies when
       the unknown_adapter method is invoked.  However, the POA must be created
       before the unknown_adapter method is invoked, so that the parent knows
       when concurrent attempts are made to create the same POA.
       Calling the POAImpl constructor results in a new POA in state STATE_START.
       Calling initialize( POAManager, Policies ) results in state STATE_RUN.
       Calling destroy results in STATE_DESTROY, which marks the beginning of
       POA destruction.
    */

    // Notes on concurrency.
    // The POA requires careful design for concurrency management to correctly
    // implement the specification and avoid deadlocks.  The order of acquiring
    // locks must respect the following locking hierarchy:
    //
    // 1. Lock POAs before POAManagers
    // 2. Lock a POA before locking its child POA
    //
    // Also note that there are 3 separate conditions on which threads may wait
    // in the POA, as defined by invokeCV, beingDestroyedCV, and
    // adapterActivatorCV.  This means that (for this reason as well as others)
    // we cannot simply use the standard Java synchronized primitive.
    // This implementation uses a modified version of Doug Lea's
    // util.concurrent (version 1.3.0) that supports reentrant
    // mutexes to handle the locking.  This will all be replaced by the new JSR
    // 166 concurrency primitives in J2SE 1.5 and later once the ORB moves to
    // J2SE 1.5.

    // POA state constants
    //
    // Note that ordering is important here: we must have the state defined in
    // this order so that ordered comparison is possible.
    // DO NOT CHANGE THE VALUES OF THE STATE CONSTANTS!!!  In particular, the
    // initialization related states must be lower than STATE_RUN.
    //
    // POA is created in STATE_START
    //
    // Valid state transitions:
    //
    // START to INIT                        after find_POA constructor call
    // START to RUN                         after initialize completes
    // INIT to INIT_DONE                    after initialize completes
    // INIT to DESTROYED                    after failed unknown_adapter
    // INIT_DONE to RUN                     after successful unknown_adapter
    // STATE_RUN to STATE_DESTROYING        after start of destruction
    // STATE_DESTROYING to STATE_DESTROYED  after destruction completes.

    private static final int STATE_START        = 0 ; // constructor complete
    private static final int STATE_INIT         = 1 ; // waiting for adapter activator
    private static final int STATE_INIT_DONE    = 2 ; // adapter activator called create_POA
    private static final int STATE_RUN          = 3 ; // initialized and running
    private static final int STATE_DESTROYING   = 4 ; // being destroyed
    private static final int STATE_DESTROYED    = 5 ; // destruction complete

    private String stateToString()
    {
        switch (state) {
            case STATE_START :
                return "START" ;
            case STATE_INIT :
                return "INIT" ;
            case STATE_INIT_DONE :
                return "INIT_DONE" ;
            case STATE_RUN :
                return "RUN" ;
            case STATE_DESTROYING :
                return "DESTROYING" ;
            case STATE_DESTROYED :
                return "DESTROYED" ;
            default :
                return "UNKNOWN(" + state + ")" ;
        }
    }

    // Current state of the POA
    private int state ;

    // The POA request handler that performs all policy specific operations
    // Note that POAImpl handles all synchronization, so mediator is (mostly)
    // unsynchronized.
    private POAPolicyMediator mediator;

    // Representation of object adapter ID
    private int numLevels;          // counts depth of tree.  Root = 1.
    private ObjectAdapterId poaId ; // the actual object adapter ID for this POA
    private String name;            // the name of this POA

    private POAManagerImpl manager; // This POA's POAManager
    private int uniquePOAId ;       // ID for this POA that is unique relative
                                    // to the POAFactory, which has the same
                                    // lifetime as the ORB.
    private POAImpl parent;         // The POA that created this POA.
    private Map children;           // Map from name to POA of POAs created by
                                    // this POA.

    private AdapterActivator activator;
    private int invocationCount ; // pending invocations on this POA.

    // Data used to control POA concurrency
    // XXX revisit for JSR 166

    // Master lock for all POA synchronization.  See lock and unlock.
    // package private for access by AOMEntry.
    Sync poaMutex ;

    // Wait on this CV for AdapterActivator upcalls to complete
    private CondVar adapterActivatorCV ;

    // Wait on this CV for all active invocations to complete
    private CondVar invokeCV ;

    // Wait on this CV for the destroy method to complete doing its work
    private CondVar beingDestroyedCV ;

    // thread local variable to store a boolean to detect deadlock in
    // POA.destroy().
    protected ThreadLocal isDestroying ;

    // This includes the most important information for debugging
    // POA problems.
    public String toString()
    {
        return "POA[" + poaId.toString() +
            ", uniquePOAId=" + uniquePOAId +
            ", state=" + stateToString() +
            ", invocationCount=" + invocationCount + "]" ;
    }

    // package private for mediator implementations.
    boolean getDebug()
    {
        return debug ;
    }

    // package private for access to servant to POA map
    static POAFactory getPOAFactory( ORB orb )
    {
        return (POAFactory)orb.getRequestDispatcherRegistry().
            getObjectAdapterFactory( ORBConstants.TRANSIENT_SCID ) ;
    }

    // package private so that POAFactory can access it.
    static POAImpl makeRootPOA( ORB orb )
    {
        POAManagerImpl poaManager = new POAManagerImpl( getPOAFactory( orb ),
            orb.getPIHandler() ) ;

        POAImpl result = new POAImpl( ORBConstants.ROOT_POA_NAME,
            null, orb, STATE_START ) ;
        result.initialize( poaManager, Policies.rootPOAPolicies ) ;

        return result ;
    }

    // package private so that POAPolicyMediatorBase can access it.
    int getPOAId()
    {
        return uniquePOAId ;
    }


    // package private so that POAPolicyMediator can access it.
    void lock()
    {
        SyncUtil.acquire( poaMutex ) ;

        if (debug) {
            ORBUtility.dprint( this, "LOCKED poa " + this ) ;
        }
    }

    // package private so that POAPolicyMediator can access it.
    void unlock()
    {
        if (debug) {
            ORBUtility.dprint( this, "UNLOCKED poa " + this ) ;
        }

        poaMutex.release() ;
    }

    // package private so that DelegateImpl can access it.
    Policies getPolicies()
    {
        return mediator.getPolicies() ;
    }

    // Note that the parent POA must be locked when this constructor is called.
    private POAImpl( String name, POAImpl parent, ORB orb, int initialState )
    {
        super( orb ) ;

        debug = orb.poaDebugFlag ;

        if (debug) {
            ORBUtility.dprint( this, "Creating POA with name=" + name +
                " parent=" + parent ) ;
        }

        this.state     = initialState ;
        this.name      = name ;
        this.parent    = parent;
        children = new HashMap();
        activator = null ;

        // This was done in initialize, but I moved it here
        // to get better searchability when tracing.
        uniquePOAId = getPOAFactory( orb ).newPOAId() ;

        if (parent == null) {
            // This is the root POA, which counts as 1 level
            numLevels = 1 ;
        } else {
            // My level is one more than that of my parent
            numLevels = parent.numLevels + 1 ;

            parent.children.put(name, this);
        }

        // Get an array of all of the POA names in order to
        // create the poaid.
        String[] names = new String[ numLevels ] ;
        POAImpl poaImpl = this ;
        int ctr = numLevels - 1 ;
        while (poaImpl != null) {
            names[ctr--] = poaImpl.name ;
            poaImpl = poaImpl.parent ;
        }

        poaId = new ObjectAdapterIdArray( names ) ;

        invocationCount = 0;

        poaMutex = new ReentrantMutex( orb.poaConcurrencyDebugFlag ) ;

        adapterActivatorCV = new CondVar( poaMutex,
            orb.poaConcurrencyDebugFlag ) ;
        invokeCV           = new CondVar( poaMutex,
            orb.poaConcurrencyDebugFlag ) ;
        beingDestroyedCV   = new CondVar( poaMutex,
            orb.poaConcurrencyDebugFlag ) ;

        isDestroying = new ThreadLocal () {
            protected java.lang.Object initialValue() {
                return Boolean.FALSE;
            }
        };
    }

    // The POA lock must be held when this method is called.
    private void initialize( POAManagerImpl manager, Policies policies )
    {
        if (debug) {
            ORBUtility.dprint( this, "Initializing poa " + this +
                " with POAManager=" + manager + " policies=" + policies ) ;
        }

        this.manager = manager;
        manager.addPOA(this);

        mediator = POAPolicyMediatorFactory.create( policies, this ) ;

        // Construct the object key template
        int serverid = mediator.getServerId() ;
        int scid = mediator.getScid() ;
        String orbId = getORB().getORBData().getORBId();

        ObjectKeyTemplate oktemp = new POAObjectKeyTemplate( getORB(),
            scid, serverid, orbId, poaId ) ;

        if (debug) {
            ORBUtility.dprint( this, "Initializing poa: oktemp=" + oktemp ) ;
        }

        // Note that parent == null iff this is the root POA.
        // This was used to avoid executing interceptors on the RootPOA.
        // That is no longer necessary.
        boolean objectAdapterCreated = true; // parent != null ;

        // XXX extract codebase from policies and pass into initializeTemplate
        // after the codebase policy change is finalized.
        initializeTemplate( oktemp, objectAdapterCreated,
                            policies,
                            null, // codebase
                            null, // manager id
                            oktemp.getObjectAdapterId()
                            ) ;

        if (state == STATE_START)
            state = STATE_RUN ;
        else if (state == STATE_INIT)
            state = STATE_INIT_DONE ;
        else
            throw lifecycleWrapper().illegalPoaStateTrans() ;
    }

    // The poaMutex must be held when this method is called
    private boolean waitUntilRunning()
    {
        if (debug) {
            ORBUtility.dprint( this,
                "Calling waitUntilRunning on poa " + this ) ;
        }

        while (state < STATE_RUN) {
            try {
                adapterActivatorCV.await() ;
            } catch (InterruptedException exc) {
                // NO-OP
            }
        }

        if (debug) {
            ORBUtility.dprint( this,
                "Exiting waitUntilRunning on poa " + this ) ;
        }

        // Note that a POA could be destroyed while in STATE_INIT due to a
        // failure in the AdapterActivator upcall.
        return (state == STATE_RUN) ;
    }

    // This method checks that the AdapterActivator finished the
    // initialization of a POA activated in find_POA.  This is
    // determined by checking the state of the POA.  If the state is
    // STATE_INIT, the AdapterActivator did not complete the
    // inialization.  In this case, we destroy the POA that was
    // partially created and return false.  Otherwise, we return true.
    // In any case, we must wake up all threads waiting for the adapter
    // activator, either to continue their invocations, or to return
    // errors to their client.
    //
    // The poaMutex must NOT be held when this method is called.
    private boolean destroyIfNotInitDone()
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling destroyIfNotInitDone on poa " + this ) ;
            }

            boolean success = (state == STATE_INIT_DONE) ;

            if (success)
                state = STATE_RUN ;
            else {
                // Don't just use destroy, because the check for
                // deadlock is too general, and can prevent this from
                // functioning properly.
                DestroyThread destroyer = new DestroyThread( false, debug );
                destroyer.doIt( this, true ) ;
            }

            return success ;
        } finally {
            adapterActivatorCV.broadcast() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting destroyIfNotInitDone on poa " + this ) ;
            }

            unlock() ;
        }
    }

    private byte[] internalReferenceToId(
        org.omg.CORBA.Object reference ) throws WrongAdapter
    {
        IOR ior = ORBUtility.getIOR( reference ) ;
        IORTemplateList thisTemplate = ior.getIORTemplates() ;

        ObjectReferenceFactory orf = getCurrentFactory() ;
        IORTemplateList poaTemplate =
            IORFactories.getIORTemplateList( orf ) ;

        if (!poaTemplate.isEquivalent( thisTemplate ))
            throw new WrongAdapter();

        // Extract the ObjectId from the first TaggedProfile in the IOR.
        // If ior was created in this POA, the same ID was used for
        // every profile through the profile templates in the currentFactory,
        // so we will get the same result from any profile.
        Iterator iter = ior.iterator() ;
        if (!iter.hasNext())
            throw iorWrapper().noProfilesInIor() ;
        TaggedProfile prof = (TaggedProfile)(iter.next()) ;
        ObjectId oid = prof.getObjectId() ;

        return oid.getId();
    }

    // Converted from anonymous class to local class
    // so that we can call performDestroy() directly.
    static class DestroyThread extends Thread {
        private boolean wait ;
        private boolean etherealize ;
        private boolean debug ;
        private POAImpl thePoa ;

        public DestroyThread( boolean etherealize, boolean debug )
        {
            this.etherealize = etherealize ;
            this.debug = debug ;
        }

        public void doIt( POAImpl thePoa, boolean wait )
        {
            if (debug) {
                ORBUtility.dprint( this,
                    "Calling DestroyThread.doIt(thePOA=" + thePoa +
                    " wait=" + wait + " etherealize=" + etherealize ) ;
            }

            this.thePoa = thePoa ;
            this.wait = wait ;

            if (wait) {
                run() ;
            } else {
                // Catch exceptions since setDaemon can cause a
                // security exception to be thrown under netscape
                // in the Applet mode
                try { setDaemon(true); } catch (Exception e) {}
                start() ;
            }
        }

        public void run()
        {
            Set destroyedPOATemplates = new HashSet() ;

            performDestroy( thePoa, destroyedPOATemplates );

            Iterator iter = destroyedPOATemplates.iterator() ;
            ObjectReferenceTemplate[] orts = new ObjectReferenceTemplate[
                destroyedPOATemplates.size() ] ;
            int index = 0 ;
            while (iter.hasNext())
                orts[ index++ ] = (ObjectReferenceTemplate)iter.next();

            thePoa.getORB().getPIHandler().adapterStateChanged( orts,
                NON_EXISTENT.value ) ;
        }

        // Returns true if destruction must be completed, false
        // if not, which means that another thread is already
        // destroying poa.
        private boolean prepareForDestruction( POAImpl poa,
            Set destroyedPOATemplates )
        {
            POAImpl[] childPoas = null ;

            // Note that we do not synchronize on this, since this is
            // the PerformDestroy instance, not the POA.
            try {
                poa.lock() ;

                if (debug) {
                    ORBUtility.dprint( this,
                        "Calling performDestroy on poa " + poa ) ;
                }

                if (poa.state <= STATE_RUN) {
                    poa.state = STATE_DESTROYING ;
                } else {
                    // destroy may be called multiple times, and each call
                    // is allowed to proceed with its own setting of the wait
                    // flag, but the etherealize value is used from the first
                    // call to destroy.  Also all children should be destroyed
                    // before the parent POA.  If the poa is already destroyed,
                    // we can just return.  If the poa has started destruction,
                    // but not completed, and wait is true, we need to wait
                    // until destruction is complete, then just return.
                    if (wait)
                        while (poa.state != STATE_DESTROYED) {
                            try {
                                poa.beingDestroyedCV.await() ;
                            } catch (InterruptedException exc) {
                                // NO-OP
                            }
                        }

                    return false ;
                }

                poa.isDestroying.set(Boolean.TRUE);

                // Make a copy since we can't hold the lock while destroying
                // the children, and an iterator is not deletion-safe.
                childPoas = (POAImpl[])poa.children.values().toArray(
                    new POAImpl[0] );
            } finally {
                poa.unlock() ;
            }

            // We are not holding the POA mutex here to avoid holding it
            // while destroying the POA's children, since this may involve
            // upcalls to etherealize methods.

            for (int ctr=0; ctr<childPoas.length; ctr++ ) {
                performDestroy( childPoas[ctr], destroyedPOATemplates ) ;
            }

            return true ;
        }

        public void performDestroy( POAImpl poa, Set destroyedPOATemplates )
        {
            if (!prepareForDestruction( poa, destroyedPOATemplates ))
                return ;

            // NOTE: If we are here, poa is in STATE_DESTROYING state. All
            // other state checks are taken care of in prepareForDestruction.
            // No other threads may either be starting new invocations
            // by calling enter or starting to destroy poa.  There may
            // still be pending invocations.

            POAImpl parent = poa.parent ;
            boolean isRoot = parent == null ;

            try {
                // Note that we must lock the parent before the child.
                // The parent lock is required (if poa is not the root)
                // to safely remove poa from parent's children Map.
                if (!isRoot)
                    parent.lock() ;

                try {
                    poa.lock() ;

                    completeDestruction( poa, parent,
                        destroyedPOATemplates ) ;
                } finally {
                    poa.unlock() ;

                    if (isRoot)
                        // We have just destroyed the root POA, so we need to
                        // make sure that the next call to
                        // resolve_initial_reference( "RootPOA" )
                        // will recreate a valid root POA.
                        poa.manager.getFactory().registerRootPOA() ;
                }
            } finally {
                if (!isRoot) {
                    parent.unlock() ;
                    poa.parent = null ;
                }
            }
        }

        private void completeDestruction( POAImpl poa, POAImpl parent,
            Set destroyedPOATemplates )
        {
            if (debug) {
                ORBUtility.dprint( this,
                    "Calling completeDestruction on poa " + poa ) ;
            }

            try {
                while (poa.invocationCount != 0) {
                    try {
                        poa.invokeCV.await() ;
                    } catch (InterruptedException ex) {
                        // NO-OP
                    }
                }

                if (poa.mediator != null) {
                    if (etherealize)
                        poa.mediator.etherealizeAll();

                    poa.mediator.clearAOM() ;
                }

                if (poa.manager != null)
                    poa.manager.removePOA(poa);

                if (parent != null)
                    parent.children.remove( poa.name ) ;

                destroyedPOATemplates.add( poa.getAdapterTemplate() ) ;
            } catch (Throwable thr) {
                if (thr instanceof ThreadDeath)
                    throw (ThreadDeath)thr ;

                poa.lifecycleWrapper().unexpectedException( thr, poa.toString() ) ;
            } finally {
                poa.state = STATE_DESTROYED ;
                poa.beingDestroyedCV.broadcast();
                poa.isDestroying.set(Boolean.FALSE);

                if (debug) {
                    ORBUtility.dprint( this,
                        "Exiting completeDestruction on poa " + poa ) ;
                }
            }
        }
    }

    void etherealizeAll()
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling etheralizeAll on poa " + this ) ;
            }

            mediator.etherealizeAll() ;
        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting etheralizeAll on poa " + this ) ;
            }

            unlock() ;
        }
    }

 //*******************************************************************
 // Public POA API
 //*******************************************************************

    /**
     * <code>create_POA
     * <b>Section 3.3.8.2
     */
    public POA create_POA(String name, POAManager
        theManager, Policy[] policies) throws AdapterAlreadyExists,
        InvalidPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling create_POA(name=" + name +
                    " theManager=" + theManager + " policies=" + policies +
                    ") on poa " + this ) ;
            }

            // We cannot create children of a POA that is (being) destroyed.
            // This has been added to the CORBA 3.0 spec.
            if (state > STATE_RUN)
                throw omgLifecycleWrapper().createPoaDestroy() ;

            POAImpl poa = (POAImpl)(children.get(name)) ;

            if (poa == null) {
                poa = new POAImpl( name, this, getORB(), STATE_START ) ;
            }

            try {
                poa.lock() ;

                if (debug) {
                    ORBUtility.dprint( this,
                        "Calling create_POA: new poa is " + poa ) ;
                }

                if ((poa.state != STATE_START) && (poa.state != STATE_INIT))
                    throw new AdapterAlreadyExists();

                POAManagerImpl newManager = (POAManagerImpl)theManager ;
                if (newManager == null)
                    newManager = new POAManagerImpl( manager.getFactory(),
                        manager.getPIHandler() );

                int defaultCopierId =
                    getORB().getCopierManager().getDefaultId() ;
                Policies POAPolicies =
                    new Policies( policies, defaultCopierId ) ;

                poa.initialize( newManager, POAPolicies ) ;

                return poa;
            } finally {
                poa.unlock() ;
            }
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>find_POA
     * <b>Section 3.3.8.3
     */
    public POA find_POA(String name, boolean activate)
        throws AdapterNonExistent
    {
        POAImpl found = null ;
        AdapterActivator act = null ;

        lock() ;

        if (debug) {
            ORBUtility.dprint( this, "Calling find_POA(name=" + name +
                " activate=" + activate + ") on poa " + this ) ;
        }

        found = (POAImpl) children.get(name);

        if (found != null) {
            if (debug) {
                ORBUtility.dprint( this,
                    "Calling find_POA: found poa " + found ) ;
            }

            try {
                found.lock() ;

                // Do not hold the parent POA lock while
                // waiting for child to complete initialization.
                unlock() ;

                // Make sure that the child has completed its initialization,
                // if it was created by an AdapterActivator, otherwise throw
                // a standard TRANSIENT exception with minor code 4 (see
                // CORBA 3.0 11.3.9.3, in reference to unknown_adapter)
                if (!found.waitUntilRunning())
                    throw omgLifecycleWrapper().poaDestroyed() ;

                // Note that found may be in state DESTROYING or DESTROYED at
                // this point.  That's OK, since destruction could start at
                // any time.
            } finally {
                found.unlock() ;
            }
        } else {
            try {
                if (debug) {
                    ORBUtility.dprint( this,
                        "Calling find_POA: no poa found" ) ;
                }

                if (activate && (activator != null)) {
                    // Create a child, but don't initialize it.  The newly
                    // created POA will be in state STATE_START, which will
                    // cause other calls to find_POA that are creating the same
                    // POA to block on the waitUntilRunning call above.
                    // Initialization must be completed by a call to create_POA
                    // inside the unknown_adapter upcall.  Note that
                    // this.poaMutex must be held here so that this.children
                    // can be safely updated.  The state is set to STATE_INIT
                    // so that initialize can make the correct state transition
                    // when create_POA is called inside the AdapterActivator.
                    // This avoids activating the new POA too soon
                    // by transitioning to STATE_RUN after unknown_adapter
                    // returns.
                    found = new POAImpl( name, this, getORB(), STATE_INIT ) ;

                    if (debug) {
                        ORBUtility.dprint( this,
                            "Calling find_POA: created poa " + found ) ;
                    }

                    act = activator ;
                } else {
                    throw new AdapterNonExistent();
                }
            } finally {
                unlock() ;
            }
        }

        // assert (found != null)
        // assert not holding this.poaMutex OR found.poaMutex

        // We must not hold either this.poaMutex or found.poaMutex here while
        // waiting for intialization of found to complete to prevent possible
        // deadlocks.

        if (act != null) {
            boolean status = false ;
            boolean adapterResult = false ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling find_POA: calling AdapterActivator"  ) ;
            }

            try {
                // Prevent more than one thread at a time from executing in act
                // in case act is shared between multiple POAs.
                synchronized (act) {
                    status = act.unknown_adapter(this, name);
                }
            } catch (SystemException exc) {
                throw omgLifecycleWrapper().adapterActivatorException( exc,
                    name, poaId.toString() ) ;
            } catch (Throwable thr) {
                // ignore most non-system exceptions, but log them for
                // diagnostic purposes.
                lifecycleWrapper().unexpectedException( thr, this.toString() ) ;

                if (thr instanceof ThreadDeath)
                    throw (ThreadDeath)thr ;
            } finally {
                // At this point, we have completed adapter activation.
                // Whether this was successful or not, we must call
                // destroyIfNotInitDone so that calls to enter() and create_POA()
                // that are waiting can execute again.  Failing to do this
                // will cause the system to hang in complex tests.
                adapterResult = found.destroyIfNotInitDone() ;
            }

            if (status) {
                if (!adapterResult)
                    throw omgLifecycleWrapper().adapterActivatorException( name,
                        poaId.toString() ) ;
            } else {
                if (debug) {
                    ORBUtility.dprint( this,
                        "Calling find_POA: AdapterActivator returned false"  ) ;
                }

                // OMG Issue 3740 is resolved to throw AdapterNonExistent if
                // unknown_adapter() returns false.
                throw new AdapterNonExistent();
            }
        }

        return found;
    }

    /**
     * <code>destroy
     * <b>Section 3.3.8.4
     */
    public void destroy(boolean etherealize, boolean wait_for_completion)
    {
        // This is to avoid deadlock
        if (wait_for_completion && getORB().isDuringDispatch()) {
            throw lifecycleWrapper().destroyDeadlock() ;
        }

        DestroyThread destroyer = new DestroyThread( etherealize, debug );
        destroyer.doIt( this, wait_for_completion ) ;
    }

    /**
     * <code>create_thread_policy
     * <b>Section 3.3.8.5
     */
    public ThreadPolicy create_thread_policy(
        ThreadPolicyValue value)
    {
        return new ThreadPolicyImpl(value);
    }

    /**
     * <code>create_lifespan_policy
     * <b>Section 3.3.8.5
     */
    public LifespanPolicy create_lifespan_policy(
        LifespanPolicyValue value)
    {
        return new LifespanPolicyImpl(value);
    }

    /**
     * <code>create_id_uniqueness_policy
     * <b>Section 3.3.8.5
     */
    public IdUniquenessPolicy create_id_uniqueness_policy(
        IdUniquenessPolicyValue value)
    {
        return new IdUniquenessPolicyImpl(value);
    }

    /**
     * <code>create_id_assignment_policy
     * <b>Section 3.3.8.5
     */
    public IdAssignmentPolicy create_id_assignment_policy(
        IdAssignmentPolicyValue value)
    {
        return new IdAssignmentPolicyImpl(value);
    }

    /**
     * <code>create_implicit_activation_policy
     * <b>Section 3.3.8.5
     */
    public ImplicitActivationPolicy create_implicit_activation_policy(
        ImplicitActivationPolicyValue value)
    {
        return new ImplicitActivationPolicyImpl(value);
    }

    /**
     * <code>create_servant_retention_policy
     * <b>Section 3.3.8.5
     */
    public ServantRetentionPolicy create_servant_retention_policy(
        ServantRetentionPolicyValue value)
    {
        return new ServantRetentionPolicyImpl(value);
    }

    /**
     * <code>create_request_processing_policy
     * <b>Section 3.3.8.5
     */
    public RequestProcessingPolicy create_request_processing_policy(
        RequestProcessingPolicyValue value)
    {
        return new RequestProcessingPolicyImpl(value);
    }

    /**
     * <code>the_name
     * <b>Section 3.3.8.6
     */
    public String the_name()
    {
        try {
            lock() ;

            return name;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>the_parent
     * <b>Section 3.3.8.7
     */
    public POA the_parent()
    {
        try {
            lock() ;

            return parent;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>the_children
     */
    public org.omg.PortableServer.POA[] the_children()
    {
        try {
            lock() ;

            Collection coll = children.values() ;
            int size = coll.size() ;
            POA[] result = new POA[ size ] ;
            int index = 0 ;
            Iterator iter = coll.iterator() ;
            while (iter.hasNext()) {
                POA poa = (POA)(iter.next()) ;
                result[ index++ ] = poa ;
            }

            return result ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>the_POAManager
     * <b>Section 3.3.8.8
     */
    public POAManager the_POAManager()
    {
        try {
            lock() ;

            return manager;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>the_activator
     * <b>Section 3.3.8.9
     */
    public AdapterActivator the_activator()
    {
        try {
            lock() ;

            return activator;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>the_activator
     * <b>Section 3.3.8.9
     */
    public void the_activator(AdapterActivator activator)
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling the_activator on poa " +
                    this + " activator=" + activator ) ;
            }

            this.activator = activator;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>get_servant_manager
     * <b>Section 3.3.8.10
     */
    public ServantManager get_servant_manager() throws WrongPolicy
    {
        try {
            lock() ;

            return mediator.getServantManager() ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>set_servant_manager
     * <b>Section 3.3.8.10
     */
    public void set_servant_manager(ServantManager servantManager)
        throws WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling set_servant_manager on poa " +
                    this + " servantManager=" + servantManager ) ;
            }

            mediator.setServantManager( servantManager ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>get_servant
     * <b>Section 3.3.8.12
     */
    public Servant get_servant() throws NoServant, WrongPolicy
    {
        try {
            lock() ;

            return mediator.getDefaultServant() ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>set_servant
     * <b>Section 3.3.8.13
     */
    public void set_servant(Servant defaultServant)
        throws WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling set_servant on poa " +
                    this + " defaultServant=" + defaultServant ) ;
            }

            mediator.setDefaultServant( defaultServant ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>activate_object
     * <b>Section 3.3.8.14
     */
    public byte[] activate_object(Servant servant)
        throws ServantAlreadyActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling activate_object on poa " + this +
                    " (servant=" + servant + ")" ) ;
            }

            // Allocate a new system-generated object-id.
            // This will throw WrongPolicy if not SYSTEM_ID
            // policy.
            byte[] id = mediator.newSystemId();

            try {
                mediator.activateObject( id, servant ) ;
            } catch (ObjectAlreadyActive oaa) {
                // This exception can not occur in this case,
                // since id is always brand new.
                //
            }

            return id ;
        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting activate_object on poa " + this ) ;
            }

            unlock() ;
        }
    }

    /**
     * <code>activate_object_with_id
     * <b>Section 3.3.8.15
     */
    public void activate_object_with_id(byte[] id,
                                                     Servant servant)
        throws ObjectAlreadyActive, ServantAlreadyActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling activate_object_with_id on poa " + this +
                    " (servant=" + servant + " id=" + id + ")" ) ;
            }

            // Clone the id to avoid possible errors due to aliasing
            // (e.g. the client passes the id in and then changes it later).
            byte[] idClone = (byte[])(id.clone()) ;

            mediator.activateObject( idClone, servant ) ;
        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting activate_object_with_id on poa " + this ) ;
            }

            unlock() ;
        }
    }

    /**
     * <code>deactivate_object
     * <b>3.3.8.16
     */
    public void deactivate_object(byte[] id)
        throws ObjectNotActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling deactivate_object on poa " + this +
                    " (id=" + id + ")" ) ;
            }

            mediator.deactivateObject( id ) ;
        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting deactivate_object on poa " + this ) ;
            }

            unlock() ;
        }
    }

    /**
     * <code>create_reference
     * <b>3.3.8.17
     */
    public org.omg.CORBA.Object create_reference(String repId)
        throws WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling create_reference(repId=" +
                    repId + ") on poa " + this ) ;
            }

            return makeObject( repId, mediator.newSystemId()) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>create_reference_with_id
     * <b>3.3.8.18
     */
    public org.omg.CORBA.Object
        create_reference_with_id(byte[] oid, String repId)
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling create_reference_with_id(oid=" +
                    oid + " repId=" + repId + ") on poa " + this ) ;
            }

            // Clone the id to avoid possible errors due to aliasing
            // (e.g. the client passes the id in and then changes it later).
            byte[] idClone = (byte[])(oid.clone()) ;

            return makeObject( repId, idClone ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>servant_to_id
     * <b>3.3.8.19
     */
    public byte[] servant_to_id(Servant servant)
        throws ServantNotActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling servant_to_id(servant=" +
                    servant + ") on poa " + this ) ;
            }

            return mediator.servantToId( servant ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>servant_to_reference
     * <b>3.3.8.20
     */
    public org.omg.CORBA.Object servant_to_reference(Servant servant)
        throws ServantNotActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling servant_to_reference(servant=" +
                    servant + ") on poa " + this ) ;
            }

            byte[] oid = mediator.servantToId(servant);
            String repId = servant._all_interfaces( this, oid )[0] ;
            return create_reference_with_id(oid, repId);
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>reference_to_servant
     * <b>3.3.8.21
     */
    public Servant reference_to_servant(org.omg.CORBA.Object reference)
        throws ObjectNotActive, WrongPolicy, WrongAdapter
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling reference_to_servant(reference=" +
                    reference + ") on poa " + this ) ;
            }

            if ( state >= STATE_DESTROYING ) {
                throw lifecycleWrapper().adapterDestroyed() ;
            }

            // reference_to_id should throw WrongAdapter
            // if the objref was not created by this POA
            byte [] id = internalReferenceToId(reference);

            return mediator.idToServant( id ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>reference_to_id
     * <b>3.3.8.22
     */
    public byte[] reference_to_id(org.omg.CORBA.Object reference)
        throws WrongAdapter, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling reference_to_id(reference=" +
                    reference + ") on poa " + this ) ;
            }

            if( state >= STATE_DESTROYING ) {
                throw lifecycleWrapper().adapterDestroyed() ;
            }

            return internalReferenceToId( reference ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>id_to_servant
     * <b>3.3.8.23
     */
    public Servant id_to_servant(byte[] id)
        throws ObjectNotActive, WrongPolicy
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling id_to_servant(id=" +
                    id + ") on poa " + this ) ;
            }

            if( state >= STATE_DESTROYING ) {
                throw lifecycleWrapper().adapterDestroyed() ;
            }
            return mediator.idToServant( id ) ;
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>id_to_reference
     * <b>3.3.8.24
     */
    public org.omg.CORBA.Object id_to_reference(byte[] id)
        throws ObjectNotActive, WrongPolicy

    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling id_to_reference(id=" +
                    id + ") on poa " + this ) ;
            }

            if( state >= STATE_DESTROYING ) {
                throw lifecycleWrapper().adapterDestroyed() ;
            }

            Servant s = mediator.idToServant( id ) ;
            String repId = s._all_interfaces( this, id )[0] ;
            return makeObject(repId, id );
        } finally {
            unlock() ;
        }
    }

    /**
     * <code>id
     * <b>11.3.8.26 in ptc/00-08-06
     */
    public byte[] id()
    {
        try {
            lock() ;

            return getAdapterId() ;
        } finally {
            unlock() ;
        }
    }

    //***************************************************************
    //Implementation of ObjectAdapter interface
    //***************************************************************

    public Policy getEffectivePolicy( int type )
    {
        return mediator.getPolicies().get_effective_policy( type ) ;
    }

    public int getManagerId()
    {
        return manager.getManagerId() ;
    }

    public short getState()
    {
        return manager.getORTState() ;
    }

    public String[] getInterfaces( java.lang.Object servant, byte[] objectId )
    {
        Servant serv = (Servant)servant ;
        return serv._all_interfaces( this, objectId ) ;
    }

    protected ObjectCopierFactory getObjectCopierFactory()
    {
        int copierId = mediator.getPolicies().getCopierId() ;
        CopierManager cm = getORB().getCopierManager() ;
        return cm.getObjectCopierFactory( copierId ) ;
    }

    public void enter() throws OADestroyed
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling enter on poa " + this ) ;
            }

            // Avoid deadlock if this is the thread that is processing the
            // POA.destroy because this is the only thread that can notify
            // waiters on beingDestroyedCV.  This can happen if an
            // etherealize upcall invokes a method on a colocated object
            // served by this POA.
            while ((state == STATE_DESTROYING) &&
                (isDestroying.get() == Boolean.FALSE)) {
                try {
                    beingDestroyedCV.await();
                } catch (InterruptedException ex) {
                    // NO-OP
                }
            }

            if (!waitUntilRunning())
                throw new OADestroyed() ;

            invocationCount++;
        } finally {
            if (debug) {
                ORBUtility.dprint( this, "Exiting enter on poa " + this ) ;
            }

            unlock() ;
        }

        manager.enter();
    }

    public void exit()
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this, "Calling exit on poa " + this ) ;
            }

            invocationCount--;

            if ((invocationCount == 0) && (state == STATE_DESTROYING)) {
                invokeCV.broadcast();
            }
        } finally {
            if (debug) {
                ORBUtility.dprint( this, "Exiting exit on poa " + this ) ;
            }

            unlock() ;
        }

        manager.exit();
    }

    public void getInvocationServant( OAInvocationInfo info )
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling getInvocationServant on poa " + this ) ;
            }

            java.lang.Object servant = null ;

            try {
                servant = mediator.getInvocationServant( info.id(),
                    info.getOperation() );
            } catch (ForwardRequest freq) {
                throw new ForwardException( getORB(), freq.forward_reference ) ;
            }

            info.setServant( servant ) ;
        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting getInvocationServant on poa " + this ) ;
            }

            unlock() ;
        }
    }

    public org.omg.CORBA.Object getLocalServant( byte[] objectId )
    {
        return null ;
    }

    /** Called from the subcontract to let this POA cleanup after an
     *  invocation. Note: If getServant was called, then returnServant
     *  MUST be called, even in the case of exceptions.  This may be
     *  called multiple times for a single request.
     */
    public void returnServant()
    {
        try {
            lock() ;

            if (debug) {
                ORBUtility.dprint( this,
                    "Calling returnServant on poa " + this  ) ;
            }

            mediator.returnServant();
        } catch (Throwable thr) {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exception " + thr + " in returnServant on poa " + this  ) ;
            }

            if (thr instanceof Error)
                throw (Error)thr ;
            else if (thr instanceof RuntimeException)
                throw (RuntimeException)thr ;

        } finally {
            if (debug) {
                ORBUtility.dprint( this,
                    "Exiting returnServant on poa " + this  ) ;
            }

            unlock() ;
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java POAImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.