/*
 * Copyright (c) 1997, 2002, 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.
 */

//

module activation {
    // Possible values for endpointType argument on Server.getEndpoint()
    // If you change the value of this constant then update
    // core.EndPoint accordingly.  It has a duplicate definition
    // to avoid a compilation dependency.
    const string IIOP_CLEAR_TEXT = "IIOP_CLEAR_TEXT";

    // REVISIT Use the CORBA 2.3 ORBid if we ever get the Java ORB ID
    // issue resolved.
    typedef string ORBid;
    typedef long ServerId ;
    typedef sequence<string> POAName ;

    /** Raised if getEndpoint is called on a server callback object for
    * an invalid endpoint type
    */
    exception NoSuchEndPoint {} ;

    /**
    * Raised if an attempt is made to retrieve ports corresponding to
    * non-registered ORB
    */

    exception InvalidORBid {} ;

    /** Raised if an operation is attempted against an invalid server ID.
    */
    exception ServerNotRegistered {
	ServerId serverId ;
    };

    /** Raised if an operation is attempted for a server that is not running,
    * and the server is required to be running for the operation.
    */
    exception ServerNotActive {
	ServerId serverId ;
    };

    /** Raised if an operation is attempted against a server that is in a 
    * hold down state.  A server becomes held down if it fails to activate
    * within 10 seconds.
    */
    exception ServerHeldDown {
	ServerId serverId ;
    };

    /** Raised if an attempt is made to activate a server that is already 
    * running.
    */
    exception ServerAlreadyActive{
	ServerId serverId ;
    };

    /** Raised if an attempt is made to register a serverdef with the
    * same applicationName as an existing serverdef.
    */
    exception ServerAlreadyRegistered {
	ServerId serverId;
    };

    /** Raised if an attempt is made to install a server that is currently 
    * installed.  Note that a newly created server starts out in an uninstalled
    * state.
    */
    exception ServerAlreadyInstalled {
	ServerId serverId;
    } ;

    /** Raised if an attempt is made to uninstall a server that is currently 
    * uninstalled.  Note that a newly created server starts out in an 
    * uninstalled
    * state.
    */
    exception ServerAlreadyUninstalled {
	ServerId serverId;
    } ;

    /** Raised if an attempt is made to register an invalid serverdef.
    */
    exception BadServerDefinition {
	string reason;
    };

    /** Raised if an attempt is made to register endpoints for the
     * same ORB again
     */
    exception ORBAlreadyRegistered {
	ORBid orbId;
    };

    typedef long TCPPort ;
    typedef sequence<ServerId> ServerIds;

    // passing a struct containing endpointType and port-#s
    struct EndPointInfo {
	string endpointType;
	TCPPort port;
    };

    typedef sequence<EndPointInfo> EndpointInfoList;

    // struct contain ORB and port info
    struct ORBPortInfo {
	ORBid orbId;
	TCPPort port;
    };

    typedef sequence<ORBPortInfo> ORBPortInfoList;

    typedef sequence<ORBid> ORBidList;

    /** Server callback API, passed to Activator in active method.
    */
    interface Server {
	/** Shutdown this server.  Returns after orb.shutdown() completes.
	*/
	void shutdown();

	/** Install the server.  Returns after the install hook completes
	* execution in the server.
	*/
	void install();

	/** Uninstall the server.  Returns after the uninstall hook
	* completes execution.
	*/
	void uninstall();
    };

    interface Activator {
    	// A new ORB started server registers itself with the Activator
    	void active(in ServerId serverId, in Server serverObj) 
	    raises (ServerNotRegistered);

	// Install a particular kind of endpoint
	void registerEndpoints( in ServerId serverId, in ORBid orbId, 
	    in EndpointInfoList endPointInfo) 
	    raises (ServerNotRegistered,NoSuchEndPoint, ORBAlreadyRegistered) ;

        // list active servers
	ServerIds getActiveServers();

	// If the server is not running, start it up.
	void activate(in ServerId serverId) 
	    raises (ServerAlreadyActive, ServerNotRegistered, ServerHeldDown);

	// If the server is running, shut it down
	void shutdown(in ServerId serverId) 
	    raises (ServerNotActive, ServerNotRegistered);

	// Invoke the server install hook.  If the server is not 
	// currently running, this method will activate it.
	void install(in ServerId serverId) 
	    raises (ServerNotRegistered, ServerHeldDown, 
		ServerAlreadyInstalled);

	// list all registered ORBs for a server
	ORBidList getORBNames(in ServerId serverId)
	    raises (ServerNotRegistered);

	// Invoke the server uninstall hook.  If the server is not
	// currently running, this method will activate it.
	// After this hook completes, the server may still be running.
	void uninstall(in ServerId serverId) 
	    raises (ServerNotRegistered, ServerHeldDown, 
		ServerAlreadyUninstalled);
    };

    interface Locator {

	// struct to return the list of endpoints for a server for a specific
	// endpoint
	struct ServerLocation {
	    string hostname;
	    ORBPortInfoList ports;
        };

	// struct to return the list of endpoints for a server for a specific
	// ORB
	struct ServerLocationPerORB {
	    string hostname;
	    EndpointInfoList ports;
        };

	// locate server - returns the port with a specific type for all registered
	// ORBs of an active server.
	// Starts the server if it is not already running.
	ServerLocation locateServer(
	    in ServerId serverId,
	    in string endPoint) 
	    raises(NoSuchEndPoint, ServerNotRegistered, ServerHeldDown);

	// locate server - returns all ports registered with a specified ORB for
	// an active server
	// Starts the server if it is not already running.
	ServerLocationPerORB locateServerForORB(
	    in ServerId serverId,
	    in ORBid orbId) 
	    raises(InvalidORBid, ServerNotRegistered, ServerHeldDown);

	// get the port for the endpoint of the locator
	TCPPort getEndpoint(in string endPointType)
	    raises(NoSuchEndPoint);

	// Useful from external BadServerIdHandlers which need
	// to pick a particular port type.
	TCPPort getServerPortForType(
            in ServerLocationPerORB location,
	    in string endPointType)
	    raises(NoSuchEndPoint);
    };

    interface ServerManager : Activator, Locator { };

    interface InitialNameService {
	exception NameAlreadyBound {};

	// bind initial name
	void bind (
	    in string name,
	    in Object obj,
	    in boolean isPersistant) raises (NameAlreadyBound);

    };

    interface Repository {
	// server program definition.  We should make this a ValueType.
	struct ServerDef {
	    string  applicationName;	// alias used for servers with identical
					// serverName values.
	    string  serverName;		// Class name of server's main class.
	    string  serverClassPath;	// class path used to run the server.
	    string  serverArgs;		
	    string  serverVmArgs;
	};
	
	// register server definition
	// This returns the serverId of the server.  A newly created server is
	// always uninstalled.
	ServerId registerServer (in ServerDef serverDef) 
	    raises (ServerAlreadyRegistered, BadServerDefinition);
	
	// unregister server definition
	void unregisterServer (in ServerId serverId) 
	    raises (ServerNotRegistered);

	// get server definition
	ServerDef getServer(in ServerId serverId) 
	    raises (ServerNotRegistered);

	// Return whether the server has been installed
	boolean isInstalled( in ServerId serverId ) 
	    raises (ServerNotRegistered);

	// Mark the server as being installed.  Raises ServerAlreadyInstalled
	// if the server is currently marked as installed.
	void install( in ServerId serverId ) 
	    raises (ServerNotRegistered, ServerAlreadyInstalled) ;

	// Mark the server as being uninstalled.  Raises ServerAlreadyUninstalled
	// if the server is currently marked as uninstalled.
	void uninstall( in ServerId serverId ) 
	    raises (ServerNotRegistered, ServerAlreadyUninstalled) ;

	// list registered servers
	ServerIds listRegisteredServers ();

	typedef sequence<string>    StringSeq ;

	// Returns list of ALL applicationNames defined in ServerDefs of registered 
	// servers.
	StringSeq   getApplicationNames();

	// Find the ServerID associated with the given application name.
	ServerId getServerID( in string applicationName ) 
		raises (ServerNotRegistered) ;
    };
};
