/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2008 OMC Denmark ApS.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "poa_utils.h"
#include "macros.h"

PortableServer::POA_ptr create_poa(const char *Name,
				   PortableServer::POAManager_ptr PoaManager,
				   PortableServer::POA_ptr Poa)
{
        unsigned int pol_len = 7;
        PortableServer::POA_var retval = PortableServer::POA::_nil();

        CORBA::PolicyList pl(pol_len);
        pl.length(pol_len);
        pl[0] = Poa->create_lifespan_policy(PortableServer::TRANSIENT);
        pl[1] = Poa->create_id_assignment_policy(PortableServer::SYSTEM_ID);
        pl[2] = Poa->create_id_uniqueness_policy(PortableServer::UNIQUE_ID);
        pl[3] = Poa->create_implicit_activation_policy(PortableServer::NO_IMPLICIT_ACTIVATION);
        pl[4] = Poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL);
        pl[5] = Poa->create_request_processing_policy(PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY);
        pl[6] = Poa->create_servant_retention_policy(PortableServer::RETAIN);

        try {
                retval = Poa->create_POA(Name, PoaManager, pl);
        }
        catch (PortableServer::POA::AdapterAlreadyExists &e) {
                ACE_DEBUG((LM_CRITICAL, ACE_TEXT("%N:%l - %s\n"), e._info().c_str()));
                for (unsigned int n = 0; n < pol_len; n++)
                        pl[n]->destroy();

                throw; // re-throw to caller
        }
        catch (const CORBA::Exception &e) {
                ACE_DEBUG((LM_CRITICAL, ACE_TEXT("%N:%l - %s\n"), e._info().c_str()));
                throw;
        }
        catch (...) {
                ACE_DEBUG((LM_CRITICAL, ACE_TEXT("%N:%l - Unknown C++ exception\n")));
                for (unsigned int n = 0; n < pol_len; n++)
                        pl[n]->destroy();

                return PortableServer::POA::_nil();
        }
        for (unsigned int n = 0; n < pol_len; n++)
                pl[n]->destroy();

        return retval._retn();
}
